xref: /aoo41x/main/svtools/source/control/inettbc.cxx (revision 79aad27f)
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