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/sdbc/XResultSet.hpp>
30#include <com/sun/star/sdbc/XRow.hpp>
31#include <com/sun/star/task/XInteractionHandler.hpp>
32#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
33#include <com/sun/star/ucb/UniversalContentBroker.hpp>
34#include <com/sun/star/ucb/XAnyCompareFactory.hpp>
35#include <com/sun/star/ucb/XCommandProcessor2.hpp>
36#include <com/sun/star/ucb/XProgressHandler.hpp>
37#include <com/sun/star/ucb/XContentAccess.hpp>
38#include <com/sun/star/ucb/SortedDynamicResultSetFactory.hpp>
44#include <osl/file.hxx>
45#include <osl/mutex.hxx>
76 static bool TildeParsing( OUString& aText, OUString& aBaseUrl );
80 FilterMatch::createWildCardFilterList(
u"",
m_aFilters);
97 css::uno::Reference< css::ucb::XCommandProcessor >
processor_;
103 virtual void execute()
override;
105 void Insert(
const OUString& rCompletion,
const OUString& rURL,
bool bForce =
false);
106 void ReadFolder(
const OUString& rURL,
const OUString& rMatch,
bool bSmart );
107 static void FillPicklist(std::vector<OUString>& rPickList);
117 ::osl::Mutex& theSvtMatchContextMutex()
119 static ::osl::Mutex SINGLETON;
125 : Thread(
"MatchContext_Impl" )
127 , aText(
std::move( _aText ))
129 , bOnlyDirectories( pBoxP->bOnlyDirectories )
130 , bNoSelection( pBoxP->bNoSelection )
139 aLink.ClearPendingCall();
146 sal_uInt32
nCount = seqPicklist.size();
148 for( sal_uInt32 nItem=0; nItem <
nCount; nItem++ )
151 aURL.SetURL( seqPicklist[nItem].sTitle );
158 css::uno::Reference< css::ucb::XCommandProcessor > proc;
161 std::scoped_lock g(
mutex_);
191 std::scoped_lock g(
mutex_);
201 for (
auto const& completion : aCompletions)
205 osl::FileBase::getFileURLFromSystemPath(completion, sURL);
209 if ( !sURL.isEmpty() && !sURL.endsWith(
"/") )
211 OUString sUpperURL( sURL.toAsciiUpperCase() );
213 if ( ::std::none_of( pBox->pImpl->m_aFilters.begin(),
214 pBox->pImpl->m_aFilters.end(),
215 FilterMatch( sUpperURL ) ) )
221 pBox->append_text(completion);
224 pBox->EnableAutocomplete(!bNoSelection);
227 pBox->pImpl->aURLs = aURLs;
228 pBox->pImpl->aCompletions = aCompletions;
230 aCompletions.clear();
238 const OUString& rURL,
249 aURLs.push_back(rURL);
254 const OUString& rMatch,
258 if( !UCBContentHelper::IsFolder( rURL ) )
261 bool bPureHomePath =
false;
263 bPureHomePath =
aText.startsWith(
"~" ) &&
aText.indexOf(
'/' ) == -1;
266 bool bExectMatch = bPureHomePath
268 ||
aText.endsWith(
"/.")
269 ||
aText.endsWith(
"/..");
274 if ( bPureHomePath && rMatch ==
"file:///." )
278 OUString aNewText =
aText +
"/";
279 Insert( aNewText, rURL,
true );
293 aMatchName = aMatchName.toAsciiLowerCase();
296 if ( rMatch.endsWith(
"/") )
300 sal_Int32 nMatchLen = aMatchName.getLength();
308 new ::ucbhelper::CommandEnvironment( uno::Reference< XInteractionHandler >(),
309 uno::Reference< XProgressHandler >() ),
311 uno::Reference< XResultSet > xResultSet;
318 uno::Reference< XDynamicResultSet > xDynResultSet = aCnt.createDynamicCursor( {
"Title",
"IsFolder" }, eInclude );
320 uno::Reference < XAnyCompareFactory > xCompare;
321 uno::Reference < XSortedDynamicResultSetFactory > xSRSFac =
322 SortedDynamicResultSetFactory::create( ::comphelper::getProcessComponentContext() );
324 uno::Reference< XDynamicResultSet > xDynamicResultSet =
325 xSRSFac->createSortedDynamicResultSet( xDynResultSet, { { 2,
false }, { 1,
true } }, xCompare );
327 if ( xDynamicResultSet.is() )
329 xResultSet = xDynamicResultSet->getStaticResultSet();
332 catch( css::uno::Exception& ) {}
334 if ( xResultSet.is() )
336 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
337 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
341 while ( schedule() && xResultSet->next() )
343 OUString
aURL = xContentAccess->queryContentIdentifierString();
344 OUString aTitle = xRow->getString(1);
345 bool bIsFolder = xRow->getBoolean(2);
348 aTitle = aTitle.toAsciiLowerCase();
352 (bExectMatch && aMatchName == aTitle) ||
353 (!bExectMatch && aTitle.startsWith(aMatchName))
368 OUString aInput(
aText );
371 if (
aText.endsWith(
".") || bPureHomePath)
374 aMatch = aMatch.copy( nMatchLen );
379 DBG_ASSERT( aInput.getLength() >= nMatchLen,
"Suspicious Matching!" );
380 aInput = aInput.copy( 0, aInput.getLength() - nMatchLen );
388 aInput += OUStringChar(aDelimiter);
394 catch( css::uno::Exception& )
399 catch( css::uno::Exception& )
406 ::osl::MutexGuard aGuard( theSvtMatchContextMutex() );
409 std::scoped_lock g(
mutex_);
420 if (
aText.isEmpty() )
423 if(
aText.indexOf(
'*' ) != -1 ||
aText.indexOf(
'?' ) != -1 )
437 if( eProt == INetProtocol::NotValid || eProt == eSmartProt || (eSmartProt == INetProtocol::NotValid && eProt == eBaseProt) )
442 if ( eProt == INetProtocol::NotValid )
446 if ( !aMatch.isEmpty() )
456 if ( !aMainURL.isEmpty()
457 && aURLObject.
GetProtocol() == INetProtocol::File )
463 css::uno::Reference< css::uno::XComponentContext >
466 css::ucb::XUniversalContentBroker >
ucb(
467 css::ucb::UniversalContentBroker::create(
469 css::uno::Sequence< css::beans::Property > prop{
476 css::uno::Reference< css::ucb::XCommandProcessor >
479 ucb->createContentIdentifier(aMainURL)),
480 css::uno::UNO_QUERY_THROW);
481 css::uno::Reference< css::ucb::XCommandProcessor2 >
482 proc2(proc, css::uno::UNO_QUERY);
483 sal_Int32
id = proc->createCommandIdentifier();
486 std::scoped_lock g(
mutex_);
492 "getPropertyValues", -1,
493 css::uno::Any(prop)),
496 css::ucb::XCommandEnvironment >());
500 proc2->releaseCommandIdentifier(
id);
501 }
catch (css::uno::RuntimeException &) {
508 proc2->releaseCommandIdentifier(
id);
511 std::scoped_lock g(
mutex_);
522 css::uno::Reference< css::sdbc::XRow > row(
523 res, css::uno::UNO_QUERY_THROW);
524 folder = row->getBoolean(1) && !row->wasNull();
525 }
catch (css::uno::Exception &) {
550 OUString aCurString, aCurMainURL;
552 aObj.
SetSmartProtocol( eSmartProt == INetProtocol::NotValid ? INetProtocol::Http : eSmartProt );
564 if( eProt != INetProtocol::NotValid && aCurObj.
GetProtocol() != eProt )
567 if( eSmartProt != INetProtocol::NotValid && aCurObj.
GetProtocol() != eSmartProt )
572 case INetProtocol::Http:
573 case INetProtocol::Https:
574 case INetProtocol::Ftp:
576 if( eProt == INetProtocol::NotValid && !bFull )
583 aCurString = aCurMainURL;
584 if( eProt == INetProtocol::NotValid )
588 if ( aScheme.startsWithIgnoreAsciiCase(
aText ) &&
aText.getLength() < aScheme.getLength() )
604 aCurString = aCurString.copy( aScheme.getLength() );
607 if( aCurString.startsWithIgnoreAsciiCase(
aText ) )
619 OUString
aURL( aMatch );
620 if( eProt == INetProtocol::NotValid )
623 if(
aText.getLength() < aMatch.getLength() )
635 if( aCurMainURL.startsWith(
aText) )
637 if(
aText.getLength() < aCurMainURL.getLength() )
638 Insert( aCurMainURL, aCurMainURL );
669 if( aText.startsWith(
"~" ) )
671 OUString aParseTilde;
672 bool bTrailingSlash =
true;
674 if( aText.getLength() == 1 || aText[ 1 ] ==
'/' )
677 const char* aHomeLocation = getenv(
"HOME" );
681 aParseTilde = OUString::createFromAscii(aHomeLocation);
685 if( aText.getLength() == 1 )
686 bTrailingSlash =
false;
691 sal_Int32 nNameEnd = aText.indexOf(
'/' );
692 OUString aUserName = aText.copy( 1, ( nNameEnd != -1 ) ? nNameEnd : ( aText.getLength() - 1 ) );
694 struct passwd* pPasswd =
nullptr;
696 Sequence< sal_Int8 > sBuf( 1024 );
698 sal_Int32 nRes = getpwnam_r(
OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US ).getStr(),
700 (
char*)sBuf.getArray(),
703 if( !nRes && pPasswd )
704 aParseTilde = OUString::createFromAscii(pPasswd->pw_dir);
708 pPasswd = getpwnam(
OUStringToOString( aUserName, RTL_TEXTENCODING_ASCII_US ).getStr() );
710 aParseTilde = OUString::createFromAscii(pPasswd->pw_dir);
718 bTrailingSlash =
false;
721 if( !bTrailingSlash )
723 if( aParseTilde.isEmpty() || aParseTilde ==
"/" )
736 if( !aParseTilde.endsWith(
"/") )
738 if( aText.getLength() > 2 )
739 aParseTilde += aText.subView( 2 );
755 OUString aText = _aText;
768 if( aText.startsWith(
"/" ) )
784 OUString aSmart( aText );
792 if( aText.startsWith(
"\\") && (aText.getLength() < 2 || aText[ 1 ] !=
'\\') )
799 aSmart = aSmart.copy(1);
806 bool bWasAbsolute =
false;
813 if ( aText.endsWith(
".") )
824 osl::FileBase::getFileURLFromSystemPath( aText, aTmpMatch );
833 OUString aCurText =
m_xWidget->get_active_text();
834 int nStartPos, nEndPos;
835 m_xWidget->get_entry_selection_bounds(nStartPos, nEndPos);
836 if (std::max(nStartPos, nEndPos) != aCurText.getLength())
839 auto nLen = std::min(nStartPos, nEndPos);
840 aCurText = aCurText.copy( 0, nLen );
841 if (!aCurText.isEmpty())
857 : aChangedIdle(
"svtools::URLBox aChangedIdle")
859 , bOnlyDirectories( false )
860 , bHistoryDisabled( false )
861 , bNoSelection( false )
919 aCurObj.
SetURL( rPropertySet.sURL );
921 if ( !rPropertySet.sURL.isEmpty() && (
eSmartProtocol != INetProtocol::NotValid ) )
929 if ( !
aURL.isEmpty() )
931 bool bFound =
aURL.endsWith(
"/");
934 OUString aUpperURL =
aURL.toAsciiUpperCase();
936 bFound = ::std::any_of(
pImpl->m_aFilters.begin(),
937 pImpl->m_aFilters.end(),
938 FilterMatch( aUpperURL ) );
943 if (osl::FileBase::getSystemPathFromFileURL(
aURL, aFile) == osl::FileBase::E_None)
955 aChangedIdle.Start();
993 ::osl::MutexGuard aGuard( theSvtMatchContextMutex() );
995 OUString aText(
m_xWidget->get_active_text());
1000 for(std::vector<OUString>::iterator
i =
pImpl->aCompletions.begin(), j =
pImpl->aURLs.begin();
i !=
pImpl->aCompletions.end() && j !=
pImpl->aURLs.end(); ++
i, ++j)
1010 if ( aText.isEmpty() )
1016 if( aText.indexOf(
'*' ) != -1 || aText.indexOf(
'?' ) != -1 )
1028 if ( aObj.
GetProtocol() == INetProtocol::NotValid )
1033 if (
aURL.isEmpty() )
1042 Any aAny = UCBContentHelper::GetProperty(
aURL,
"CasePreservingURL");
1043 bool success = (aAny >>= aFileURL);
1052 UCBContentHelper::GetTitle(
aURL,&aTitle);
1054 if( success && aTitle !=
"/" && aTitle !=
"." )
1068 ::osl::MutexGuard aGuard( theSvtMatchContextMutex() );
1071 pImpl->aCompletions.clear();
1072 pImpl->aURLs.clear();
1085 pImpl->m_aFilters.clear();
1086 FilterMatch::createWildCardFilterList(_sFilter,
pImpl->m_aFilters);
1089void FilterMatch::createWildCardFilterList(std::u16string_view _rFilterList,::std::vector< WildCard >& _rFilters)
1091 if( !_rFilterList.empty() )
1099 if ( !sToken.isEmpty() )
1101 _rFilters.emplace_back( sToken.toAsciiUpperCase() );
1104 while ( nIndex >= 0 );
1109 _rFilters.emplace_back(u
"*" );
OUString getName(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true, DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
void SetSmartProtocol(INetProtocol eTheSmartScheme)
static OUString GetScheme(INetProtocol eTheScheme)
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
INetURLObject smartRel2Abs(OUString const &rTheRelURIRef, bool &rWasAbsolute, bool bIgnoreFragment=false, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, bool bRelativeNonURIs=false, FSysStyle eStyle=FSysStyle::Detect) const
bool removeSegment(sal_Int32 nIndex=LAST_SEGMENT, bool bIgnoreFinalSlash=true)
bool SetSmartURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8, FSysStyle eStyle=FSysStyle::Detect)
static INetProtocol CompareProtocolScheme(std::u16string_view aTheAbsURIRef)
OUString GetURLPath(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool setName(std::u16string_view rTheName, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool hasFinalSlash() const
bool SetURLPath(std::u16string_view rThePath, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
INetProtocol GetProtocol() const
bool SetMark(std::u16string_view rTheFragment, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool SetParam(std::u16string_view rTheQuery, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
OUString getFSysPath(FSysStyle eStyle, sal_Unicode *pDelimiter=nullptr) const
OUString GetURLNoPass(DecodeMechanism eMechanism=DecodeMechanism::ToIUri, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool SetURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
static OUString encode(std::u16string_view rText, Part ePart, EncodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
constexpr tools::Long Width() const
DECL_LINK(Select_Impl, void *, void)
static void FillPicklist(std::vector< OUString > &rPickList)
void ReadFolder(const OUString &rURL, const OUString &rMatch, bool bSmart)
std::vector< OUString > aURLs
virtual void execute() override
std::vector< OUString > aCompletions
std::vector< OUString > aPickList
virtual ~SvtMatchContext_Impl() override
SvtMatchContext_Impl(SvtURLBox *pBoxP, OUString aText)
svtools::AsynchronLink aLink
void Insert(const OUString &rCompletion, const OUString &rURL, bool bForce=false)
css::uno::Reference< css::ucb::XCommandProcessor > processor_
std::vector< WildCard > m_aFilters
std::vector< OUString > aCompletions
static bool TildeParsing(OUString &aText, OUString &aBaseUrl)
Parse leading ~ for Unix systems, does nothing for Windows.
std::vector< OUString > aURLs
SVT_DLLPRIVATE void UpdatePicklistForSmartProtocol_Impl()
SvtURLBox(std::unique_ptr< weld::ComboBox > xWidget)
rtl::Reference< SvtMatchContext_Impl > pCtx
bool MatchesPlaceHolder(std::u16string_view sToMatch) const
void SetOnlyDirectories(bool bDir)
std::unique_ptr< SvtURLBox_Impl > pImpl
std::unique_ptr< weld::ComboBox > m_xWidget
INetProtocol GetSmartProtocol() const
void SetSmartProtocol(INetProtocol eProt)
SVT_DLLPRIVATE void Init()
void SetBaseURL(const OUString &rURL)
INetProtocol eSmartProtocol
static OUString ParseSmart(const OUString &aText, const OUString &aBaseURL)
void SetNoURLSelection(bool bSet)
void SetFilter(std::u16string_view _sFilter)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
css::uno::Type const & get()
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
IMPL_LINK_NOARG(SvtMatchContext_Impl, Select_Impl, void *, void)
#define LINK(Instance, Class, Member)
std::vector< HistoryItem > GetList(EHistoryType eHistory)
OString stripEnd(const OString &rIn, char c)
Reference< XComponentContext > getProcessComponentContext()
OSQLColumns::const_iterator find(const OSQLColumns::const_iterator &first, const OSQLColumns::const_iterator &last, std::u16string_view _rVal, const ::comphelper::UStringMixEqual &_rCase)
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
INCLUDE_FOLDERS_AND_DOCUMENTS