1*5900e8ecSAndrew Rist /**************************************************************
2*5900e8ecSAndrew Rist *
3*5900e8ecSAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4*5900e8ecSAndrew Rist * or more contributor license agreements. See the NOTICE file
5*5900e8ecSAndrew Rist * distributed with this work for additional information
6*5900e8ecSAndrew Rist * regarding copyright ownership. The ASF licenses this file
7*5900e8ecSAndrew Rist * to you under the Apache License, Version 2.0 (the
8*5900e8ecSAndrew Rist * "License"); you may not use this file except in compliance
9*5900e8ecSAndrew Rist * with the License. You may obtain a copy of the License at
10*5900e8ecSAndrew Rist *
11*5900e8ecSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*5900e8ecSAndrew Rist *
13*5900e8ecSAndrew Rist * Unless required by applicable law or agreed to in writing,
14*5900e8ecSAndrew Rist * software distributed under the License is distributed on an
15*5900e8ecSAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*5900e8ecSAndrew Rist * KIND, either express or implied. See the License for the
17*5900e8ecSAndrew Rist * specific language governing permissions and limitations
18*5900e8ecSAndrew Rist * under the License.
19*5900e8ecSAndrew Rist *
20*5900e8ecSAndrew Rist *************************************************************/
21*5900e8ecSAndrew Rist
22*5900e8ecSAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svtools.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir #ifdef UNX
28cdf0e10cSrcweir #include <pwd.h>
29cdf0e10cSrcweir #include <sys/types.h>
30cdf0e10cSrcweir #endif
31cdf0e10cSrcweir
32cdf0e10cSrcweir #include <svtools/inettbc.hxx>
33cdf0e10cSrcweir #include <com/sun/star/uno/Any.hxx>
34cdf0e10cSrcweir #include <com/sun/star/uno/Reference.hxx>
35cdf0e10cSrcweir #include <com/sun/star/beans/PropertyValue.hpp>
36cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
37cdf0e10cSrcweir #include <com/sun/star/sdbc/XResultSet.hpp>
38cdf0e10cSrcweir #include <com/sun/star/sdbc/XRow.hpp>
39cdf0e10cSrcweir #include <com/sun/star/task/XInteractionHandler.hpp>
40cdf0e10cSrcweir #include <com/sun/star/ucb/NumberedSortingInfo.hpp>
41cdf0e10cSrcweir #include <com/sun/star/ucb/XAnyCompareFactory.hpp>
42cdf0e10cSrcweir #include <com/sun/star/ucb/XProgressHandler.hpp>
43cdf0e10cSrcweir #include <com/sun/star/ucb/XContentAccess.hpp>
44cdf0e10cSrcweir #include <com/sun/star/ucb/XSortedDynamicResultSetFactory.hpp>
45cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
46cdf0e10cSrcweir #include <vcl/toolbox.hxx>
47cdf0e10cSrcweir #include <vos/thread.hxx>
48cdf0e10cSrcweir #include <vos/mutex.hxx>
49cdf0e10cSrcweir #include <vcl/svapp.hxx>
50cdf0e10cSrcweir #include <unotools/historyoptions.hxx>
51cdf0e10cSrcweir #include <svl/eitem.hxx>
52cdf0e10cSrcweir #include <svl/stritem.hxx>
53cdf0e10cSrcweir #include <svl/itemset.hxx>
54cdf0e10cSrcweir #include "svl/urihelper.hxx"
55cdf0e10cSrcweir #include <unotools/pathoptions.hxx>
56cdf0e10cSrcweir
57cdf0e10cSrcweir #define _SVSTDARR_STRINGSDTOR
58cdf0e10cSrcweir #include <svl/svstdarr.hxx>
59cdf0e10cSrcweir #include <ucbhelper/commandenvironment.hxx>
60cdf0e10cSrcweir #include <ucbhelper/content.hxx>
61cdf0e10cSrcweir #include <unotools/localfilehelper.hxx>
62cdf0e10cSrcweir #include <unotools/ucbhelper.hxx>
63cdf0e10cSrcweir #include "iodlg.hrc"
64cdf0e10cSrcweir #include <svtools/asynclink.hxx>
65cdf0e10cSrcweir #include <svl/urlfilter.hxx>
66cdf0e10cSrcweir
67cdf0e10cSrcweir #include <vector>
68cdf0e10cSrcweir #include <algorithm>
69cdf0e10cSrcweir
70cdf0e10cSrcweir // -----------------------------------------------------------------------
71cdf0e10cSrcweir
72cdf0e10cSrcweir using namespace ::rtl;
73cdf0e10cSrcweir using namespace ::ucbhelper;
74cdf0e10cSrcweir using namespace ::utl;
75cdf0e10cSrcweir using namespace ::com::sun::star;
76cdf0e10cSrcweir using namespace ::com::sun::star::beans;
77cdf0e10cSrcweir using namespace ::com::sun::star::lang;
78cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
79cdf0e10cSrcweir using namespace ::com::sun::star::task;
80cdf0e10cSrcweir using namespace ::com::sun::star::ucb;
81cdf0e10cSrcweir using namespace ::com::sun::star::uno;
82cdf0e10cSrcweir
83cdf0e10cSrcweir // -----------------------------------------------------------------------
84cdf0e10cSrcweir class SvtURLBox_Impl
85cdf0e10cSrcweir {
86cdf0e10cSrcweir public:
87cdf0e10cSrcweir SvStringsDtor* pURLs;
88cdf0e10cSrcweir SvStringsDtor* pCompletions;
89cdf0e10cSrcweir const IUrlFilter* pUrlFilter;
90cdf0e10cSrcweir ::std::vector< WildCard > m_aFilters;
91cdf0e10cSrcweir
92cdf0e10cSrcweir static sal_Bool TildeParsing( String& aText, String& aBaseUrl );
93cdf0e10cSrcweir
SvtURLBox_Impl()94cdf0e10cSrcweir inline SvtURLBox_Impl( )
95cdf0e10cSrcweir :pURLs( NULL )
96cdf0e10cSrcweir ,pCompletions( NULL )
97cdf0e10cSrcweir ,pUrlFilter( NULL )
98cdf0e10cSrcweir {
99cdf0e10cSrcweir FilterMatch::createWildCardFilterList(String(),m_aFilters);
100cdf0e10cSrcweir }
101cdf0e10cSrcweir };
102cdf0e10cSrcweir
103cdf0e10cSrcweir // -----------------------------------------------------------------------
104cdf0e10cSrcweir class SvtMatchContext_Impl : public ::vos::OThread
105cdf0e10cSrcweir {
106cdf0e10cSrcweir static ::vos::OMutex* pDirMutex;
107cdf0e10cSrcweir
108cdf0e10cSrcweir SvStringsDtor aPickList;
109cdf0e10cSrcweir SvStringsDtor* pCompletions;
110cdf0e10cSrcweir SvStringsDtor* pURLs;
111cdf0e10cSrcweir svtools::AsynchronLink aLink;
112cdf0e10cSrcweir String aBaseURL;
113cdf0e10cSrcweir String aText;
114cdf0e10cSrcweir SvtURLBox* pBox;
115cdf0e10cSrcweir sal_Bool bStop;
116cdf0e10cSrcweir sal_Bool bOnlyDirectories;
117cdf0e10cSrcweir sal_Bool bNoSelection;
118cdf0e10cSrcweir
119cdf0e10cSrcweir DECL_STATIC_LINK( SvtMatchContext_Impl, Select_Impl, void* );
120cdf0e10cSrcweir
121cdf0e10cSrcweir virtual void SAL_CALL onTerminated( );
122cdf0e10cSrcweir virtual void SAL_CALL run();
123cdf0e10cSrcweir virtual void SAL_CALL Cancel();
124cdf0e10cSrcweir void Insert( const String& rCompletion, const String& rURL, sal_Bool bForce = sal_False);
125cdf0e10cSrcweir void ReadFolder( const String& rURL, const String& rMatch, sal_Bool bSmart );
126cdf0e10cSrcweir void FillPicklist( SvStringsDtor& rPickList );
127cdf0e10cSrcweir
128cdf0e10cSrcweir public:
129cdf0e10cSrcweir static ::vos::OMutex* GetMutex();
130cdf0e10cSrcweir
131cdf0e10cSrcweir SvtMatchContext_Impl( SvtURLBox* pBoxP, const String& rText );
132cdf0e10cSrcweir ~SvtMatchContext_Impl();
133cdf0e10cSrcweir void Stop();
134cdf0e10cSrcweir };
135cdf0e10cSrcweir
136cdf0e10cSrcweir ::vos::OMutex* SvtMatchContext_Impl::pDirMutex = 0;
137cdf0e10cSrcweir
GetMutex()138cdf0e10cSrcweir ::vos::OMutex* SvtMatchContext_Impl::GetMutex()
139cdf0e10cSrcweir {
140cdf0e10cSrcweir ::vos::OGuard aGuard( ::vos::OMutex::getGlobalMutex() );
141cdf0e10cSrcweir if( !pDirMutex )
142cdf0e10cSrcweir pDirMutex = new ::vos::OMutex;
143cdf0e10cSrcweir return pDirMutex;
144cdf0e10cSrcweir }
145cdf0e10cSrcweir
146cdf0e10cSrcweir //-------------------------------------------------------------------------
SvtMatchContext_Impl(SvtURLBox * pBoxP,const String & rText)147cdf0e10cSrcweir SvtMatchContext_Impl::SvtMatchContext_Impl(
148cdf0e10cSrcweir SvtURLBox* pBoxP, const String& rText )
149cdf0e10cSrcweir : aLink( STATIC_LINK( this, SvtMatchContext_Impl, Select_Impl ) )
150cdf0e10cSrcweir , aBaseURL( pBoxP->aBaseURL )
151cdf0e10cSrcweir , aText( rText )
152cdf0e10cSrcweir , pBox( pBoxP )
153cdf0e10cSrcweir , bStop( sal_False )
154cdf0e10cSrcweir , bOnlyDirectories( pBoxP->bOnlyDirectories )
155cdf0e10cSrcweir , bNoSelection( pBoxP->bNoSelection )
156cdf0e10cSrcweir {
157cdf0e10cSrcweir pURLs = new SvStringsDtor;
158cdf0e10cSrcweir pCompletions = new SvStringsDtor;
159cdf0e10cSrcweir
160cdf0e10cSrcweir aLink.CreateMutex();
161cdf0e10cSrcweir
162cdf0e10cSrcweir FillPicklist( aPickList );
163cdf0e10cSrcweir
164cdf0e10cSrcweir create();
165cdf0e10cSrcweir }
166cdf0e10cSrcweir
167cdf0e10cSrcweir //-------------------------------------------------------------------------
~SvtMatchContext_Impl()168cdf0e10cSrcweir SvtMatchContext_Impl::~SvtMatchContext_Impl()
169cdf0e10cSrcweir {
170cdf0e10cSrcweir aLink.ClearPendingCall();
171cdf0e10cSrcweir delete pURLs;
172cdf0e10cSrcweir delete pCompletions;
173cdf0e10cSrcweir }
174cdf0e10cSrcweir
175cdf0e10cSrcweir //-------------------------------------------------------------------------
FillPicklist(SvStringsDtor & rPickList)176cdf0e10cSrcweir void SvtMatchContext_Impl::FillPicklist( SvStringsDtor& rPickList )
177cdf0e10cSrcweir {
178cdf0e10cSrcweir // Einlesung der Historypickliste
179cdf0e10cSrcweir Sequence< Sequence< PropertyValue > > seqPicklist = SvtHistoryOptions().GetList( eHISTORY );
180cdf0e10cSrcweir sal_uInt32 nCount = seqPicklist.getLength();
181cdf0e10cSrcweir
182cdf0e10cSrcweir for( sal_uInt32 nItem=0; nItem < nCount; nItem++ )
183cdf0e10cSrcweir {
184cdf0e10cSrcweir Sequence< PropertyValue > seqPropertySet = seqPicklist[ nItem ];
185cdf0e10cSrcweir
186cdf0e10cSrcweir OUString sTitle;
187cdf0e10cSrcweir INetURLObject aURL;
188cdf0e10cSrcweir
189cdf0e10cSrcweir sal_uInt32 nPropertyCount = seqPropertySet.getLength();
190cdf0e10cSrcweir
191cdf0e10cSrcweir for( sal_uInt32 nProperty=0; nProperty < nPropertyCount; nProperty++ )
192cdf0e10cSrcweir {
193cdf0e10cSrcweir if( seqPropertySet[nProperty].Name == HISTORY_PROPERTYNAME_TITLE )
194cdf0e10cSrcweir {
195cdf0e10cSrcweir seqPropertySet[nProperty].Value >>= sTitle;
196cdf0e10cSrcweir aURL.SetURL( sTitle );
197cdf0e10cSrcweir const StringPtr pStr = new String( aURL.GetMainURL( INetURLObject::DECODE_WITH_CHARSET ) );
198cdf0e10cSrcweir rPickList.Insert( pStr, (sal_uInt16) nItem );
199cdf0e10cSrcweir break;
200cdf0e10cSrcweir }
201cdf0e10cSrcweir }
202cdf0e10cSrcweir }
203cdf0e10cSrcweir }
204cdf0e10cSrcweir
205cdf0e10cSrcweir //-------------------------------------------------------------------------
Cancel()206cdf0e10cSrcweir void SAL_CALL SvtMatchContext_Impl::Cancel()
207cdf0e10cSrcweir {
208cdf0e10cSrcweir // Cancel button pressed
209cdf0e10cSrcweir terminate();
210cdf0e10cSrcweir }
211cdf0e10cSrcweir
212cdf0e10cSrcweir //-------------------------------------------------------------------------
Stop()213cdf0e10cSrcweir void SvtMatchContext_Impl::Stop()
214cdf0e10cSrcweir {
215cdf0e10cSrcweir bStop = sal_True;
216cdf0e10cSrcweir
217cdf0e10cSrcweir if( isRunning() )
218cdf0e10cSrcweir terminate();
219cdf0e10cSrcweir }
220cdf0e10cSrcweir
221cdf0e10cSrcweir //-------------------------------------------------------------------------
onTerminated()222cdf0e10cSrcweir void SvtMatchContext_Impl::onTerminated( )
223cdf0e10cSrcweir {
224cdf0e10cSrcweir aLink.Call( this );
225cdf0e10cSrcweir }
226cdf0e10cSrcweir
227cdf0e10cSrcweir //-------------------------------------------------------------------------
228cdf0e10cSrcweir // This method is called via AsynchronLink, so it has the SolarMutex and
229cdf0e10cSrcweir // calling solar code ( VCL ... ) is safe. It is called when the thread is
230cdf0e10cSrcweir // terminated ( finished work or stopped ). Cancelling the thread via
231cdf0e10cSrcweir // Cancellable does not not discard the information gained so far, it
232cdf0e10cSrcweir // inserts all collected completions into the listbox.
233cdf0e10cSrcweir
234cdf0e10cSrcweir IMPL_STATIC_LINK( SvtMatchContext_Impl, Select_Impl, void*, )
235cdf0e10cSrcweir {
236cdf0e10cSrcweir // avoid recursion through cancel button
237cdf0e10cSrcweir if( pThis->bStop )
238cdf0e10cSrcweir {
239cdf0e10cSrcweir // completions was stopped, no display
240cdf0e10cSrcweir delete pThis;
241cdf0e10cSrcweir return 0;
242cdf0e10cSrcweir }
243cdf0e10cSrcweir
244cdf0e10cSrcweir SvtURLBox* pBox = pThis->pBox;
245cdf0e10cSrcweir pBox->bAutoCompleteMode = sal_True;
246cdf0e10cSrcweir
247cdf0e10cSrcweir // did we filter completions which otherwise would have been valid?
248cdf0e10cSrcweir // (to be filled below)
249cdf0e10cSrcweir bool bValidCompletionsFiltered = false;
250cdf0e10cSrcweir
251cdf0e10cSrcweir // insert all completed strings into the listbox
252cdf0e10cSrcweir pBox->Clear();
253cdf0e10cSrcweir
254cdf0e10cSrcweir for( sal_uInt16 nPos = 0; nPos<pThis->pCompletions->Count(); nPos++ )
255cdf0e10cSrcweir {
256cdf0e10cSrcweir String sCompletion( *(*pThis->pCompletions)[nPos] );
257cdf0e10cSrcweir
258cdf0e10cSrcweir // convert the file into an URL
259cdf0e10cSrcweir String sURL( sCompletion );
260cdf0e10cSrcweir ::utl::LocalFileHelper::ConvertPhysicalNameToURL( sCompletion, sURL );
261cdf0e10cSrcweir // note: if this doesn't work, we're not interested in: we're checking the
262cdf0e10cSrcweir // untouched sCompletion then
263cdf0e10cSrcweir
264cdf0e10cSrcweir if ( pBox->pImp->pUrlFilter )
265cdf0e10cSrcweir {
266cdf0e10cSrcweir if ( !pBox->pImp->pUrlFilter->isUrlAllowed( sURL ) )
267cdf0e10cSrcweir { // this URL is not allowed
268cdf0e10cSrcweir bValidCompletionsFiltered = true;
269cdf0e10cSrcweir continue;
270cdf0e10cSrcweir }
271cdf0e10cSrcweir }
272cdf0e10cSrcweir if (( sURL.Len() > 0 ) && ( sURL.GetChar(sURL.Len()-1) != '/' ))
273cdf0e10cSrcweir {
274cdf0e10cSrcweir String sUpperURL( sURL );
275cdf0e10cSrcweir sUpperURL.ToUpperAscii();
276cdf0e10cSrcweir
277cdf0e10cSrcweir ::std::vector< WildCard >::const_iterator aMatchingFilter =
278cdf0e10cSrcweir ::std::find_if(
279cdf0e10cSrcweir pBox->pImp->m_aFilters.begin(),
280cdf0e10cSrcweir pBox->pImp->m_aFilters.end(),
281cdf0e10cSrcweir FilterMatch( sUpperURL )
282cdf0e10cSrcweir );
283cdf0e10cSrcweir if ( aMatchingFilter == pBox->pImp->m_aFilters.end() )
284cdf0e10cSrcweir
285cdf0e10cSrcweir { // this URL is not allowed
286cdf0e10cSrcweir bValidCompletionsFiltered = true;
287cdf0e10cSrcweir continue;
288cdf0e10cSrcweir }
289cdf0e10cSrcweir }
290cdf0e10cSrcweir
291cdf0e10cSrcweir pBox->InsertEntry( sCompletion );
292cdf0e10cSrcweir }
293cdf0e10cSrcweir
294cdf0e10cSrcweir if( !pThis->bNoSelection && pThis->pCompletions->Count() && !bValidCompletionsFiltered )
295cdf0e10cSrcweir {
296cdf0e10cSrcweir // select the first one
297cdf0e10cSrcweir String aTmp( pBox->GetEntry(0) );
298cdf0e10cSrcweir pBox->SetText( aTmp );
299cdf0e10cSrcweir pBox->SetSelection( Selection( pThis->aText.Len(), aTmp.Len() ) );
300cdf0e10cSrcweir }
301cdf0e10cSrcweir
302cdf0e10cSrcweir // transfer string lists to listbox and forget them
303cdf0e10cSrcweir delete pBox->pImp->pURLs;
304cdf0e10cSrcweir delete pBox->pImp->pCompletions;
305cdf0e10cSrcweir pBox->pImp->pURLs = pThis->pURLs;
306cdf0e10cSrcweir pBox->pImp->pCompletions = pThis->pCompletions;
307cdf0e10cSrcweir pThis->pURLs = NULL;
308cdf0e10cSrcweir pThis->pCompletions = NULL;
309cdf0e10cSrcweir
310cdf0e10cSrcweir // force listbox to resize ( it may be open )
311cdf0e10cSrcweir pBox->Resize();
312cdf0e10cSrcweir
313cdf0e10cSrcweir // the box has this control as a member so we have to set that member
314cdf0e10cSrcweir // to zero before deleting ourself.
315cdf0e10cSrcweir pBox->pCtx = NULL;
316cdf0e10cSrcweir delete pThis;
317cdf0e10cSrcweir
318cdf0e10cSrcweir return 0;
319cdf0e10cSrcweir }
320cdf0e10cSrcweir
321cdf0e10cSrcweir //-------------------------------------------------------------------------
Insert(const String & rCompletion,const String & rURL,sal_Bool bForce)322cdf0e10cSrcweir void SvtMatchContext_Impl::Insert( const String& rCompletion,
323cdf0e10cSrcweir const String& rURL,
324cdf0e10cSrcweir sal_Bool bForce )
325cdf0e10cSrcweir {
326cdf0e10cSrcweir if( !bForce )
327cdf0e10cSrcweir {
328cdf0e10cSrcweir // avoid doubles
329cdf0e10cSrcweir for( sal_uInt16 nPos = pCompletions->Count(); nPos--; )
330cdf0e10cSrcweir if( *(*pCompletions)[ nPos ] == rCompletion )
331cdf0e10cSrcweir return;
332cdf0e10cSrcweir }
333cdf0e10cSrcweir
334cdf0e10cSrcweir const StringPtr pCompletion = new String( rCompletion );
335cdf0e10cSrcweir pCompletions->Insert( pCompletion, pCompletions->Count() );
336cdf0e10cSrcweir const StringPtr pURL = new String( rURL );
337cdf0e10cSrcweir pURLs->Insert( pURL, pURLs->Count() );
338cdf0e10cSrcweir }
339cdf0e10cSrcweir
340cdf0e10cSrcweir //-------------------------------------------------------------------------
ReadFolder(const String & rURL,const String & rMatch,sal_Bool bSmart)341cdf0e10cSrcweir void SvtMatchContext_Impl::ReadFolder( const String& rURL,
342cdf0e10cSrcweir const String& rMatch,
343cdf0e10cSrcweir sal_Bool bSmart )
344cdf0e10cSrcweir {
345cdf0e10cSrcweir // check folder to scan
346cdf0e10cSrcweir if( !UCBContentHelper::IsFolder( rURL ) )
347cdf0e10cSrcweir return;
348cdf0e10cSrcweir
349cdf0e10cSrcweir sal_Bool bPureHomePath = sal_False;
350cdf0e10cSrcweir #ifdef UNX
351cdf0e10cSrcweir bPureHomePath = aText.Search( '~' ) == 0 && aText.Search( '/' ) == STRING_NOTFOUND;
352cdf0e10cSrcweir #endif
353cdf0e10cSrcweir
354cdf0e10cSrcweir sal_Bool bExectMatch = bPureHomePath
355cdf0e10cSrcweir || aText.CompareToAscii( "." ) == COMPARE_EQUAL
356cdf0e10cSrcweir || (aText.Len() > 1 && aText.Copy( aText.Len() - 2, 2 ).CompareToAscii( "/." ) == COMPARE_EQUAL)
357cdf0e10cSrcweir || (aText.Len() > 2 && aText.Copy( aText.Len() - 3, 3 ).CompareToAscii( "/.." ) == COMPARE_EQUAL);
358cdf0e10cSrcweir
359cdf0e10cSrcweir // for pure home pathes ( ~username ) the '.' at the end of rMatch
360cdf0e10cSrcweir // means that it poits to root catalog
361cdf0e10cSrcweir // this is done only for file contents since home pathes parsing is usefull only for them
362cdf0e10cSrcweir if ( bPureHomePath && rMatch.Equals( String::CreateFromAscii( "file:///." ) ) )
363cdf0e10cSrcweir {
364cdf0e10cSrcweir // a home that refers to /
365cdf0e10cSrcweir
366cdf0e10cSrcweir String aNewText( aText );
367cdf0e10cSrcweir aNewText += '/';
368cdf0e10cSrcweir Insert( aNewText, rURL, sal_True );
369cdf0e10cSrcweir
370cdf0e10cSrcweir return;
371cdf0e10cSrcweir }
372cdf0e10cSrcweir
373cdf0e10cSrcweir // string to match with
374cdf0e10cSrcweir INetURLObject aMatchObj( rMatch );
375cdf0e10cSrcweir String aMatchName;
376cdf0e10cSrcweir
377cdf0e10cSrcweir if ( rURL != String(aMatchObj.GetMainURL( INetURLObject::NO_DECODE ) ))
378cdf0e10cSrcweir {
379cdf0e10cSrcweir aMatchName = aMatchObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
380cdf0e10cSrcweir
381cdf0e10cSrcweir // matching is always done case insensitive, but completion will be case sensitive and case preserving
382cdf0e10cSrcweir aMatchName.ToLowerAscii();
383cdf0e10cSrcweir
384cdf0e10cSrcweir // if the matchstring ends with a slash, we must search for this also
385cdf0e10cSrcweir if ( rMatch.GetChar(rMatch.Len()-1) == '/' )
386cdf0e10cSrcweir aMatchName += '/';
387cdf0e10cSrcweir }
388cdf0e10cSrcweir
389cdf0e10cSrcweir xub_StrLen nMatchLen = aMatchName.Len();
390cdf0e10cSrcweir
391cdf0e10cSrcweir INetURLObject aFolderObj( rURL );
392cdf0e10cSrcweir DBG_ASSERT( aFolderObj.GetProtocol() != INET_PROT_NOT_VALID, "Invalid URL!" );
393cdf0e10cSrcweir
394cdf0e10cSrcweir try
395cdf0e10cSrcweir {
396cdf0e10cSrcweir uno::Reference< XMultiServiceFactory > xFactory = ::comphelper::getProcessServiceFactory();
397cdf0e10cSrcweir
398cdf0e10cSrcweir Content aCnt( aFolderObj.GetMainURL( INetURLObject::NO_DECODE ),
399cdf0e10cSrcweir new ::ucbhelper::CommandEnvironment( uno::Reference< XInteractionHandler >(),
400cdf0e10cSrcweir uno::Reference< XProgressHandler >() ) );
401cdf0e10cSrcweir uno::Reference< XResultSet > xResultSet;
402cdf0e10cSrcweir Sequence< OUString > aProps(2);
403cdf0e10cSrcweir OUString* pProps = aProps.getArray();
404cdf0e10cSrcweir pProps[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "Title" ) );
405cdf0e10cSrcweir pProps[1] = OUString( RTL_CONSTASCII_USTRINGPARAM( "IsFolder" ) );
406cdf0e10cSrcweir
407cdf0e10cSrcweir try
408cdf0e10cSrcweir {
409cdf0e10cSrcweir uno::Reference< XDynamicResultSet > xDynResultSet;
410cdf0e10cSrcweir ResultSetInclude eInclude = INCLUDE_FOLDERS_AND_DOCUMENTS;
411cdf0e10cSrcweir if ( bOnlyDirectories )
412cdf0e10cSrcweir eInclude = INCLUDE_FOLDERS_ONLY;
413cdf0e10cSrcweir
414cdf0e10cSrcweir xDynResultSet = aCnt.createDynamicCursor( aProps, eInclude );
415cdf0e10cSrcweir
416cdf0e10cSrcweir uno::Reference < XAnyCompareFactory > xCompare;
417cdf0e10cSrcweir uno::Reference < XSortedDynamicResultSetFactory > xSRSFac(
418cdf0e10cSrcweir xFactory->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM("com.sun.star.ucb.SortedDynamicResultSetFactory") ) ), UNO_QUERY );
419cdf0e10cSrcweir
420cdf0e10cSrcweir Sequence< NumberedSortingInfo > aSortInfo( 2 );
421cdf0e10cSrcweir NumberedSortingInfo* pInfo = aSortInfo.getArray();
422cdf0e10cSrcweir pInfo[ 0 ].ColumnIndex = 2;
423cdf0e10cSrcweir pInfo[ 0 ].Ascending = sal_False;
424cdf0e10cSrcweir pInfo[ 1 ].ColumnIndex = 1;
425cdf0e10cSrcweir pInfo[ 1 ].Ascending = sal_True;
426cdf0e10cSrcweir
427cdf0e10cSrcweir uno::Reference< XDynamicResultSet > xDynamicResultSet;
428cdf0e10cSrcweir xDynamicResultSet =
429cdf0e10cSrcweir xSRSFac->createSortedDynamicResultSet( xDynResultSet, aSortInfo, xCompare );
430cdf0e10cSrcweir
431cdf0e10cSrcweir if ( xDynamicResultSet.is() )
432cdf0e10cSrcweir {
433cdf0e10cSrcweir xResultSet = xDynamicResultSet->getStaticResultSet();
434cdf0e10cSrcweir }
435cdf0e10cSrcweir }
436cdf0e10cSrcweir catch( ::com::sun::star::uno::Exception& ) {}
437cdf0e10cSrcweir
438cdf0e10cSrcweir if ( xResultSet.is() )
439cdf0e10cSrcweir {
440cdf0e10cSrcweir uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
441cdf0e10cSrcweir uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
442cdf0e10cSrcweir
443cdf0e10cSrcweir try
444cdf0e10cSrcweir {
445cdf0e10cSrcweir while ( schedule() && xResultSet->next() )
446cdf0e10cSrcweir {
447cdf0e10cSrcweir String aURL = xContentAccess->queryContentIdentifierString();
448cdf0e10cSrcweir String aTitle = xRow->getString(1);
449cdf0e10cSrcweir sal_Bool bIsFolder = xRow->getBoolean(2);
450cdf0e10cSrcweir
451cdf0e10cSrcweir // matching is always done case insensitive, but completion will be case sensitive and case preserving
452cdf0e10cSrcweir aTitle.ToLowerAscii();
453cdf0e10cSrcweir
454cdf0e10cSrcweir if (
455cdf0e10cSrcweir !nMatchLen ||
456cdf0e10cSrcweir (bExectMatch && aMatchName.Equals(aTitle)) ||
457cdf0e10cSrcweir (!bExectMatch && aMatchName.CompareTo(aTitle, nMatchLen) == COMPARE_EQUAL)
458cdf0e10cSrcweir )
459cdf0e10cSrcweir {
460cdf0e10cSrcweir // all names fit if matchstring is empty
461cdf0e10cSrcweir INetURLObject aObj( aURL );
462cdf0e10cSrcweir sal_Unicode aDelimiter = '/';
463cdf0e10cSrcweir if ( bSmart )
464cdf0e10cSrcweir // when parsing is done "smart", the delimiter must be "guessed"
465cdf0e10cSrcweir aObj.getFSysPath( (INetURLObject::FSysStyle)(INetURLObject::FSYS_DETECT & ~INetURLObject::FSYS_VOS), &aDelimiter );
466cdf0e10cSrcweir
467cdf0e10cSrcweir if ( bIsFolder )
468cdf0e10cSrcweir aObj.setFinalSlash();
469cdf0e10cSrcweir
470cdf0e10cSrcweir // get the last name of the URL
471cdf0e10cSrcweir String aMatch = aObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
472cdf0e10cSrcweir String aInput( aText );
473cdf0e10cSrcweir if ( nMatchLen )
474cdf0e10cSrcweir {
475cdf0e10cSrcweir if ((aText.Len() && aText.GetChar(aText.Len() - 1) == '.') || bPureHomePath)
476cdf0e10cSrcweir {
477cdf0e10cSrcweir // if a "special folder" URL was typed, don't touch the user input
478cdf0e10cSrcweir aMatch.Erase( 0, nMatchLen );
479cdf0e10cSrcweir }
480cdf0e10cSrcweir else
481cdf0e10cSrcweir {
482cdf0e10cSrcweir // make the user input case preserving
483cdf0e10cSrcweir DBG_ASSERT( aInput.Len() >= nMatchLen, "Suspicious Matching!" );
484cdf0e10cSrcweir aInput.Erase( aInput.Len() - nMatchLen );
485cdf0e10cSrcweir }
486cdf0e10cSrcweir }
487cdf0e10cSrcweir
488cdf0e10cSrcweir aInput += aMatch;
489cdf0e10cSrcweir
490cdf0e10cSrcweir // folders should get a final slash automatically
491cdf0e10cSrcweir if ( bIsFolder )
492cdf0e10cSrcweir aInput += aDelimiter;
493cdf0e10cSrcweir
494cdf0e10cSrcweir Insert( aInput, aObj.GetMainURL( INetURLObject::NO_DECODE ), sal_True );
495cdf0e10cSrcweir }
496cdf0e10cSrcweir }
497cdf0e10cSrcweir }
498cdf0e10cSrcweir catch( ::com::sun::star::uno::Exception& )
499cdf0e10cSrcweir {
500cdf0e10cSrcweir }
501cdf0e10cSrcweir }
502cdf0e10cSrcweir }
503cdf0e10cSrcweir catch( ::com::sun::star::uno::Exception& )
504cdf0e10cSrcweir {
505cdf0e10cSrcweir }
506cdf0e10cSrcweir }
507cdf0e10cSrcweir
508cdf0e10cSrcweir //-------------------------------------------------------------------------
ParseSmart(String aText,String aBaseURL,String aWorkDir)509cdf0e10cSrcweir String SvtURLBox::ParseSmart( String aText, String aBaseURL, String aWorkDir )
510cdf0e10cSrcweir {
511cdf0e10cSrcweir String aMatch;
512cdf0e10cSrcweir
513cdf0e10cSrcweir // parse ~ for Unix systems
514cdf0e10cSrcweir // does nothing for Windows
515cdf0e10cSrcweir if( !SvtURLBox_Impl::TildeParsing( aText, aBaseURL ) )
516cdf0e10cSrcweir return String();
517cdf0e10cSrcweir
518cdf0e10cSrcweir INetURLObject aURLObject;
519cdf0e10cSrcweir if( aBaseURL.Len() )
520cdf0e10cSrcweir {
521cdf0e10cSrcweir INetProtocol eBaseProt = INetURLObject::CompareProtocolScheme( aBaseURL );
522cdf0e10cSrcweir
523cdf0e10cSrcweir // if a base URL is set the string may be parsed relative
524cdf0e10cSrcweir if( aText.Search( '/' ) == 0 )
525cdf0e10cSrcweir {
526cdf0e10cSrcweir // text starting with slashes means absolute file URLs
527cdf0e10cSrcweir String aTemp = INetURLObject::GetScheme( eBaseProt );
528cdf0e10cSrcweir
529cdf0e10cSrcweir // file URL must be correctly encoded!
530cdf0e10cSrcweir String aTextURL = INetURLObject::encode( aText, INetURLObject::PART_FPATH,
531cdf0e10cSrcweir '%', INetURLObject::ENCODE_ALL );
532cdf0e10cSrcweir aTemp += aTextURL;
533cdf0e10cSrcweir
534cdf0e10cSrcweir INetURLObject aTmp( aTemp );
535cdf0e10cSrcweir if ( !aTmp.HasError() && aTmp.GetProtocol() != INET_PROT_NOT_VALID )
536cdf0e10cSrcweir aMatch = aTmp.GetMainURL( INetURLObject::NO_DECODE );
537cdf0e10cSrcweir }
538cdf0e10cSrcweir else
539cdf0e10cSrcweir {
540cdf0e10cSrcweir String aSmart( aText );
541cdf0e10cSrcweir INetURLObject aObj( aBaseURL );
542cdf0e10cSrcweir
543cdf0e10cSrcweir // HRO: I suppose this hack should only be done for Windows !!!???
544cdf0e10cSrcweir #ifdef WNT
545cdf0e10cSrcweir // HRO: INetURLObject::smatRel2Abs does not recognize '\\' as a relative path
546cdf0e10cSrcweir // but in case of "\\\\" INetURLObject is right - this is an absolute path !
547cdf0e10cSrcweir
548cdf0e10cSrcweir if( aText.Search( '\\' ) == 0 && (aText.Len() < 2 || aText.GetChar( 1 ) != '\\') )
549cdf0e10cSrcweir {
550cdf0e10cSrcweir // cut to first segment
551cdf0e10cSrcweir String aTmp = INetURLObject::GetScheme( eBaseProt );
552cdf0e10cSrcweir aTmp += '/';
553cdf0e10cSrcweir aTmp += String(aObj.getName( 0, true, INetURLObject::DECODE_WITH_CHARSET ));
554cdf0e10cSrcweir aObj.SetURL( aTmp );
555cdf0e10cSrcweir
556cdf0e10cSrcweir aSmart.Erase(0,1);
557cdf0e10cSrcweir }
558cdf0e10cSrcweir #endif
559cdf0e10cSrcweir // base URL must be a directory !
560cdf0e10cSrcweir aObj.setFinalSlash();
561cdf0e10cSrcweir
562cdf0e10cSrcweir // take base URL and append current input
563cdf0e10cSrcweir bool bWasAbsolute = sal_False;
564cdf0e10cSrcweir #ifdef UNX
565cdf0e10cSrcweir // don't support FSYS_MAC under Unix, because here ':' is a valid character for a filename
566cdf0e10cSrcweir INetURLObject::FSysStyle eStyle = static_cast< INetURLObject::FSysStyle >( INetURLObject::FSYS_VOS | INetURLObject::FSYS_UNX | INetURLObject::FSYS_DOS );
567cdf0e10cSrcweir // encode file URL correctly
568cdf0e10cSrcweir aSmart = INetURLObject::encode( aSmart, INetURLObject::PART_FPATH, '%', INetURLObject::ENCODE_ALL );
569cdf0e10cSrcweir INetURLObject aTmp( aObj.smartRel2Abs(
570cdf0e10cSrcweir aSmart, bWasAbsolute, false, INetURLObject::WAS_ENCODED, RTL_TEXTENCODING_UTF8, false, eStyle ) );
571cdf0e10cSrcweir #else
572cdf0e10cSrcweir INetURLObject aTmp( aObj.smartRel2Abs( aSmart, bWasAbsolute ) );
573cdf0e10cSrcweir #endif
574cdf0e10cSrcweir
575cdf0e10cSrcweir if ( aText.GetChar( aText.Len() - 1 ) == '.' )
576cdf0e10cSrcweir // INetURLObject appends a final slash for the directories "." and "..", this is a bug!
577cdf0e10cSrcweir // Remove it as a workaround
578cdf0e10cSrcweir aTmp.removeFinalSlash();
579cdf0e10cSrcweir if ( !aTmp.HasError() && aTmp.GetProtocol() != INET_PROT_NOT_VALID )
580cdf0e10cSrcweir aMatch = aTmp.GetMainURL( INetURLObject::NO_DECODE );
581cdf0e10cSrcweir }
582cdf0e10cSrcweir }
583cdf0e10cSrcweir else
584cdf0e10cSrcweir {
585cdf0e10cSrcweir ::utl::LocalFileHelper::ConvertSystemPathToURL( aText, aWorkDir, aMatch );
586cdf0e10cSrcweir }
587cdf0e10cSrcweir
588cdf0e10cSrcweir return aMatch;
589cdf0e10cSrcweir }
590cdf0e10cSrcweir
591cdf0e10cSrcweir //-------------------------------------------------------------------------
run()592cdf0e10cSrcweir void SvtMatchContext_Impl::run()
593cdf0e10cSrcweir {
594cdf0e10cSrcweir ::vos::OGuard aGuard( GetMutex() );
595cdf0e10cSrcweir if( bStop )
596cdf0e10cSrcweir // have we been stopped while we were waiting for the mutex?
597cdf0e10cSrcweir return;
598cdf0e10cSrcweir
599cdf0e10cSrcweir // Reset match lists
600cdf0e10cSrcweir pCompletions->Remove( 0, pCompletions->Count() );
601cdf0e10cSrcweir pURLs->Remove( 0, pURLs->Count() );
602cdf0e10cSrcweir
603cdf0e10cSrcweir // check for input
604cdf0e10cSrcweir sal_uInt16 nTextLen = aText.Len();
605cdf0e10cSrcweir if ( !nTextLen )
606cdf0e10cSrcweir return;
607cdf0e10cSrcweir
608cdf0e10cSrcweir if( aText.Search( '*' ) != STRING_NOTFOUND || aText.Search( '?' ) != STRING_NOTFOUND )
609cdf0e10cSrcweir // no autocompletion for wildcards
610cdf0e10cSrcweir return;
611cdf0e10cSrcweir
612cdf0e10cSrcweir String aMatch;
613cdf0e10cSrcweir String aWorkDir( SvtPathOptions().GetWorkPath() );
614cdf0e10cSrcweir INetProtocol eProt = INetURLObject::CompareProtocolScheme( aText );
615cdf0e10cSrcweir INetProtocol eBaseProt = INetURLObject::CompareProtocolScheme( aBaseURL );
616cdf0e10cSrcweir if ( !aBaseURL.Len() )
617cdf0e10cSrcweir eBaseProt = INetURLObject::CompareProtocolScheme( aWorkDir );
618cdf0e10cSrcweir INetProtocol eSmartProt = pBox->GetSmartProtocol();
619cdf0e10cSrcweir
620cdf0e10cSrcweir // if the user input is a valid URL, go on with it
621cdf0e10cSrcweir // otherwise it could be parsed smart with a predefined smart protocol
622cdf0e10cSrcweir // ( or if this is not set with the protocol of a predefined base URL )
623cdf0e10cSrcweir if( eProt == INET_PROT_NOT_VALID || eProt == eSmartProt || (eSmartProt == INET_PROT_NOT_VALID && eProt == eBaseProt) )
624cdf0e10cSrcweir {
625cdf0e10cSrcweir // not stopped yet ?
626cdf0e10cSrcweir if( schedule() )
627cdf0e10cSrcweir {
628cdf0e10cSrcweir if ( eProt == INET_PROT_NOT_VALID )
629cdf0e10cSrcweir aMatch = SvtURLBox::ParseSmart( aText, aBaseURL, aWorkDir );
630cdf0e10cSrcweir else
631cdf0e10cSrcweir aMatch = aText;
632cdf0e10cSrcweir if ( aMatch.Len() )
633cdf0e10cSrcweir {
634cdf0e10cSrcweir INetURLObject aURLObject( aMatch );
635cdf0e10cSrcweir String aMainURL( aURLObject.GetMainURL( INetURLObject::NO_DECODE ) );
636cdf0e10cSrcweir if ( aMainURL.Len() )
637cdf0e10cSrcweir {
638cdf0e10cSrcweir // if text input is a directory, it must be part of the match list! Until then it is scanned
639cdf0e10cSrcweir if ( UCBContentHelper::IsFolder( aMainURL ) && aURLObject.hasFinalSlash() )
640cdf0e10cSrcweir Insert( aText, aMatch );
641cdf0e10cSrcweir else
642cdf0e10cSrcweir // otherwise the parent folder will be taken
643cdf0e10cSrcweir aURLObject.removeSegment();
644cdf0e10cSrcweir
645cdf0e10cSrcweir // scan directory and insert all matches
646cdf0e10cSrcweir ReadFolder( aURLObject.GetMainURL( INetURLObject::NO_DECODE ), aMatch, eProt == INET_PROT_NOT_VALID );
647cdf0e10cSrcweir }
648cdf0e10cSrcweir }
649cdf0e10cSrcweir }
650cdf0e10cSrcweir }
651cdf0e10cSrcweir
652cdf0e10cSrcweir if ( bOnlyDirectories )
653cdf0e10cSrcweir // don't scan history picklist if only directories are allowed, picklist contains only files
654cdf0e10cSrcweir return;
655cdf0e10cSrcweir
656cdf0e10cSrcweir sal_Bool bFull = sal_False;
657cdf0e10cSrcweir int nCount = aPickList.Count();
658cdf0e10cSrcweir
659cdf0e10cSrcweir INetURLObject aCurObj;
660cdf0e10cSrcweir String aEmpty, aCurString, aCurMainURL;
661cdf0e10cSrcweir INetURLObject aObj;
662cdf0e10cSrcweir aObj.SetSmartProtocol( eSmartProt == INET_PROT_NOT_VALID ? INET_PROT_HTTP : eSmartProt );
663cdf0e10cSrcweir for( ;; )
664cdf0e10cSrcweir {
665cdf0e10cSrcweir for( sal_uInt16 nPos = 0; schedule() && nPos < nCount; nPos++ )
666cdf0e10cSrcweir {
667cdf0e10cSrcweir aCurObj.SetURL( *aPickList.GetObject( nPos ) );
668cdf0e10cSrcweir aCurObj.SetSmartURL( aCurObj.GetURLNoPass());
669cdf0e10cSrcweir aCurMainURL = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
670cdf0e10cSrcweir
671cdf0e10cSrcweir if( eProt != INET_PROT_NOT_VALID && aCurObj.GetProtocol() != eProt )
672cdf0e10cSrcweir continue;
673cdf0e10cSrcweir
674cdf0e10cSrcweir if( eSmartProt != INET_PROT_NOT_VALID && aCurObj.GetProtocol() != eSmartProt )
675cdf0e10cSrcweir continue;
676cdf0e10cSrcweir
677cdf0e10cSrcweir switch( aCurObj.GetProtocol() )
678cdf0e10cSrcweir {
679cdf0e10cSrcweir case INET_PROT_HTTP:
680cdf0e10cSrcweir case INET_PROT_HTTPS:
681cdf0e10cSrcweir case INET_PROT_FTP:
682cdf0e10cSrcweir {
683cdf0e10cSrcweir if( eProt == INET_PROT_NOT_VALID && !bFull )
684cdf0e10cSrcweir {
685cdf0e10cSrcweir aObj.SetSmartURL( aText );
686cdf0e10cSrcweir if( aObj.GetURLPath().getLength() > 1 )
687cdf0e10cSrcweir continue;
688cdf0e10cSrcweir }
689cdf0e10cSrcweir
690cdf0e10cSrcweir aCurString = aCurMainURL;
691cdf0e10cSrcweir if( eProt == INET_PROT_NOT_VALID )
692cdf0e10cSrcweir {
693cdf0e10cSrcweir // try if text matches the scheme
694cdf0e10cSrcweir String aScheme( INetURLObject::GetScheme( aCurObj.GetProtocol() ) );
695cdf0e10cSrcweir if ( aText.CompareIgnoreCaseToAscii( aScheme, aText.Len() ) == COMPARE_EQUAL && aText.Len() < aScheme.Len() )
696cdf0e10cSrcweir {
697cdf0e10cSrcweir if( bFull )
698cdf0e10cSrcweir aMatch = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
699cdf0e10cSrcweir else
700cdf0e10cSrcweir {
701cdf0e10cSrcweir aCurObj.SetMark( aEmpty );
702cdf0e10cSrcweir aCurObj.SetParam( aEmpty );
703cdf0e10cSrcweir aCurObj.SetURLPath( aEmpty );
704cdf0e10cSrcweir aMatch = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
705cdf0e10cSrcweir }
706cdf0e10cSrcweir
707cdf0e10cSrcweir Insert( aMatch, aMatch );
708cdf0e10cSrcweir }
709cdf0e10cSrcweir
710cdf0e10cSrcweir // now try smart matching
711cdf0e10cSrcweir aCurString.Erase( 0, aScheme.Len() );
712cdf0e10cSrcweir }
713cdf0e10cSrcweir
714cdf0e10cSrcweir if( aText.CompareIgnoreCaseToAscii( aCurString, aText.Len() )== COMPARE_EQUAL )
715cdf0e10cSrcweir {
716cdf0e10cSrcweir if( bFull )
717cdf0e10cSrcweir aMatch = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
718cdf0e10cSrcweir else
719cdf0e10cSrcweir {
720cdf0e10cSrcweir aCurObj.SetMark( aEmpty );
721cdf0e10cSrcweir aCurObj.SetParam( aEmpty );
722cdf0e10cSrcweir aCurObj.SetURLPath( aEmpty );
723cdf0e10cSrcweir aMatch = aCurObj.GetMainURL( INetURLObject::NO_DECODE );
724cdf0e10cSrcweir }
725cdf0e10cSrcweir
726cdf0e10cSrcweir String aURL( aMatch );
727cdf0e10cSrcweir if( eProt == INET_PROT_NOT_VALID )
728cdf0e10cSrcweir aMatch.Erase( 0, sal::static_int_cast< xub_StrLen >(INetURLObject::GetScheme( aCurObj.GetProtocol() ).getLength()) );
729cdf0e10cSrcweir
730cdf0e10cSrcweir if( aText.Len() < aMatch.Len() )
731cdf0e10cSrcweir Insert( aMatch, aURL );
732cdf0e10cSrcweir
733cdf0e10cSrcweir continue;
734cdf0e10cSrcweir }
735cdf0e10cSrcweir break;
736cdf0e10cSrcweir }
737cdf0e10cSrcweir default:
738cdf0e10cSrcweir {
739cdf0e10cSrcweir if( bFull )
740cdf0e10cSrcweir continue;
741cdf0e10cSrcweir
742cdf0e10cSrcweir if( aText.CompareTo( aCurMainURL, aText.Len() ) == COMPARE_EQUAL )
743cdf0e10cSrcweir {
744cdf0e10cSrcweir if( aText.Len() < aCurMainURL.Len() )
745cdf0e10cSrcweir Insert( aCurMainURL, aCurMainURL );
746cdf0e10cSrcweir
747cdf0e10cSrcweir continue;
748cdf0e10cSrcweir }
749cdf0e10cSrcweir break;
750cdf0e10cSrcweir }
751cdf0e10cSrcweir }
752cdf0e10cSrcweir }
753cdf0e10cSrcweir
754cdf0e10cSrcweir if( !bFull )
755cdf0e10cSrcweir bFull = sal_True;
756cdf0e10cSrcweir else
757cdf0e10cSrcweir break;
758cdf0e10cSrcweir }
759cdf0e10cSrcweir
760cdf0e10cSrcweir return;
761cdf0e10cSrcweir }
762cdf0e10cSrcweir
763cdf0e10cSrcweir //-------------------------------------------------------------------------
764cdf0e10cSrcweir //-------------------------------------------------------------------------
765cdf0e10cSrcweir //-------------------------------------------------------------------------
TryAutoComplete(sal_Bool bForce)766cdf0e10cSrcweir void SvtURLBox::TryAutoComplete( sal_Bool bForce )
767cdf0e10cSrcweir {
768cdf0e10cSrcweir if( Application::AnyInput( INPUT_KEYBOARD ) ) return;
769cdf0e10cSrcweir
770cdf0e10cSrcweir String aMatchString;
771cdf0e10cSrcweir String aCurText = GetText();
772cdf0e10cSrcweir Selection aSelection( GetSelection() );
773cdf0e10cSrcweir if( aSelection.Max() != aCurText.Len() && !bForce )
774cdf0e10cSrcweir return;
775cdf0e10cSrcweir sal_uInt16 nLen = (sal_uInt16)aSelection.Min();
776cdf0e10cSrcweir aCurText.Erase( nLen );
777cdf0e10cSrcweir if( aCurText.Len() && bIsAutoCompleteEnabled )
778cdf0e10cSrcweir {
779cdf0e10cSrcweir if ( pCtx )
780cdf0e10cSrcweir {
781cdf0e10cSrcweir pCtx->Stop();
782cdf0e10cSrcweir pCtx = NULL;
783cdf0e10cSrcweir }
784cdf0e10cSrcweir pCtx = new SvtMatchContext_Impl( this, aCurText );
785cdf0e10cSrcweir }
786cdf0e10cSrcweir }
787cdf0e10cSrcweir
788cdf0e10cSrcweir //-------------------------------------------------------------------------
SvtURLBox(Window * pParent,INetProtocol eSmart)789cdf0e10cSrcweir SvtURLBox::SvtURLBox( Window* pParent, INetProtocol eSmart )
790cdf0e10cSrcweir : ComboBox( pParent , WB_DROPDOWN | WB_AUTOSIZE | WB_AUTOHSCROLL ),
791cdf0e10cSrcweir pCtx( 0 ),
792cdf0e10cSrcweir eSmartProtocol( eSmart ),
793cdf0e10cSrcweir bAutoCompleteMode( sal_False ),
794cdf0e10cSrcweir bOnlyDirectories( sal_False ),
795cdf0e10cSrcweir bTryAutoComplete( sal_False ),
796cdf0e10cSrcweir bCtrlClick( sal_False ),
797cdf0e10cSrcweir bHistoryDisabled( sal_False ),
798cdf0e10cSrcweir bNoSelection( sal_False ),
799cdf0e10cSrcweir bIsAutoCompleteEnabled( sal_True )
800cdf0e10cSrcweir {
801cdf0e10cSrcweir ImplInit();
802cdf0e10cSrcweir
803cdf0e10cSrcweir if ( GetDesktopRectPixel().GetWidth() > 800 )
804cdf0e10cSrcweir SetSizePixel( Size( 300, 240 ) );
805cdf0e10cSrcweir else
806cdf0e10cSrcweir SetSizePixel( Size( 225, 240 ) );
807cdf0e10cSrcweir }
808cdf0e10cSrcweir
809cdf0e10cSrcweir //-------------------------------------------------------------------------
SvtURLBox(Window * pParent,WinBits _nStyle,INetProtocol eSmart)810cdf0e10cSrcweir SvtURLBox::SvtURLBox( Window* pParent, WinBits _nStyle, INetProtocol eSmart )
811cdf0e10cSrcweir : ComboBox( pParent, _nStyle ),
812cdf0e10cSrcweir pCtx( 0 ),
813cdf0e10cSrcweir eSmartProtocol( eSmart ),
814cdf0e10cSrcweir bAutoCompleteMode( sal_False ),
815cdf0e10cSrcweir bOnlyDirectories( sal_False ),
816cdf0e10cSrcweir bTryAutoComplete( sal_False ),
817cdf0e10cSrcweir bCtrlClick( sal_False ),
818cdf0e10cSrcweir bHistoryDisabled( sal_False ),
819cdf0e10cSrcweir bNoSelection( sal_False ),
820cdf0e10cSrcweir bIsAutoCompleteEnabled( sal_True )
821cdf0e10cSrcweir {
822cdf0e10cSrcweir ImplInit();
823cdf0e10cSrcweir }
824cdf0e10cSrcweir
825cdf0e10cSrcweir //-------------------------------------------------------------------------
SvtURLBox(Window * pParent,const ResId & _rResId,INetProtocol eSmart)826cdf0e10cSrcweir SvtURLBox::SvtURLBox( Window* pParent, const ResId& _rResId, INetProtocol eSmart )
827cdf0e10cSrcweir : ComboBox( pParent , _rResId ),
828cdf0e10cSrcweir pCtx( 0 ),
829cdf0e10cSrcweir eSmartProtocol( eSmart ),
830cdf0e10cSrcweir bAutoCompleteMode( sal_False ),
831cdf0e10cSrcweir bOnlyDirectories( sal_False ),
832cdf0e10cSrcweir bTryAutoComplete( sal_False ),
833cdf0e10cSrcweir bCtrlClick( sal_False ),
834cdf0e10cSrcweir bHistoryDisabled( sal_False ),
835cdf0e10cSrcweir bNoSelection( sal_False ),
836cdf0e10cSrcweir bIsAutoCompleteEnabled( sal_True )
837cdf0e10cSrcweir {
838cdf0e10cSrcweir ImplInit();
839cdf0e10cSrcweir }
840cdf0e10cSrcweir
841cdf0e10cSrcweir //-------------------------------------------------------------------------
ImplInit()842cdf0e10cSrcweir void SvtURLBox::ImplInit()
843cdf0e10cSrcweir {
844cdf0e10cSrcweir pImp = new SvtURLBox_Impl();
845cdf0e10cSrcweir
846cdf0e10cSrcweir if ( GetHelpId().getLength() == 0 )
847cdf0e10cSrcweir SetHelpId( ".uno:OpenURL" );
848cdf0e10cSrcweir EnableAutocomplete( sal_False );
849cdf0e10cSrcweir
850cdf0e10cSrcweir SetText( String() );
851cdf0e10cSrcweir
852cdf0e10cSrcweir GetSubEdit()->SetAutocompleteHdl( LINK( this, SvtURLBox, AutoCompleteHdl_Impl ) );
853cdf0e10cSrcweir UpdatePicklistForSmartProtocol_Impl();
854cdf0e10cSrcweir }
855cdf0e10cSrcweir
856cdf0e10cSrcweir //-------------------------------------------------------------------------
~SvtURLBox()857cdf0e10cSrcweir SvtURLBox::~SvtURLBox()
858cdf0e10cSrcweir {
859cdf0e10cSrcweir if( pCtx )
860cdf0e10cSrcweir {
861cdf0e10cSrcweir pCtx->Stop();
862cdf0e10cSrcweir pCtx = NULL;
863cdf0e10cSrcweir }
864cdf0e10cSrcweir
865cdf0e10cSrcweir delete pImp->pURLs;
866cdf0e10cSrcweir delete pImp->pCompletions;
867cdf0e10cSrcweir delete pImp;
868cdf0e10cSrcweir }
869cdf0e10cSrcweir
870cdf0e10cSrcweir //-------------------------------------------------------------------------
UpdatePickList()871cdf0e10cSrcweir void SvtURLBox::UpdatePickList( )
872cdf0e10cSrcweir {
873cdf0e10cSrcweir if( pCtx )
874cdf0e10cSrcweir {
875cdf0e10cSrcweir pCtx->Stop();
876cdf0e10cSrcweir pCtx = NULL;
877cdf0e10cSrcweir }
878cdf0e10cSrcweir
879cdf0e10cSrcweir String sText = GetText();
880cdf0e10cSrcweir if ( sText.Len() && bIsAutoCompleteEnabled )
881cdf0e10cSrcweir pCtx = new SvtMatchContext_Impl( this, sText );
882cdf0e10cSrcweir }
883cdf0e10cSrcweir
884cdf0e10cSrcweir //-------------------------------------------------------------------------
SetSmartProtocol(INetProtocol eProt)885cdf0e10cSrcweir void SvtURLBox::SetSmartProtocol( INetProtocol eProt )
886cdf0e10cSrcweir {
887cdf0e10cSrcweir if ( eSmartProtocol != eProt )
888cdf0e10cSrcweir {
889cdf0e10cSrcweir eSmartProtocol = eProt;
890cdf0e10cSrcweir UpdatePicklistForSmartProtocol_Impl();
891cdf0e10cSrcweir }
892cdf0e10cSrcweir }
893cdf0e10cSrcweir
894cdf0e10cSrcweir //-------------------------------------------------------------------------
UpdatePicklistForSmartProtocol_Impl()895cdf0e10cSrcweir void SvtURLBox::UpdatePicklistForSmartProtocol_Impl()
896cdf0e10cSrcweir {
897cdf0e10cSrcweir Clear();
898cdf0e10cSrcweir if ( !bHistoryDisabled )
899cdf0e10cSrcweir {
900cdf0e10cSrcweir // read history pick list
901cdf0e10cSrcweir Sequence< Sequence< PropertyValue > > seqPicklist = SvtHistoryOptions().GetList( eHISTORY );
902cdf0e10cSrcweir sal_uInt32 nCount = seqPicklist.getLength();
903cdf0e10cSrcweir INetURLObject aCurObj;
904cdf0e10cSrcweir
905cdf0e10cSrcweir for( sal_uInt32 nItem=0; nItem < nCount; nItem++ )
906cdf0e10cSrcweir {
907cdf0e10cSrcweir Sequence< PropertyValue > seqPropertySet = seqPicklist[ nItem ];
908cdf0e10cSrcweir
909cdf0e10cSrcweir OUString sURL;
910cdf0e10cSrcweir
911cdf0e10cSrcweir sal_uInt32 nPropertyCount = seqPropertySet.getLength();
912cdf0e10cSrcweir
913cdf0e10cSrcweir for( sal_uInt32 nProperty=0; nProperty < nPropertyCount; nProperty++ )
914cdf0e10cSrcweir {
915cdf0e10cSrcweir if( seqPropertySet[nProperty].Name == HISTORY_PROPERTYNAME_URL )
916cdf0e10cSrcweir {
917cdf0e10cSrcweir seqPropertySet[nProperty].Value >>= sURL;
918cdf0e10cSrcweir aCurObj.SetURL( sURL );
919cdf0e10cSrcweir
920cdf0e10cSrcweir if ( sURL.getLength() && ( eSmartProtocol != INET_PROT_NOT_VALID ) )
921cdf0e10cSrcweir {
922cdf0e10cSrcweir if( aCurObj.GetProtocol() != eSmartProtocol )
923cdf0e10cSrcweir break;
924cdf0e10cSrcweir }
925cdf0e10cSrcweir
926cdf0e10cSrcweir String aURL( aCurObj.GetMainURL( INetURLObject::DECODE_WITH_CHARSET ) );
927cdf0e10cSrcweir
928cdf0e10cSrcweir if ( aURL.Len() && ( !pImp->pUrlFilter || pImp->pUrlFilter->isUrlAllowed( aURL ) ) )
929cdf0e10cSrcweir {
930cdf0e10cSrcweir sal_Bool bFound = (aURL.GetChar(aURL.Len()-1) == '/' );
931cdf0e10cSrcweir if ( !bFound )
932cdf0e10cSrcweir {
933cdf0e10cSrcweir String aUpperURL( aURL );
934cdf0e10cSrcweir aUpperURL.ToUpperAscii();
935cdf0e10cSrcweir
936cdf0e10cSrcweir bFound
937cdf0e10cSrcweir = (::std::find_if(
938cdf0e10cSrcweir pImp->m_aFilters.begin(),
939cdf0e10cSrcweir pImp->m_aFilters.end(),
940cdf0e10cSrcweir FilterMatch( aUpperURL ) )
941cdf0e10cSrcweir != pImp->m_aFilters.end());
942cdf0e10cSrcweir }
943cdf0e10cSrcweir if ( bFound )
944cdf0e10cSrcweir {
945cdf0e10cSrcweir String aFile;
946cdf0e10cSrcweir if (::utl::LocalFileHelper::ConvertURLToSystemPath(aURL,aFile))
947cdf0e10cSrcweir InsertEntry(aFile);
948cdf0e10cSrcweir else
949cdf0e10cSrcweir InsertEntry(aURL);
950cdf0e10cSrcweir }
951cdf0e10cSrcweir }
952cdf0e10cSrcweir break;
953cdf0e10cSrcweir }
954cdf0e10cSrcweir }
955cdf0e10cSrcweir }
956cdf0e10cSrcweir }
957cdf0e10cSrcweir }
958cdf0e10cSrcweir
959cdf0e10cSrcweir //-------------------------------------------------------------------------
ProcessKey(const KeyCode & rKey)960cdf0e10cSrcweir sal_Bool SvtURLBox::ProcessKey( const KeyCode& rKey )
961cdf0e10cSrcweir {
962cdf0e10cSrcweir // every key input stops the current matching thread
963cdf0e10cSrcweir if( pCtx )
964cdf0e10cSrcweir {
965cdf0e10cSrcweir pCtx->Stop();
966cdf0e10cSrcweir pCtx = NULL;
967cdf0e10cSrcweir }
968cdf0e10cSrcweir
969cdf0e10cSrcweir KeyCode aCode( rKey.GetCode() );
970cdf0e10cSrcweir if ( aCode == KEY_RETURN && GetText().Len() )
971cdf0e10cSrcweir {
972cdf0e10cSrcweir // wait for completion of matching thread
973cdf0e10cSrcweir ::vos::OGuard aGuard( SvtMatchContext_Impl::GetMutex() );
974cdf0e10cSrcweir
975cdf0e10cSrcweir if ( bAutoCompleteMode )
976cdf0e10cSrcweir {
977cdf0e10cSrcweir // reset picklist
978cdf0e10cSrcweir bAutoCompleteMode = sal_False;
979cdf0e10cSrcweir Selection aSelection( GetSelection() );
980cdf0e10cSrcweir SetSelection( Selection( aSelection.Min(), aSelection.Min() ) );
981cdf0e10cSrcweir if ( bOnlyDirectories )
982cdf0e10cSrcweir Clear();
983cdf0e10cSrcweir else
984cdf0e10cSrcweir UpdatePicklistForSmartProtocol_Impl();
985cdf0e10cSrcweir Resize();
986cdf0e10cSrcweir }
987cdf0e10cSrcweir
988cdf0e10cSrcweir bCtrlClick = rKey.IsMod1();
989cdf0e10cSrcweir sal_Bool bHandled = sal_False;
990cdf0e10cSrcweir if ( GetOpenHdl().IsSet() )
991cdf0e10cSrcweir {
992cdf0e10cSrcweir bHandled = sal_True;
993cdf0e10cSrcweir GetOpenHdl().Call(this);
994cdf0e10cSrcweir }
995cdf0e10cSrcweir else if ( GetSelectHdl().IsSet() )
996cdf0e10cSrcweir {
997cdf0e10cSrcweir bHandled = sal_True;
998cdf0e10cSrcweir GetSelectHdl().Call(this);
999cdf0e10cSrcweir }
1000cdf0e10cSrcweir
1001cdf0e10cSrcweir bCtrlClick = sal_False;
1002cdf0e10cSrcweir
1003cdf0e10cSrcweir ClearModifyFlag();
1004cdf0e10cSrcweir return bHandled;
1005cdf0e10cSrcweir }
1006cdf0e10cSrcweir else if ( aCode == KEY_RETURN && !GetText().Len() && GetOpenHdl().IsSet() )
1007cdf0e10cSrcweir {
1008cdf0e10cSrcweir // for file dialog
1009cdf0e10cSrcweir bAutoCompleteMode = sal_False;
1010cdf0e10cSrcweir GetOpenHdl().Call(this);
1011cdf0e10cSrcweir return sal_True;
1012cdf0e10cSrcweir }
1013cdf0e10cSrcweir else if( aCode == KEY_ESCAPE )
1014cdf0e10cSrcweir {
1015cdf0e10cSrcweir Selection aSelection( GetSelection() );
1016cdf0e10cSrcweir if ( bAutoCompleteMode || aSelection.Min() != aSelection.Max() )
1017cdf0e10cSrcweir {
1018cdf0e10cSrcweir SetSelection( Selection( aSelection.Min(), aSelection.Min() ) );
1019cdf0e10cSrcweir if ( bOnlyDirectories )
1020cdf0e10cSrcweir Clear();
1021cdf0e10cSrcweir else
1022cdf0e10cSrcweir UpdatePicklistForSmartProtocol_Impl();
1023cdf0e10cSrcweir Resize();
1024cdf0e10cSrcweir }
1025cdf0e10cSrcweir else
1026cdf0e10cSrcweir {
1027cdf0e10cSrcweir return sal_False;
1028cdf0e10cSrcweir }
1029cdf0e10cSrcweir
1030cdf0e10cSrcweir bAutoCompleteMode = sal_False;
1031cdf0e10cSrcweir return sal_True;
1032cdf0e10cSrcweir }
1033cdf0e10cSrcweir else
1034cdf0e10cSrcweir {
1035cdf0e10cSrcweir return sal_False;
1036cdf0e10cSrcweir }
1037cdf0e10cSrcweir }
1038cdf0e10cSrcweir
1039cdf0e10cSrcweir //-------------------------------------------------------------------------
Modify()1040cdf0e10cSrcweir void SvtURLBox::Modify()
1041cdf0e10cSrcweir {
1042cdf0e10cSrcweir ComboBox::Modify();
1043cdf0e10cSrcweir }
1044cdf0e10cSrcweir
1045cdf0e10cSrcweir //-------------------------------------------------------------------------
PreNotify(NotifyEvent & rNEvt)1046cdf0e10cSrcweir long SvtURLBox::PreNotify( NotifyEvent& rNEvt )
1047cdf0e10cSrcweir {
1048cdf0e10cSrcweir if( rNEvt.GetWindow() == GetSubEdit() && rNEvt.GetType() == EVENT_KEYINPUT )
1049cdf0e10cSrcweir {
1050cdf0e10cSrcweir
1051cdf0e10cSrcweir const KeyEvent& rEvent = *rNEvt.GetKeyEvent();
1052cdf0e10cSrcweir const KeyCode& rKey = rEvent.GetKeyCode();
1053cdf0e10cSrcweir KeyCode aCode( rKey.GetCode() );
1054cdf0e10cSrcweir if( ProcessKey( rKey ) )
1055cdf0e10cSrcweir {
1056cdf0e10cSrcweir return sal_True;
1057cdf0e10cSrcweir }
1058cdf0e10cSrcweir else if( ( aCode == KEY_UP || aCode == KEY_DOWN ) && !rKey.IsMod2() )
1059cdf0e10cSrcweir {
1060cdf0e10cSrcweir Selection aSelection( GetSelection() );
1061cdf0e10cSrcweir sal_uInt16 nLen = (sal_uInt16)aSelection.Min();
1062cdf0e10cSrcweir GetSubEdit()->KeyInput( rEvent );
1063cdf0e10cSrcweir SetSelection( Selection( nLen, GetText().Len() ) );
1064cdf0e10cSrcweir return sal_True;
1065cdf0e10cSrcweir }
1066cdf0e10cSrcweir
1067cdf0e10cSrcweir if ( MatchesPlaceHolder( GetText() ) )
1068cdf0e10cSrcweir {
1069cdf0e10cSrcweir // set the selection so a key stroke will overwrite
1070cdf0e10cSrcweir // the placeholder rather than edit it
1071cdf0e10cSrcweir SetSelection( Selection( 0, GetText().Len() ) );
1072cdf0e10cSrcweir }
1073cdf0e10cSrcweir }
1074cdf0e10cSrcweir
1075cdf0e10cSrcweir return ComboBox::PreNotify( rNEvt );
1076cdf0e10cSrcweir }
1077cdf0e10cSrcweir
1078cdf0e10cSrcweir //-------------------------------------------------------------------------
IMPL_LINK(SvtURLBox,AutoCompleteHdl_Impl,void *,EMPTYARG)1079cdf0e10cSrcweir IMPL_LINK( SvtURLBox, AutoCompleteHdl_Impl, void*, EMPTYARG )
1080cdf0e10cSrcweir {
1081cdf0e10cSrcweir if ( GetSubEdit()->GetAutocompleteAction() == AUTOCOMPLETE_KEYINPUT )
1082cdf0e10cSrcweir {
1083cdf0e10cSrcweir TryAutoComplete( sal_False );
1084cdf0e10cSrcweir return 1L;
1085cdf0e10cSrcweir }
1086cdf0e10cSrcweir
1087cdf0e10cSrcweir return 0L;
1088cdf0e10cSrcweir }
1089cdf0e10cSrcweir
1090cdf0e10cSrcweir //-------------------------------------------------------------------------
Notify(NotifyEvent & rEvt)1091cdf0e10cSrcweir long SvtURLBox::Notify( NotifyEvent &rEvt )
1092cdf0e10cSrcweir {
1093cdf0e10cSrcweir if ( EVENT_GETFOCUS == rEvt.GetType() )
1094cdf0e10cSrcweir {
1095cdf0e10cSrcweir #ifndef UNX
1096cdf0e10cSrcweir // pb: don't select automatically on unix #93251#
1097cdf0e10cSrcweir SetSelection( Selection( 0, GetText().Len() ) );
1098cdf0e10cSrcweir #endif
1099cdf0e10cSrcweir }
1100cdf0e10cSrcweir else if ( EVENT_LOSEFOCUS == rEvt.GetType() )
1101cdf0e10cSrcweir {
1102cdf0e10cSrcweir if( !GetText().Len() )
1103cdf0e10cSrcweir ClearModifyFlag();
1104cdf0e10cSrcweir if ( pCtx )
1105cdf0e10cSrcweir {
1106cdf0e10cSrcweir pCtx->Stop();
1107cdf0e10cSrcweir pCtx = NULL;
1108cdf0e10cSrcweir }
1109cdf0e10cSrcweir }
1110cdf0e10cSrcweir
1111cdf0e10cSrcweir return ComboBox::Notify( rEvt );
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir
1114cdf0e10cSrcweir //-------------------------------------------------------------------------
Select()1115cdf0e10cSrcweir void SvtURLBox::Select()
1116cdf0e10cSrcweir {
1117cdf0e10cSrcweir ComboBox::Select();
1118cdf0e10cSrcweir ClearModifyFlag();
1119cdf0e10cSrcweir }
1120cdf0e10cSrcweir
1121cdf0e10cSrcweir //-------------------------------------------------------------------------
SetOnlyDirectories(sal_Bool bDir)1122cdf0e10cSrcweir void SvtURLBox::SetOnlyDirectories( sal_Bool bDir )
1123cdf0e10cSrcweir {
1124cdf0e10cSrcweir bOnlyDirectories = bDir;
1125cdf0e10cSrcweir if ( bOnlyDirectories )
1126cdf0e10cSrcweir Clear();
1127cdf0e10cSrcweir }
1128cdf0e10cSrcweir
1129cdf0e10cSrcweir //-------------------------------------------------------------------------
SetNoURLSelection(sal_Bool bSet)1130cdf0e10cSrcweir void SvtURLBox::SetNoURLSelection( sal_Bool bSet )
1131cdf0e10cSrcweir {
1132cdf0e10cSrcweir bNoSelection = bSet;
1133cdf0e10cSrcweir }
1134cdf0e10cSrcweir
1135cdf0e10cSrcweir //-------------------------------------------------------------------------
GetURL()1136cdf0e10cSrcweir String SvtURLBox::GetURL()
1137cdf0e10cSrcweir {
1138cdf0e10cSrcweir // wait for end of autocompletion
1139cdf0e10cSrcweir ::vos::OGuard aGuard( SvtMatchContext_Impl::GetMutex() );
1140cdf0e10cSrcweir
1141cdf0e10cSrcweir String aText( GetText() );
1142cdf0e10cSrcweir if ( MatchesPlaceHolder( aText ) )
1143cdf0e10cSrcweir return aPlaceHolder;
1144cdf0e10cSrcweir // try to get the right case preserving URL from the list of URLs
1145cdf0e10cSrcweir if ( pImp->pCompletions && pImp->pURLs )
1146cdf0e10cSrcweir {
1147cdf0e10cSrcweir for( sal_uInt16 nPos=0; nPos<pImp->pCompletions->Count(); nPos++ )
1148cdf0e10cSrcweir {
1149cdf0e10cSrcweir #ifdef DBG_UTIL
1150cdf0e10cSrcweir String aTmp( *(*pImp->pCompletions)[ nPos ] );
1151cdf0e10cSrcweir #endif
1152cdf0e10cSrcweir if( *(*pImp->pCompletions)[ nPos ] == aText )
1153cdf0e10cSrcweir return *(*pImp->pURLs)[nPos];
1154cdf0e10cSrcweir }
1155cdf0e10cSrcweir }
1156cdf0e10cSrcweir
1157cdf0e10cSrcweir #ifdef WNT
1158cdf0e10cSrcweir // erase trailing spaces on Windows since thay are invalid on this OS and
1159cdf0e10cSrcweir // most of the time they are inserted by accident via copy / paste
1160cdf0e10cSrcweir aText.EraseTrailingChars();
1161cdf0e10cSrcweir if ( !aText.Len() )
1162cdf0e10cSrcweir return aText;
1163cdf0e10cSrcweir // #i9739# - 2002-12-03 - fs@openoffice.org
1164cdf0e10cSrcweir #endif
1165cdf0e10cSrcweir
1166cdf0e10cSrcweir INetURLObject aObj( aText );
1167cdf0e10cSrcweir if( aText.Search( '*' ) != STRING_NOTFOUND || aText.Search( '?' ) != STRING_NOTFOUND )
1168cdf0e10cSrcweir {
1169cdf0e10cSrcweir // no autocompletion for wildcards
1170cdf0e10cSrcweir INetURLObject aTempObj;
1171cdf0e10cSrcweir if ( eSmartProtocol != INET_PROT_NOT_VALID )
1172cdf0e10cSrcweir aTempObj.SetSmartProtocol( eSmartProtocol );
1173cdf0e10cSrcweir if ( aTempObj.SetSmartURL( aText ) )
1174cdf0e10cSrcweir return aTempObj.GetMainURL( INetURLObject::NO_DECODE );
1175cdf0e10cSrcweir else
1176cdf0e10cSrcweir return aText;
1177cdf0e10cSrcweir }
1178cdf0e10cSrcweir
1179cdf0e10cSrcweir if ( aObj.GetProtocol() == INET_PROT_NOT_VALID )
1180cdf0e10cSrcweir {
1181cdf0e10cSrcweir String aName = ParseSmart( aText, aBaseURL, SvtPathOptions().GetWorkPath() );
1182cdf0e10cSrcweir aObj.SetURL( aName );
1183cdf0e10cSrcweir ::rtl::OUString aURL( aObj.GetMainURL( INetURLObject::NO_DECODE ) );
1184cdf0e10cSrcweir if ( !aURL.getLength() )
1185cdf0e10cSrcweir // aText itself is invalid, and even together with aBaseURL, it could not
1186cdf0e10cSrcweir // made valid -> no chance
1187cdf0e10cSrcweir return aText;
1188cdf0e10cSrcweir
1189cdf0e10cSrcweir bool bSlash = aObj.hasFinalSlash();
1190cdf0e10cSrcweir {
1191cdf0e10cSrcweir static const rtl::OUString aPropName(
1192cdf0e10cSrcweir rtl::OUString::createFromAscii("CasePreservingURL"));
1193cdf0e10cSrcweir
1194cdf0e10cSrcweir rtl::OUString aFileURL;
1195cdf0e10cSrcweir
1196cdf0e10cSrcweir Any aAny =
1197cdf0e10cSrcweir UCBContentHelper::GetProperty(aURL,aPropName);
1198cdf0e10cSrcweir sal_Bool success = (aAny >>= aFileURL);
1199cdf0e10cSrcweir String aTitle;
1200cdf0e10cSrcweir if(success)
1201cdf0e10cSrcweir aTitle = String(
1202cdf0e10cSrcweir INetURLObject(aFileURL).getName(
1203cdf0e10cSrcweir INetURLObject::LAST_SEGMENT,
1204cdf0e10cSrcweir true,
1205cdf0e10cSrcweir INetURLObject::DECODE_WITH_CHARSET ));
1206cdf0e10cSrcweir else
1207cdf0e10cSrcweir success =
1208cdf0e10cSrcweir UCBContentHelper::GetTitle(aURL,aTitle);
1209cdf0e10cSrcweir
1210cdf0e10cSrcweir if( success &&
1211cdf0e10cSrcweir ( aTitle.Len() > 1 ||
1212cdf0e10cSrcweir (aTitle.CompareToAscii("/") != 0 &&
1213cdf0e10cSrcweir aTitle.CompareToAscii(".") != 0) ) )
1214cdf0e10cSrcweir {
1215cdf0e10cSrcweir aObj.SetName( aTitle );
1216cdf0e10cSrcweir if ( bSlash )
1217cdf0e10cSrcweir aObj.setFinalSlash();
1218cdf0e10cSrcweir }
1219cdf0e10cSrcweir }
1220cdf0e10cSrcweir }
1221cdf0e10cSrcweir
1222cdf0e10cSrcweir return aObj.GetMainURL( INetURLObject::NO_DECODE );
1223cdf0e10cSrcweir }
1224cdf0e10cSrcweir
1225cdf0e10cSrcweir //-------------------------------------------------------------------------
DisableHistory()1226cdf0e10cSrcweir void SvtURLBox::DisableHistory()
1227cdf0e10cSrcweir {
1228cdf0e10cSrcweir bHistoryDisabled = sal_True;
1229cdf0e10cSrcweir UpdatePicklistForSmartProtocol_Impl();
1230cdf0e10cSrcweir }
1231cdf0e10cSrcweir
1232cdf0e10cSrcweir //-------------------------------------------------------------------------
SetBaseURL(const String & rURL)1233cdf0e10cSrcweir void SvtURLBox::SetBaseURL( const String& rURL )
1234cdf0e10cSrcweir {
1235cdf0e10cSrcweir ::vos::OGuard aGuard( SvtMatchContext_Impl::GetMutex() );
1236cdf0e10cSrcweir
1237cdf0e10cSrcweir // Reset match lists
1238cdf0e10cSrcweir if ( pImp->pCompletions )
1239cdf0e10cSrcweir pImp->pCompletions->Remove( 0, pImp->pCompletions->Count() );
1240cdf0e10cSrcweir
1241cdf0e10cSrcweir if ( pImp->pURLs )
1242cdf0e10cSrcweir pImp->pURLs->Remove( 0, pImp->pURLs->Count() );
1243cdf0e10cSrcweir
1244cdf0e10cSrcweir aBaseURL = rURL;
1245cdf0e10cSrcweir }
1246cdf0e10cSrcweir
1247cdf0e10cSrcweir //-------------------------------------------------------------------------
1248cdf0e10cSrcweir /** Parse leading ~ for Unix systems,
1249cdf0e10cSrcweir does nothing for Windows
1250cdf0e10cSrcweir */
TildeParsing(String & aText,String & aBaseURL)1251cdf0e10cSrcweir sal_Bool SvtURLBox_Impl::TildeParsing(
1252cdf0e10cSrcweir String&
1253cdf0e10cSrcweir #ifdef UNX
1254cdf0e10cSrcweir aText
1255cdf0e10cSrcweir #endif
1256cdf0e10cSrcweir , String&
1257cdf0e10cSrcweir #ifdef UNX
1258cdf0e10cSrcweir aBaseURL
1259cdf0e10cSrcweir #endif
1260cdf0e10cSrcweir )
1261cdf0e10cSrcweir {
1262cdf0e10cSrcweir #ifdef UNX
1263cdf0e10cSrcweir if( aText.Search( '~' ) == 0 )
1264cdf0e10cSrcweir {
1265cdf0e10cSrcweir String aParseTilde;
1266cdf0e10cSrcweir sal_Bool bTrailingSlash = sal_True; // use trailing slash
1267cdf0e10cSrcweir
1268cdf0e10cSrcweir if( aText.Len() == 1 || aText.GetChar( 1 ) == '/' )
1269cdf0e10cSrcweir {
1270cdf0e10cSrcweir // covers "~" or "~/..." cases
1271cdf0e10cSrcweir const char* aHomeLocation = getenv( "HOME" );
1272cdf0e10cSrcweir if( !aHomeLocation )
1273cdf0e10cSrcweir aHomeLocation = "";
1274cdf0e10cSrcweir
1275cdf0e10cSrcweir aParseTilde = String::CreateFromAscii( aHomeLocation );
1276cdf0e10cSrcweir
1277cdf0e10cSrcweir // in case the whole path is just "~" then there should
1278cdf0e10cSrcweir // be no trailing slash at the end
1279cdf0e10cSrcweir if( aText.Len() == 1 )
1280cdf0e10cSrcweir bTrailingSlash = sal_False;
1281cdf0e10cSrcweir }
1282cdf0e10cSrcweir else
1283cdf0e10cSrcweir {
1284cdf0e10cSrcweir // covers "~username" and "~username/..." cases
1285cdf0e10cSrcweir xub_StrLen nNameEnd = aText.Search( '/' );
1286cdf0e10cSrcweir String aUserName = aText.Copy( 1, ( nNameEnd != STRING_NOTFOUND ) ? nNameEnd : ( aText.Len() - 1 ) );
1287cdf0e10cSrcweir
1288cdf0e10cSrcweir struct passwd* pPasswd = NULL;
1289cdf0e10cSrcweir #ifdef SOLARIS
1290cdf0e10cSrcweir Sequence< sal_Int8 > sBuf( 1024 );
1291cdf0e10cSrcweir struct passwd aTmp;
1292cdf0e10cSrcweir sal_Int32 nRes = getpwnam_r( OUStringToOString( OUString( aUserName ), RTL_TEXTENCODING_ASCII_US ).getStr(),
1293cdf0e10cSrcweir &aTmp,
1294cdf0e10cSrcweir (char*)sBuf.getArray(),
1295cdf0e10cSrcweir 1024,
1296cdf0e10cSrcweir &pPasswd );
1297cdf0e10cSrcweir if( !nRes && pPasswd )
1298cdf0e10cSrcweir aParseTilde = String::CreateFromAscii( pPasswd->pw_dir );
1299cdf0e10cSrcweir else
1300cdf0e10cSrcweir return sal_False; // no such user
1301cdf0e10cSrcweir #else
1302cdf0e10cSrcweir pPasswd = getpwnam( OUStringToOString( OUString( aUserName ), RTL_TEXTENCODING_ASCII_US ).getStr() );
1303cdf0e10cSrcweir if( pPasswd )
1304cdf0e10cSrcweir aParseTilde = String::CreateFromAscii( pPasswd->pw_dir );
1305cdf0e10cSrcweir else
1306cdf0e10cSrcweir return sal_False; // no such user
1307cdf0e10cSrcweir #endif
1308cdf0e10cSrcweir
1309cdf0e10cSrcweir // in case the path is "~username" then there should
1310cdf0e10cSrcweir // be no trailing slash at the end
1311cdf0e10cSrcweir if( nNameEnd == STRING_NOTFOUND )
1312cdf0e10cSrcweir bTrailingSlash = sal_False;
1313cdf0e10cSrcweir }
1314cdf0e10cSrcweir
1315cdf0e10cSrcweir if( !bTrailingSlash )
1316cdf0e10cSrcweir {
1317cdf0e10cSrcweir if( !aParseTilde.Len() || aParseTilde.EqualsAscii( "/" ) )
1318cdf0e10cSrcweir {
1319cdf0e10cSrcweir // "/" path should be converted to "/."
1320cdf0e10cSrcweir aParseTilde = String::CreateFromAscii( "/." );
1321cdf0e10cSrcweir }
1322cdf0e10cSrcweir else
1323cdf0e10cSrcweir {
1324cdf0e10cSrcweir // "blabla/" path should be converted to "blabla"
1325cdf0e10cSrcweir aParseTilde.EraseTrailingChars( '/' );
1326cdf0e10cSrcweir }
1327cdf0e10cSrcweir }
1328cdf0e10cSrcweir else
1329cdf0e10cSrcweir {
1330cdf0e10cSrcweir if( aParseTilde.GetChar( aParseTilde.Len() - 1 ) != '/' )
1331cdf0e10cSrcweir aParseTilde += '/';
1332cdf0e10cSrcweir if( aText.Len() > 2 )
1333cdf0e10cSrcweir aParseTilde += aText.Copy( 2 );
1334cdf0e10cSrcweir }
1335cdf0e10cSrcweir
1336cdf0e10cSrcweir aText = aParseTilde;
1337cdf0e10cSrcweir aBaseURL = String(); // tilde provide absolute path
1338cdf0e10cSrcweir }
1339cdf0e10cSrcweir #endif
1340cdf0e10cSrcweir
1341cdf0e10cSrcweir return sal_True;
1342cdf0e10cSrcweir }
1343cdf0e10cSrcweir
1344cdf0e10cSrcweir //-------------------------------------------------------------------------
SetUrlFilter(const IUrlFilter * _pFilter)1345cdf0e10cSrcweir void SvtURLBox::SetUrlFilter( const IUrlFilter* _pFilter )
1346cdf0e10cSrcweir {
1347cdf0e10cSrcweir pImp->pUrlFilter = _pFilter;
1348cdf0e10cSrcweir }
1349cdf0e10cSrcweir
1350cdf0e10cSrcweir //-------------------------------------------------------------------------
GetUrlFilter() const1351cdf0e10cSrcweir const IUrlFilter* SvtURLBox::GetUrlFilter( ) const
1352cdf0e10cSrcweir {
1353cdf0e10cSrcweir return pImp->pUrlFilter;
1354cdf0e10cSrcweir }
1355cdf0e10cSrcweir // -----------------------------------------------------------------------------
SetFilter(const String & _sFilter)1356cdf0e10cSrcweir void SvtURLBox::SetFilter(const String& _sFilter)
1357cdf0e10cSrcweir {
1358cdf0e10cSrcweir pImp->m_aFilters.clear();
1359cdf0e10cSrcweir FilterMatch::createWildCardFilterList(_sFilter,pImp->m_aFilters);
1360cdf0e10cSrcweir }
1361cdf0e10cSrcweir
1362