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

Generated by: LCOV version 1.10