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

Generated by: LCOV version 1.10