LCOV - code coverage report
Current view: top level - libreoffice/svtools/source/control - inettbc.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 540 0.0 %
Date: 2012-12-17 Functions: 0 38 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10