summaryrefslogtreecommitdiffstats
path: root/framework/source/inc/accelerators
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 09:06:44 +0000
commited5640d8b587fbcfed7dd7967f3de04b37a76f26 (patch)
tree7a5f7c6c9d02226d7471cb3cc8fbbf631b415303 /framework/source/inc/accelerators
parentInitial commit. (diff)
downloadlibreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.tar.xz
libreoffice-ed5640d8b587fbcfed7dd7967f3de04b37a76f26.zip
Adding upstream version 4:7.4.7.upstream/4%7.4.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'framework/source/inc/accelerators')
-rw-r--r--framework/source/inc/accelerators/acceleratorcache.hxx115
-rw-r--r--framework/source/inc/accelerators/acceleratorconfiguration.hxx312
-rw-r--r--framework/source/inc/accelerators/keymapping.hxx126
-rw-r--r--framework/source/inc/accelerators/presethandler.hxx378
-rw-r--r--framework/source/inc/accelerators/storageholder.hxx182
5 files changed, 1113 insertions, 0 deletions
diff --git a/framework/source/inc/accelerators/acceleratorcache.hxx b/framework/source/inc/accelerators/acceleratorcache.hxx
new file mode 100644
index 000000000..adfdf8fe5
--- /dev/null
+++ b/framework/source/inc/accelerators/acceleratorcache.hxx
@@ -0,0 +1,115 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <stdtypes.h>
+
+#include <com/sun/star/awt/KeyEvent.hpp>
+
+#include <unordered_map>
+#include <vector>
+
+// definition
+
+namespace framework
+{
+
+/**
+ @short implements a cache for any accelerator configuration.
+
+ @descr It's implemented threadsafe, supports copy-on-write pattern
+ and a flush mechanism to support concurrent access to the same
+ configuration.
+
+ copy-on-write ... How? Do the following:
+ */
+class AcceleratorCache
+{
+ public:
+
+ /**
+ commands -> keys
+ */
+ typedef ::std::vector< css::awt::KeyEvent > TKeyList;
+
+ private:
+
+ typedef std::unordered_map<OUString, TKeyList> TCommand2Keys;
+
+ /**
+ keys -> commands
+ */
+ typedef std::unordered_map< css::awt::KeyEvent ,
+ OUString ,
+ KeyEventHashCode ,
+ KeyEventEqualsFunc > TKey2Commands;
+
+ /** map commands to keys in relation 1:n.
+ First key is interpreted as preferred one! */
+ TCommand2Keys m_lCommand2Keys;
+
+ /** map keys to commands in relation 1:1. */
+ TKey2Commands m_lKey2Commands;
+
+ public:
+ /** @short checks if the specified key exists.
+
+ @param aKey
+ the key, which should be checked.
+
+ @return [bool]
+ sal_True if the specified key exists inside this container.
+ */
+ bool hasKey(const css::awt::KeyEvent& aKey) const;
+ bool hasCommand(const OUString& sCommand) const;
+
+ TKeyList getAllKeys() const;
+
+ /** @short add a new or change an existing key-command pair
+ of this container.
+
+ @param aKey
+ describe the key.
+
+ @param sCommand
+ describe the command.
+ */
+ void setKeyCommandPair(const css::awt::KeyEvent& aKey ,
+ const OUString& sCommand);
+
+ /** @short returns the list of keys, which are registered
+ for this command.
+
+ @param sCommand
+ describe the command.
+
+ @return [TKeyList]
+ the list of registered keys. Can be empty!
+ */
+ TKeyList getKeysByCommand(const OUString& sCommand) const;
+
+ OUString getCommandByKey(const css::awt::KeyEvent& aKey) const;
+ void removeKey(const css::awt::KeyEvent& aKey);
+ void removeCommand(const OUString& sCommand);
+};
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/acceleratorconfiguration.hxx b/framework/source/inc/accelerators/acceleratorconfiguration.hxx
new file mode 100644
index 000000000..725148ebb
--- /dev/null
+++ b/framework/source/inc/accelerators/acceleratorconfiguration.hxx
@@ -0,0 +1,312 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <accelerators/presethandler.hxx>
+#include <accelerators/acceleratorcache.hxx>
+
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/ui/XAcceleratorConfiguration.hpp>
+
+#include <com/sun/star/io/XInputStream.hpp>
+#include <com/sun/star/io/XOutputStream.hpp>
+#include <com/sun/star/util/XChangesListener.hpp>
+
+// TODO use XPresetHandler interface instead if available
+#include <com/sun/star/form/XReset.hpp>
+
+#include <cppuhelper/implbase.hxx>
+
+// definition
+
+namespace framework
+{
+
+inline constexpr OUStringLiteral CFG_ENTRY_PRIMARY = u"PrimaryKeys";
+inline constexpr OUStringLiteral CFG_ENTRY_GLOBAL = u"Global";
+inline constexpr OUStringLiteral CFG_ENTRY_MODULES = u"Modules";
+
+/**
+ implements a read/write access to the accelerator configuration.
+ */
+class XMLBasedAcceleratorConfiguration : public ::cppu::WeakImplHelper<
+ css::form::XReset, // TODO use XPresetHandler instead if available
+ css::ui::XAcceleratorConfiguration > // => css::ui::XUIConfigurationPersistence
+ // css::ui::XUIConfigurationStorage
+ // css::ui::XUIConfiguration
+{
+
+ // member
+
+ protected:
+
+ /** the global uno service manager.
+ Must be used to create own needed services. */
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+
+ /** used to:
+ i ) copy configuration files from the share to the user layer
+ ii ) provide access to these config files
+ iii) cache all sub storages on the path from the top to the bottom(!)
+ iv ) provide commit for changes. */
+ PresetHandler m_aPresetHandler;
+
+ /** contains the cached configuration data */
+ AcceleratorCache m_aReadCache;
+
+ /** used to implement the copy on write pattern! */
+ std::unique_ptr<AcceleratorCache> m_pWriteCache;
+
+ // native interface!
+
+ public:
+
+ XMLBasedAcceleratorConfiguration( const css::uno::Reference< css::uno::XComponentContext >& xContext);
+ virtual ~XMLBasedAcceleratorConfiguration( ) override;
+
+ // uno interface!
+
+ public:
+
+ // XAcceleratorConfiguration
+ virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getAllKeyEvents() override;
+
+ virtual OUString SAL_CALL getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent) override;
+
+ virtual void SAL_CALL setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
+ const OUString& sCommand ) override;
+
+ virtual void SAL_CALL removeKeyEvent(const css::awt::KeyEvent& aKeyEvent) override;
+
+ virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getKeyEventsByCommand(const OUString& sCommand) override;
+
+ virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPreferredKeyEventsForCommandList(const css::uno::Sequence< OUString >& lCommandList) override;
+
+ virtual void SAL_CALL removeCommandFromAllKeyEvents(const OUString& sCommand) override;
+
+ // XUIConfigurationPersistence
+ virtual void SAL_CALL reload() override;
+
+ virtual void SAL_CALL store() override;
+
+ virtual void SAL_CALL storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage) override;
+
+ virtual sal_Bool SAL_CALL isModified() override;
+
+ virtual sal_Bool SAL_CALL isReadOnly() override;
+
+ // XUIConfigurationStorage
+ virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage) override;
+
+ virtual sal_Bool SAL_CALL hasStorage() override;
+
+ // XUIConfiguration
+ virtual void SAL_CALL addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener) override;
+
+ virtual void SAL_CALL removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener) override;
+
+ // XReset
+ // TODO use XPresetHandler instead if available
+ virtual void SAL_CALL reset() override;
+
+ virtual void SAL_CALL addResetListener(const css::uno::Reference< css::form::XResetListener >& xListener) override;
+
+ virtual void SAL_CALL removeResetListener(const css::uno::Reference< css::form::XResetListener >& xListener) override;
+
+ // called when changes occurred in the storage
+ void changesOccurred();
+
+ // helper for derived classes
+
+ protected:
+
+ /** @short return the current office locale.
+
+ @descr We do not cache this value, because we are not listen
+ for changes on the configuration layer ...
+
+ @return OUString
+ The current office locale as BCP47 string.
+ */
+ OUString impl_ts_getLocale() const;
+
+ // helper
+
+ private:
+
+ /** @short load a configuration set, using the given stream.
+
+ @param xStream
+ provides the XML structure as stream.
+ */
+ void impl_ts_load(const css::uno::Reference< css::io::XInputStream >& xStream);
+
+ /** @short save a configuration set, using the given stream.
+
+ @param xStream
+ the XML structure can be written there.
+ */
+ void impl_ts_save(const css::uno::Reference< css::io::XOutputStream >& xStream);
+
+ /** @short returns a reference to one of our internal cache members.
+
+ @descr We implement the copy-on-write pattern. Doing so
+ we know two caches internally. The second one is used
+ only, if the container was changed.
+
+ This method here returns access to one of these
+ caches - depending on the change state of this
+ configuration service.
+
+ @param bWriteAccessRequested
+ if the outside code wish to change the container
+ it must call this method with "sal_True". So the internal
+ cache can be prepared for that (means copy-on-write ...).
+
+ @return [AcceleratorCache]
+ c++ reference(!) to one of our internal caches.
+ */
+ AcceleratorCache& impl_getCFG(bool bWriteAccessRequested = false);
+
+};
+
+class XCUBasedAcceleratorConfiguration : public ::cppu::WeakImplHelper<
+ css::util::XChangesListener,
+ css::form::XReset, // TODO use XPresetHandler instead if available
+ css::ui::XAcceleratorConfiguration > // => css::ui::XUIConfigurationPersistence
+ // css::ui::XUIConfigurationStorage
+ // css::ui::XUIConfiguration
+{
+
+ // member
+
+ protected:
+
+ /** the global uno service manager.
+ Must be used to create own needed services. */
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+
+ css::uno::Reference< css::container::XNameAccess > m_xCfg;
+ AcceleratorCache m_aPrimaryReadCache;
+ AcceleratorCache m_aSecondaryReadCache;
+ std::unique_ptr<AcceleratorCache> m_pPrimaryWriteCache;
+ std::unique_ptr<AcceleratorCache> m_pSecondaryWriteCache;
+
+ OUString m_sGlobalOrModules;
+ OUString m_sModuleCFG;
+
+ // native interface!
+
+ public:
+
+ XCUBasedAcceleratorConfiguration( css::uno::Reference< css::uno::XComponentContext > xContext );
+ virtual ~XCUBasedAcceleratorConfiguration( ) override;
+
+ // uno interface!
+
+ public:
+
+ // XAcceleratorConfiguration
+ virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getAllKeyEvents() override;
+
+ virtual OUString SAL_CALL getCommandByKeyEvent(const css::awt::KeyEvent& aKeyEvent) override;
+
+ virtual void SAL_CALL setKeyEvent(const css::awt::KeyEvent& aKeyEvent,
+ const OUString& sCommand ) override;
+
+ virtual void SAL_CALL removeKeyEvent(const css::awt::KeyEvent& aKeyEvent) override;
+
+ virtual css::uno::Sequence< css::awt::KeyEvent > SAL_CALL getKeyEventsByCommand(const OUString& sCommand) override;
+
+ virtual css::uno::Sequence< css::uno::Any > SAL_CALL getPreferredKeyEventsForCommandList(const css::uno::Sequence< OUString >& lCommandList) override;
+
+ virtual void SAL_CALL removeCommandFromAllKeyEvents(const OUString& sCommand) override;
+
+ // XUIConfigurationPersistence
+ virtual void SAL_CALL reload() override;
+
+ virtual void SAL_CALL store() override;
+
+ virtual void SAL_CALL storeToStorage(const css::uno::Reference< css::embed::XStorage >& xStorage) override;
+
+ virtual sal_Bool SAL_CALL isModified() override;
+
+ virtual sal_Bool SAL_CALL isReadOnly() override;
+
+ // XUIConfigurationStorage
+ virtual void SAL_CALL setStorage(const css::uno::Reference< css::embed::XStorage >& xStorage) override;
+
+ virtual sal_Bool SAL_CALL hasStorage() override;
+
+ // XUIConfiguration
+ virtual void SAL_CALL addConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener) override;
+
+ virtual void SAL_CALL removeConfigurationListener(const css::uno::Reference< css::ui::XUIConfigurationListener >& xListener) override;
+
+ // XReset
+ // TODO use XPresetHandler instead if available
+ virtual void SAL_CALL reset() override;
+
+ virtual void SAL_CALL addResetListener(const css::uno::Reference< css::form::XResetListener >& xListener) override;
+
+ virtual void SAL_CALL removeResetListener(const css::uno::Reference< css::form::XResetListener >& xListener) override;
+
+ // css.util.XChangesListener
+ virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent) override;
+
+ // css.lang.XEventListener
+ virtual void SAL_CALL disposing(const css::lang::EventObject& aEvent) override;
+
+ // helper for derived classes
+
+ protected:
+
+ /** @short return the current office locale.
+
+ @descr We do not cache this value, because we are not listen
+ for changes on the configuration layer ...
+
+ @return OUString
+ The current office locale as BCP47 string.
+ */
+ OUString impl_ts_getLocale() const;
+
+ // helper
+
+ private:
+
+ void impl_ts_load(bool bPreferred, const css::uno::Reference< css::container::XNameAccess >& xCfg);
+ void impl_ts_save(bool bPreferred);
+
+ void insertKeyToConfiguration(const css::awt::KeyEvent& aKeyEvent, const OUString& sCommand, const bool bPreferred);
+ void removeKeyFromConfiguration(const css::awt::KeyEvent& aKeyEvent, const bool bPreferred);
+
+ void reloadChanged(const OUString& sPrimarySecondary, std::u16string_view sGlobalModules, const OUString& sModule, const OUString& sKey);
+ AcceleratorCache& impl_getCFG(bool bPreferred, bool bWriteAccessRequested = false);
+
+};
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/keymapping.hxx b/framework/source/inc/accelerators/keymapping.hxx
new file mode 100644
index 000000000..88429a012
--- /dev/null
+++ b/framework/source/inc/accelerators/keymapping.hxx
@@ -0,0 +1,126 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <rtl/ustring.hxx>
+#include <unordered_map>
+
+// definition
+
+namespace framework
+{
+
+/**
+ can be used to map key identifier to the
+ corresponding key codes ...
+ */
+class KeyMapping
+{
+
+ // const, types
+
+ private:
+
+ /** @short is used to map a key code
+ to the right key identifier, which is
+ used to make the xml file "human readable"
+ */
+ struct KeyIdentifierInfo
+ {
+ sal_Int16 Code;
+ const char* Identifier;
+ };
+
+ /** @short hash structure to map identifier to key codes. */
+ typedef std::unordered_map<OUString, sal_Int16> Identifier2CodeHash;
+
+ /** @short hash structure to map key codes to identifier. */
+ typedef std::unordered_map<sal_Int16, OUString> Code2IdentifierHash;
+
+ // member
+
+ private:
+
+ static KeyIdentifierInfo const KeyIdentifierMap[];
+
+ /** @short hash to map identifier to key codes. */
+ Identifier2CodeHash m_lIdentifierHash;
+
+ /** @short hash to map key codes to identifier. */
+ Code2IdentifierHash m_lCodeHash;
+
+ // interface
+
+ public:
+
+ KeyMapping();
+
+ static KeyMapping & get();
+
+ /** @short return a suitable key code
+ for the specified key identifier.
+
+ @param sIdentifier
+ string value, which describe the key.
+
+ @return [css::awt::KeyEvent]
+ the corresponding key code as
+ short value.
+
+ @throw [css::lang::IllegalArgumentException]
+ if the given identifier does not describe
+ a well known key code.
+ */
+ sal_uInt16 mapIdentifierToCode(const OUString& sIdentifier);
+
+ /** @short return a suitable key identifier
+ for the specified key code.
+
+ @param nCode
+ short value, which describe the key.
+
+ @return The corresponding string identifier.
+ */
+ OUString mapCodeToIdentifier(sal_uInt16 nCode);
+
+ // helper
+
+ private:
+
+ /** @short check if the given string describe a numeric
+ value ... and convert it.
+
+ @param sIdentifier
+ the string value, which should be converted.
+
+ @param rCode
+ contains the converted code, but is defined only
+ if this method returns sal_True!
+
+ @return [boolean]
+ sal_True if conversion was successful.
+ */
+ bool impl_st_interpretIdentifierAsPureKeyCode(std::u16string_view sIdentifier,
+ sal_uInt16& rCode );
+};
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/presethandler.hxx b/framework/source/inc/accelerators/presethandler.hxx
new file mode 100644
index 000000000..b0fee38b4
--- /dev/null
+++ b/framework/source/inc/accelerators/presethandler.hxx
@@ -0,0 +1,378 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/config.h>
+
+#include <string_view>
+
+#include <accelerators/storageholder.hxx>
+
+#include <com/sun/star/embed/XStorage.hpp>
+
+#include <com/sun/star/uno/XComponentContext.hpp>
+
+#include <i18nlangtag/languagetag.hxx>
+
+namespace framework
+{
+/**
+ TODO document me
+
+ <layer>/global/<resourcetype>/<preset>.xml
+ <layer>/modules/<moduleid>/<resourcetype>/<preset>.xml
+
+ RESOURCETYPE PRESET TARGET
+ (share) (user)
+ "accelerator" "default" "current"
+ "word"
+ "excel"
+
+ "menubar" "default" "menubar"
+
+ */
+class PresetHandler
+{
+ public:
+
+ /** @short this handler can provide different
+ types of configuration.
+
+ @descr Means: a global or a module dependent
+ or ... configuration.
+ */
+ enum EConfigType
+ {
+ E_GLOBAL,
+ E_MODULES,
+ E_DOCUMENT
+ };
+
+ private:
+
+ /** @short can be used to create on needed uno resources. */
+ css::uno::Reference< css::uno::XComponentContext > m_xContext;
+
+ /** @short knows the type of provided configuration.
+
+ @descr e.g. global, modules, ...
+ */
+ EConfigType m_eConfigType;
+
+ /** @short if we run in document mode, we can't use the global root storages!
+ We have to use a special document storage explicitly. */
+ StorageHolder m_lDocumentStorages;
+
+ /** @short holds the folder storage of the share layer alive,
+ where the current configuration set exists.
+
+ @descr Note: If this preset handler works in document mode
+ this member is meant relative to the document root...
+ not to the share layer root!
+
+ Further is defined, that m_xWorkingStorageUser
+ is equals to m_xWorkingStorageShare then!
+ */
+ css::uno::Reference< css::embed::XStorage > m_xWorkingStorageShare;
+
+ /** @short global language-independent storage
+ */
+ css::uno::Reference< css::embed::XStorage > m_xWorkingStorageNoLang;
+
+ /** @short holds the folder storage of the user layer alive,
+ where the current configuration set exists.
+
+ @descr Note: If this preset handler works in document mode
+ this member is meant relative to the document root...
+ not to the user layer root!
+
+ Further is defined, that m_xWorkingStorageUser
+ is equals to m_xWorkingStorageShare then!
+ */
+ css::uno::Reference< css::embed::XStorage > m_xWorkingStorageUser;
+
+ /** @short knows the relative path from the root. */
+ OUString m_sRelPathShare;
+ OUString m_sRelPathUser;
+
+ // native interface
+
+ public:
+
+ /** @short does nothing real.
+
+ @param xContext
+ points to a uno service manager, which is used internally
+ to create own needed uno resources.
+ */
+ PresetHandler(css::uno::Reference< css::uno::XComponentContext > xContext);
+
+ /** @short copy ctor */
+ PresetHandler(const PresetHandler& rCopy);
+
+ /** @short closes all open storages ... if user forgot that .-) */
+ ~PresetHandler();
+
+ /** @short free all currently cache(!) storages. */
+ void forgetCachedStorages();
+
+ /** @short return access to the internally used and cached root storage.
+
+ @descr These root storages are the base of all further opened
+ presets and targets. They are provided here only, to support
+ older implementations, which base on them ...
+
+ getOrCreate...() - What does it mean?
+ Such root storage will be created one times only and
+ cached then internally till the last instance of such PresetHandler
+ dies.
+
+ @return css::embed::XStorage
+ which represent a root storage.
+ */
+ css::uno::Reference< css::embed::XStorage > getOrCreateRootStorageShare();
+ css::uno::Reference< css::embed::XStorage > getOrCreateRootStorageUser();
+
+ /** @short provides access to the current working storages.
+
+ @descr Working storages are the "lowest" storages, where the
+ preset and target files exists.
+
+ @return css::embed::XStorage
+ which the current working storage.
+ */
+ css::uno::Reference< css::embed::XStorage > getWorkingStorageUser() const;
+
+ /** @short check if there is a parent storage well known for
+ the specified child storage and return it.
+
+ @param xChild
+ the child storage where a paranet storage should be searched for.
+
+ @return css::embed::XStorage
+ A valid storage if a paranet exists. NULL otherwise.
+ */
+ css::uno::Reference< css::embed::XStorage > getParentStorageShare();
+ css::uno::Reference< css::embed::XStorage > getParentStorageUser ();
+
+ /** @short free all internal structures and let this handler
+ work on a new type of configuration sets.
+
+ @param eConfigType
+ differ between global or module dependent configuration.
+
+ @param sResourceType
+ differ between menubar/toolbar/accelerator/... configuration.
+
+ @param sModule
+ if sResourceType is set to a module dependent configuration,
+ it address the current application module.
+
+ @param xDocumentRoot
+ if sResourceType is set to E_DOCUMENT, this value points to the
+ root storage inside the document, where we can save our
+ configuration files. Note: that's not the real root of the document...
+ its only a sub storage. But we interpret it as our root storage.
+
+ @param rLanguageTag
+ in case this configuration supports localized entries,
+ the current locale must be set.
+
+ Localization will be represented as directory structure
+ of provided presets. Means: you call us with a preset name "default";
+ and we use e.g. "/en-US/default.xml" internally.
+
+ If no localization exists for this preset set, this class
+ will work in default mode - means "no locale" - automatically.
+ e.g. "/default.xml"
+
+ @throw css::uno::RuntimeException(!)
+ if the specified resource couldn't be located.
+ */
+ void connectToResource( EConfigType eConfigType ,
+ std::u16string_view sResourceType ,
+ std::u16string_view sModule ,
+ const css::uno::Reference< css::embed::XStorage >& xDocumentRoot ,
+ const LanguageTag& rLanguageTag = LanguageTag(LANGUAGE_USER_PRIV_NOTRANSLATE));
+
+ /** @short try to copy the specified preset from the share
+ layer to the user layer and establish it as the
+ specified target.
+
+ @descr Means: copy share/.../<preset>.xml user/.../<target>.xml
+ Note: The target will be overwritten completely or
+ created as new by this operation!
+
+ @param sPreset
+ the ALIAS name of an existing preset.
+
+ @param sTarget
+ the ALIAS name of the target.
+
+ @throw css::container::NoSuchElementException
+ if the specified preset does not exists.
+
+ @throw css::io::IOException
+ if copying failed.
+ */
+ void copyPresetToTarget(std::u16string_view sPreset,
+ std::u16string_view sTarget);
+
+ /** @short open the specified preset as stream object
+ and return it.
+
+ @descr Note: Because presets resist inside the share
+ layer, they will be opened readonly every time.
+
+ @param sPreset
+ the ALIAS name of an existing preset.
+
+ Accesses the global language-independent storage instead of the preset storage
+
+ @return The opened preset stream ... or NULL if the preset does not exists.
+ */
+ css::uno::Reference< css::io::XStream > openPreset(std::u16string_view sPreset);
+
+ /** @short open the specified target as stream object
+ and return it.
+
+ @descr Note: Targets resist inside the user
+ layer. Normally they are opened in read/write mode.
+ But it will be opened readonly automatically if that isn't possible
+ (may be the file is write protected on the system ...).
+
+ @param sTarget
+ the ALIAS name of the target.
+
+ @return The opened target stream ... or NULL if the target does not exists
+ or couldn't be created as new one.
+ */
+ css::uno::Reference< css::io::XStream > openTarget(
+ std::u16string_view sTarget, sal_Int32 nMode);
+
+ /** @short do anything which is necessary to flush all changes
+ back to disk.
+
+ @descr We have to call commit on all cached sub storages on the
+ path from the root storage upside down to the working storage
+ (which are not really used, but required to be holded alive!).
+ */
+ void commitUserChanges();
+
+ /** TODO */
+ void addStorageListener(XMLBasedAcceleratorConfiguration* pListener);
+ void removeStorageListener(XMLBasedAcceleratorConfiguration* pListener);
+
+ // helper
+
+ private:
+
+ /** @short open a config path ignoring errors (catching exceptions).
+
+ @descr We catch only normal exceptions here - no runtime exceptions.
+
+ @param sPath
+ the configuration path, which should be opened.
+
+ @param eMode
+ the open mode (READ/READWRITE)
+
+ @param bShare
+ force using of the share layer instead of the user layer.
+
+ @return An opened storage in case method was successful - null otherwise.
+ */
+ css::uno::Reference< css::embed::XStorage > impl_openPathIgnoringErrors(const OUString& sPath ,
+ sal_Int32 eMode ,
+ bool bShare);
+
+ /** @short try to find the specified locale inside list of possible ones.
+
+ @descr The list of possible locale values was e.g. retrieved from the system
+ (configuration, directory listing etcpp). The locale normally represent
+ the current office locale. This method search for a suitable item by using
+ different algorithm.
+ a) exact search
+ b) search with using fallbacks
+
+ @param lLocalizedValues
+ list of BCP47 language tags / locale codes
+
+ @param rLanguageTag
+ [IN ] the current office locale, which should be searched inside lLocalizedValues.
+ [OUT] in case fallbacks was allowed, it contains afterwards the fallback locale.
+
+ @param bAllowFallbacks
+ enable/disable using of fallbacks
+
+ @return An iterator, which points directly into lLocalizedValue list.
+ As a negative result the special iterator lLocalizedValues.end() will be returned.
+ */
+ ::std::vector< OUString >::const_iterator impl_findMatchingLocalizedValue(const ::std::vector< OUString >& lLocalizedValues,
+ OUString& rLanguageTag ,
+ bool bAllowFallbacks );
+
+ /** @short open a config path ignoring errors (catching exceptions).
+
+ @descr We catch only normal exceptions here - no runtime exceptions.
+ Further the path itself is tries in different versions (using locale
+ specific attributes).
+ e.g. "path/e-US" => "path/en" => "path/de"
+
+ @param sPath
+ the configuration path, which should be opened.
+ It's further used as out parameter too, so we can return the localized
+ path!
+
+ @param eMode
+ the open mode (READ/READWRITE)
+
+ @param bShare
+ force using of the share layer instead of the user layer.
+
+ @param rLanguageTag
+ [IN ] contains the start locale for searching localized sub dirs.
+ [OUT] contains the locale of a found localized sub dir
+
+ @param bAllowFallback
+ enable/disable fallback handling for locales
+
+ @return An opened storage in case method was successful - null otherwise.
+ */
+ css::uno::Reference< css::embed::XStorage > impl_openLocalizedPathIgnoringErrors(OUString& sPath ,
+ sal_Int32 eMode ,
+ bool bShare ,
+ OUString& rLanguageTag ,
+ bool bAllowFallback);
+
+ /** @short returns the names of all sub storages of specified storage.
+
+ @param xFolder
+ the base storage for this operation.
+
+ @return [vector< string >]
+ a list of folder names.
+ */
+ ::std::vector< OUString > impl_getSubFolderNames(const css::uno::Reference< css::embed::XStorage >& xFolder);
+};
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/framework/source/inc/accelerators/storageholder.hxx b/framework/source/inc/accelerators/storageholder.hxx
new file mode 100644
index 000000000..355bedeaa
--- /dev/null
+++ b/framework/source/inc/accelerators/storageholder.hxx
@@ -0,0 +1,182 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <com/sun/star/embed/XStorage.hpp>
+
+#include <mutex>
+#include <unordered_map>
+#include <vector>
+
+namespace framework
+{
+
+class XMLBasedAcceleratorConfiguration;
+/**
+ TODO document me
+ */
+class StorageHolder final
+{
+
+ // types
+ public:
+
+ /** @short TODO */
+ typedef ::std::vector< css::uno::Reference< css::embed::XStorage > > TStorageList;
+
+ typedef ::std::vector< XMLBasedAcceleratorConfiguration* > TStorageListenerList;
+
+ struct TStorageInfo
+ {
+ public:
+ css::uno::Reference< css::embed::XStorage > Storage;
+ sal_Int32 UseCount;
+ TStorageListenerList Listener;
+
+ TStorageInfo()
+ : UseCount(0)
+ {}
+ };
+
+ /** @short TODO */
+ typedef std::unordered_map< OUString,
+ TStorageInfo > TPath2StorageInfo;
+
+ // member
+ private:
+ mutable std::mutex m_mutex;
+
+ /** @short TODO */
+ css::uno::Reference< css::embed::XStorage > m_xRoot;
+
+ /** @short TODO */
+ TPath2StorageInfo m_lStorages;
+
+ // interface
+ public:
+
+ /** @short TODO
+ */
+ StorageHolder();
+
+ /** @short TODO
+ */
+ ~StorageHolder();
+
+ /** @short TODO
+ */
+ void forgetCachedStorages();
+
+ /** @short TODO
+ */
+ void setRootStorage(const css::uno::Reference< css::embed::XStorage >& xRoot);
+
+ /** @short TODO
+ */
+ css::uno::Reference< css::embed::XStorage > getRootStorage() const;
+
+ /** @short TODO
+ open or get!
+ */
+ css::uno::Reference< css::embed::XStorage > openPath(const OUString& sPath ,
+ sal_Int32 nOpenMode);
+
+ /** @short TODO
+ */
+ StorageHolder::TStorageList getAllPathStorages(const OUString& sPath);
+
+ /** @short TODO
+ */
+ void commitPath(const OUString& sPath);
+
+ /** @short TODO
+ */
+ void closePath(const OUString& sPath);
+
+ /** @short TODO
+ */
+ void notifyPath(const OUString& sPath);
+
+ /** @short TODO
+ */
+ void addStorageListener( XMLBasedAcceleratorConfiguration* pListener,
+ const OUString& sPath );
+
+ /** @short TODO
+ */
+ void removeStorageListener( XMLBasedAcceleratorConfiguration* pListener,
+ const OUString& sPath );
+
+ /** @short TODO
+ */
+ OUString getPathOfStorage(const css::uno::Reference< css::embed::XStorage >& xStorage);
+
+ /** @short TODO
+ */
+ css::uno::Reference< css::embed::XStorage > getParentStorage(const css::uno::Reference< css::embed::XStorage >& xChild);
+
+ /** @short TODO
+ */
+ css::uno::Reference< css::embed::XStorage > getParentStorage(const OUString& sChildPath);
+
+ /** @short TODO
+ */
+ StorageHolder& operator=(const StorageHolder& rCopy);
+
+ /** @short opens a sub element of the specified base storage.
+ If eOpenMode contains an ELEMENT_WRITE flag remove it and try it with the rest of eOpenMode flags
+ again.
+
+ @descr First this method try to open the requested sub element
+ using the given open mode. If it failed there is second step,
+ which tries to do the same again ... but removing a might existing
+ WRITE flag from the open mode. The user can suppress this fallback
+ handling by setting the parameter bAllowFallback to sal_False.
+
+ @param xBaseStorage
+ the storage, where the sub element should be searched.
+
+ @param sSubElement
+ the full name of the sub element.
+ e.g. "default.xml"
+
+ @param eOpenMode
+ a flag field, which set the open mode for this operation.
+
+ */
+ static css::uno::Reference< css::embed::XStorage > openSubStorageWithFallback(const css::uno::Reference< css::embed::XStorage >& xBaseStorage ,
+ const OUString& sSubStorage ,
+ sal_Int32 eOpenMode);
+
+ // helper
+ private:
+
+ /** @short TODO
+ */
+ static OUString impl_st_normPath(const OUString& sPath);
+
+ /** @short TODO
+ */
+ static std::vector<OUString> impl_st_parsePath(std::u16string_view sPath);
+};
+
+} // namespace framework
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */