1*5900e8ecSAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 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 10cdf0e10cSrcweir * 11*5900e8ecSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 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. 19cdf0e10cSrcweir * 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 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 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 168cdf0e10cSrcweir SvtMatchContext_Impl::~SvtMatchContext_Impl() 169cdf0e10cSrcweir { 170cdf0e10cSrcweir aLink.ClearPendingCall(); 171cdf0e10cSrcweir delete pURLs; 172cdf0e10cSrcweir delete pCompletions; 173cdf0e10cSrcweir } 174cdf0e10cSrcweir 175cdf0e10cSrcweir //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 206cdf0e10cSrcweir void SAL_CALL SvtMatchContext_Impl::Cancel() 207cdf0e10cSrcweir { 208cdf0e10cSrcweir // Cancel button pressed 209cdf0e10cSrcweir terminate(); 210cdf0e10cSrcweir } 211cdf0e10cSrcweir 212cdf0e10cSrcweir //------------------------------------------------------------------------- 213cdf0e10cSrcweir void SvtMatchContext_Impl::Stop() 214cdf0e10cSrcweir { 215cdf0e10cSrcweir bStop = sal_True; 216cdf0e10cSrcweir 217cdf0e10cSrcweir if( isRunning() ) 218cdf0e10cSrcweir terminate(); 219cdf0e10cSrcweir } 220cdf0e10cSrcweir 221cdf0e10cSrcweir //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 885cdf0e10cSrcweir void SvtURLBox::SetSmartProtocol( INetProtocol eProt ) 886cdf0e10cSrcweir { 887cdf0e10cSrcweir if ( eSmartProtocol != eProt ) 888cdf0e10cSrcweir { 889cdf0e10cSrcweir eSmartProtocol = eProt; 890cdf0e10cSrcweir UpdatePicklistForSmartProtocol_Impl(); 891cdf0e10cSrcweir } 892cdf0e10cSrcweir } 893cdf0e10cSrcweir 894cdf0e10cSrcweir //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 1040cdf0e10cSrcweir void SvtURLBox::Modify() 1041cdf0e10cSrcweir { 1042cdf0e10cSrcweir ComboBox::Modify(); 1043cdf0e10cSrcweir } 1044cdf0e10cSrcweir 1045cdf0e10cSrcweir //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 1115cdf0e10cSrcweir void SvtURLBox::Select() 1116cdf0e10cSrcweir { 1117cdf0e10cSrcweir ComboBox::Select(); 1118cdf0e10cSrcweir ClearModifyFlag(); 1119cdf0e10cSrcweir } 1120cdf0e10cSrcweir 1121cdf0e10cSrcweir //------------------------------------------------------------------------- 1122cdf0e10cSrcweir void SvtURLBox::SetOnlyDirectories( sal_Bool bDir ) 1123cdf0e10cSrcweir { 1124cdf0e10cSrcweir bOnlyDirectories = bDir; 1125cdf0e10cSrcweir if ( bOnlyDirectories ) 1126cdf0e10cSrcweir Clear(); 1127cdf0e10cSrcweir } 1128cdf0e10cSrcweir 1129cdf0e10cSrcweir //------------------------------------------------------------------------- 1130cdf0e10cSrcweir void SvtURLBox::SetNoURLSelection( sal_Bool bSet ) 1131cdf0e10cSrcweir { 1132cdf0e10cSrcweir bNoSelection = bSet; 1133cdf0e10cSrcweir } 1134cdf0e10cSrcweir 1135cdf0e10cSrcweir //------------------------------------------------------------------------- 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 //------------------------------------------------------------------------- 1226cdf0e10cSrcweir void SvtURLBox::DisableHistory() 1227cdf0e10cSrcweir { 1228cdf0e10cSrcweir bHistoryDisabled = sal_True; 1229cdf0e10cSrcweir UpdatePicklistForSmartProtocol_Impl(); 1230cdf0e10cSrcweir } 1231cdf0e10cSrcweir 1232cdf0e10cSrcweir //------------------------------------------------------------------------- 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 */ 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 //------------------------------------------------------------------------- 1345cdf0e10cSrcweir void SvtURLBox::SetUrlFilter( const IUrlFilter* _pFilter ) 1346cdf0e10cSrcweir { 1347cdf0e10cSrcweir pImp->pUrlFilter = _pFilter; 1348cdf0e10cSrcweir } 1349cdf0e10cSrcweir 1350cdf0e10cSrcweir //------------------------------------------------------------------------- 1351cdf0e10cSrcweir const IUrlFilter* SvtURLBox::GetUrlFilter( ) const 1352cdf0e10cSrcweir { 1353cdf0e10cSrcweir return pImp->pUrlFilter; 1354cdf0e10cSrcweir } 1355cdf0e10cSrcweir // ----------------------------------------------------------------------------- 1356cdf0e10cSrcweir void SvtURLBox::SetFilter(const String& _sFilter) 1357cdf0e10cSrcweir { 1358cdf0e10cSrcweir pImp->m_aFilters.clear(); 1359cdf0e10cSrcweir FilterMatch::createWildCardFilterList(_sFilter,pImp->m_aFilters); 1360cdf0e10cSrcweir } 1361cdf0e10cSrcweir 1362