summaryrefslogtreecommitdiff
path: root/fpicker
diff options
context:
space:
mode:
authorCaolán McNamara <caolanm@redhat.com>2019-10-04 13:23:55 +0100
committerCaolán McNamara <caolanm@redhat.com>2019-10-05 16:06:59 +0200
commit76c5f33e65e9a36c94c46f1ed0b6d33721d21cfb (patch)
tree35efc002c6f8e300b6fb7b408f5727cf999361a8 /fpicker
parent108d1b7c62bba7220f0e61bba8bb04ccc545bc63 (diff)
move file picker only code to fpicker
Change-Id: I47cc2cb7db396a06a2abeffe4a5d40a039f21c58 Reviewed-on: https://gerrit.libreoffice.org/80222 Tested-by: Jenkins Reviewed-by: Caolán McNamara <caolanm@redhat.com> Tested-by: Caolán McNamara <caolanm@redhat.com>
Diffstat (limited to 'fpicker')
-rw-r--r--fpicker/Library_fps_office.mk5
-rw-r--r--fpicker/inc/bitmaps.hlst2
-rw-r--r--fpicker/source/office/OfficeControlAccess.hxx2
-rw-r--r--fpicker/source/office/RemoteFilesDialog.hxx4
-rw-r--r--fpicker/source/office/asyncfilepicker.cxx2
-rw-r--r--fpicker/source/office/contentenumeration.cxx330
-rw-r--r--fpicker/source/office/contentenumeration.hxx240
-rw-r--r--fpicker/source/office/fileview.cxx1922
-rw-r--r--fpicker/source/office/fileview.hxx197
-rw-r--r--fpicker/source/office/foldertree.cxx170
-rw-r--r--fpicker/source/office/foldertree.hxx47
-rw-r--r--fpicker/source/office/iconview.cxx233
-rw-r--r--fpicker/source/office/iconview.hxx41
-rw-r--r--fpicker/source/office/iconviewimpl.cxx662
-rw-r--r--fpicker/source/office/iconviewimpl.hxx68
-rw-r--r--fpicker/source/office/iodlg.cxx2
-rw-r--r--fpicker/source/office/iodlgimp.cxx2
17 files changed, 3923 insertions, 6 deletions
diff --git a/fpicker/Library_fps_office.mk b/fpicker/Library_fps_office.mk
index 996e5994d07a..626f357a98b3 100644
--- a/fpicker/Library_fps_office.mk
+++ b/fpicker/Library_fps_office.mk
@@ -45,9 +45,14 @@ $(eval $(call gb_Library_add_exception_objects,fps_office,\
fpicker/source/office/asyncfilepicker \
fpicker/source/office/breadcrumb \
fpicker/source/office/commonpicker \
+ fpicker/source/office/contentenumeration \
+ fpicker/source/office/fileview \
+ fpicker/source/office/foldertree \
fpicker/source/office/fpinteraction \
fpicker/source/office/fpsmartcontent \
fpicker/source/office/fps_office \
+ fpicker/source/office/iconview \
+ fpicker/source/office/iconviewimpl \
fpicker/source/office/iodlg \
fpicker/source/office/iodlgimp \
fpicker/source/office/OfficeControlAccess \
diff --git a/fpicker/inc/bitmaps.hlst b/fpicker/inc/bitmaps.hlst
index 61d5b71186de..878058154fb6 100644
--- a/fpicker/inc/bitmaps.hlst
+++ b/fpicker/inc/bitmaps.hlst
@@ -10,10 +10,12 @@
#ifndef INCLUDED_FPICKER_INC_BITMAPS_HRC
#define INCLUDED_FPICKER_INC_BITMAPS_HRC
+#define RID_BMP_FOLDER_OPEN "res/folderop.png"
#define BMP_FILEDLG_BTN_UP "res/fp010.png"
#define BMP_FILEDLG_CREATEFOLDER "fpicker/res/fp014.png"
#define BMP_FILEDLG_PLACE_LOCAL "fpicker/res/fp015.png"
#define BMP_FILEDLG_PLACE_REMOTE "fpicker/res/fp016.png"
+#define RID_BMP_FOLDER "svtools/res/folder.png"
#endif
diff --git a/fpicker/source/office/OfficeControlAccess.hxx b/fpicker/source/office/OfficeControlAccess.hxx
index 7f1600bd587c..fcba48674dc9 100644
--- a/fpicker/source/office/OfficeControlAccess.hxx
+++ b/fpicker/source/office/OfficeControlAccess.hxx
@@ -20,9 +20,9 @@
#ifndef INCLUDED_FPICKER_SOURCE_OFFICE_OFFICECONTROLACCESS_HXX
#define INCLUDED_FPICKER_SOURCE_OFFICE_OFFICECONTROLACCESS_HXX
-#include <svtools/fileview.hxx>
#include <vcl/lstbox.hxx>
#include <com/sun/star/lang/IllegalArgumentException.hpp>
+#include "fileview.hxx"
#include "pickercallbacks.hxx"
#include <o3tl/typed_flags_set.hxx>
diff --git a/fpicker/source/office/RemoteFilesDialog.hxx b/fpicker/source/office/RemoteFilesDialog.hxx
index 140dd65622ec..5331107018d5 100644
--- a/fpicker/source/office/RemoteFilesDialog.hxx
+++ b/fpicker/source/office/RemoteFilesDialog.hxx
@@ -11,10 +11,8 @@
#define INCLUDED_SVTOOLS_REMOTEFILESDIALOG_HXX
#include <svtools/autocmpledit.hxx>
-#include <svtools/foldertree.hxx>
#include <svtools/place.hxx>
#include <svtools/PlaceEditDialog.hxx>
-#include <svtools/fileview.hxx>
#include <vcl/errinf.hxx>
@@ -38,6 +36,8 @@
#include "fpdialogbase.hxx"
#include "breadcrumb.hxx"
+#include "fileview.hxx"
+#include "foldertree.hxx"
#include "QueryFolderName.hxx"
using namespace ::com::sun::star::beans;
diff --git a/fpicker/source/office/asyncfilepicker.cxx b/fpicker/source/office/asyncfilepicker.cxx
index f547b2fd634f..4dc64af3d4eb 100644
--- a/fpicker/source/office/asyncfilepicker.cxx
+++ b/fpicker/source/office/asyncfilepicker.cxx
@@ -19,8 +19,8 @@
#include "asyncfilepicker.hxx"
+#include "fileview.hxx"
#include "iodlg.hxx"
-#include <svtools/fileview.hxx>
#include <tools/debug.hxx>
#include <osl/diagnose.h>
diff --git a/fpicker/source/office/contentenumeration.cxx b/fpicker/source/office/contentenumeration.cxx
new file mode 100644
index 000000000000..2ca057036a64
--- /dev/null
+++ b/fpicker/source/office/contentenumeration.cxx
@@ -0,0 +1,330 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "contentenumeration.hxx"
+#include <svtools/imagemgr.hxx>
+
+#include <com/sun/star/sdbc/XResultSet.hpp>
+#include <com/sun/star/sdbc/XRow.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <com/sun/star/ucb/XDynamicResultSet.hpp>
+#include <com/sun/star/ucb/XContentAccess.hpp>
+#include <com/sun/star/util/DateTime.hpp>
+#include <com/sun/star/document/DocumentProperties.hpp>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/sequence.hxx>
+#include <vcl/svapp.hxx>
+#include <osl/mutex.hxx>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <tools/diagnose_ex.h>
+#include <tools/urlobj.hxx>
+
+namespace svt
+{
+
+
+#define ROW_TITLE 1
+#define ROW_SIZE 2
+#define ROW_DATE_MOD 3
+#define ROW_DATE_CREATE 4
+#define ROW_IS_FOLDER 5
+#define ROW_TARGET_URL 6
+#define ROW_IS_HIDDEN 7
+#define ROW_IS_VOLUME 8
+#define ROW_IS_REMOTE 9
+#define ROW_IS_REMOVABLE 10
+#define ROW_IS_FLOPPY 11
+#define ROW_IS_COMPACTDISC 12
+
+ using ::com::sun::star::uno::Reference;
+ using ::com::sun::star::uno::Sequence;
+ using ::com::sun::star::uno::Exception;
+ using ::com::sun::star::uno::UNO_QUERY;
+ using ::com::sun::star::util::DateTime;
+ using ::com::sun::star::sdbc::XResultSet;
+ using ::com::sun::star::sdbc::XRow;
+ using ::com::sun::star::ucb::XDynamicResultSet;
+ using ::com::sun::star::ucb::CommandAbortedException;
+ using ::com::sun::star::ucb::XContentAccess;
+ using ::com::sun::star::ucb::XCommandEnvironment;
+ using ::com::sun::star::beans::PropertyValue;
+ using ::com::sun::star::document::DocumentProperties;
+ using ::ucbhelper::ResultSetInclude;
+ using ::ucbhelper::INCLUDE_FOLDERS_AND_DOCUMENTS;
+
+
+ //= FileViewContentEnumerator
+
+
+ FileViewContentEnumerator::FileViewContentEnumerator(
+ const Reference< XCommandEnvironment >& _rxCommandEnv,
+ ContentData& _rContentToFill, ::osl::Mutex& _rContentMutex )
+ :Thread ( "FileViewContentEnumerator" )
+ ,m_rContent ( _rContentToFill )
+ ,m_rContentMutex ( _rContentMutex )
+ ,m_xCommandEnv ( _rxCommandEnv )
+ ,m_pResultHandler ( nullptr )
+ ,m_bCancelled ( false )
+ ,m_rBlackList ( css::uno::Sequence< OUString >() )
+ {
+ }
+
+
+ FileViewContentEnumerator::~FileViewContentEnumerator()
+ {
+ }
+
+
+ void FileViewContentEnumerator::cancel()
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_bCancelled = true;
+ m_pResultHandler = nullptr;
+ m_aFolder.aContent = ::ucbhelper::Content();
+ m_aFolder.sURL.clear();
+ }
+
+
+ EnumerationResult FileViewContentEnumerator::enumerateFolderContentSync(
+ const FolderDescriptor& _rFolder,
+ const css::uno::Sequence< OUString >& rBlackList )
+ {
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aFolder = _rFolder;
+ m_pResultHandler = nullptr;
+ m_rBlackList = rBlackList;
+ }
+ return enumerateFolderContent();
+ }
+
+
+ void FileViewContentEnumerator::enumerateFolderContent(
+ const FolderDescriptor& _rFolder, IEnumerationResultHandler* _pResultHandler )
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aFolder = _rFolder;
+ m_pResultHandler = _pResultHandler;
+
+ OSL_ENSURE( m_aFolder.aContent.get().is() || !m_aFolder.sURL.isEmpty(),
+ "FileViewContentEnumerator::enumerateFolderContent: invalid folder descriptor!" );
+
+ launch();
+ //TODO: a protocol is missing how to join with the launched thread
+ // before exit(3), to ensure the thread is no longer relying on any
+ // infrastructure while that infrastructure is being shut down in
+ // atexit handlers
+ }
+
+
+ EnumerationResult FileViewContentEnumerator::enumerateFolderContent()
+ {
+ EnumerationResult eResult = EnumerationResult::ERROR;
+ try
+ {
+
+ Reference< XResultSet > xResultSet;
+ Sequence< OUString > aProps(12);
+
+ aProps[0] = "Title";
+ aProps[1] = "Size";
+ aProps[2] = "DateModified";
+ aProps[3] = "DateCreated";
+ aProps[4] = "IsFolder";
+ aProps[5] = "TargetURL";
+ aProps[6] = "IsHidden";
+ aProps[7] = "IsVolume";
+ aProps[8] = "IsRemote";
+ aProps[9] = "IsRemoveable";
+ aProps[10] = "IsFloppy";
+ aProps[11] = "IsCompactDisc";
+
+ Reference< XCommandEnvironment > xEnvironment;
+ try
+ {
+ FolderDescriptor aFolder;
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ aFolder = m_aFolder;
+ xEnvironment = m_xCommandEnv;
+ }
+ if ( !aFolder.aContent.get().is() )
+ {
+ aFolder.aContent = ::ucbhelper::Content( aFolder.sURL, xEnvironment, comphelper::getProcessComponentContext() );
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ m_aFolder.aContent = aFolder.aContent;
+ }
+ }
+
+ Reference< XDynamicResultSet > xDynResultSet = aFolder.aContent.createDynamicCursor( aProps, INCLUDE_FOLDERS_AND_DOCUMENTS );
+
+ if ( xDynResultSet.is() )
+ xResultSet = xDynResultSet->getStaticResultSet();
+ }
+ catch( CommandAbortedException& )
+ {
+ SAL_WARN( "svtools.contnr", "createCursor: CommandAbortedException" );
+ }
+ catch( Exception& )
+ {
+ }
+
+ if ( xResultSet.is() )
+ {
+ Reference< XRow > xRow( xResultSet, UNO_QUERY );
+ Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
+
+ try
+ {
+ DateTime aDT;
+
+ bool bCancelled = false;
+ while ( !bCancelled && xResultSet->next() )
+ {
+ bool bIsHidden = xRow->getBoolean( ROW_IS_HIDDEN );
+ // don't show hidden files
+ if ( !bIsHidden || xRow->wasNull() )
+ {
+ aDT = xRow->getTimestamp( ROW_DATE_MOD );
+ bool bContainsDate = !xRow->wasNull();
+ if ( !bContainsDate )
+ {
+ aDT = xRow->getTimestamp( ROW_DATE_CREATE );
+ bContainsDate = !xRow->wasNull();
+ }
+
+ OUString aContentURL = xContentAccess->queryContentIdentifierString();
+ OUString aTargetURL = xRow->getString( ROW_TARGET_URL );
+ bool bHasTargetURL = !xRow->wasNull() && !aTargetURL.isEmpty();
+
+ OUString sRealURL = bHasTargetURL ? aTargetURL : aContentURL;
+
+ // check for restrictions
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ if ( /* m_rBlackList.hasElements() && */ URLOnBlackList ( sRealURL ) )
+ continue;
+ }
+
+ std::unique_ptr<SortingData_Impl> pData(new SortingData_Impl);
+ pData->maTargetURL = sRealURL;
+
+ pData->mbIsFolder = xRow->getBoolean( ROW_IS_FOLDER ) && !xRow->wasNull();
+ pData->mbIsVolume = xRow->getBoolean( ROW_IS_VOLUME ) && !xRow->wasNull();
+ pData->mbIsRemote = xRow->getBoolean( ROW_IS_REMOTE ) && !xRow->wasNull();
+ pData->mbIsRemoveable = xRow->getBoolean( ROW_IS_REMOVABLE ) && !xRow->wasNull();
+ pData->mbIsFloppy = xRow->getBoolean( ROW_IS_FLOPPY ) && !xRow->wasNull();
+ pData->mbIsCompactDisc = xRow->getBoolean( ROW_IS_COMPACTDISC ) && !xRow->wasNull();
+ pData->SetNewTitle( xRow->getString( ROW_TITLE ) );
+ pData->maSize = xRow->getLong( ROW_SIZE );
+
+ if ( bHasTargetURL &&
+ INetURLObject( aContentURL ).GetProtocol() == INetProtocol::VndSunStarHier )
+ {
+ ::ucbhelper::Content aCnt( aTargetURL, xEnvironment, comphelper::getProcessComponentContext() );
+ try
+ {
+ aCnt.getPropertyValue("Size") >>= pData->maSize;
+ aCnt.getPropertyValue("DateModified") >>= aDT;
+ }
+ catch (...) {}
+ }
+
+ if ( bContainsDate )
+ {
+ pData->maModDate = ::DateTime( aDT );
+ }
+
+ if ( pData->mbIsFolder )
+ {
+ SolarMutexGuard aGuard;
+ ::svtools::VolumeInfo aVolInfo( pData->mbIsVolume, pData->mbIsRemote,
+ pData->mbIsRemoveable, pData->mbIsFloppy,
+ pData->mbIsCompactDisc );
+ pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo );
+ }
+ else
+ pData->maType = SvFileInformationManager::GetFileDescription(
+ INetURLObject( pData->maTargetURL ) );
+
+ {
+ ::osl::MutexGuard aGuard( m_rContentMutex );
+ m_rContent.push_back( std::move(pData) );
+ }
+ }
+
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ bCancelled = m_bCancelled;
+ }
+ }
+ eResult = EnumerationResult::SUCCESS;
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent: caught an exception while enumerating");
+ }
+ }
+ }
+ catch( Exception const & )
+ {
+ TOOLS_WARN_EXCEPTION( "svtools.contnr", "FileViewContentEnumerator::enumerateFolderContent" );
+ }
+
+ IEnumerationResultHandler* pHandler = nullptr;
+ {
+ ::osl::MutexGuard aGuard( m_aMutex );
+ pHandler = m_pResultHandler;
+ if ( m_bCancelled )
+ return EnumerationResult::ERROR;
+ }
+
+ {
+ ::osl::MutexGuard aGuard( m_rContentMutex );
+ if ( eResult != EnumerationResult::SUCCESS )
+ // clear any "intermediate" and unfinished result
+ m_rContent.clear();
+ }
+
+ if ( pHandler )
+ pHandler->enumerationDone( eResult );
+ return eResult;
+ }
+
+
+ bool FileViewContentEnumerator::URLOnBlackList ( const OUString& sRealURL )
+ {
+ OUString entryName = sRealURL.copy( sRealURL.lastIndexOf( '/' ) + 1 );
+
+ return comphelper::findValue(m_rBlackList, entryName) != -1;
+ }
+
+
+ void FileViewContentEnumerator::execute()
+ {
+ enumerateFolderContent();
+ }
+
+
+} // namespace svt
+
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/contentenumeration.hxx b/fpicker/source/office/contentenumeration.hxx
new file mode 100644
index 000000000000..0e6c529e65b3
--- /dev/null
+++ b/fpicker/source/office/contentenumeration.hxx
@@ -0,0 +1,240 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SVTOOLS_SOURCE_CONTNR_CONTENTENUMERATION_HXX
+#define INCLUDED_SVTOOLS_SOURCE_CONTNR_CONTENTENUMERATION_HXX
+
+#include <com/sun/star/ucb/XCommandEnvironment.hpp>
+#include <salhelper/thread.hxx>
+#include <ucbhelper/content.hxx>
+#include <rtl/ustring.hxx>
+#include <tools/datetime.hxx>
+#include <vcl/image.hxx>
+
+
+namespace svt
+{
+
+
+ //= SortingData_Impl
+
+ struct SortingData_Impl
+ {
+ private:
+ OUString maFilename; // only filename in upper case - for compare purposes
+ OUString maTitle; // -> be careful when changing maTitle to update maFilename only when new
+ OUString maLowerTitle;
+
+
+ public:
+ OUString maType;
+ OUString maTargetURL;
+ OUString maDisplayText;
+ DateTime maModDate;
+ Image maImage;
+ sal_Int64 maSize;
+ bool mbIsFolder;
+ bool mbIsVolume;
+ bool mbIsRemote;
+ bool mbIsRemoveable;
+ bool mbIsFloppy;
+ bool mbIsCompactDisc;
+
+ inline SortingData_Impl();
+ inline const OUString& GetTitle() const;
+ inline const OUString& GetLowerTitle() const;
+ inline const OUString& GetFileName() const;
+ inline void SetNewTitle( const OUString& rNewTitle ); // new maTitle is set -> maFilename is set to same!
+
+ private:
+ inline void SetTitles( const OUString& rNewTitle );
+ };
+
+ inline SortingData_Impl::SortingData_Impl() :
+ maModDate ( DateTime::EMPTY ),
+ maSize ( 0 ),
+ mbIsFolder ( false ),
+ mbIsVolume ( false ),
+ mbIsRemote ( false ),
+ mbIsRemoveable ( false ),
+ mbIsFloppy ( false ),
+ mbIsCompactDisc ( false )
+ {
+ }
+
+ inline const OUString& SortingData_Impl::GetTitle() const
+ {
+ return maTitle;
+ }
+
+ inline const OUString& SortingData_Impl::GetLowerTitle() const
+ {
+ return maLowerTitle;
+ }
+
+ inline const OUString& SortingData_Impl::GetFileName() const
+ {
+ return maFilename;
+ }
+
+ inline void SortingData_Impl::SetNewTitle( const OUString& rNewTitle )
+ {
+ SetTitles( rNewTitle );
+ maFilename = rNewTitle.toAsciiUpperCase();
+ }
+
+ inline void SortingData_Impl::SetTitles( const OUString& rNewTitle )
+ {
+ maTitle = rNewTitle;
+ maLowerTitle = rNewTitle.toAsciiLowerCase();
+ }
+
+
+ //= EnumerationResult
+
+ enum class EnumerationResult
+ {
+ SUCCESS, /// the enumeration was successful
+ ERROR, /// the enumeration was unsuccessful
+ };
+
+
+ //= FolderDescriptor
+
+ struct FolderDescriptor
+ {
+ /** a content object describing the folder. Can be <NULL/>, in this case <member>sURL</member>
+ is relevant.
+ */
+ ::ucbhelper::Content aContent;
+ /** the URL of a folder. Will be ignored if <member>aContent</member> is not <NULL/>.
+ */
+ OUString sURL;
+
+ FolderDescriptor() { }
+
+ explicit FolderDescriptor( const ::ucbhelper::Content& _rContent )
+ :aContent( _rContent )
+ {
+ }
+
+ explicit FolderDescriptor( const OUString& _rURL )
+ :sURL( _rURL )
+ {
+ }
+ };
+
+
+ //= IEnumerationResultHandler
+
+ class IEnumerationResultHandler
+ {
+ public:
+ virtual void enumerationDone( EnumerationResult _eResult ) = 0;
+
+ protected:
+ ~IEnumerationResultHandler() {}
+ };
+
+
+ //= FileViewContentEnumerator
+
+ class FileViewContentEnumerator: public salhelper::Thread
+ {
+ public:
+ typedef ::std::vector< std::unique_ptr<SortingData_Impl> > ContentData;
+
+ private:
+ ContentData& m_rContent;
+ ::osl::Mutex& m_rContentMutex;
+
+ mutable ::osl::Mutex m_aMutex;
+
+ FolderDescriptor m_aFolder;
+ css::uno::Reference< css::ucb::XCommandEnvironment >
+ m_xCommandEnv;
+ IEnumerationResultHandler* m_pResultHandler;
+ bool m_bCancelled;
+
+ css::uno::Sequence< OUString > m_rBlackList;
+
+ bool URLOnBlackList ( const OUString& sRealURL );
+
+ public:
+ /** constructs an enumerator instance
+
+ @param _rContentToFill
+ the structure which is to be filled with the found content
+ @param _rContentMutex
+ the mutex which protects the access to <arg>_rContentToFill</arg>
+ @param _pTranslator
+ an instance which should be used to translate content titles. May be <NULL/>
+ */
+ FileViewContentEnumerator(
+ const css::uno::Reference< css::ucb::XCommandEnvironment >& _rxCommandEnv,
+ ContentData& _rContentToFill,
+ ::osl::Mutex& _rContentMutex
+ );
+
+ /** enumerates the content of a given folder
+
+ @param _rFolder
+ the folder whose content is to be enumerated
+ @param _pFilter
+ a filter to apply to the found contents
+ @param _pResultHandler
+ an instance which should handle the results of the enumeration
+ */
+ void enumerateFolderContent(
+ const FolderDescriptor& _rFolder,
+ IEnumerationResultHandler* _pResultHandler
+ );
+
+ /** enumerates the content of a given folder synchronously
+ */
+ EnumerationResult enumerateFolderContentSync(
+ const FolderDescriptor& _rFolder,
+ const css::uno::Sequence< OUString >& rBlackList
+ );
+
+ /** cancels the running operation.
+
+ Note that "cancel" may mean that the operation is running, but its result
+ is simply disregarded later on.
+ */
+ void cancel();
+
+ protected:
+ virtual ~FileViewContentEnumerator() override;
+
+ private:
+ EnumerationResult enumerateFolderContent();
+
+ // Thread overridables
+ virtual void execute() override;
+
+ };
+
+
+} // namespace svt
+
+
+#endif // INCLUDED_SVTOOLS_SOURCE_CONTNR_CONTENTENUMERATION_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/fileview.cxx b/fpicker/source/office/fileview.cxx
new file mode 100644
index 000000000000..09ff753dd373
--- /dev/null
+++ b/fpicker/source/office/fileview.cxx
@@ -0,0 +1,1922 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/treelistbox.hxx>
+#include <sal/config.h>
+#include <sal/log.hxx>
+#include <osl/diagnose.h>
+#include <vcl/treelistentry.hxx>
+#include <svtools/svtresid.hxx>
+#include <svtools/imagemgr.hxx>
+#include <svtools/querydelete.hxx>
+#include <vcl/event.hxx>
+#include <vcl/headbar.hxx>
+#include <vcl/svtabbx.hxx>
+#include <svtools/strings.hrc>
+#include <bitmaps.hlst>
+#include <toolkit/helper/vclunohelper.hxx>
+#include "contentenumeration.hxx"
+#include <vcl/AccessibleBrowseBoxObjType.hxx>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include <com/sun/star/ucb/XProgressHandler.hpp>
+#include <com/sun/star/ucb/XContent.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <com/sun/star/ucb/CommandAbortedException.hpp>
+#include <vcl/waitobj.hxx>
+#include <vcl/settings.hxx>
+#include <com/sun/star/ucb/XCommandInfo.hpp>
+#include <com/sun/star/beans/XPropertySetInfo.hpp>
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+
+#include <algorithm>
+#include <vector>
+#include <tools/urlobj.hxx>
+#include <comphelper/processfactory.hxx>
+#include <comphelper/string.hxx>
+#include <ucbhelper/content.hxx>
+#include <ucbhelper/commandenvironment.hxx>
+#include <rtl/math.hxx>
+#include <osl/mutex.hxx>
+#include <osl/conditn.hxx>
+#include <salhelper/timer.hxx>
+#include <vcl/svapp.hxx>
+#include <vcl/dialog.hxx>
+#include <unotools/collatorwrapper.hxx>
+#include <unotools/localedatawrapper.hxx>
+#include <unotools/intlwrapper.hxx>
+#include <unotools/syslocale.hxx>
+#include <svtools/urlfilter.hxx>
+#include <o3tl/typed_flags_set.hxx>
+#include <memory>
+#include "fileview.hxx"
+#include "iconview.hxx"
+
+using namespace ::com::sun::star::lang;
+using namespace ::com::sun::star::sdbc;
+using namespace ::com::sun::star::task;
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::com::sun::star::io;
+using namespace ::com::sun::star::beans;
+using namespace ::comphelper;
+using ::svt::SortingData_Impl;
+using ::svt::FolderDescriptor;
+
+#define ALL_FILES_FILTER "*.*"
+
+#define COLUMN_TITLE 1
+#define COLUMN_TYPE 2
+#define COLUMN_SIZE 3
+#define COLUMN_DATE 4
+
+#define ROW_HEIGHT 17 // the height of a row has to be a little higher than the bitmap
+#define QUICK_SEARCH_TIMEOUT 1500 // time in mSec before the quicksearch string will be reset
+
+enum class FileViewFlags
+{
+ NONE = 0x00,
+ ONLYFOLDER = 0x01,
+ MULTISELECTION = 0x02,
+ SHOW_TYPE = 0x04,
+ SHOW_NONE = 0x20,
+};
+namespace o3tl
+{
+ template<> struct typed_flags<FileViewFlags> : is_typed_flags<FileViewFlags, 0x27> {};
+}
+
+namespace
+{
+
+ //= CallbackTimer
+
+ class CallbackTimer : public ::salhelper::Timer
+ {
+ protected:
+ SvtFileView_Impl* const m_pTimeoutHandler;
+
+ public:
+ explicit CallbackTimer( SvtFileView_Impl* _pHandler ) : m_pTimeoutHandler( _pHandler ) { }
+
+ protected:
+ virtual void SAL_CALL onShot() override;
+ };
+
+
+}
+
+
+class ViewTabListBox_Impl : public SvHeaderTabListBox
+{
+private:
+ Reference< XCommandEnvironment > mxCmdEnv;
+ std::unique_ptr<VclBuilder> mxBuilder;
+ VclPtr<PopupMenu> mxMenu;
+
+ ::osl::Mutex maMutex;
+ VclPtr<HeaderBar> mpHeaderBar;
+ SvtFileView_Impl* mpParent;
+ Timer maResetQuickSearch;
+ OUString maQuickSearchText;
+ OUString const msAccessibleDescText;
+ OUString const msFolder;
+ OUString const msFile;
+ sal_uInt32 mnSearchIndex;
+ bool mbResizeDisabled : 1;
+ bool mbAutoResize : 1;
+ bool mbEnableDelete : 1;
+ bool const mbShowHeader;
+
+ void DeleteEntries();
+ void DoQuickSearch( sal_Unicode rChar );
+ bool Kill( const OUString& rURL );
+
+protected:
+ virtual bool DoubleClickHdl() override;
+ virtual OUString GetAccessibleObjectDescription( ::vcl::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos = -1 ) const override;
+
+public:
+ ViewTabListBox_Impl( vcl::Window* pParentWin, SvtFileView_Impl* pParent, FileViewFlags nFlags );
+ virtual ~ViewTabListBox_Impl() override;
+ virtual void dispose() override;
+
+ virtual void Resize() override;
+ virtual void KeyInput( const KeyEvent& rKEvt ) override;
+ virtual bool EditedEntry( SvTreeListEntry* pEntry, const OUString& rNewText ) override;
+
+ void ClearAll();
+ HeaderBar* GetHeaderBar() const { return mpHeaderBar; }
+
+ void EnableAutoResize() { mbAutoResize = true; }
+ void EnableDelete( bool bEnable ) { mbEnableDelete = bEnable; }
+
+ const Reference< XCommandEnvironment >& GetCommandEnvironment() const { return mxCmdEnv; }
+
+ DECL_LINK(ResetQuickSearch_Impl, Timer *, void);
+
+ virtual VclPtr<PopupMenu> CreateContextMenu() override;
+ virtual void ExecuteContextMenuAction( sal_uInt16 nSelectedPopentry ) override;
+};
+
+
+//= SvtFileView_Impl
+
+
+class SvtFileView_Impl :public ::svt::IEnumerationResultHandler
+{
+protected:
+ VclPtr<SvtFileView> mpAntiImpl;
+ Link<SvTreeListBox*,void> m_aSelectHandler;
+
+ ::rtl::Reference< ::svt::FileViewContentEnumerator >
+ m_xContentEnumerator;
+ Link<void*,void> m_aCurrentAsyncActionHandler;
+ ::osl::Condition m_aAsyncActionFinished;
+ ::rtl::Reference< ::salhelper::Timer > m_xCancelAsyncTimer;
+ ::svt::EnumerationResult m_eAsyncActionResult;
+ bool m_bRunningAsyncAction;
+ bool m_bAsyncActionCancelled;
+
+public:
+
+ ::std::vector< std::unique_ptr<SortingData_Impl> > maContent;
+ ::osl::Mutex maMutex;
+
+ VclPtr<SvTreeListBox> mpCurView;
+ VclPtr<ViewTabListBox_Impl> mpView;
+ VclPtr<IconView> mpIconView;
+ sal_uInt16 mnSortColumn;
+ bool mbAscending : 1;
+ bool const mbOnlyFolder : 1;
+ sal_Int16 mnSuspendSelectCallback : 1;
+ bool mbIsFirstResort : 1;
+
+ IntlWrapper const aIntlWrapper;
+
+ OUString maViewURL;
+ OUString maCurrentFilter;
+ Image const maFolderImage;
+ Link<SvtFileView*,void> maOpenDoneLink;
+ Reference< XCommandEnvironment > mxCmdEnv;
+
+ SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommandEnvironment > const & xEnv,
+ FileViewFlags nFlags,
+ bool bOnlyFolder );
+ virtual ~SvtFileView_Impl();
+
+ void Clear();
+
+ FileViewResult GetFolderContent_Impl(
+ const OUString& rFolder,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const css::uno::Sequence< OUString >& rBlackList );
+
+ FileViewResult GetFolderContent_Impl(
+ const FolderDescriptor& _rFolder,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const css::uno::Sequence< OUString >& rBlackList );
+ void FilterFolderContent_Impl( const OUString &rFilter );
+ void CancelRunningAsyncAction();
+
+ void OpenFolder_Impl();
+ static void ReplaceTabWithString( OUString& aValue );
+ void CreateDisplayText_Impl();
+ void SortFolderContent_Impl();
+
+ void EntryRemoved( const OUString& rURL );
+ void EntryRenamed( OUString& rURL,
+ const OUString& rName );
+ OUString FolderInserted( const OUString& rURL,
+ const OUString& rTitle );
+
+ sal_uLong GetEntryPos( const OUString& rURL );
+
+ void SetViewMode( FileViewMode eMode );
+
+ inline void EnableDelete( bool bEnable );
+
+ void Resort_Impl( sal_Int16 nColumn, bool bAscending );
+ bool SearchNextEntry( sal_uInt32 &nIndex,
+ const OUString& rTitle,
+ bool bWrapAround );
+
+ void SetSelectHandler( const Link<SvTreeListBox*,void>& _rHdl );
+
+ void InitSelection();
+ void ResetCursor();
+
+ inline void EndEditing();
+
+ void onTimeout();
+
+protected:
+ DECL_LINK( SelectionMultiplexer, SvTreeListBox*, void );
+
+ // IEnumerationResultHandler overridables
+ virtual void enumerationDone( ::svt::EnumerationResult eResult ) override;
+ void implEnumerationSuccess();
+};
+
+inline void SvtFileView_Impl::EnableDelete( bool bEnable )
+{
+ mpView->EnableDelete( bEnable );
+}
+
+inline void SvtFileView_Impl::EndEditing()
+{
+ if ( mpCurView->IsEditingActive() )
+ mpCurView->EndEditing();
+}
+
+namespace
+{
+ // functions -------------------------------------------------------------
+
+ OUString CreateExactSizeText( sal_Int64 nSize )
+ {
+ double fSize( static_cast<double>(nSize) );
+ int nDec;
+
+ long nMega = 1024 * 1024;
+ long nGiga = nMega * 1024;
+
+ OUString aUnitStr(' ');
+
+ if ( nSize < 10000 )
+ {
+ aUnitStr += SvtResId(STR_SVT_BYTES );
+ nDec = 0;
+ }
+ else if ( nSize < nMega )
+ {
+ fSize /= 1024;
+ aUnitStr += SvtResId(STR_SVT_KB);
+ nDec = 1;
+ }
+ else if ( nSize < nGiga )
+ {
+ fSize /= nMega;
+ aUnitStr += SvtResId(STR_SVT_MB);
+ nDec = 2;
+ }
+ else
+ {
+ fSize /= nGiga;
+ aUnitStr += SvtResId(STR_SVT_GB);
+ nDec = 3;
+ }
+
+ OUString aSizeStr( ::rtl::math::doubleToUString( fSize,
+ rtl_math_StringFormat_F, nDec,
+ SvtSysLocale().GetLocaleData().getNumDecimalSep()[0]) );
+ aSizeStr += aUnitStr;
+
+ return aSizeStr;
+ }
+}
+
+ViewTabListBox_Impl::ViewTabListBox_Impl( vcl::Window* pParentWin,
+ SvtFileView_Impl* pParent,
+ FileViewFlags nFlags ) :
+
+ SvHeaderTabListBox( pParentWin, WB_TABSTOP ),
+
+ mpHeaderBar ( nullptr ),
+ mpParent ( pParent ),
+ msAccessibleDescText( SvtResId(STR_SVT_ACC_DESC_FILEVIEW) ),
+ msFolder ( SvtResId(STR_SVT_ACC_DESC_FOLDER) ),
+ msFile ( SvtResId(STR_SVT_ACC_DESC_FILE) ),
+ mnSearchIndex ( 0 ),
+ mbResizeDisabled ( false ),
+ mbAutoResize ( false ),
+ mbEnableDelete ( false ),
+ mbShowHeader ( !(nFlags & FileViewFlags::SHOW_NONE) )
+{
+ Size aBoxSize = pParentWin->GetSizePixel();
+ mpHeaderBar = VclPtr<HeaderBar>::Create( pParentWin, WB_BUTTONSTYLE | WB_BOTTOMBORDER );
+ mpHeaderBar->SetPosSizePixel( Point( 0, 0 ), mpHeaderBar->CalcWindowSizePixel() );
+
+ HeaderBarItemBits nBits = HeaderBarItemBits::LEFT | HeaderBarItemBits::CLICKABLE;
+
+ long aTabPositions[] = { 20, 180, 320, 400, 600 };
+ SetTabs(SAL_N_ELEMENTS(aTabPositions), aTabPositions, MapUnit::MapPixel);
+ SetTabJustify(2, SvTabJustify::AdjustRight); // column "Size"
+
+ mpHeaderBar->InsertItem(COLUMN_TITLE, SvtResId(STR_SVT_FILEVIEW_COLUMN_TITLE), 180, nBits | HeaderBarItemBits::UPARROW);
+ if (nFlags & FileViewFlags::SHOW_TYPE)
+ {
+ mpHeaderBar->InsertItem(COLUMN_TYPE, SvtResId(STR_SVT_FILEVIEW_COLUMN_TYPE), 140, nBits);
+ }
+ mpHeaderBar->InsertItem(COLUMN_SIZE, SvtResId(STR_SVT_FILEVIEW_COLUMN_SIZE), 80, nBits);
+ mpHeaderBar->InsertItem(COLUMN_DATE, SvtResId(STR_SVT_FILEVIEW_COLUMN_DATE), 500, nBits);
+
+ Size aHeadSize = mpHeaderBar->GetSizePixel();
+ SetPosSizePixel( Point( 0, aHeadSize.Height() ),
+ Size( aBoxSize.Width(), aBoxSize.Height() - aHeadSize.Height() ) );
+ InitHeaderBar( mpHeaderBar );
+ SetHighlightRange();
+ SetEntryHeight( ROW_HEIGHT );
+ if (nFlags & FileViewFlags::MULTISELECTION)
+ SetSelectionMode( SelectionMode::Multiple );
+
+ Show();
+ if( mbShowHeader )
+ mpHeaderBar->Show();
+
+ maResetQuickSearch.SetTimeout( QUICK_SEARCH_TIMEOUT );
+ maResetQuickSearch.SetInvokeHandler( LINK( this, ViewTabListBox_Impl, ResetQuickSearch_Impl ) );
+
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< XInteractionHandler > xInteractionHandler(
+ InteractionHandler::createWithParent(xContext, VCLUnoHelper::GetInterface(GetParentDialog())), UNO_QUERY_THROW );
+
+ mxCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
+
+ EnableContextMenuHandling();
+}
+
+ViewTabListBox_Impl::~ViewTabListBox_Impl()
+{
+ disposeOnce();
+}
+
+void ViewTabListBox_Impl::dispose()
+{
+ maResetQuickSearch.Stop();
+
+ mxMenu.disposeAndClear();
+ mxBuilder.reset();
+
+ mpHeaderBar.disposeAndClear();
+ SvHeaderTabListBox::dispose();
+}
+
+IMPL_LINK_NOARG(ViewTabListBox_Impl, ResetQuickSearch_Impl, Timer *, void)
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ maQuickSearchText.clear();
+ mnSearchIndex = 0;
+}
+
+
+void ViewTabListBox_Impl::Resize()
+{
+ SvTabListBox::Resize();
+ Size aBoxSize = Control::GetParent()->GetOutputSizePixel();
+
+ if ( mbResizeDisabled || !aBoxSize.Width() )
+ return;
+
+ Size aBarSize;
+ if ( mbShowHeader )
+ {
+ aBarSize = mpHeaderBar->GetSizePixel();
+ aBarSize.setWidth( mbAutoResize ? aBoxSize.Width() : GetSizePixel().Width() );
+ mpHeaderBar->SetSizePixel( aBarSize );
+ }
+
+ if ( mbAutoResize )
+ {
+ mbResizeDisabled = true;
+ SetPosSizePixel( Point( 0, aBarSize.Height() ),
+ Size( aBoxSize.Width(), aBoxSize.Height() - aBarSize.Height() ) );
+ mbResizeDisabled = false;
+ }
+}
+
+
+void ViewTabListBox_Impl::KeyInput( const KeyEvent& rKEvt )
+{
+ bool bHandled = false;
+
+ const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
+ if ( 0 == rKeyCode.GetModifier() )
+ {
+ if ( rKeyCode.GetCode() == KEY_RETURN )
+ {
+ ResetQuickSearch_Impl( nullptr );
+ GetDoubleClickHdl().Call( this );
+ bHandled = true;
+ }
+ else if ( ( rKeyCode.GetCode() == KEY_DELETE ) &&
+ mbEnableDelete )
+ {
+ ResetQuickSearch_Impl( nullptr );
+ DeleteEntries();
+ bHandled = true;
+ }
+ else if ( ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_NUM ) ||
+ ( rKEvt.GetKeyCode().GetGroup() == KEYGROUP_ALPHA ) )
+ {
+ DoQuickSearch( rKEvt.GetCharCode() );
+ bHandled = true;
+ }
+ }
+
+ if ( !bHandled )
+ {
+ ResetQuickSearch_Impl( nullptr );
+ SvHeaderTabListBox::KeyInput( rKEvt );
+ }
+}
+
+
+VclPtr<PopupMenu> ViewTabListBox_Impl::CreateContextMenu()
+{
+ bool bEnableDelete = mbEnableDelete;
+ bool bEnableRename = true;
+
+ if ( bEnableDelete || bEnableRename )
+ {
+ sal_Int32 nSelectedEntries = GetSelectionCount();
+ bEnableDelete &= nSelectedEntries > 0;
+ bEnableRename &= nSelectedEntries == 1;
+ }
+
+ if ( bEnableDelete || bEnableRename )
+ {
+ SvTreeListEntry* pEntry = FirstSelected();
+ while ( pEntry )
+ {
+ ::ucbhelper::Content aCnt;
+ try
+ {
+ OUString aURL( static_cast< SvtContentEntry * >(
+ pEntry->GetUserData() )->maURL );
+ aCnt = ::ucbhelper::Content( aURL, mxCmdEnv, comphelper::getProcessComponentContext() );
+ }
+ catch( Exception const & )
+ {
+ bEnableDelete = bEnableRename = false;
+ }
+
+ if ( bEnableDelete )
+ {
+ try
+ {
+ Reference< XCommandInfo > aCommands = aCnt.getCommands();
+ if ( aCommands.is() )
+ bEnableDelete = aCommands->hasCommandByName( "delete" );
+ else
+ bEnableDelete = false;
+ }
+ catch( Exception const & )
+ {
+ bEnableDelete = false;
+ }
+ }
+
+ if ( bEnableRename )
+ {
+ try
+ {
+ Reference< XPropertySetInfo > aProps = aCnt.getProperties();
+ if ( aProps.is() )
+ {
+ Property aProp = aProps->getPropertyByName("Title");
+ bEnableRename
+ = !( aProp.Attributes & PropertyAttribute::READONLY );
+ }
+ else
+ bEnableRename = false;
+ }
+ catch( Exception const & )
+ {
+ bEnableRename = false;
+ }
+ }
+
+ pEntry = ( bEnableDelete || bEnableRename )
+ ? NextSelected( pEntry )
+ : nullptr;
+ }
+ }
+
+ if ( bEnableDelete || bEnableRename )
+ {
+ mxMenu.disposeAndClear();
+ mxBuilder.reset(new VclBuilder(nullptr, VclBuilderContainer::getUIRootDir(), "svt/ui/fileviewmenu.ui", ""));
+ mxMenu.set(mxBuilder->get_menu("menu"));
+ mxMenu->EnableItem(mxMenu->GetItemId("delete"), bEnableDelete);
+ mxMenu->EnableItem(mxMenu->GetItemId("rename"), bEnableRename);
+ mxMenu->RemoveDisabledEntries( true, true );
+ return mxMenu;
+ }
+
+ return nullptr;
+}
+
+void ViewTabListBox_Impl::ExecuteContextMenuAction( sal_uInt16 nSelectedPopupEntry )
+{
+ if (nSelectedPopupEntry == mxMenu->GetItemId("delete"))
+ DeleteEntries();
+ else if (nSelectedPopupEntry == mxMenu->GetItemId("rename"))
+ EditEntry( FirstSelected() );
+}
+
+void ViewTabListBox_Impl::ClearAll()
+{
+ for ( sal_uLong i = 0; i < GetEntryCount(); ++i )
+ delete static_cast<SvtContentEntry*>(GetEntry(i)->GetUserData());
+ Clear();
+}
+
+
+void ViewTabListBox_Impl::DeleteEntries()
+{
+ short eResult = svtools::QUERYDELETE_YES;
+ SvTreeListEntry* pEntry = FirstSelected();
+ OUString aURL;
+
+ while ( pEntry )
+ {
+ SvTreeListEntry *pCurEntry = pEntry;
+ pEntry = NextSelected( pEntry );
+
+ if ( pCurEntry->GetUserData() )
+ aURL = static_cast<SvtContentEntry*>(pCurEntry->GetUserData())->maURL;
+
+ if ( aURL.isEmpty() )
+ continue;
+
+ bool canDelete = true;
+ try
+ {
+ ::ucbhelper::Content aCnt( aURL, mxCmdEnv, comphelper::getProcessComponentContext() );
+ Reference< XCommandInfo > aCommands = aCnt.getCommands();
+ if ( aCommands.is() )
+ canDelete = aCommands->hasCommandByName( "delete" );
+ else
+ canDelete = false;
+ }
+ catch( Exception const & )
+ {
+ canDelete = false;
+ }
+
+ if (!canDelete)
+ continue; // process next entry
+
+ if ( eResult != svtools::QUERYDELETE_ALL )
+ {
+ INetURLObject aObj( aURL );
+ svtools::QueryDeleteDlg_Impl aDlg(
+ GetFrameWeld(), aObj.GetLastName(INetURLObject::DecodeMechanism::WithCharset));
+
+ if ( GetSelectionCount() > 1 )
+ aDlg.EnableAllButton();
+
+ eResult = aDlg.run();
+ }
+
+ if ( ( eResult == svtools::QUERYDELETE_ALL ) ||
+ ( eResult == svtools::QUERYDELETE_YES ) )
+ {
+ if ( Kill( aURL ) )
+ {
+ delete static_cast<SvtContentEntry*>(pCurEntry->GetUserData());
+ GetModel()->Remove( pCurEntry );
+ mpParent->EntryRemoved( aURL );
+ }
+ }
+ }
+}
+
+
+bool ViewTabListBox_Impl::EditedEntry( SvTreeListEntry* pEntry,
+ const OUString& rNewText )
+{
+ bool bRet = false;
+
+ OUString aURL;
+ SvtContentEntry* pData = static_cast<SvtContentEntry*>(pEntry->GetUserData());
+
+ if ( pData )
+ aURL = pData->maURL;
+
+ if ( aURL.isEmpty() )
+ return bRet;
+
+ try
+ {
+ OUString aPropName( "Title" );
+ bool canRename = true;
+ ::ucbhelper::Content aContent( aURL, mxCmdEnv, comphelper::getProcessComponentContext() );
+
+ try
+ {
+ Reference< XPropertySetInfo > aProps = aContent.getProperties();
+ if ( aProps.is() )
+ {
+ Property aProp = aProps->getPropertyByName( aPropName );
+ canRename = !( aProp.Attributes & PropertyAttribute::READONLY );
+ }
+ else
+ {
+ canRename = false;
+ }
+ }
+ catch ( Exception const & )
+ {
+ canRename = false;
+ }
+
+ if ( canRename )
+ {
+ Any aValue;
+ aValue <<= rNewText;
+ aContent.setPropertyValue( aPropName, aValue );
+ mpParent->EntryRenamed( aURL, rNewText );
+
+ if (pData)
+ pData->maURL = aURL;
+
+ pEntry->SetUserData( pData );
+
+ bRet = true;
+ }
+ }
+ catch( Exception const & )
+ {
+ }
+
+ return bRet;
+}
+
+
+void ViewTabListBox_Impl::DoQuickSearch( sal_Unicode rChar )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ maResetQuickSearch.Stop();
+
+ OUString aLastText = maQuickSearchText;
+ sal_uInt32 aLastPos = mnSearchIndex;
+
+ maQuickSearchText += OUString(rChar).toAsciiLowerCase();
+
+ bool bFound = mpParent->SearchNextEntry( mnSearchIndex, maQuickSearchText, false );
+
+ if ( !bFound && ( aLastText.getLength() == 1 ) &&
+ ( aLastText == OUStringLiteral1(rChar) ) )
+ {
+ mnSearchIndex = aLastPos + 1;
+ maQuickSearchText = aLastText;
+ bFound = mpParent->SearchNextEntry( mnSearchIndex, maQuickSearchText, true );
+ }
+
+ if ( bFound )
+ {
+ SvTreeListEntry* pEntry = GetEntry( mnSearchIndex );
+ if ( pEntry )
+ {
+ SelectAll( false );
+ Select( pEntry );
+ SetCurEntry( pEntry );
+ MakeVisible( pEntry );
+ }
+ }
+
+ maResetQuickSearch.Start();
+}
+
+
+bool ViewTabListBox_Impl::DoubleClickHdl()
+{
+ SvHeaderTabListBox::DoubleClickHdl();
+ return false;
+ // this means "do no additional handling". Especially this means that the SvImpLBox does not
+ // recognize that the entry at the double click position change after the handler call (which is
+ // the case if in the handler, our content was replaced)
+ // If it _would_ recognize this change, it would take this as a reason to select the entry, again
+ // - which is not what in the case of content replace
+ // (I really doubt that this behaviour of the SvImpLBox does make any sense at all, but
+ // who knows ...)
+}
+
+OUString ViewTabListBox_Impl::GetAccessibleObjectDescription( ::vcl::AccessibleBrowseBoxObjType _eType, sal_Int32 _nPos ) const
+{
+ OUString sRet = SvHeaderTabListBox::GetAccessibleObjectDescription( _eType, _nPos );
+ if ( ::vcl::BBTYPE_TABLECELL == _eType )
+ {
+ sal_Int32 nRow = -1;
+ const sal_uInt16 nColumnCount = GetColumnCount();
+ if (nColumnCount > 0)
+ nRow = _nPos / nColumnCount;
+ SvTreeListEntry* pEntry = GetEntry( nRow );
+ if ( pEntry )
+ {
+ SvtContentEntry* pData = static_cast<SvtContentEntry*>(pEntry->GetUserData());
+ if ( pData )
+ {
+ const OUString sVar1( "%1" );
+ const OUString sVar2( "%2" );
+ OUString aText( msAccessibleDescText );
+ aText = aText.replaceAll( sVar1, pData->mbIsFolder ? msFolder : msFile );
+ aText = aText.replaceAll( sVar2, pData->maURL );
+ sRet += aText;
+ }
+ }
+ }
+
+ return sRet;
+}
+
+
+bool ViewTabListBox_Impl::Kill( const OUString& rContent )
+{
+ bool bRet = true;
+
+ try
+ {
+ ::ucbhelper::Content aCnt( rContent, mxCmdEnv, comphelper::getProcessComponentContext() );
+ aCnt.executeCommand( "delete", makeAny( true ) );
+ }
+ catch( css::ucb::CommandAbortedException const & )
+ {
+ SAL_INFO( "svtools.contnr", "CommandAbortedException" );
+ bRet = false;
+ }
+ catch( Exception const & )
+ {
+ SAL_INFO( "svtools.contnr", "Any other exception" );
+ bRet = false;
+ }
+
+ return bRet;
+}
+
+SvtFileView::SvtFileView( vcl::Window* pParent, WinBits nBits,
+ bool bOnlyFolder, bool bMultiSelection, bool bShowType ) :
+
+ Control( pParent, nBits )
+{
+ FileViewFlags nFlags = FileViewFlags::NONE;
+ if ( bOnlyFolder )
+ nFlags |= FileViewFlags::ONLYFOLDER;
+ if ( bMultiSelection )
+ nFlags |= FileViewFlags::MULTISELECTION;
+ if ( bShowType )
+ nFlags |= FileViewFlags::SHOW_TYPE;
+
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< XInteractionHandler > xInteractionHandler(
+ InteractionHandler::createWithParent(xContext, VCLUnoHelper::GetInterface(GetParentDialog())), UNO_QUERY_THROW );
+ Reference < XCommandEnvironment > xCmdEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
+
+ mpImpl.reset( new SvtFileView_Impl( this, xCmdEnv, nFlags, bOnlyFolder ) );
+ mpImpl->mpView->ForbidEmptyText();
+
+ HeaderBar* pHeaderBar = mpImpl->mpView->GetHeaderBar();
+ pHeaderBar->SetSelectHdl( LINK( this, SvtFileView, HeaderSelect_Impl ) );
+ pHeaderBar->SetEndDragHdl( LINK( this, SvtFileView, HeaderEndDrag_Impl ) );
+}
+
+SvtFileView::~SvtFileView()
+{
+ disposeOnce();
+}
+
+void SvtFileView::dispose()
+{
+ mpImpl.reset();
+ Control::dispose();
+}
+
+Size SvtFileView::GetOptimalSize() const
+{
+ return LogicToPixel(Size(208, 50), MapMode(MapUnit::MapAppFont));
+}
+
+void SvtFileView::SetViewMode( FileViewMode eMode )
+{
+ mpImpl->SetViewMode( eMode );
+}
+
+OUString SvtFileView::GetURL( SvTreeListEntry const * pEntry )
+{
+ OUString aURL;
+ if ( pEntry && pEntry->GetUserData() )
+ aURL = static_cast<SvtContentEntry*>(pEntry->GetUserData())->maURL;
+ return aURL;
+}
+
+
+OUString SvtFileView::GetCurrentURL() const
+{
+ OUString aURL;
+ SvTreeListEntry* pEntry = mpImpl->mpCurView->FirstSelected();
+ if ( pEntry && pEntry->GetUserData() )
+ aURL = static_cast<SvtContentEntry*>(pEntry->GetUserData())->maURL;
+ return aURL;
+}
+
+
+void SvtFileView::CreatedFolder( const OUString& rUrl, const OUString& rNewFolder )
+{
+ OUString sEntry = mpImpl->FolderInserted( rUrl, rNewFolder );
+
+ SvTreeListEntry* pEntry = mpImpl->mpView->InsertEntry( sEntry, mpImpl->maFolderImage, mpImpl->maFolderImage );
+ SvtContentEntry* pUserData = new SvtContentEntry( rUrl, true );
+ pEntry->SetUserData( pUserData );
+ mpImpl->mpView->MakeVisible( pEntry );
+
+ SvTreeListEntry* pEntry2 = mpImpl->mpIconView->InsertEntry( sEntry.getToken( 0, '\t' ), mpImpl->maFolderImage, mpImpl->maFolderImage );
+ SvtContentEntry* pUserData2 = new SvtContentEntry( rUrl, true );
+ pEntry2->SetUserData( pUserData2 );
+ mpImpl->mpIconView->MakeVisible( pEntry2 );
+}
+
+
+FileViewResult SvtFileView::PreviousLevel( const FileViewAsyncAction* pAsyncDescriptor )
+{
+ FileViewResult eResult = eFailure;
+
+ OUString sParentURL;
+ if ( GetParentURL( sParentURL ) )
+ eResult = Initialize( sParentURL, mpImpl->maCurrentFilter, pAsyncDescriptor, mpBlackList );
+
+ return eResult;
+}
+
+
+bool SvtFileView::GetParentURL( OUString& rParentURL ) const
+{
+ bool bRet = false;
+ try
+ {
+ ::ucbhelper::Content aCnt( mpImpl->maViewURL, mpImpl->mxCmdEnv, comphelper::getProcessComponentContext() );
+ Reference< XContent > xContent( aCnt.get() );
+ Reference< css::container::XChild > xChild( xContent, UNO_QUERY );
+ if ( xChild.is() )
+ {
+ Reference< XContent > xParent( xChild->getParent(), UNO_QUERY );
+ if ( xParent.is() )
+ {
+ rParentURL = xParent->getIdentifier()->getContentIdentifier();
+ bRet = !rParentURL.isEmpty() && rParentURL != mpImpl->maViewURL;
+ }
+ }
+ }
+ catch( Exception const & )
+ {
+ // perhaps an unknown url protocol (e.g. "private:newdoc")
+ }
+
+ return bRet;
+}
+
+
+const OString& SvtFileView::GetHelpId( ) const
+{
+ return mpImpl->mpView->GetHelpId( );
+}
+
+
+void SvtFileView::SetHelpId( const OString& rHelpId )
+{
+ mpImpl->mpView->SetHelpId( rHelpId );
+}
+
+
+void SvtFileView::SetSizePixel( const Size& rNewSize )
+{
+ Control::SetSizePixel( rNewSize );
+ mpImpl->mpView->SetSizePixel( rNewSize );
+ mpImpl->mpIconView->SetSizePixel( rNewSize );
+}
+
+
+void SvtFileView::SetPosSizePixel( const Point& rNewPos, const Size& rNewSize )
+{
+ SetPosPixel( rNewPos );
+ SetSizePixel( rNewSize );
+}
+
+
+bool SvtFileView::Initialize( const css::uno::Reference< css::ucb::XContent>& _xContent )
+{
+ WaitObject aWaitCursor( this );
+
+ mpImpl->Clear();
+ ::ucbhelper::Content aContent(_xContent, mpImpl->mxCmdEnv, comphelper::getProcessComponentContext() );
+ FileViewResult eResult = mpImpl->GetFolderContent_Impl( FolderDescriptor( aContent ), nullptr, css::uno::Sequence< OUString >() );
+ OSL_ENSURE( eResult != eStillRunning, "SvtFileView::Initialize: this was expected to be synchronous!" );
+ if ( eResult != eSuccess )
+ return false;
+
+ mpImpl->FilterFolderContent_Impl( OUString() );
+
+ mpImpl->SortFolderContent_Impl(); // possibly not necessary!!!!!!!!!!
+ mpImpl->CreateDisplayText_Impl();
+ mpImpl->OpenFolder_Impl();
+
+ mpImpl->maOpenDoneLink.Call( this );
+ return true;
+}
+
+
+FileViewResult SvtFileView::Initialize(
+ const OUString& rURL,
+ const OUString& rFilter,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const css::uno::Sequence< OUString >& rBlackList )
+{
+ WaitObject aWaitCursor( this );
+ mpBlackList = rBlackList;
+
+ OUString sPushURL( mpImpl->maViewURL );
+
+ mpImpl->maViewURL = rURL;
+ FileViewResult eResult = ExecuteFilter( rFilter, pAsyncDescriptor );
+ switch ( eResult )
+ {
+ case eFailure:
+ case eTimeout:
+ mpImpl->maViewURL = sPushURL;
+ return eResult;
+
+ case eStillRunning:
+ OSL_ENSURE( pAsyncDescriptor, "SvtFileView::Initialize: we told it to read synchronously!" );
+ [[fallthrough]];
+ case eSuccess:
+ return eResult;
+ }
+
+ OSL_FAIL( "SvtFileView::Initialize: unreachable!" );
+ return eFailure;
+}
+
+FileViewResult SvtFileView::ExecuteFilter( const OUString& rFilter, const FileViewAsyncAction* pAsyncDescriptor )
+{
+ mpImpl->maCurrentFilter = rFilter.toAsciiLowerCase();
+
+ mpImpl->Clear();
+ FileViewResult eResult = mpImpl->GetFolderContent_Impl( mpImpl->maViewURL, pAsyncDescriptor, mpBlackList );
+ OSL_ENSURE( ( eResult != eStillRunning ) || pAsyncDescriptor, "SvtFileView::ExecuteFilter: we told it to read synchronously!" );
+ return eResult;
+}
+
+void SvtFileView::CancelRunningAsyncAction()
+{
+ mpImpl->CancelRunningAsyncAction();
+}
+
+void SvtFileView::SetNoSelection()
+{
+ mpImpl->mpCurView->SelectAll( false );
+}
+
+
+void SvtFileView::GetFocus()
+{
+ Control::GetFocus();
+ if ( mpImpl && mpImpl->mpCurView )
+ mpImpl->mpCurView->GrabFocus();
+}
+
+
+void SvtFileView::SetSelectHdl( const Link<SvTreeListBox*,void>& rHdl )
+{
+ mpImpl->SetSelectHandler( rHdl );
+}
+
+
+void SvtFileView::SetDoubleClickHdl( const Link<SvTreeListBox*,bool>& rHdl )
+{
+ mpImpl->mpView->SetDoubleClickHdl( rHdl );
+ mpImpl->mpIconView->SetDoubleClickHdl( rHdl );
+}
+
+
+sal_uLong SvtFileView::GetSelectionCount() const
+{
+ return mpImpl->mpCurView->GetSelectionCount();
+}
+
+
+SvTreeListEntry* SvtFileView::FirstSelected() const
+{
+ return mpImpl->mpCurView->FirstSelected();
+}
+
+
+SvTreeListEntry* SvtFileView::NextSelected( SvTreeListEntry* pEntry ) const
+{
+ return mpImpl->mpCurView->NextSelected( pEntry );
+}
+
+void SvtFileView::EnableAutoResize()
+{
+ mpImpl->mpView->EnableAutoResize();
+}
+
+const OUString& SvtFileView::GetViewURL() const
+{
+ return mpImpl->maViewURL;
+}
+
+void SvtFileView::SetOpenDoneHdl( const Link<SvtFileView*,void>& rHdl )
+{
+ mpImpl->maOpenDoneLink = rHdl;
+}
+
+void SvtFileView::EnableDelete( bool bEnable )
+{
+ mpImpl->EnableDelete( bEnable );
+}
+
+void SvtFileView::EndInplaceEditing()
+{
+ return mpImpl->EndEditing();
+}
+
+IMPL_LINK( SvtFileView, HeaderSelect_Impl, HeaderBar*, pBar, void )
+{
+ DBG_ASSERT( pBar, "no headerbar" );
+ sal_uInt16 nItemID = pBar->GetCurItemId();
+
+ HeaderBarItemBits nBits;
+
+ // clear the arrow of the recently used column
+ if ( nItemID != mpImpl->mnSortColumn )
+ {
+ if ( !nItemID )
+ {
+ // first call -> remove arrow from title column,
+ // because another column is the sort column
+ nItemID = mpImpl->mnSortColumn;
+ mpImpl->mnSortColumn = COLUMN_TITLE;
+ }
+ nBits = pBar->GetItemBits( mpImpl->mnSortColumn );
+ nBits &= ~HeaderBarItemBits( HeaderBarItemBits::UPARROW | HeaderBarItemBits::DOWNARROW );
+ pBar->SetItemBits( mpImpl->mnSortColumn, nBits );
+ }
+
+ nBits = pBar->GetItemBits( nItemID );
+
+ bool bUp = ( ( nBits & HeaderBarItemBits::UPARROW ) == HeaderBarItemBits::UPARROW );
+
+ if ( bUp )
+ {
+ nBits &= ~HeaderBarItemBits::UPARROW;
+ nBits |= HeaderBarItemBits::DOWNARROW;
+ }
+ else
+ {
+ nBits &= ~HeaderBarItemBits::DOWNARROW;
+ nBits |= HeaderBarItemBits::UPARROW;
+ }
+
+ pBar->SetItemBits( nItemID, nBits );
+ mpImpl->Resort_Impl( nItemID, !bUp );
+}
+
+
+IMPL_LINK( SvtFileView, HeaderEndDrag_Impl, HeaderBar*, pBar, void )
+{
+ if ( pBar->IsItemMode() )
+ return;
+
+ Size aSize;
+ sal_uInt16 nTabs = pBar->GetItemCount();
+ long nTmpSize = 0;
+
+ for ( sal_uInt16 i = 1; i <= nTabs; ++i )
+ {
+ long nWidth = pBar->GetItemSize(i);
+ aSize.setWidth( nWidth + nTmpSize );
+ nTmpSize += nWidth;
+ mpImpl->mpView->SetTab( i, aSize.Width(), MapUnit::MapPixel );
+ }
+}
+
+
+OUString SvtFileView::GetConfigString() const
+{
+ OUString sRet;
+ HeaderBar* pBar = mpImpl->mpView->GetHeaderBar();
+ DBG_ASSERT( pBar, "invalid headerbar" );
+
+ // sort order
+ sRet += OUString::number( mpImpl->mnSortColumn ) + ";";
+ HeaderBarItemBits nBits = pBar->GetItemBits( mpImpl->mnSortColumn );
+ bool bUp = ( ( nBits & HeaderBarItemBits::UPARROW ) == HeaderBarItemBits::UPARROW );
+ sRet += bUp ? OUString("1") : OUString("0");
+ sRet += ";";
+
+ sal_uInt16 nCount = pBar->GetItemCount();
+ for ( sal_uInt16 i = 0; i < nCount; ++i )
+ {
+ sal_uInt16 nId = pBar->GetItemId(i);
+ sRet += OUString::number( nId )
+ + ";"
+ + OUString::number( pBar->GetItemSize( nId ) )
+ + ";";
+ }
+
+ sRet = comphelper::string::stripEnd(sRet, ';');
+ return sRet;
+}
+
+::std::vector< SvtContentEntry > SvtFileView::GetContent()
+{
+ ::std::vector< SvtContentEntry > aContent;
+
+ for(auto const& elem : mpImpl->maContent)
+ {
+ SvtContentEntry aEntry( elem->maTargetURL, elem->mbIsFolder );
+ aContent.push_back( aEntry );
+ }
+
+ return aContent;
+}
+
+void SvtFileView::SetConfigString( const OUString& rCfgStr )
+{
+ HeaderBar* pBar = mpImpl->mpView->GetHeaderBar();
+ DBG_ASSERT( pBar, "invalid headerbar" );
+
+ sal_Int32 nIdx = 0;
+ mpImpl->mnSortColumn = static_cast<sal_uInt16>(rCfgStr.getToken( 0, ';', nIdx ).toInt32());
+ bool bUp = static_cast<bool>(static_cast<sal_uInt16>(rCfgStr.getToken( 0, ';', nIdx ).toInt32()));
+ HeaderBarItemBits nBits = pBar->GetItemBits( mpImpl->mnSortColumn );
+
+ if ( bUp )
+ {
+ nBits &= ~HeaderBarItemBits::UPARROW;
+ nBits |= HeaderBarItemBits::DOWNARROW;
+ }
+ else
+ {
+ nBits &= ~HeaderBarItemBits::DOWNARROW;
+ nBits |= HeaderBarItemBits::UPARROW;
+ }
+ pBar->SetItemBits( mpImpl->mnSortColumn, nBits );
+
+ while ( nIdx != -1 )
+ {
+ sal_uInt16 nItemId = static_cast<sal_uInt16>(rCfgStr.getToken( 0, ';', nIdx ).toInt32());
+ pBar->SetItemSize( nItemId, rCfgStr.getToken( 0, ';', nIdx ).toInt32() );
+ }
+
+ HeaderSelect_Impl( pBar );
+ HeaderEndDrag_Impl( pBar );
+}
+
+
+void SvtFileView::StateChanged( StateChangedType nStateChange )
+{
+ if ( nStateChange == StateChangedType::Enable )
+ Invalidate();
+ Control::StateChanged( nStateChange );
+}
+
+
+// class SvtFileView_Impl
+
+
+SvtFileView_Impl::SvtFileView_Impl( SvtFileView* pAntiImpl, Reference < XCommandEnvironment > const & xEnv, FileViewFlags nFlags, bool bOnlyFolder )
+
+ :mpAntiImpl ( pAntiImpl )
+ ,m_eAsyncActionResult ( ::svt::EnumerationResult::ERROR )
+ ,m_bRunningAsyncAction ( false )
+ ,m_bAsyncActionCancelled ( false )
+ ,mnSortColumn ( COLUMN_TITLE )
+ ,mbAscending ( true )
+ ,mbOnlyFolder ( bOnlyFolder )
+ ,mnSuspendSelectCallback ( 0 )
+ ,mbIsFirstResort ( true )
+ ,aIntlWrapper ( Application::GetSettings().GetLanguageTag() )
+ ,maFolderImage (StockImage::Yes, RID_BMP_FOLDER)
+ ,mxCmdEnv ( xEnv )
+
+{
+ mpView = VclPtr<ViewTabListBox_Impl>::Create( mpAntiImpl, this, nFlags );
+ mpCurView = mpView;
+ mpIconView = VclPtr<IconView>::Create( mpAntiImpl, WB_TABSTOP );
+ mpIconView->Hide();
+ mpView->EnableCellFocus();
+}
+
+
+SvtFileView_Impl::~SvtFileView_Impl()
+{
+ Clear();
+ mpView.disposeAndClear();
+ mpCurView.clear();
+ mpIconView.disposeAndClear();
+ mpAntiImpl.clear();
+}
+
+
+void SvtFileView_Impl::Clear()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ maContent.clear();
+}
+
+
+FileViewResult SvtFileView_Impl::GetFolderContent_Impl(
+ const OUString& rFolder,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const css::uno::Sequence< OUString >& rBlackList )
+{
+ ::osl::ClearableMutexGuard aGuard( maMutex );
+ INetURLObject aFolderObj( rFolder );
+ DBG_ASSERT( aFolderObj.GetProtocol() != INetProtocol::NotValid, "Invalid URL!" );
+
+ FolderDescriptor aFolder( aFolderObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
+
+ aGuard.clear();
+ return GetFolderContent_Impl( aFolder, pAsyncDescriptor, rBlackList );
+}
+
+
+FileViewResult SvtFileView_Impl::GetFolderContent_Impl(
+ const FolderDescriptor& _rFolder,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const css::uno::Sequence< OUString >& rBlackList )
+{
+ DBG_TESTSOLARMUTEX();
+ ::osl::ClearableMutexGuard aGuard( maMutex );
+
+ OSL_ENSURE( !m_xContentEnumerator.is(), "SvtFileView_Impl::GetFolderContent_Impl: still running another enumeration!" );
+ m_xContentEnumerator.set(new ::svt::FileViewContentEnumerator(
+ mpView->GetCommandEnvironment(), maContent, maMutex));
+ // TODO: should we cache and re-use this thread?
+
+ if ( !pAsyncDescriptor )
+ {
+ ::svt::EnumerationResult eResult = m_xContentEnumerator->enumerateFolderContentSync( _rFolder, rBlackList );
+ if ( ::svt::EnumerationResult::SUCCESS == eResult )
+ {
+ implEnumerationSuccess();
+ m_xContentEnumerator.clear();
+ return eSuccess;
+ }
+ m_xContentEnumerator.clear();
+ return eFailure;
+ }
+
+ m_bRunningAsyncAction = true;
+ m_bAsyncActionCancelled = false;
+ m_eAsyncActionResult = ::svt::EnumerationResult::ERROR;
+ m_aAsyncActionFinished.reset();
+
+ // don't (yet) set m_aCurrentAsyncActionHandler to pTimeout->aFinishHandler.
+ // By definition, this handler *only* gets called when the result cannot be obtained
+ // during the minimum wait time, so it is only set below, when needed.
+ m_aCurrentAsyncActionHandler = Link<void*,void>();
+
+ // minimum time to wait
+ std::unique_ptr< TimeValue > pTimeout( new TimeValue );
+ sal_Int32 nMinTimeout = pAsyncDescriptor->nMinTimeout;
+ OSL_ENSURE( nMinTimeout > 0, "SvtFileView_Impl::GetFolderContent_Impl: invalid minimum timeout!" );
+ if ( nMinTimeout <= 0 )
+ nMinTimeout = sal_Int32( 1000 );
+ pTimeout->Seconds = nMinTimeout / 1000L;
+ pTimeout->Nanosec = ( nMinTimeout % 1000L ) * 1000000L;
+
+ m_xContentEnumerator->enumerateFolderContent( _rFolder, this );
+
+ // wait until the enumeration is finished
+ // for this, release our own mutex (which is used by the enumerator thread)
+ aGuard.clear();
+
+ ::osl::Condition::Result eResult = ::osl::Condition::result_ok;
+ {
+ // also release the SolarMutex. Not all code which is needed during the enumeration
+ // is Solar-Thread-Safe, in particular there is some code which needs to access
+ // string resources (and our resource system relies on the SolarMutex :()
+ SolarMutexReleaser aSolarRelease;
+
+ // now wait. Note that if we didn't get a pAsyncDescriptor, then this is an infinite wait.
+ eResult = m_aAsyncActionFinished.wait( pTimeout.get() );
+ }
+
+ ::osl::MutexGuard aGuard2( maMutex );
+ if ( ::osl::Condition::result_timeout == eResult )
+ {
+ // maximum time to wait
+ OSL_ENSURE(!m_xCancelAsyncTimer,
+ "SvtFileView_Impl::GetFolderContent_Impl: there's still a previous timer!");
+ m_xCancelAsyncTimer.set(new CallbackTimer(this));
+ sal_Int32 nMaxTimeout = pAsyncDescriptor->nMaxTimeout;
+ OSL_ENSURE( nMaxTimeout > nMinTimeout,
+ "SvtFileView_Impl::GetFolderContent_Impl: invalid maximum timeout!" );
+ if ( nMaxTimeout <= nMinTimeout )
+ nMaxTimeout = nMinTimeout + 5000;
+ m_xCancelAsyncTimer->setRemainingTime( salhelper::TTimeValue( nMaxTimeout - nMinTimeout ) );
+ // we already waited for nMinTimeout milliseconds, so take this into account
+ m_xCancelAsyncTimer->start();
+
+ m_aCurrentAsyncActionHandler = pAsyncDescriptor->aFinishHandler;
+ DBG_ASSERT( m_aCurrentAsyncActionHandler.IsSet(), "SvtFileView_Impl::GetFolderContent_Impl: nobody interested when it's finished?" );
+ mpView->ClearAll();
+ mpIconView->ClearAll();
+ return eStillRunning;
+ }
+
+ m_bRunningAsyncAction = false;
+ switch ( m_eAsyncActionResult )
+ {
+ case ::svt::EnumerationResult::SUCCESS:
+ return eSuccess;
+
+ case ::svt::EnumerationResult::ERROR:
+ return eFailure;
+ }
+
+ SAL_WARN( "svtools.contnr", "SvtFileView_Impl::GetFolderContent_Impl: unreachable!" );
+ return eFailure;
+}
+
+
+void SvtFileView_Impl::FilterFolderContent_Impl( const OUString &rFilter )
+{
+ if ( rFilter.isEmpty() || ( rFilter == ALL_FILES_FILTER ) )
+ // when replacing names, there is always something to filter (no view of ".nametranslation.table")
+ return;
+
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( maContent.empty() )
+ return;
+
+ // collect the filter tokens
+ ::std::vector< WildCard > aFilters;
+ FilterMatch::createWildCardFilterList(rFilter,aFilters);
+
+
+ // do the filtering
+ maContent.erase(std::remove_if(maContent.begin(), maContent.end(),
+ [&aFilters](const std::unique_ptr<SortingData_Impl>& rxContent) {
+ if (rxContent->mbIsFolder)
+ return false;
+ // normalize the content title (we always match case-insensitive)
+ // 91872 - 11.09.2001 - frank.schoenheit@sun.com
+ OUString sCompareString = rxContent->GetFileName(); // filter works on file name, not on title!
+ return std::none_of(aFilters.begin(), aFilters.end(), FilterMatch(sCompareString));
+ }),
+ maContent.end());
+}
+
+
+IMPL_LINK( SvtFileView_Impl, SelectionMultiplexer, SvTreeListBox*, _pSource, void )
+{
+ if (!mnSuspendSelectCallback)
+ m_aSelectHandler.Call( _pSource );
+}
+
+
+void SvtFileView_Impl::SetSelectHandler( const Link<SvTreeListBox*,void>& _rHdl )
+{
+ m_aSelectHandler = _rHdl;
+
+ Link<SvTreeListBox*,void> aMasterHandler;
+ if ( m_aSelectHandler.IsSet() )
+ aMasterHandler = LINK( this, SvtFileView_Impl, SelectionMultiplexer );
+
+ mpView->SetSelectHdl( aMasterHandler );
+ mpIconView->SetSelectHdl( aMasterHandler );
+}
+
+
+void SvtFileView_Impl::InitSelection()
+{
+ mpCurView->SelectAll( false );
+ SvTreeListEntry* pFirst = mpCurView->First();
+ if ( pFirst )
+ mpCurView->SetCursor( pFirst, true );
+}
+
+
+void SvtFileView_Impl::OpenFolder_Impl()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ mpView->SetUpdateMode( false );
+ mpIconView->SetUpdateMode( false );
+ mpView->ClearAll();
+ mpIconView->ClearAll();
+
+ for (auto const& elem : maContent)
+ {
+ if ( mbOnlyFolder && ! elem->mbIsFolder )
+ continue;
+
+ // insert entry and set user data
+ SvTreeListEntry* pEntry = mpView->InsertEntry( elem->maDisplayText,
+ elem->maImage,
+ elem->maImage );
+
+ SvTreeListEntry* pEntry2 = mpIconView->InsertEntry( elem->maDisplayText.getToken( 0, '\t' ),
+ elem->maImage, elem->maImage );
+
+ SvtContentEntry* pUserData = new SvtContentEntry( elem->maTargetURL,
+ elem->mbIsFolder );
+ SvtContentEntry* pUserData2 = new SvtContentEntry( elem->maTargetURL,
+ elem->mbIsFolder );
+
+ pEntry->SetUserData( pUserData );
+ pEntry2->SetUserData( pUserData2 );
+ }
+
+ InitSelection();
+
+ ++mnSuspendSelectCallback;
+ mpView->SetUpdateMode( true );
+ mpIconView->SetUpdateMode( true );
+ --mnSuspendSelectCallback;
+
+ ResetCursor();
+}
+
+
+void SvtFileView_Impl::ResetCursor()
+{
+ // deselect
+ SvTreeListEntry* pEntry = mpCurView->FirstSelected();
+ if ( pEntry )
+ mpCurView->Select( pEntry, false );
+ // set cursor to the first entry
+ mpCurView->SetCursor( mpCurView->First(), true );
+ mpCurView->Update();
+}
+
+
+void SvtFileView_Impl::CancelRunningAsyncAction()
+{
+ DBG_TESTSOLARMUTEX();
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( !m_xContentEnumerator.is() )
+ return;
+
+ m_bAsyncActionCancelled = true;
+ m_xContentEnumerator->cancel();
+ m_bRunningAsyncAction = false;
+
+ m_xContentEnumerator.clear();
+ if ( m_xCancelAsyncTimer.is() && m_xCancelAsyncTimer->isTicking() )
+ m_xCancelAsyncTimer->stop();
+ m_xCancelAsyncTimer.clear();
+}
+
+
+void SvtFileView_Impl::onTimeout()
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( maMutex );
+ if ( !m_bRunningAsyncAction )
+ // there might have been a race condition while we waited for the mutex
+ return;
+
+ CancelRunningAsyncAction();
+
+ if ( m_aCurrentAsyncActionHandler.IsSet() )
+ {
+ Application::PostUserEvent( m_aCurrentAsyncActionHandler, reinterpret_cast< void* >( eTimeout ) );
+ m_aCurrentAsyncActionHandler = Link<void*,void>();
+ }
+}
+
+
+void SvtFileView_Impl::enumerationDone( ::svt::EnumerationResult eResult )
+{
+ SolarMutexGuard aSolarGuard;
+ ::osl::MutexGuard aGuard( maMutex );
+
+ m_xContentEnumerator.clear();
+ if ( m_xCancelAsyncTimer.is() && m_xCancelAsyncTimer->isTicking() )
+ m_xCancelAsyncTimer->stop();
+ m_xCancelAsyncTimer.clear();
+
+ if ( m_bAsyncActionCancelled )
+ // this is to prevent race conditions
+ return;
+
+ m_eAsyncActionResult = eResult;
+ m_bRunningAsyncAction = false;
+
+ m_aAsyncActionFinished.set();
+
+ if ( svt::EnumerationResult::SUCCESS == eResult )
+ implEnumerationSuccess();
+
+ if ( m_aCurrentAsyncActionHandler.IsSet() )
+ {
+ Application::PostUserEvent( m_aCurrentAsyncActionHandler, reinterpret_cast< void* >( m_eAsyncActionResult ) );
+ m_aCurrentAsyncActionHandler = Link<void*,void>();
+ }
+}
+
+
+void SvtFileView_Impl::implEnumerationSuccess()
+{
+ FilterFolderContent_Impl( maCurrentFilter );
+ SortFolderContent_Impl();
+ CreateDisplayText_Impl();
+ OpenFolder_Impl();
+ maOpenDoneLink.Call( mpAntiImpl );
+}
+
+
+void SvtFileView_Impl::ReplaceTabWithString( OUString& aValue )
+{
+ OUString const aTab( "\t" );
+ OUString const aTabString( "%09" );
+ sal_Int32 iPos;
+
+ while ( ( iPos = aValue.indexOf( aTab ) ) >= 0 )
+ aValue = aValue.replaceAt( iPos, 1, aTabString );
+}
+
+
+void SvtFileView_Impl::CreateDisplayText_Impl()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ OUString const aTab( "\t" );
+ OUString const aDateSep( ", " );
+
+ for (auto const& elem : maContent)
+ {
+ // title, type, size, date
+ OUString aValue = elem->GetTitle();
+ ReplaceTabWithString( aValue );
+ aValue += aTab + elem->maType + aTab;
+ // folders don't have a size
+ if ( ! elem->mbIsFolder )
+ aValue += CreateExactSizeText( elem->maSize );
+ aValue += aTab;
+ // set the date, but volumes have no date
+ if ( ! elem->mbIsFolder || ! elem->mbIsVolume )
+ {
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData();
+ aValue += rLocaleData.getDate( elem->maModDate )
+ + aDateSep
+ + rLocaleData.getTime( elem->maModDate, false );
+ }
+ elem->maDisplayText = aValue;
+
+ // detect image
+ if ( elem->mbIsFolder )
+ {
+ ::svtools::VolumeInfo aVolInfo( elem->mbIsVolume, elem->mbIsRemote,
+ elem->mbIsRemoveable, elem->mbIsFloppy,
+ elem->mbIsCompactDisc );
+ elem->maImage = SvFileInformationManager::GetFolderImage( aVolInfo );
+ }
+ else
+ elem->maImage = SvFileInformationManager::GetFileImage( INetURLObject( elem->maTargetURL ) );
+ }
+}
+
+void SvtFileView_Impl::Resort_Impl( sal_Int16 nColumn, bool bAscending )
+{
+ // TODO: IconView ()
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( ( nColumn == mnSortColumn ) &&
+ ( bAscending == mbAscending ) )
+ return;
+
+ // reset the quick search index
+ mpView->ResetQuickSearch_Impl( nullptr );
+
+ OUString aEntryURL;
+ SvTreeListEntry* pEntry = mpView->GetCurEntry();
+ if ( pEntry && pEntry->GetUserData() )
+ aEntryURL = static_cast<SvtContentEntry*>(pEntry->GetUserData())->maURL;
+
+ mnSortColumn = nColumn;
+ mbAscending = bAscending;
+
+ SortFolderContent_Impl();
+ OpenFolder_Impl();
+
+ if ( !mbIsFirstResort )
+ {
+ sal_uLong nPos = GetEntryPos( aEntryURL );
+ if ( nPos < mpView->GetEntryCount() )
+ {
+ pEntry = mpView->GetEntry( nPos );
+
+ ++mnSuspendSelectCallback; // #i15668#
+ mpView->SetCurEntry( pEntry );
+ --mnSuspendSelectCallback;
+ }
+ }
+ else
+ mbIsFirstResort = false;
+}
+
+
+static bool gbAscending = true;
+static sal_Int16 gnColumn = COLUMN_TITLE;
+static const CollatorWrapper* pCollatorWrapper = nullptr;
+
+/* this function returns true, if aOne is less than aTwo
+*/
+static bool CompareSortingData_Impl( std::unique_ptr<SortingData_Impl> const & aOne, std::unique_ptr<SortingData_Impl> const & aTwo )
+{
+ DBG_ASSERT( pCollatorWrapper, "*CompareSortingData_Impl(): Can't work this way!" );
+
+ sal_Int32 nComp;
+ bool bRet = false;
+ bool bEqual = false;
+
+ if ( aOne->mbIsFolder != aTwo->mbIsFolder )
+ {
+ bRet = aOne->mbIsFolder;
+
+ // !!! pb: #100376# folder always on top
+ if ( !gbAscending )
+ bRet = !bRet;
+ }
+ else
+ {
+ switch ( gnColumn )
+ {
+ case COLUMN_TITLE:
+ // compare case insensitive first
+ nComp = pCollatorWrapper->compareString( aOne->GetLowerTitle(), aTwo->GetLowerTitle() );
+
+ if ( nComp == 0 )
+ nComp = pCollatorWrapper->compareString( aOne->GetTitle(), aTwo->GetTitle() );
+
+ if ( nComp < 0 )
+ bRet = true;
+ else if ( nComp > 0 )
+ bRet = false;
+ else
+ bEqual = true;
+ break;
+ case COLUMN_TYPE:
+ nComp = pCollatorWrapper->compareString( aOne->maType, aTwo->maType );
+ if ( nComp < 0 )
+ bRet = true;
+ else if ( nComp > 0 )
+ bRet = false;
+ else
+ bEqual = true;
+ break;
+ case COLUMN_SIZE:
+ if ( aOne->maSize < aTwo->maSize )
+ bRet = true;
+ else if ( aOne->maSize > aTwo->maSize )
+ bRet = false;
+ else
+ bEqual = true;
+ break;
+ case COLUMN_DATE:
+ if ( aOne->maModDate < aTwo->maModDate )
+ bRet = true;
+ else if ( aOne->maModDate > aTwo->maModDate )
+ bRet = false;
+ else
+ bEqual = true;
+ break;
+ default:
+ SAL_INFO( "svtools.contnr", "CompareSortingData_Impl: Compare unknown type!" );
+ bRet = false;
+ }
+ }
+
+ // when the two elements are equal, we must not return sal_True (which would
+ // happen if we just return ! ( a < b ) when not sorting ascending )
+ if ( bEqual )
+ return false;
+
+ return gbAscending ? bRet : !bRet;
+}
+
+
+void SvtFileView_Impl::SortFolderContent_Impl()
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ if ( maContent.size() > 1 )
+ {
+ gbAscending = mbAscending;
+ gnColumn = mnSortColumn;
+ pCollatorWrapper = aIntlWrapper.getCaseCollator();
+
+ std::stable_sort( maContent.begin(), maContent.end(), CompareSortingData_Impl );
+
+ pCollatorWrapper = nullptr;
+ }
+}
+
+
+void SvtFileView_Impl::EntryRemoved( const OUString& rURL )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ maContent.erase(std::find_if(maContent.begin(), maContent.end(),
+ [&](const std::unique_ptr<SortingData_Impl> & data) { return data->maTargetURL == rURL; }));
+}
+
+
+void SvtFileView_Impl::EntryRenamed( OUString& rURL,
+ const OUString& rTitle )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ auto aFoundElem = std::find_if(maContent.begin(), maContent.end(),
+ [&](const std::unique_ptr<SortingData_Impl> & data) { return data->maTargetURL == rURL; });
+ if (aFoundElem != maContent.end())
+ {
+ (*aFoundElem)->SetNewTitle( rTitle );
+ OUString aDisplayText = (*aFoundElem)->maDisplayText;
+ sal_Int32 nIndex = aDisplayText.indexOf( '\t' );
+
+ if ( nIndex > 0 )
+ (*aFoundElem)->maDisplayText = aDisplayText.replaceAt( 0, nIndex, rTitle );
+
+ INetURLObject aURLObj( rURL );
+ aURLObj.setName( rTitle, INetURLObject::EncodeMechanism::All );
+
+ rURL = aURLObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
+
+ (*aFoundElem)->maTargetURL = rURL;
+ }
+}
+
+
+OUString SvtFileView_Impl::FolderInserted( const OUString& rURL, const OUString& rTitle )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ std::unique_ptr<SortingData_Impl> pData(new SortingData_Impl);
+
+ pData->SetNewTitle( rTitle );
+ pData->maSize = 0;
+ pData->mbIsFolder = true;
+ pData->maTargetURL = rURL;
+
+ ::svtools::VolumeInfo aVolInfo;
+ pData->maType = SvFileInformationManager::GetFolderDescription( aVolInfo );
+ pData->maImage = SvFileInformationManager::GetFolderImage( aVolInfo );
+
+ OUString aValue;
+ OUString const aTab( "\t" );
+ OUString const aDateSep( ", " );
+
+ // title, type, size, date
+ aValue = pData->GetTitle();
+ ReplaceTabWithString( aValue );
+ aValue += aTab + pData->maType + aTab +
+ // folders don't have a size
+ aTab;
+ // set the date
+ SvtSysLocale aSysLocale;
+ const LocaleDataWrapper& rLocaleData = aSysLocale.GetLocaleData();
+ aValue += rLocaleData.getDate( pData->maModDate )
+ + aDateSep
+ + rLocaleData.getTime( pData->maModDate );
+
+ pData->maDisplayText = aValue;
+ maContent.push_back( std::move(pData) );
+
+ return aValue;
+}
+
+
+sal_uLong SvtFileView_Impl::GetEntryPos( const OUString& rURL )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ auto aFoundElem = std::find_if(maContent.begin(), maContent.end(),
+ [&](const std::unique_ptr<SortingData_Impl> & data) { return data->maTargetURL == rURL; });
+ return aFoundElem != maContent.end()?std::distance(maContent.begin(), aFoundElem):0;
+}
+
+
+void SvtFileView_Impl::SetViewMode( FileViewMode eMode )
+{
+ switch ( eMode )
+ {
+ case eDetailedList:
+ mpCurView = mpView;
+ mpView->Show();
+ mpView->GetHeaderBar()->Show();
+ mpIconView->Hide();
+ break;
+
+ case eIcon:
+ mpCurView = mpIconView;
+ mpView->Hide();
+ mpView->GetHeaderBar()->Hide();
+ mpIconView->Show();
+ break;
+
+ default:
+ mpCurView = mpView;
+ mpView->Show();
+ mpView->GetHeaderBar()->Show();
+ mpIconView->Hide();
+ };
+}
+
+
+bool SvtFileView_Impl::SearchNextEntry( sal_uInt32& nIndex, const OUString& rTitle, bool bWrapAround )
+{
+ ::osl::MutexGuard aGuard( maMutex );
+
+ sal_uInt32 nEnd = maContent.size();
+ sal_uInt32 nStart = nIndex;
+ while ( nIndex < nEnd )
+ {
+ SortingData_Impl* pData = maContent[ nIndex ].get();
+ if ( pData->GetLowerTitle().startsWith( rTitle ) )
+ return true;
+ ++nIndex;
+ }
+
+ if ( bWrapAround )
+ {
+ nIndex = 0;
+ while ( nIndex < nEnd && nIndex <= nStart )
+ {
+ SortingData_Impl* pData = maContent[ nIndex ].get();
+ if ( pData->GetLowerTitle().startsWith( rTitle ) )
+ return true;
+ ++nIndex;
+ }
+ }
+
+ return false;
+}
+
+namespace {
+ void SAL_CALL CallbackTimer::onShot()
+ {
+ OSL_ENSURE( m_pTimeoutHandler, "CallbackTimer::onShot: nobody interested in?" );
+ SvtFileView_Impl* pHandler( m_pTimeoutHandler );
+ if ( pHandler )
+ pHandler->onTimeout();
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/fileview.hxx b/fpicker/source/office/fileview.hxx
new file mode 100644
index 000000000000..e655b8c4dcd3
--- /dev/null
+++ b/fpicker/source/office/fileview.hxx
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+#ifndef INCLUDED_VCL_FILEVIEW_HXX
+#define INCLUDED_VCL_FILEVIEW_HXX
+
+#include <memory>
+#include <com/sun/star/uno/Sequence.h>
+#include <vcl/ctrl.hxx>
+#include <vcl/weld.hxx>
+#include <rtl/ustring.hxx>
+
+namespace com :: sun :: star :: ucb { class XContent; }
+
+// class SvtFileView -----------------------------------------------------
+
+class SvtFileView_Impl;
+class SvTreeListEntry;
+class HeaderBar;
+struct SvtContentEntry;
+class SvTreeListBox;
+
+/// the result of an action in the FileView
+enum FileViewResult
+{
+ eSuccess,
+ eFailure,
+ eTimeout,
+ eStillRunning
+};
+
+enum FileViewMode
+{
+ eDetailedList,
+ eIcon
+};
+
+/// describes parameters for doing an action on the FileView asynchronously
+struct FileViewAsyncAction
+{
+ sal_uInt32 nMinTimeout; /// minimum time to wait for a result, in milliseconds
+ sal_uInt32 nMaxTimeout; /// maximum time to wait for a result, in milliseconds, until eTimeout is returned
+ Link<void*,void> aFinishHandler; /// the handler to be called when the action is finished. Called in every case, no matter of the result
+
+ FileViewAsyncAction()
+ {
+ nMinTimeout = nMaxTimeout = 0;
+ }
+};
+
+class SvtFileView : public Control
+{
+private:
+ std::unique_ptr<SvtFileView_Impl> mpImpl;
+ css::uno::Sequence< OUString > mpBlackList;
+
+ DECL_LINK( HeaderSelect_Impl, HeaderBar*, void );
+ DECL_LINK( HeaderEndDrag_Impl, HeaderBar*, void );
+
+protected:
+ virtual void GetFocus() override;
+
+public:
+ SvtFileView( vcl::Window* pParent, WinBits nBits, bool bOnlyFolder, bool bMultiSelection, bool bShowType = true );
+ virtual ~SvtFileView() override;
+ virtual void dispose() override;
+
+ virtual Size GetOptimalSize() const override;
+
+ void SetViewMode( FileViewMode eMode );
+
+ const OUString& GetViewURL() const;
+ static OUString GetURL( SvTreeListEntry const * pEntry );
+ OUString GetCurrentURL() const;
+
+ bool GetParentURL( OUString& _rParentURL ) const;
+ void CreatedFolder( const OUString& rUrl, const OUString& rNewFolder );
+
+ void SetHelpId( const OString& rHelpId );
+ const OString& GetHelpId( ) const;
+ void SetSizePixel( const Size& rNewSize ) override;
+ virtual void SetPosSizePixel( const Point& rNewPos, const Size& rNewSize ) override;
+
+ /** initialize the view with the content of a folder given by URL, and apply an immediate filter
+
+ @param rFolderURL
+ the URL of the folder whose content is to be read
+ @param rFilter
+ the initial filter to be applied
+ @param pAsyncDescriptor
+ If not <NULL/>, this struct describes the parameters for doing the
+ action asynchronously.
+ */
+ FileViewResult Initialize(
+ const OUString& rFolderURL,
+ const OUString& rFilter,
+ const FileViewAsyncAction* pAsyncDescriptor,
+ const css::uno::Sequence< OUString >& rBlackList
+ );
+
+ /** initializes the view with the content of a folder given by a UCB content
+ */
+ bool Initialize( const css::uno::Reference< css::ucb::XContent>& _xContent );
+
+ /** reads the current content of the current folder again, and applies the given filter to it
+
+ Note 1: The folder is really read a second time. This implies that any new elements (which were
+ not present when you called Initialize the last time) are now displayed.
+
+ Note 2: This method must not be called when you previously initialized the view from a sequence
+ of strings, or a UNO content object.
+
+ @param rFilter
+ the filter to be applied
+ @param pAsyncDescriptor
+ If not <NULL/>, this struct describes the parameters for doing the
+ action asynchronously.
+ */
+ FileViewResult ExecuteFilter(
+ const OUString& rFilter,
+ const FileViewAsyncAction* pAsyncDescriptor
+ );
+
+ /** cancels a running async action (if any)
+
+ @seealso Initialize
+ @seealso ExecuteFilter
+ @seealso FileViewAsyncAction
+ */
+ void CancelRunningAsyncAction();
+
+ /** initializes the view with the parent folder of the current folder
+
+ @param rNewURL
+ the URL of the folder which we just navigated to
+ @param pAsyncDescriptor
+ If not <NULL/>, this struct describes the parameters for doing the
+ action asynchronously.
+ */
+ FileViewResult PreviousLevel(
+ const FileViewAsyncAction* pAsyncDescriptor
+ );
+
+ void SetNoSelection();
+
+ void SetSelectHdl( const Link<SvTreeListBox*,void>& rHdl );
+ void SetDoubleClickHdl( const Link<SvTreeListBox*,bool>& rHdl );
+ void SetOpenDoneHdl( const Link<SvtFileView*,void>& rHdl );
+
+ sal_uLong GetSelectionCount() const;
+ SvTreeListEntry* FirstSelected() const;
+ SvTreeListEntry* NextSelected( SvTreeListEntry* pEntry ) const;
+ void EnableAutoResize();
+
+ void EnableDelete( bool bEnable );
+
+ // save and load column size and sort order
+ OUString GetConfigString() const;
+ void SetConfigString( const OUString& rCfgStr );
+
+ void EndInplaceEditing();
+
+ ::std::vector< SvtContentEntry > GetContent();
+
+protected:
+ virtual void StateChanged( StateChangedType nStateChange ) override;
+};
+
+// struct SvtContentEntry ------------------------------------------------
+
+struct SvtContentEntry
+{
+ bool const mbIsFolder;
+ OUString maURL;
+
+ SvtContentEntry( const OUString& rURL, bool bIsFolder ) :
+ mbIsFolder( bIsFolder ), maURL( rURL ) {}
+};
+
+#endif // INCLUDED_VCL_FILEVIEW_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/foldertree.cxx b/fpicker/source/office/foldertree.cxx
new file mode 100644
index 000000000000..a2cc56aca385
--- /dev/null
+++ b/fpicker/source/office/foldertree.cxx
@@ -0,0 +1,170 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <comphelper/processfactory.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <tools/urlobj.hxx>
+#include <ucbhelper/commandenvironment.hxx>
+#include <vcl/dialog.hxx>
+#include <vcl/treelistentry.hxx>
+#include <vcl/ptrstyle.hxx>
+#include <com/sun/star/task/InteractionHandler.hpp>
+#include "contentenumeration.hxx"
+#include "foldertree.hxx"
+#include <bitmaps.hlst>
+
+using namespace ::com::sun::star::task;
+
+FolderTree::FolderTree( vcl::Window* pParent, WinBits nBits )
+ : SvTreeListBox( pParent, nBits | WB_SORT | WB_TABSTOP )
+{
+ Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
+ Reference< XInteractionHandler > xInteractionHandler(
+ InteractionHandler::createWithParent(xContext, VCLUnoHelper::GetInterface(GetParentDialog())), UNO_QUERY_THROW );
+ m_xEnv = new ::ucbhelper::CommandEnvironment( xInteractionHandler, Reference< XProgressHandler >() );
+
+ Image aFolderImage(StockImage::Yes, RID_BMP_FOLDER);
+ Image aFolderExpandedImage(StockImage::Yes, RID_BMP_FOLDER_OPEN);
+ SetDefaultCollapsedEntryBmp( aFolderImage );
+ SetDefaultExpandedEntryBmp( aFolderExpandedImage );
+}
+
+void FolderTree::RequestingChildren( SvTreeListEntry* pEntry )
+{
+ EnableChildPointerOverwrite( true );
+ SetPointer( PointerStyle::Wait );
+ Invalidate(InvalidateFlags::Update);
+
+ FillTreeEntry( pEntry );
+
+ SetPointer( PointerStyle::Arrow );
+ EnableChildPointerOverwrite( false );
+}
+
+void FolderTree::FillTreeEntry( SvTreeListEntry* pEntry )
+{
+ if( !pEntry )
+ return;
+
+ OUString* pURL = static_cast< OUString* >( pEntry->GetUserData() );
+
+ if( pURL && m_sLastUpdatedDir != *pURL )
+ {
+ while (SvTreeListEntry* pChild = FirstChild(pEntry))
+ {
+ GetModel()->Remove(pChild);
+ }
+
+ ::std::vector< std::unique_ptr<SortingData_Impl> > aContent;
+
+ ::rtl::Reference< ::svt::FileViewContentEnumerator >
+ xContentEnumerator(new FileViewContentEnumerator(
+ m_xEnv, aContent, m_aMutex));
+
+ FolderDescriptor aFolder( *pURL );
+
+ EnumerationResult eResult =
+ xContentEnumerator->enumerateFolderContentSync( aFolder, m_aBlackList );
+
+ if ( EnumerationResult::SUCCESS == eResult )
+ {
+ for(const auto & i : aContent)
+ {
+ if( i->mbIsFolder )
+ {
+ SvTreeListEntry* pNewEntry = InsertEntry( i->GetTitle(), pEntry, true );
+
+ OUString* sData = new OUString( i->maTargetURL );
+ pNewEntry->SetUserData( static_cast< void* >( sData ) );
+ }
+ }
+ }
+ }
+ else
+ {
+ // this dir was updated recently
+ // next time read this remote folder
+ m_sLastUpdatedDir.clear();
+ }
+}
+
+void FolderTree::FillTreeEntry( const OUString & rUrl, const ::std::vector< std::pair< OUString, OUString > >& rFolders )
+{
+ SetTreePath( rUrl );
+
+ SvTreeListEntry* pParent = GetCurEntry();
+
+ if( !(pParent && !IsExpanded( pParent )) )
+ return;
+
+ while (SvTreeListEntry* pChild = FirstChild(pParent))
+ {
+ GetModel()->Remove(pChild);
+ }
+
+ for (auto const& folder : rFolders)
+ {
+ SvTreeListEntry* pNewEntry = InsertEntry( folder.first, pParent, true );
+ OUString* sData = new OUString( folder.second );
+ pNewEntry->SetUserData( static_cast< void* >( sData ) );
+ }
+
+ m_sLastUpdatedDir = rUrl;
+ Expand( pParent );
+}
+
+void FolderTree::SetTreePath( OUString const & sUrl )
+{
+ INetURLObject aUrl( sUrl );
+ aUrl.setFinalSlash();
+
+ OUString sPath = aUrl.GetURLPath( INetURLObject::DecodeMechanism::WithCharset );
+
+ SvTreeListEntry* pEntry = First();
+ bool end = false;
+
+ while( pEntry && !end )
+ {
+ if( pEntry->GetUserData() )
+ {
+ OUString sNodeUrl = *static_cast< OUString* >( pEntry->GetUserData() );
+
+ INetURLObject aUrlObj( sNodeUrl );
+ aUrlObj.setFinalSlash();
+
+ sNodeUrl = aUrlObj.GetURLPath( INetURLObject::DecodeMechanism::WithCharset );
+
+ if( sPath == sNodeUrl )
+ {
+ Select( pEntry );
+ end = true;
+ }
+ else if( sPath.startsWith( sNodeUrl ) )
+ {
+ if( !IsExpanded( pEntry ) )
+ Expand( pEntry );
+
+ pEntry = FirstChild( pEntry );
+ }
+ else
+ {
+ pEntry = pEntry->NextSibling();
+ }
+ }
+ else
+ break;
+ }
+}
+
+void FolderTree::SetBlackList( const css::uno::Sequence< OUString >& rBlackList )
+{
+ m_aBlackList = rBlackList;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/foldertree.hxx b/fpicker/source/office/foldertree.hxx
new file mode 100644
index 000000000000..03710efb2076
--- /dev/null
+++ b/fpicker/source/office/foldertree.hxx
@@ -0,0 +1,47 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#ifndef INCLUDED_SVTOOLS_FOLDERTREE_HXX
+#define INCLUDED_SVTOOLS_FOLDERTREE_HXX
+
+#include <com/sun/star/uno/Sequence.hxx>
+#include <tools/wintypes.hxx>
+#include <vcl/treelistbox.hxx>
+
+namespace com :: sun :: star :: ucb { class XCommandEnvironment; }
+
+class SvTreeListEntry;
+
+using namespace ::com::sun::star::ucb;
+using namespace ::com::sun::star::uno;
+using namespace ::svt;
+
+class FolderTree : public SvTreeListBox
+{
+private:
+ Reference< XCommandEnvironment > m_xEnv;
+ ::osl::Mutex m_aMutex;
+ Sequence< OUString > m_aBlackList;
+
+ OUString m_sLastUpdatedDir;
+
+public:
+ FolderTree( vcl::Window* pParent, WinBits nBits );
+
+ virtual void RequestingChildren( SvTreeListEntry* pEntry ) override;
+
+ void FillTreeEntry( SvTreeListEntry* pEntry );
+ void FillTreeEntry( const OUString & rUrl, const ::std::vector< std::pair< OUString, OUString > >& rFolders );
+ void SetTreePath( OUString const & sUrl );
+ void SetBlackList( const css::uno::Sequence< OUString >& rBlackList );
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/iconview.cxx b/fpicker/source/office/iconview.cxx
new file mode 100644
index 000000000000..b6571b72d1da
--- /dev/null
+++ b/fpicker/source/office/iconview.cxx
@@ -0,0 +1,233 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/treelistentry.hxx>
+#include <vcl/viewdataentry.hxx>
+#include "fileview.hxx"
+#include "iconview.hxx"
+#include "iconviewimpl.hxx"
+
+IconView::IconView( vcl::Window* pParent, WinBits nBits )
+: SvTreeListBox( pParent, nBits )
+{
+ nColumns = 1;
+ mbCenterAndClipText = true;
+ SetEntryHeight( 100 );
+ SetEntryWidth( 100 );
+
+ pImpl.reset( new IconViewImpl( this, GetModel(), GetStyle() ) );
+}
+
+void IconView::Resize()
+{
+ Size aBoxSize = Control::GetParent()->GetOutputSizePixel();
+
+ if ( !aBoxSize.Width() )
+ return;
+
+ SetSizePixel( aBoxSize );
+
+ nColumns = aBoxSize.Width() / nEntryWidth;
+
+ SvTreeListBox::Resize();
+}
+
+tools::Rectangle IconView::GetFocusRect( SvTreeListEntry*, long nEntryPos )
+{
+ Size aSize;
+ aSize.setHeight( nEntryHeight );
+ aSize.setWidth( nEntryWidth );
+
+ Point aPos;
+ aPos.setX( 0 );
+ aPos.setY( 0 );
+
+ tools::Rectangle aRect;
+
+ short nCols = GetColumnsCount();
+
+ if(nCols)
+ {
+ aPos.setY( ( nEntryPos / nCols ) * nEntryHeight );
+ aPos.setX( ( nEntryPos % nCols ) * nEntryWidth );
+ }
+
+ aRect.SetPos( aPos );
+ aRect.SetSize( aSize );
+
+ return aRect;
+}
+
+void IconView::ClearAll()
+{
+ for ( sal_uLong i = 0; i < GetEntryCount(); ++i )
+ delete static_cast<SvtContentEntry*>(GetEntry(i)->GetUserData());
+
+ Clear();
+}
+
+void IconView::PaintEntry(SvTreeListEntry& rEntry, long nX, long nY,
+ vcl::RenderContext& rRenderContext)
+{
+
+ tools::Rectangle aRect; // multi purpose
+
+ PreparePaint(rRenderContext, rEntry);
+
+ pImpl->UpdateContextBmpWidthMax(&rEntry);
+
+ short nTempEntryHeight = GetEntryHeight();
+ short nTempEntryWidth = GetEntryWidth();
+
+ Point aEntryPos;
+
+ Color aBackupTextColor(rRenderContext.GetTextColor());
+ vcl::Font aBackupFont(rRenderContext.GetFont());
+ Color aBackupColor = rRenderContext.GetFillColor();
+
+ bool bCurFontIsSel = false;
+ const WinBits nWindowStyle = GetStyle();
+ const bool bHideSelection = (nWindowStyle & WB_HIDESELECTION) !=0 && !HasFocus();
+ const StyleSettings& rSettings = rRenderContext.GetSettings().GetStyleSettings();
+
+ vcl::Font aHighlightFont(rRenderContext.GetFont());
+ const Color aHighlightTextColor(rSettings.GetHighlightTextColor());
+ aHighlightFont.SetColor(aHighlightTextColor);
+
+ Size aRectSize(nTempEntryWidth, nTempEntryHeight);
+
+ SvViewDataEntry* pViewDataEntry = GetViewDataEntry( &rEntry );
+
+ sal_uInt16 nItemCount = rEntry.ItemCount();
+ sal_uInt16 nCurItem = 0;
+ sal_uInt16 nIconItem = nItemCount;
+
+ while (nCurItem < nItemCount)
+ {
+ SvLBoxItem* pItem = nCurItem < nItemCount ? &rEntry.GetItem(nCurItem) : nullptr;
+ SvLBoxItemType nItemType = pItem->GetType();
+
+ if (nItemType == SvLBoxItemType::ContextBmp)
+ {
+ nIconItem = nCurItem;
+ nCurItem++;
+ continue;
+ }
+
+ auto nItemHeight = SvLBoxItem::GetHeight(pViewDataEntry, nCurItem);
+
+ aEntryPos.setX( nX );
+ aEntryPos.setY( nY );
+
+ // set background pattern/color
+
+ Wallpaper aWallpaper = rRenderContext.GetBackground();
+
+ if (pViewDataEntry->IsHighlighted())
+ {
+ Color aNewWallColor = rSettings.GetHighlightColor();
+ // if the face color is bright then the deactivate color is also bright
+ // -> so you can't see any deactivate selection
+ if (bHideSelection && !rSettings.GetFaceColor().IsBright()
+ && aWallpaper.GetColor().IsBright() != rSettings.GetDeactiveColor().IsBright())
+ {
+ aNewWallColor = rSettings.GetDeactiveColor();
+ }
+ // set font color to highlight
+ if (!bCurFontIsSel)
+ {
+ rRenderContext.SetTextColor(aHighlightTextColor);
+ rRenderContext.SetFont(aHighlightFont);
+ bCurFontIsSel = true;
+ }
+ aWallpaper.SetColor(aNewWallColor);
+ }
+ else // no selection
+ {
+ if (bCurFontIsSel)
+ {
+ bCurFontIsSel = false;
+ rRenderContext.SetTextColor(aBackupTextColor);
+ rRenderContext.SetFont(aBackupFont);
+ }
+ else
+ {
+ aWallpaper.SetColor(rEntry.GetBackColor());
+ }
+ }
+
+ // draw background
+ if (!(nTreeFlags & SvTreeFlags::USESEL))
+ {
+ aRect.SetPos(aEntryPos);
+ aRect.SetSize(aRectSize);
+
+ Color aBackgroundColor = aWallpaper.GetColor();
+ if (aBackgroundColor != COL_TRANSPARENT)
+ {
+ rRenderContext.SetFillColor(aBackgroundColor);
+ // this case may occur for smaller horizontal resizes
+ if (aRect.Left() < aRect.Right())
+ rRenderContext.DrawRect(aRect);
+ }
+ }
+
+ // center vertically
+ aEntryPos.AdjustY((nTempEntryHeight - nItemHeight) / 2 );
+
+ // draw item
+ pViewDataEntry->SetPaintRectangle(aRect);
+
+ aEntryPos.AdjustY(15 );
+
+ pItem->Paint(aEntryPos, *this, rRenderContext, pViewDataEntry, rEntry);
+
+ rRenderContext.SetFillColor(aBackupColor);
+
+ nCurItem++;
+ }
+
+ // draw icon
+ if(nIconItem != nItemCount && nIconItem < nItemCount)
+ {
+ SvLBoxItem* pItem = &rEntry.GetItem(nIconItem);
+ auto nItemWidth = pItem->GetWidth(this, pViewDataEntry, nIconItem);
+ auto nItemHeight = SvLBoxItem::GetHeight(pViewDataEntry, nIconItem);
+
+ aEntryPos.setX( nX );
+ aEntryPos.setY( nY );
+
+ // center horizontally
+ aEntryPos.AdjustX((nTempEntryWidth - nItemWidth) / 2 );
+ // center vertically
+ aEntryPos.AdjustY((nTempEntryHeight - nItemHeight) / 2 );
+
+ aEntryPos.AdjustY( -10 );
+
+ pItem->Paint(aEntryPos, *this, rRenderContext, pViewDataEntry, rEntry);
+ }
+
+ if (bCurFontIsSel)
+ {
+ rRenderContext.SetTextColor(aBackupTextColor);
+ rRenderContext.SetFont(aBackupFont);
+ }
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/iconview.hxx b/fpicker/source/office/iconview.hxx
new file mode 100644
index 000000000000..17a9103e9c2f
--- /dev/null
+++ b/fpicker/source/office/iconview.hxx
@@ -0,0 +1,41 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_SVTOOLS_ICONVIEW_HXX
+#define INCLUDED_SVTOOLS_ICONVIEW_HXX
+
+#include <vcl/treelistbox.hxx>
+
+class IconView : public SvTreeListBox
+{
+public:
+ IconView( vcl::Window* pParent, WinBits nBits );
+
+ virtual void Resize() override;
+
+ virtual tools::Rectangle GetFocusRect( SvTreeListEntry*, long nEntryPos ) override;
+
+ void ClearAll();
+
+ void PaintEntry( SvTreeListEntry&, long nX, long nY, vcl::RenderContext& rRenderContext);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/iconviewimpl.cxx b/fpicker/source/office/iconviewimpl.cxx
new file mode 100644
index 000000000000..ff3bdfcd9e76
--- /dev/null
+++ b/fpicker/source/office/iconviewimpl.cxx
@@ -0,0 +1,662 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <vcl/svapp.hxx>
+#include <tools/debug.hxx>
+#include "iconview.hxx"
+#include "iconviewimpl.hxx"
+
+IconViewImpl::IconViewImpl( SvTreeListBox* pTreeListBox, SvTreeList* pTreeList, WinBits nWinStyle )
+: SvImpLBox( pTreeListBox, pTreeList, nWinStyle )
+{
+}
+
+void IconViewImpl::CursorUp()
+{
+ if (!m_pStartEntry)
+ return;
+
+ SvTreeListEntry* pPrevFirstToDraw = m_pStartEntry;
+
+ for(short i = 0; i < m_pView->GetColumnsCount() && pPrevFirstToDraw; i++)
+ pPrevFirstToDraw = m_pView->PrevVisible(pPrevFirstToDraw);
+
+ if( !pPrevFirstToDraw )
+ return;
+
+ m_nFlags &= ~LBoxFlags::Filling;
+ long nEntryHeight = m_pView->GetEntryHeight();
+ ShowCursor( false );
+ m_pView->Update();
+ m_pStartEntry = pPrevFirstToDraw;
+ tools::Rectangle aArea( GetVisibleArea() );
+ aArea.AdjustBottom( -nEntryHeight );
+ m_pView->Scroll( 0, nEntryHeight, aArea, ScrollFlags::NoChildren );
+ m_pView->Update();
+ ShowCursor( true );
+ m_pView->NotifyScrolled();
+}
+
+void IconViewImpl::CursorDown()
+{
+ if (!m_pStartEntry)
+ return;
+
+ SvTreeListEntry* pNextFirstToDraw = m_pStartEntry;
+
+ for(short i = 0; i < m_pView->GetColumnsCount(); i++)
+ pNextFirstToDraw = m_pView->NextVisible(pNextFirstToDraw);
+
+ if( pNextFirstToDraw )
+ {
+ m_nFlags &= ~LBoxFlags::Filling;
+ ShowCursor( false );
+ m_pView->Update();
+ m_pStartEntry = pNextFirstToDraw;
+ tools::Rectangle aArea( GetVisibleArea() );
+ m_pView->Scroll( 0, -(m_pView->GetEntryHeight()), aArea, ScrollFlags::NoChildren );
+ m_pView->Update();
+ ShowCursor( true );
+ m_pView->NotifyScrolled();
+ }
+}
+
+void IconViewImpl::PageDown( sal_uInt16 nDelta )
+{
+ sal_uInt16 nRealDelta = nDelta * m_pView->GetColumnsCount();
+
+ if( !nDelta )
+ return;
+
+ if (!m_pStartEntry)
+ return;
+
+ SvTreeListEntry* pNext = m_pView->NextVisible(m_pStartEntry, nRealDelta);
+ if( pNext == m_pStartEntry )
+ return;
+
+ ShowCursor( false );
+
+ m_nFlags &= ~LBoxFlags::Filling;
+ m_pView->Update();
+ m_pStartEntry = pNext;
+
+ if( nRealDelta >= m_nVisibleCount )
+ {
+ m_pView->Invalidate( GetVisibleArea() );
+ m_pView->Update();
+ }
+ else
+ {
+ tools::Rectangle aArea( GetVisibleArea() );
+ long nScroll = m_pView->GetEntryHeight() * static_cast<long>(nRealDelta);
+ nScroll = -nScroll;
+ m_pView->Update();
+ m_pView->Scroll( 0, nScroll, aArea, ScrollFlags::NoChildren );
+ m_pView->Update();
+ m_pView->NotifyScrolled();
+ }
+
+ ShowCursor( true );
+}
+
+void IconViewImpl::PageUp( sal_uInt16 nDelta )
+{
+ sal_uInt16 nRealDelta = nDelta * m_pView->GetColumnsCount();
+ if( !nDelta )
+ return;
+
+ if (!m_pStartEntry)
+ return;
+
+ SvTreeListEntry* pPrev = m_pView->PrevVisible(m_pStartEntry, nRealDelta);
+ if( pPrev == m_pStartEntry )
+ return;
+
+ m_nFlags &= ~LBoxFlags::Filling;
+ ShowCursor( false );
+
+ m_pView->Update();
+ m_pStartEntry = pPrev;
+ if( nRealDelta >= m_nVisibleCount )
+ {
+ m_pView->Invalidate( GetVisibleArea() );
+ m_pView->Update();
+ }
+ else
+ {
+ long nEntryHeight = m_pView->GetEntryHeight();
+ tools::Rectangle aArea( GetVisibleArea() );
+ m_pView->Update();
+ m_pView->Scroll( 0, nEntryHeight*nRealDelta, aArea, ScrollFlags::NoChildren );
+ m_pView->Update();
+ m_pView->NotifyScrolled();
+ }
+
+ ShowCursor( true );
+}
+
+void IconViewImpl::KeyDown( bool bPageDown )
+{
+ if( !m_aVerSBar->IsVisible() )
+ return;
+
+ long nDelta;
+ if( bPageDown )
+ nDelta = m_aVerSBar->GetPageSize();
+ else
+ nDelta = 1;
+
+ long nThumbPos = m_aVerSBar->GetThumbPos();
+
+ if( nDelta <= 0 )
+ return;
+
+ m_nFlags &= ~LBoxFlags::Filling;
+ BeginScroll();
+
+ m_aVerSBar->SetThumbPos( nThumbPos+nDelta );
+ if( bPageDown )
+ PageDown( static_cast<short>(nDelta) );
+ else
+ CursorDown();
+
+ EndScroll();
+}
+
+void IconViewImpl::KeyUp( bool bPageUp )
+{
+ if( !m_aVerSBar->IsVisible() )
+ return;
+
+ long nDelta;
+ if( bPageUp )
+ nDelta = m_aVerSBar->GetPageSize();
+ else
+ nDelta = 1;
+
+ long nThumbPos = m_aVerSBar->GetThumbPos();
+
+ if( nThumbPos < nDelta )
+ nDelta = nThumbPos;
+
+ if( nDelta < 0 )
+ return;
+
+ m_nFlags &= ~LBoxFlags::Filling;
+ BeginScroll();
+
+ m_aVerSBar->SetThumbPos( nThumbPos - nDelta );
+ if( bPageUp )
+ PageUp( static_cast<short>(nDelta) );
+ else
+ CursorUp();
+
+ EndScroll();
+}
+
+long IconViewImpl::GetEntryLine( SvTreeListEntry* pEntry ) const
+{
+ if(!m_pStartEntry )
+ return -1; // invisible position
+
+ long nFirstVisPos = m_pView->GetVisiblePos( m_pStartEntry );
+ long nEntryVisPos = m_pView->GetVisiblePos( pEntry );
+ nFirstVisPos = nEntryVisPos - nFirstVisPos;
+
+ return nFirstVisPos;
+}
+
+Point IconViewImpl::GetEntryPosition( SvTreeListEntry* pEntry ) const
+{
+ const int pos = m_pView->GetAbsPos( pEntry );
+
+ return Point( ( pos % m_pView->GetColumnsCount() ) * m_pView->GetEntryWidth(),
+ ( pos / m_pView->GetColumnsCount() ) * m_pView->GetEntryHeight() );
+}
+
+SvTreeListEntry* IconViewImpl::GetClickedEntry( const Point& rPoint ) const
+{
+ DBG_ASSERT( m_pView->GetModel(), "IconViewImpl::GetClickedEntry: how can this ever happen?" );
+ if ( !m_pView->GetModel() )
+ return nullptr;
+ if( m_pView->GetEntryCount() == 0 || !m_pStartEntry || !m_pView->GetEntryHeight() || !m_pView->GetEntryWidth())
+ return nullptr;
+
+ sal_uInt16 nY = static_cast<sal_uInt16>(rPoint.Y() / m_pView->GetEntryHeight() );
+ sal_uInt16 nX = static_cast<sal_uInt16>(rPoint.X() / m_pView->GetEntryWidth() );
+ sal_uInt16 nTemp = nY * m_pView->GetColumnsCount() + nX;
+
+ SvTreeListEntry* pEntry = m_pView->NextVisible(m_pStartEntry, nTemp);
+
+ return pEntry;
+}
+
+bool IconViewImpl::IsEntryInView( SvTreeListEntry* pEntry ) const
+{
+ // parent collapsed
+ if( !m_pView->IsEntryVisible(pEntry) )
+ return false;
+
+ long nY = GetEntryLine( pEntry ) / m_pView->GetColumnsCount() * m_pView->GetEntryHeight();
+ if( nY < 0 )
+ return false;
+
+ long nMax = m_nVisibleCount / m_pView->GetColumnsCount() * m_pView->GetEntryHeight();
+ if( nY >= nMax )
+ return false;
+
+ long nStart = GetEntryLine( pEntry ) - GetEntryLine( m_pStartEntry );
+ return nStart >= 0;
+}
+
+void IconViewImpl::AdjustScrollBars( Size& rSize )
+{
+ long nEntryHeight = m_pView->GetEntryHeight();
+ if( !nEntryHeight )
+ return;
+
+ sal_uInt16 nResult = 0;
+
+ Size aOSize( m_pView->Control::GetOutputSizePixel() );
+
+ const WinBits nWindowStyle = m_pView->GetStyle();
+ bool bVerSBar = ( nWindowStyle & WB_VSCROLL ) != 0;
+
+ // number of entries that are not collapsed
+ sal_uLong nTotalCount = m_pView->GetVisibleCount();
+
+ // number of entries visible within the view
+ m_nVisibleCount = aOSize.Height() / nEntryHeight * m_pView->GetColumnsCount();
+
+ long nRows = ( nTotalCount / m_pView->GetColumnsCount() ) + 1;
+
+ // do we need a vertical scrollbar?
+ if( bVerSBar || nTotalCount > m_nVisibleCount )
+ {
+ nResult = 1;
+ }
+
+ PositionScrollBars( aOSize, nResult );
+
+ // adapt Range, VisibleRange etc.
+
+ // refresh output size, in case we have to scroll
+ tools::Rectangle aRect;
+ aRect.SetSize( aOSize );
+ m_aSelEng.SetVisibleArea( aRect );
+
+ // vertical scrollbar
+ if( !m_bInVScrollHdl )
+ {
+ m_aVerSBar->SetPageSize( nTotalCount );
+ m_aVerSBar->SetVisibleSize( nTotalCount - nRows );
+ }
+ else
+ {
+ m_nFlags |= LBoxFlags::EndScrollSetVisSize;
+ }
+
+ if( nResult & 0x0001 )
+ m_aVerSBar->Show();
+ else
+ m_aVerSBar->Hide();
+
+ rSize = aOSize;
+}
+
+// returns 0 if position is just past the last entry
+SvTreeListEntry* IconViewImpl::GetEntry( const Point& rPoint ) const
+{
+ if( (m_pView->GetEntryCount() == 0) || !m_pStartEntry ||
+ (rPoint.Y() > m_aOutputSize.Height())
+ || !m_pView->GetEntryHeight()
+ || !m_pView->GetEntryWidth())
+ return nullptr;
+
+ sal_uInt16 nClickedEntry = static_cast<sal_uInt16>(rPoint.Y() / m_pView->GetEntryHeight() * m_pView->GetColumnsCount() + rPoint.X() / m_pView->GetEntryWidth() );
+ sal_uInt16 nTemp = nClickedEntry;
+ SvTreeListEntry* pEntry = m_pView->NextVisible(m_pStartEntry, nTemp);
+ if( nTemp != nClickedEntry )
+ pEntry = nullptr;
+ return pEntry;
+}
+
+void IconViewImpl::SyncVerThumb()
+{
+ if( m_pStartEntry )
+ {
+ long nEntryPos = m_pView->GetVisiblePos( m_pStartEntry );
+ m_aVerSBar->SetThumbPos( nEntryPos );
+ }
+ else
+ m_aVerSBar->SetThumbPos( 0 );
+}
+
+void IconViewImpl::UpdateAll( bool bInvalidateCompleteView )
+{
+ FindMostRight( nullptr );
+ m_aVerSBar->SetRange( Range( 0, m_pView->GetVisibleCount() ) );
+ SyncVerThumb();
+ FillView();
+ ShowVerSBar();
+ if( m_bSimpleTravel && m_pCursor && m_pView->HasFocus() )
+ m_pView->Select( m_pCursor );
+ ShowCursor( true );
+ if( bInvalidateCompleteView )
+ m_pView->Invalidate();
+ else
+ m_pView->Invalidate( GetVisibleArea() );
+}
+
+void IconViewImpl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
+{
+ if (!m_pView->GetVisibleCount())
+ return;
+
+ m_nFlags |= LBoxFlags::InPaint;
+
+ if (m_nFlags & LBoxFlags::Filling)
+ {
+ SvTreeListEntry* pFirst = m_pView->First();
+ if (pFirst != m_pStartEntry)
+ {
+ ShowCursor(false);
+ m_pStartEntry = m_pView->First();
+ m_aVerSBar->SetThumbPos( 0 );
+ StopUserEvent();
+ ShowCursor(true);
+ m_nCurUserEvent = Application::PostUserEvent(LINK(this, SvImpLBox, MyUserEvent),
+ reinterpret_cast<void*>(1));
+ return;
+ }
+ }
+
+ if (!m_pStartEntry)
+ {
+ m_pStartEntry = m_pView->First();
+ }
+
+ long nRectHeight = rRect.GetHeight();
+ long nRectWidth = rRect.GetWidth();
+ long nEntryHeight = m_pView->GetEntryHeight();
+ long nEntryWidth = m_pView->GetEntryWidth();
+
+ // calculate area for the entries we want to draw
+ sal_uInt16 nStartId = static_cast<sal_uInt16>(rRect.Top() / nEntryHeight * m_pView->GetColumnsCount() + (rRect.Left() / nEntryWidth));
+ sal_uInt16 nCount = static_cast<sal_uInt16>(( nRectHeight / nEntryHeight + 1 ) * nRectWidth / nEntryWidth);
+ nCount += 2; // don't miss an entry
+
+ long nY = nStartId / m_pView->GetColumnsCount() * nEntryHeight;
+ long nX = 0;
+ SvTreeListEntry* pEntry = m_pStartEntry;
+ while (nStartId && pEntry)
+ {
+ pEntry = m_pView->NextVisible(pEntry);
+ nStartId--;
+ }
+
+ vcl::Region aClipRegion(GetClipRegionRect());
+
+ if (!m_pCursor && !mbNoAutoCurEntry)
+ {
+ // do not select if multiselection or explicit set
+ bool bNotSelect = (m_aSelEng.GetSelectionMode() == SelectionMode::Multiple ) || ((m_nStyle & WB_NOINITIALSELECTION) == WB_NOINITIALSELECTION);
+ SetCursor(m_pStartEntry, bNotSelect);
+ }
+
+ for(sal_uInt16 n = 0; n< nCount && pEntry; n++)
+ {
+ static_cast<IconView*>(m_pView.get())->PaintEntry(*pEntry, nX, nY, rRenderContext);
+ nX += nEntryWidth;
+
+ if(nX + m_pView->GetEntryWidth() > nEntryWidth * m_pView->GetColumnsCount())
+ {
+ nY += nEntryHeight;
+ nX = 0;
+ }
+ pEntry = m_pView->NextVisible(pEntry);
+ }
+
+ m_nFlags &= ~LBoxFlags::DeselectAll;
+ rRenderContext.SetClipRegion();
+ m_nFlags &= ~LBoxFlags::InPaint;
+}
+
+void IconViewImpl::InvalidateEntry( long nId ) const
+{
+ if( m_nFlags & LBoxFlags::InPaint )
+ return;
+
+ tools::Rectangle aRect( GetVisibleArea() );
+ long nMaxBottom = aRect.Bottom();
+ aRect.SetTop( nId / m_pView->GetColumnsCount() * m_pView->GetEntryHeight() );
+ aRect.SetBottom( aRect.Top() ); aRect.AdjustBottom(m_pView->GetEntryHeight() );
+
+ if( aRect.Top() > nMaxBottom )
+ return;
+ if( aRect.Bottom() > nMaxBottom )
+ aRect.SetBottom( nMaxBottom );
+ m_pView->Invalidate( aRect );
+}
+
+bool IconViewImpl::KeyInput( const KeyEvent& rKEvt )
+{
+ const vcl::KeyCode& rKeyCode = rKEvt.GetKeyCode();
+
+ if( rKeyCode.IsMod2() )
+ return false; // don't evaluate Alt key
+
+ m_nFlags &= ~LBoxFlags::Filling;
+
+ if( !m_pCursor )
+ m_pCursor = m_pStartEntry;
+ if( !m_pCursor )
+ return false;
+
+ sal_uInt16 aCode = rKeyCode.GetCode();
+
+ bool bShift = rKeyCode.IsShift();
+ bool bMod1 = rKeyCode.IsMod1();
+
+ SvTreeListEntry* pNewCursor;
+
+ bool bHandled = true;
+
+ long i;
+ long nColumns = m_pView->GetColumnsCount();
+
+ switch( aCode )
+ {
+ case KEY_LEFT:
+ if( !IsEntryInView( m_pCursor ) )
+ MakeVisible( m_pCursor );
+
+ pNewCursor = m_pCursor;
+ do
+ {
+ pNewCursor = m_pView->PrevVisible(pNewCursor);
+ } while( pNewCursor && !IsSelectable(pNewCursor) );
+
+ // if there is no next entry, take the current one
+ // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
+ // the cursor key
+ if (!pNewCursor)
+ pNewCursor = m_pCursor;
+
+ m_aSelEng.CursorPosChanging( bShift, bMod1 );
+ SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
+ if( !IsEntryInView( pNewCursor ) )
+ KeyUp( false );
+ break;
+
+ case KEY_RIGHT:
+ if( !IsEntryInView( m_pCursor ) )
+ MakeVisible( m_pCursor );
+
+ pNewCursor = m_pCursor;
+ do
+ {
+ pNewCursor = m_pView->NextVisible(pNewCursor);
+ } while( pNewCursor && !IsSelectable(pNewCursor) );
+
+ // if there is no next entry, take the current one
+ // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
+ // the cursor key
+ if ( !pNewCursor && m_pCursor )
+ pNewCursor = m_pCursor;
+
+ if( pNewCursor )
+ {
+ m_aSelEng.CursorPosChanging( bShift, bMod1 );
+ if( IsEntryInView( pNewCursor ) )
+ SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
+ else
+ {
+ if( m_pCursor )
+ m_pView->Select( m_pCursor, false );
+ KeyDown( false );
+ SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
+ }
+ }
+ else
+ KeyDown( false ); // because scrollbar range might still
+ // allow scrolling
+ break;
+
+ case KEY_UP:
+ {
+ if( !IsEntryInView( m_pCursor ) )
+ MakeVisible( m_pCursor );
+
+ pNewCursor = m_pCursor;
+ for( i = 0; i < nColumns && pNewCursor; i++)
+ {
+ do
+ {
+ pNewCursor = m_pView->PrevVisible(pNewCursor);
+ } while( pNewCursor && !IsSelectable(pNewCursor) );
+ }
+
+ // if there is no next entry, take the current one
+ // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
+ // the cursor key
+ if ( !pNewCursor && m_pCursor )
+ pNewCursor = m_pCursor;
+
+ if( pNewCursor )
+ {
+ m_aSelEng.CursorPosChanging( bShift, bMod1 );
+ SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
+ if( !IsEntryInView( pNewCursor ) )
+ KeyUp( false );
+ }
+ break;
+ }
+
+ case KEY_DOWN:
+ {
+ if( !IsEntryInView( m_pCursor ) )
+ MakeVisible( m_pCursor );
+
+ pNewCursor = m_pCursor;
+ for( i = 0; i < nColumns && pNewCursor; i++)
+ {
+ do
+ {
+ pNewCursor = m_pView->NextVisible(pNewCursor);
+ } while( pNewCursor && !IsSelectable(pNewCursor) );
+ }
+
+ // if there is no next entry, take the current one
+ // this ensures that in case of _one_ entry in the list, this entry is selected when pressing
+ // the cursor key
+ if ( !pNewCursor && m_pCursor )
+ pNewCursor = m_pCursor;
+
+ if( pNewCursor )
+ {
+ m_aSelEng.CursorPosChanging( bShift, bMod1 );
+ if( IsEntryInView( pNewCursor ) )
+ SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
+ else
+ {
+ if( m_pCursor )
+ m_pView->Select( m_pCursor, false );
+ KeyDown( false );
+ SetCursor( pNewCursor, bMod1 ); // no selection, when Ctrl is on
+ }
+ }
+ else
+ KeyDown( false ); // because scrollbar range might still
+ // allow scrolling
+ break;
+ }
+
+ case KEY_RETURN:
+ {
+ m_pView->aDoubleClickHdl.Call( m_pView );
+ bHandled = true;
+
+ break;
+ }
+
+ case KEY_END:
+ {
+ pNewCursor = m_pView->GetModel()->Last();
+
+ while( pNewCursor && !IsSelectable(pNewCursor) )
+ {
+ pNewCursor = m_pView->PrevVisible(pNewCursor);
+ }
+
+ m_pStartEntry = pNewCursor;
+
+ while( m_pStartEntry && m_pView->GetAbsPos( m_pStartEntry ) % m_pView->GetColumnsCount() != 0 )
+ {
+ m_pStartEntry = m_pView->PrevVisible(m_pStartEntry);
+ }
+
+ if( pNewCursor && pNewCursor != m_pCursor)
+ {
+// SelAllDestrAnch( false );
+ m_aSelEng.CursorPosChanging( bShift, bMod1 );
+ SetCursor( pNewCursor );
+ SyncVerThumb();
+ }
+
+ bHandled = true;
+
+ break;
+ }
+
+ default:
+ {
+ bHandled = false;
+ break;
+ }
+ }
+
+ if(!bHandled)
+ return SvImpLBox::KeyInput( rKEvt );
+
+ return true;
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/iconviewimpl.hxx b/fpicker/source/office/iconviewimpl.hxx
new file mode 100644
index 000000000000..df11f5952426
--- /dev/null
+++ b/fpicker/source/office/iconviewimpl.hxx
@@ -0,0 +1,68 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#ifndef INCLUDED_VCL_SOURCE_INC_ICONVIEWIMPL_HXX
+#define INCLUDED_VCL_SOURCE_INC_ICONVIEWIMPL_HXX
+
+#include <vcl/svimpbox.hxx>
+
+class SvTreeListBox;
+class Point;
+
+class IconViewImpl : public SvImpLBox
+{
+public:
+ IconViewImpl( SvTreeListBox* pTreeListBox, SvTreeList* pTreeList, WinBits nWinStyle );
+
+ void KeyDown( bool bPageDown ) override;
+
+ void KeyUp( bool bPageUp ) override;
+
+ Point GetEntryPosition( SvTreeListEntry* pEntry ) const override;
+
+ SvTreeListEntry* GetClickedEntry( const Point& rPoint ) const override;
+
+ bool IsEntryInView( SvTreeListEntry* pEntry ) const override;
+
+ void Paint( vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect ) override;
+
+ // returns 0 if position is just past the last entry
+ SvTreeListEntry* GetEntry( const Point& rPoint ) const override;
+
+ void UpdateAll( bool bInvalidateCompleteView ) override;
+
+ bool KeyInput( const KeyEvent& ) override;
+
+ void InvalidateEntry( long nId ) const override;
+
+protected:
+ long GetEntryLine( SvTreeListEntry* pEntry ) const override;
+
+ void CursorUp() override;
+ void CursorDown() override;
+ void PageDown( sal_uInt16 nDelta ) override;
+ void PageUp( sal_uInt16 nDelta ) override;
+
+ void SyncVerThumb() override;
+ void AdjustScrollBars( Size& rSize ) override;
+};
+
+#endif // INCLUDED_VCL_SOURCE_INC_ICONVIEWIMPL_HXX
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/fpicker/source/office/iodlg.cxx b/fpicker/source/office/iodlg.cxx
index abd187f13a24..ed097017dc5e 100644
--- a/fpicker/source/office/iodlg.cxx
+++ b/fpicker/source/office/iodlg.cxx
@@ -21,6 +21,7 @@
#include <sal/macros.h>
#include <sal/log.hxx>
+#include "fileview.hxx"
#include "iodlg.hxx"
#include <svtools/PlaceEditDialog.hxx>
#include "PlacesListBox.hxx"
@@ -37,7 +38,6 @@
#include <svl/urihelper.hxx>
#include <unotools/pathoptions.hxx>
#include <unotools/viewoptions.hxx>
-#include <svtools/fileview.hxx>
#include <svtools/sfxecode.hxx>
#include <vcl/svtabbx.hxx>
#include <vcl/treelistentry.hxx>
diff --git a/fpicker/source/office/iodlgimp.cxx b/fpicker/source/office/iodlgimp.cxx
index a19f55c9319f..b78603711847 100644
--- a/fpicker/source/office/iodlgimp.cxx
+++ b/fpicker/source/office/iodlgimp.cxx
@@ -17,6 +17,7 @@
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
+#include "fileview.hxx"
#include "iodlgimp.hxx"
#include <vcl/headbar.hxx>
#include <tools/debug.hxx>
@@ -26,7 +27,6 @@
#include <vcl/svapp.hxx>
#include <svl/eitem.hxx>
#include <unotools/viewoptions.hxx>
-#include <svtools/fileview.hxx>
#include <svtools/inettbc.hxx>
#include "iodlg.hxx"
#include <bitmaps.hlst>