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