diff options
author | Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de> | 2021-07-08 05:50:25 +0200 |
---|---|---|
committer | Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de> | 2021-07-12 14:31:20 +0200 |
commit | d157c1bd70d630a58db33910d550bb8dee9fe62e (patch) | |
tree | 6a7d4a63cc524fcbbdcdfd8c4271fcbb7cd3c983 /sfx2/source/dialog/filedlghelper.cxx | |
parent | c62bb20032cef7479e9293e84a8d57a2c74399d0 (diff) |
tdf#126665 Remember last used file picker directory
This introduces internal tracking of last used directories.
Each caller of the file picker can pass a "context". The selected
directory will then be saved & restored when opening the file picker
with the same context again.
After ffa636ba74b04b3258ec9a696bc4eac33581fa24 , the Windows file picker
no longer tracks the last used directory itself.
This is a replacement and an improvement at the same time, since there is not
one global last used directory, but one per context.
Change-Id: I10650cfb9359922690954fa65c89b4e47477e2c5
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118597
Tested-by: Jenkins
Reviewed-by: Heiko Tietze <heiko.tietze@documentfoundation.org>
Reviewed-by: Samuel Mehrbrodt <samuel.mehrbrodt@allotropia.de>
Diffstat (limited to 'sfx2/source/dialog/filedlghelper.cxx')
-rw-r--r-- | sfx2/source/dialog/filedlghelper.cxx | 246 |
1 files changed, 215 insertions, 31 deletions
diff --git a/sfx2/source/dialog/filedlghelper.cxx b/sfx2/source/dialog/filedlghelper.cxx index c388b909a3a4..abbdc48ae73d 100644 --- a/sfx2/source/dialog/filedlghelper.cxx +++ b/sfx2/source/dialog/filedlghelper.cxx @@ -38,12 +38,16 @@ #include <com/sun/star/ui/dialogs/XFilePicker3.hpp> #include <com/sun/star/ui/dialogs/XAsynchronousExecutableDialog.hpp> #include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XSingleServiceFactory.hpp> #include <com/sun/star/lang/XMultiServiceFactory.hpp> #include <com/sun/star/beans/PropertyValue.hpp> #include <com/sun/star/beans/NamedValue.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> #include <com/sun/star/embed/ElementModes.hpp> #include <com/sun/star/container/XEnumeration.hpp> #include <com/sun/star/container/XContainerQuery.hpp> +#include <com/sun/star/container/XNameAccess.hpp> +#include <com/sun/star/container/XNameContainer.hpp> #include <com/sun/star/task/InteractionHandler.hpp> #include <com/sun/star/task/XInteractionRequest.hpp> #include <com/sun/star/util/RevisionTag.hpp> @@ -88,6 +92,7 @@ #include <sal/log.hxx> #include <comphelper/sequence.hxx> #include <tools/diagnose_ex.h> +#include <officecfg/Office/Common.hxx> #ifdef UNX #include <errno.h> @@ -133,9 +138,9 @@ static std::optional<OUString> GetLastFilterConfigId( FileDialogHelper::Context switch( _eContext ) { - case FileDialogHelper::SD_EXPORT: return aSD_EXPORT_IDENTIFIER; - case FileDialogHelper::SI_EXPORT: return aSI_EXPORT_IDENTIFIER; - case FileDialogHelper::SW_EXPORT: return aSW_EXPORT_IDENTIFIER; + case FileDialogHelper::DrawExport: return aSD_EXPORT_IDENTIFIER; + case FileDialogHelper::ImpressExport: return aSI_EXPORT_IDENTIFIER; + case FileDialogHelper::WriterExport: return aSW_EXPORT_IDENTIFIER; default: break; } @@ -851,7 +856,7 @@ FileDialogHelper_Impl::FileDialogHelper_Impl( const css::uno::Sequence< OUString >& rDenyList ) :m_nDialogType ( nDialogType ) - ,meContext ( FileDialogHelper::UNKNOWN_CONTEXT ) + ,meContext ( FileDialogHelper::UnknownContext ) { const char* pServiceName=nullptr; switch (nDialog) @@ -1979,6 +1984,46 @@ static void SetToken( OUString& rOrigStr, sal_Int32 nToken, sal_Unicode cTok, co rOrigStr = rOrigStr.replaceAt( nFirstChar, i-nFirstChar, rStr ); } +namespace +{ +void SaveLastDirectory(OUString const& sContext, OUString const& sDirectory) +{ + if (sContext.isEmpty()) + return; + + std::shared_ptr<comphelper::ConfigurationChanges> batch( + comphelper::ConfigurationChanges::create()); + Reference<container::XNameContainer> set( + officecfg::Office::Common::Misc::FilePickerLastDirectory::get(batch)); + + bool found; + Any v; + try + { + v = set->getByName(sContext); + found = true; + } + catch (container::NoSuchElementException&) + { + found = false; + } + if (found) + { + Reference<XPropertySet> el(v.get<Reference<XPropertySet>>(), UNO_SET_THROW); + el->setPropertyValue("LastPath", makeAny(sDirectory)); + } + else + { + Reference<XPropertySet> el( + (Reference<lang::XSingleServiceFactory>(set, UNO_QUERY_THROW)->createInstance()), + UNO_QUERY_THROW); + el->setPropertyValue("LastPath", makeAny(sDirectory)); + Any v2(makeAny(el)); + set->insertByName(sContext, v2); + } + batch->commit(); +} +} void FileDialogHelper_Impl::saveConfig() { @@ -2069,43 +2114,67 @@ void FileDialogHelper_Impl::saveConfig() aDlgOpt.SetUserItem( USERITEM_NAME, makeAny( aUserData ) ); } - SfxApplication *pSfxApp = SfxGetpApp(); - pSfxApp->SetLastDir_Impl( getPath() ); + // Store to config, if explicit context is set. Otherwise store in (global) runtime var. + if (meContext != FileDialogHelper::UnknownContext) + { + SaveLastDirectory(FileDialogHelper::contextToString(meContext), getPath()); + } + else + { + SfxApplication *pSfxApp = SfxGetpApp(); + pSfxApp->SetLastDir_Impl( getPath() ); + } } -namespace +OUString FileDialogHelper_Impl::getInitPath(const OUString& _rFallback, + const sal_Int32 _nFallbackToken) { - OUString getInitPath( const OUString& _rFallback, const sal_Int32 _nFallbackToken ) + OUString sPath; + // Load from config, if explicit context is set. Otherwise load from (global) runtime var. + if (meContext != FileDialogHelper::UnknownContext) + { + OUString sContext = FileDialogHelper::contextToString(meContext); + Reference<XNameAccess> set(officecfg::Office::Common::Misc::FilePickerLastDirectory::get()); + Any v; + try + { + v = set->getByName(sContext); + Reference<XPropertySet> el(v.get<Reference<XPropertySet>>(), UNO_SET_THROW); + sPath = el->getPropertyValue("LastPath").get<OUString>(); + } + catch (NoSuchElementException&) + { + } + } + else { SfxApplication *pSfxApp = SfxGetpApp(); - OUString sPath = pSfxApp->GetLastDir_Impl(); + sPath = pSfxApp->GetLastDir_Impl(); + } - if ( sPath.isEmpty() ) - sPath = _rFallback.getToken( _nFallbackToken, ' ' ); + if ( sPath.isEmpty() ) + sPath = _rFallback.getToken( _nFallbackToken, ' ' ); - // check if the path points to a valid (accessible) directory - bool bValid = false; - if ( !sPath.isEmpty() ) + // check if the path points to a valid (accessible) directory + bool bValid = false; + if ( !sPath.isEmpty() ) + { + OUString sPathCheck( sPath ); + if ( sPathCheck[ sPathCheck.getLength() - 1 ] != '/' ) + sPathCheck += "/"; + sPathCheck += "."; + try { - OUString sPathCheck( sPath ); - if ( sPathCheck[ sPathCheck.getLength() - 1 ] != '/' ) - sPathCheck += "/"; - sPathCheck += "."; - try - { - ::ucbhelper::Content aContent( sPathCheck, - utl::UCBContentHelper::getDefaultCommandEnvironment(), - comphelper::getProcessComponentContext() ); - bValid = aContent.isFolder(); - } - catch( const Exception& ) {} + ::ucbhelper::Content aContent( sPathCheck, + utl::UCBContentHelper::getDefaultCommandEnvironment(), + comphelper::getProcessComponentContext() ); + bValid = aContent.isFolder(); } - - if ( !bValid ) - sPath.clear(); - - return sPath; + catch( const Exception& ) {} } + if ( !bValid ) + sPath.clear(); + return sPath; } void FileDialogHelper_Impl::loadConfig() @@ -2375,6 +2444,121 @@ void FileDialogHelper::SetContext( Context _eNewContext ) mpImpl->SetContext( _eNewContext ); } +OUString FileDialogHelper::contextToString(Context context) +{ + // These strings are used in the configuration, to store the last used directory for each context. + // Please don't change them. + switch(context) { + case AcceleratorConfig: + return "AcceleratorConfig"; + case AutoRedact: + return "AutoRedact"; + case BaseDataSource: + return "BaseDataSource"; + case BaseSaveAs: + return "BaseSaveAs"; + case BasicExportPackage: + return "BasicExportPackage"; + case BasicInsertLib: + return "BasicInsertLib"; + case BulletsAddImage: + return "BulletsAddImage"; + case CalcDataProvider: + return "CalcDataProvider"; + case CalcDataStream: + return "CalcDataStream"; + case CalcExport: + return "CalcExport"; + case CalcSaveAs: + return "CalcSaveAs"; + case CalcXMLSource: + return "CalcXMLSource"; + case ExportImage: + return "ExportImage"; + case ExtensionManager: + return "ExtensionManager"; + case FormsAddInstance: + return "FormsAddInstance"; + case FormsInsertImage: + return "FormsInsertImage"; + case LinkClientOLE: + return "LinkClientOLE"; + case LinkClientFile: + return "LinkClientFile"; + case DrawImpressInsertFile: + return "DrawImpressInsertFile"; + case DrawImpressOpenSound: + return "DrawImpressOpenSound"; + case DrawExport: + return "DrawExport"; + case DrawSaveAs: + return "DrawSaveAs"; + case IconImport: + return "IconImport"; + case ImpressClickAction: + return "ImpressClickAction"; + case ImpressExport: + return "ImpressExport"; + case ImpressPhotoDialog: + return "ImpressPhotoDialog"; + case ImpressSaveAs: + return "ImpressSaveAs"; + case ImageMap: + return "ImageMap"; + case InsertDoc: + return "InsertDoc"; + case InsertImage: + return "InsertImage"; + case InsertOLE: + return "InsertOLE"; + case InsertMedia: + return "InsertMedia"; + case JavaClassPath: + return "JavaClassPath"; + case ReportInsertImage: + return "ReportInsertImage"; + case ScreenshotAnnotation: + return "ScreenshotAnnotation"; + case SignatureLine: + return "SignatureLine"; + case TemplateImport: + return "TemplateImport"; + case WriterCreateAddressList: + return "WriterCreateAddressList"; + case WriterExport: + return "WriterExport"; + case WriterImportAutotext: + return "WriterImportAutotext"; + case WriterInsertDoc: + return "WriterInsertDoc"; + case WriterInsertHyperlink: + return "WriterInsertHyperlink"; + case WriterInsertImage: + return "WriterInsertImage"; + case WriterInsertScript: + return "WriterInsertScript"; + case WriterLoadTemplate: + return "WriterLoadTemplate"; + case WriterMailMerge: + return "WriterMailMerge"; + case WriterMailMergeSaveAs: + return "WriterMailMergeSaveAs"; + case WriterNewHTMLGlobalDoc: + return "WriterNewHTMLGlobalDoc"; + case WriterRegisterDataSource: + return "WriterRegisterDataSource"; + case WriterSaveAs: + return "WriterSaveAs"; + case WriterSaveHTML: + return "WriterSaveHTML"; + case XMLFilterSettings: + return "XMLFilterSettings"; + case UnknownContext: + default: + return ""; + } +} + IMPL_LINK_NOARG(FileDialogHelper, ExecuteSystemFilePicker, void*, void) { m_nError = mpImpl->execute(); |