diff options
Diffstat (limited to 'framework/source/inc')
-rw-r--r-- | framework/source/inc/accelerators/acceleratorcache.hxx | 115 | ||||
-rw-r--r-- | framework/source/inc/accelerators/acceleratorconfiguration.hxx | 312 | ||||
-rw-r--r-- | framework/source/inc/accelerators/keymapping.hxx | 126 | ||||
-rw-r--r-- | framework/source/inc/accelerators/presethandler.hxx | 378 | ||||
-rw-r--r-- | framework/source/inc/accelerators/storageholder.hxx | 182 | ||||
-rw-r--r-- | framework/source/inc/dispatch/dispatchdisabler.hxx | 96 | ||||
-rw-r--r-- | framework/source/inc/dispatch/loaddispatcher.hxx | 120 | ||||
-rw-r--r-- | framework/source/inc/dispatch/windowcommanddispatch.hxx | 109 | ||||
-rw-r--r-- | framework/source/inc/loadenv/actionlockguard.hxx | 141 | ||||
-rw-r--r-- | framework/source/inc/loadenv/loadenv.hxx | 540 | ||||
-rw-r--r-- | framework/source/inc/loadenv/loadenvexception.hxx | 87 | ||||
-rw-r--r-- | framework/source/inc/loadenv/targethelper.hxx | 90 | ||||
-rw-r--r-- | framework/source/inc/pattern/frame.hxx | 79 | ||||
-rw-r--r-- | framework/source/inc/pattern/window.hxx | 62 |
14 files changed, 2437 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: */ diff --git a/framework/source/inc/dispatch/dispatchdisabler.hxx b/framework/source/inc/dispatch/dispatchdisabler.hxx new file mode 100644 index 000000000..662eeb5d7 --- /dev/null +++ b/framework/source/inc/dispatch/dispatchdisabler.hxx @@ -0,0 +1,96 @@ +/* -*- 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/. + */ +#pragma once + +#include <set> + +#include <cppuhelper/implbase.hxx> + +#include <com/sun/star/lang/XServiceInfo.hpp> +#include <com/sun/star/lang/XInitialization.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/container/XNameContainer.hpp> +#include <com/sun/star/frame/XDispatch.hpp> +#include <com/sun/star/frame/XInterceptorInfo.hpp> +#include <com/sun/star/frame/XDispatchProvider.hpp> +#include <com/sun/star/frame/XDispatchProviderInterceptor.hpp> + +namespace framework { + +/** + * Implementation of a service to make it easy to disable a whole + * suite of UNO commands in a batch - and have that act in-process. + * + * Often external re-use of LibreOffice wants a very cut-down set + * of functionality included, and disabling elements remotely one + * by one performs poorly. + */ +class DispatchDisabler final : public ::cppu::WeakImplHelper< + css::lang::XInitialization, + css::container::XNameContainer, + css::frame::XDispatchProviderInterceptor, + css::frame::XInterceptorInfo, + css::lang::XServiceInfo > +{ + std::set<OUString> maDisabledURLs; + css::uno::Reference< css::frame::XDispatchProvider > mxSlave; + css::uno::Reference< css::frame::XDispatchProvider > mxMaster; +public: + DispatchDisabler(const css::uno::Reference< css::uno::XComponentContext >& rxContext); + + // XInitialization + virtual void SAL_CALL initialize( const ::css::uno::Sequence< ::css::uno::Any >& aArguments ) override; + + // XDispatchProvider + virtual ::css::uno::Reference< ::css::frame::XDispatch > SAL_CALL + queryDispatch( const ::css::util::URL& URL, + const OUString& TargetFrameName, + ::sal_Int32 SearchFlags ) override; + virtual ::css::uno::Sequence< ::css::uno::Reference< ::css::frame::XDispatch > > SAL_CALL + queryDispatches( const ::css::uno::Sequence< ::css::frame::DispatchDescriptor >& Requests ) override; + + // XDispatchProviderInterceptor + virtual ::css::uno::Reference< ::css::frame::XDispatchProvider > SAL_CALL + getSlaveDispatchProvider() override; + virtual void SAL_CALL + setSlaveDispatchProvider( const ::css::uno::Reference< ::css::frame::XDispatchProvider >& NewDispatchProvider ) override; + virtual ::css::uno::Reference< ::css::frame::XDispatchProvider > SAL_CALL + getMasterDispatchProvider() override; + virtual void SAL_CALL + setMasterDispatchProvider( const ::css::uno::Reference< ::css::frame::XDispatchProvider >& NewSupplier ) override; + + // XInterceptorInfo + virtual ::css::uno::Sequence< OUString > SAL_CALL + getInterceptedURLs() override; + + // XElementAccess + virtual ::css::uno::Type SAL_CALL getElementType() override; + virtual ::sal_Bool SAL_CALL hasElements() override; + + // XNameAccess + virtual ::css::uno::Any SAL_CALL getByName( const OUString& aName ) override; + virtual ::css::uno::Sequence< OUString > SAL_CALL getElementNames() override; + virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override; + + // XNameReplace + virtual void SAL_CALL replaceByName( const OUString& aName, const ::css::uno::Any& aElement ) override; + + // XNameContainer + virtual void SAL_CALL insertByName( const OUString& aName, const ::css::uno::Any& aElement ) override; + virtual void SAL_CALL removeByName( const OUString& Name ) override; + + /* interface XServiceInfo */ + virtual OUString SAL_CALL getImplementationName() override; + virtual sal_Bool SAL_CALL supportsService( const OUString& sServiceName ) override; + virtual css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override; +}; + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/inc/dispatch/loaddispatcher.hxx b/framework/source/inc/dispatch/loaddispatcher.hxx new file mode 100644 index 000000000..195a46af8 --- /dev/null +++ b/framework/source/inc/dispatch/loaddispatcher.hxx @@ -0,0 +1,120 @@ +/* -*- 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 <loadenv/loadenv.hxx> + +#include <com/sun/star/frame/XNotifyingDispatch.hpp> +#include <com/sun/star/frame/XSynchronousDispatch.hpp> + +#include <cppuhelper/implbase.hxx> +#include <cppuhelper/weakref.hxx> + +namespace framework{ + +/** @short implements a dispatch object which can be used to load + non-visible components (by using the mechanism of ContentHandler) + or visible-components (by using the mechanism of FrameLoader). + */ +class LoadDispatcher final : public ::cppu::WeakImplHelper< css::frame::XNotifyingDispatch, // => XDispatch => XInterface + css::frame::XSynchronousDispatch > +{ + + // member + + private: + osl::Mutex m_mutex; + + /** @short TODO document me */ + css::uno::WeakReference< css::frame::XFrame > m_xOwnerFrame; + + /** @short TODO document me */ + OUString m_sTarget; + + /** @short TODO document me */ + sal_Int32 m_nSearchFlags; + + /** @short TODO document me */ + LoadEnv m_aLoader; + + // native interface + + public: + + /** @short creates a new instance and initialize it with all necessary parameters. + + @descr Every instance of such LoadDispatcher can be used for the specified context only. + That means: it can be used to load any further requested content into the here(!) + specified target frame. + + @param xContext + will be used to create own needed services on demand. + + @param xOwnerFrame + used as startpoint to locate the right target frame. + + @param sTargetName + the name or the target frame for loading or a special qualifier + which define such target. + + @param nSearchFlags + used in case sTargetFrame isn't a special one. + */ + LoadDispatcher(const css::uno::Reference< css::uno::XComponentContext >& xContext, + const css::uno::Reference< css::frame::XFrame >& xOwnerFrame , + OUString sTargetName , + sal_Int32 nSearchFlags); + + /** @short used to free internal resources. + */ + virtual ~LoadDispatcher() override; + + // uno interface + + public: + + // XNotifyingDispatch + virtual void SAL_CALL dispatchWithNotification(const css::util::URL& aURL , + const css::uno::Sequence< css::beans::PropertyValue >& lArguments, + const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ) override; + + // XDispatch + virtual void SAL_CALL dispatch(const css::util::URL& aURL , + const css::uno::Sequence< css::beans::PropertyValue >& lArguments) override; + + virtual void SAL_CALL addStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener, + const css::util::URL& aURL ) override; + + virtual void SAL_CALL removeStatusListener(const css::uno::Reference< css::frame::XStatusListener >& xListener, + const css::util::URL& aURL ) override; + + // XSynchronousDispatch + virtual css::uno::Any SAL_CALL dispatchWithReturnValue( const css::util::URL& aURL , + const css::uno::Sequence< css::beans::PropertyValue >& lArguments ) override; + + private: + css::uno::Any impl_dispatch( const css::util::URL& rURL, + const css::uno::Sequence< css::beans::PropertyValue >& lArguments, + const css::uno::Reference< css::frame::XDispatchResultListener >& xListener ); +}; // class LoadDispatcher + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/inc/dispatch/windowcommanddispatch.hxx b/framework/source/inc/dispatch/windowcommanddispatch.hxx new file mode 100644 index 000000000..4a8a22d81 --- /dev/null +++ b/framework/source/inc/dispatch/windowcommanddispatch.hxx @@ -0,0 +1,109 @@ +/* -*- 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/awt/XWindow.hpp> +#include <com/sun/star/frame/XFrame.hpp> + +#include <cppuhelper/weakref.hxx> +#include <tools/link.hxx> +#include <mutex> + +namespace com::sun::star::uno { + class XComponentContext; +} +class VclWindowEvent; + +namespace framework{ + +/** @short internal helper to bind e.g. MAC-Menu events to our internal dispatch API. + + @descr On e.g. MAC platform system menus are merged together with some fix entries as + e.g. "Pereferences" or "About". These menu entries trigger hard coded commands. + Here we map these commands to the right URLs and dispatch them. + + This helper knows a frame and its container window (where VCL provide the hard coded + commands). We hold those objects weak so there is no need to react for complex UNO dispose/ing() + scenarios. On the other side VCL does not hold us alive (because it doesn't know our UNO reference). + So we register at the VCL level as an event listener and + */ +class WindowCommandDispatch final +{ + private: + std::mutex m_mutex; + + /// can be used to create own needed services on demand. + css::uno::Reference< css::uno::XComponentContext > m_xContext; + + /// knows the frame, where we dispatch our commands as weak reference + css::uno::WeakReference< css::frame::XFrame > m_xFrame; + + /// knows the VCL window (where the hard coded commands occurred) as weak XWindow reference + css::uno::WeakReference< css::awt::XWindow > m_xWindow; + + // native interface + + public: + + /** @short creates a new instance and initialize it with all necessary parameters. + + @descr Every instance of such MACDispatch can be used for the specified context only. + Means: 1 MACDispatch object is bound to 1 Frame/Window pair in which context + the detected commands will be executed. + + @param xContext + will be used to create own needed services on demand. + + @param xFrame + used as for new detected commands. + */ + WindowCommandDispatch(css::uno::Reference< css::uno::XComponentContext > xContext , + const css::uno::Reference< css::frame::XFrame >& xFrame); + + /** @short used to free internal resources. + */ + ~WindowCommandDispatch(); + + // implementation + + private: + + /** @short establish all listener connections we need. + + @descr Those listener connections will be created one times only (see ctor). + Afterwards we listen for incoming events till our referred frame/window pair + will be closed. + */ + void impl_startListening(); + + /** @short drop all listener connections we need. + + */ + void impl_stopListening(); + + /** @short callback from VCL to notify new commands + */ + DECL_LINK( impl_notifyCommand, VclWindowEvent&, void ); + +}; // class WindowCommandDispatch + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/inc/loadenv/actionlockguard.hxx b/framework/source/inc/loadenv/actionlockguard.hxx new file mode 100644 index 000000000..ee52fcc0d --- /dev/null +++ b/framework/source/inc/loadenv/actionlockguard.hxx @@ -0,0 +1,141 @@ +/* -*- 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/document/XActionLockable.hpp> +#include <mutex> + +namespace framework{ + +/** @short implements a guard, which can use the interface + <type scope="css::document">XActionLockable</type>. + + @descr This guard should be used to be sure, that any lock will be + released. Otherwise the locked document can hinder the office on shutdown! +*/ +class ActionLockGuard final +{ + + // member + + private: + std::mutex m_mutex; + + /** @short points to the object, which can be locked from outside. */ + css::uno::Reference< css::document::XActionLockable > m_xActionLock; + + /** @short knows if a lock exists on the internal lock object + forced by this guard instance. */ + bool m_bActionLocked; + + // interface + + public: + + /** @short default ctor to initialize a "non working guard". + + @descr That can be useful in cases, where no resource still exists, + but will be available next time. Then this guard can be used + in a mode "use guard for more than one resources". + */ + ActionLockGuard() + : m_bActionLocked(false) + { + } + + /** @short release this guard instance and make sure, that no lock + will exist afterwards on the internal wrapped resource. + */ + ~ActionLockGuard() + { + unlock(); + } + + /** @short set a new resource for locking at this guard. + + @descr This call will fail, if an internal resource already exists + and is currently locked. + + @param xLock + points to the outside resource, which should be locked. + + @return sal_True, if new resource could be set and locked. + sal_False otherwise. + */ + bool setResource(const css::uno::Reference< css::document::XActionLockable >& xLock) + { + std::unique_lock g(m_mutex); + + if (m_bActionLocked || !xLock.is()) + return false; + + m_xActionLock = xLock; + m_xActionLock->addActionLock(); + m_bActionLocked = m_xActionLock->isActionLocked(); + + return true; + } + + /** @short set a new resource for locking at this guard. + + @descr This call will fail, if an internal resource already exists + and is currently locked. + + @param xLock + points to the outside resource, which should be locked. + + @return sal_True, if new resource could be set and locked. + sal_False otherwise. + */ + void freeResource() + { + // SAFE -> .......................... + std::unique_lock aMutexLock(m_mutex); + + css::uno::Reference< css::document::XActionLockable > xLock = m_xActionLock; + bool bLocked = m_bActionLocked; + + m_xActionLock.clear(); + m_bActionLocked = false; + + aMutexLock.unlock(); + // <- SAFE .......................... + + if (bLocked && xLock.is()) + xLock->removeActionLock(); + } + + /** @short unlock the internal wrapped resource, if it's not already done. */ + void unlock() + { + std::unique_lock g(m_mutex); + if (m_bActionLocked && m_xActionLock.is()) + { + m_xActionLock->removeActionLock(); + // don't check for any locks here ... + // May another guard use the same lock object :-( + m_bActionLocked = false; + } + } +}; + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/inc/loadenv/loadenv.hxx b/framework/source/inc/loadenv/loadenv.hxx new file mode 100644 index 000000000..351d39b94 --- /dev/null +++ b/framework/source/inc/loadenv/loadenv.hxx @@ -0,0 +1,540 @@ +/* -*- 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 <loadenv/actionlockguard.hxx> + +#include <com/sun/star/frame/XComponentLoader.hpp> +#include <com/sun/star/frame/XFrame.hpp> +#include <com/sun/star/uno/XComponentContext.hpp> +#include <com/sun/star/util/URL.hpp> +#include <rtl/ref.hxx> +#include <unotools/mediadescriptor.hxx> +#include <o3tl/typed_flags_set.hxx> + + +/** @short enable/disable special features + of a load request. + + @desrc Such features must outcome without + any special parameters. + To make enabling/disabling of + features very easy (e.g. at the ctor of + this class) these values must be combinable + as flags. That means: its values must be in + range of [2^n]! + */ +enum class LoadEnvFeatures +{ + /// we should be informed, if no feature is enabled :-) + NONE = 0, + /// enable using of UI elements during loading (means progress, interaction handler etcpp.) + WorkWithUI = 1, + /// enable loading of resources, which are not related to a target frame! (see concept of ContentHandler) + AllowContentHandler = 2 +}; +namespace o3tl { + template<> struct typed_flags<LoadEnvFeatures> : is_typed_flags<LoadEnvFeatures, 0x3> {}; +} + + +namespace framework { + +class QuietInteraction; + +/** @short implements general mechanism for loading documents. + + @descr An instance of this class can be used inside the API calls + XComponentLoader::loadComponentFromURL() and + XDispatch::dispatch(). + */ +class LoadEnv +{ +public: + /** @short classify a content. + + @descr The load environment must know, if a content + is related to a target frame or not. Only "visible" + components, which fulfill the requirements of the + model-controller-view paradigm can be loaded into a frame. + Such contents are classified as E_CAN_BE_LOADED. + + But e.g. for the dispatch framework exists special ContentHandler + objects, which can load a content in "non visible" mode ... + and do not need a target frame for its operation. Such + ContentHandler e.g. plays sounds. + Such contents are classified as E_CAN_BE_HANDLED. + + And last but not least a content can be "not valid" in general. + */ + enum EContentType + { + /// identifies a content, which seems to be invalid in general + E_UNSUPPORTED_CONTENT, + /// identifies a content, which can be used with a ContentHandler and is not related to a target frame + E_CAN_BE_HANDLED, + /// identifies a content, which can be loaded into a target frame + E_CAN_BE_LOADED, + /// special mode for non real loading, In such case the model is given directly! + E_CAN_BE_SET + }; + +private: + mutable osl::Mutex m_mutex; + + /** @short reference to a uno service manager, which must be used + to created on needed services on demand. + */ + css::uno::Reference< css::uno::XComponentContext > m_xContext; + + /** @short points to the frame, which uses this LoadEnv object + and must be used to start target search there. + */ + css::uno::Reference< css::frame::XFrame > m_xBaseFrame; + + /** @short points to the frame, into which the new component was loaded. + + @descr Note: This reference will be empty if loading failed + or a non visible content was loaded! + It can be the same frame as m_xBaseFrame it describe, in case + the target "_self", "" or the search flag "SELF" was used. + Otherwise it's the new created or recycled frame, which was + used for loading and contains further the new component. + + Please use method getTarget() or getTargetComponent() + to return the frame/controller or model to any interested + user of the results of this load request. + */ + css::uno::Reference< css::frame::XFrame > m_xTargetFrame; + + /** @short contains the name of the target, in which the specified resource + of this instance must be loaded. + */ + OUString m_sTarget; + + /** @short if m_sTarget is not a special one, this flags regulate searching + of a suitable one. + */ + sal_Int32 m_nSearchFlags; + + /** @short contains all needed information about the resource, + which should be loaded. + + @descr Inside this struct e.g. the URL, its type and filter name, + the stream or a model directly are saved. + */ + utl::MediaDescriptor m_lMediaDescriptor; + + /** @short because the mediadescriptor contains the complete URL ... but + some functionality need the structured version, we hold it twice :-(. + */ + css::util::URL m_aURL; + + /** @short enable/disable special features of a load request. */ + LoadEnvFeatures m_eFeature; + + /** @short classify the content, which should be loaded by this instance. */ + EContentType m_eContentType; + + /** @short it indicates, that the member m_xTargetFrame was new created for this + load request and must be closed in case loading (not handling!) + operation failed. The default value is sal_False! + */ + bool m_bCloseFrameOnError; + + /** @short it indicates, that the old document (which was located inside m_xBaseFrame + in combination with the m_sTarget value "_self") was suspended. + Normally it will be replaced by the new loaded document. But in case + loading (not handling!) failed, it must be reactivated. + The default value is sal_False! + */ + bool m_bReactivateControllerOnError; + + /** @short it holds one (!) asynchronous used contenthandler or frameloader + alive, till the asynchronous operation will be finished. + */ + css::uno::Reference< css::uno::XInterface > m_xAsynchronousJob; + + /** @short holds the information about the finished load process. + + @descr The content of m_xTargetFrame can't be used as valid indicator, + (in case the existing old document was reactivated) + we must hold the result of the load process explicitly. + */ + bool m_bLoaded; + + /** @short holds an XActionLock on the internal used task member. + + @seealso m_xTargetFrame + */ + ActionLockGuard m_aTargetLock; + + rtl::Reference<QuietInteraction> m_pQuietInteraction; + +public: + + /** @short initialize a new instance of this load environment. + + @param xContext + reference to a uno service manager, which can be used internally + to create on needed services on demand. + + @throw Currently there is no reason to throw such exception! + + @throw A RuntimeException in case any internal process indicates, that + the whole runtime can't be used any longer. + */ + LoadEnv(css::uno::Reference< css::uno::XComponentContext > xContext); + + /** @short deinitialize an instance of this class in the right way. + */ + ~LoadEnv(); + + /// @throws css::lang::IllegalArgumentException + /// @throws css::io::IOException + /// @throws css::uno::RuntimeException + static css::uno::Reference< css::lang::XComponent > loadComponentFromURL(const css::uno::Reference< css::frame::XComponentLoader >& xLoader, + const css::uno::Reference< css::uno::XComponentContext >& xContext, + const OUString& sURL , + const OUString& sTarget, + sal_Int32 nFlags , + const css::uno::Sequence< css::beans::PropertyValue >& lArgs ); + + /** @short start loading of a resource + + @descr The parameter for targeting, the content description, and + some environment specifier (UI, dispatch functionality) + can be set here. Of course a still running load request + will be detected here and a suitable exception will be thrown. + Such constellation can be detected outside by using provided + synchronisation methods or callbacks. + + There is no direct return value possible here. Because it depends + from the usage of this instance! E.g. for loading a "visible component" + a frame with a controller/model inside can be possible. For loading + of a "non visible component" only an information about a successfully start + can be provided. + Further it can't be guaranteed, that the internal process runs synchronous. + that's why we prefer using of specialized methods afterwards e.g. to: + - wait till the internal job will be finished + and get the results + - or to let it run without any further control from outside. + + @param sURL + points to the resource, which should be loaded. + + @param lMediaDescriptor + contains additional information for the following load request. + + @param xBaseFrame + points to the frame which must be used as start point for target search. + + @param sTarget + regulate searching/creating of frames, which should contain the + new loaded component afterwards. + + @param nSearchFlags + regulate searching of targets, if sTarget is not a special one. + + @param eFeature + flag field, which enable/disable special features of this + new instance for following load call. + + @throw A LoadEnvException e.g. if another load operation is till in progress + or initialization of a new one fail by other reasons. + The real reason, a suitable message and ID will be given here immediately. + + @throw A RuntimeException in case any internal process indicates, that + the whole runtime can't be used any longer. + */ + void startLoading(const OUString& sURL , + const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor, + const css::uno::Reference< css::frame::XFrame >& xBaseFrame , + const OUString& sTarget , + sal_Int32 nSearchFlags , + LoadEnvFeatures eFeature = LoadEnvFeatures::NONE); + + /** @short wait for an already running load request (started by calling + startLoading() before). + + @descr The timeout parameter can be used to wait some times only + or forever. The return value indicates if the load request + was finished during the specified timeout period. + But it indicates not, if the load request was successful or not! + + @param nTimeout + specify a timeout in [ms]. + A value 0 let it wait forever! + + @return sal_True if the started load process could be finished in time; + sal_False if the specified time was over. + + @throw ... currently not used :-) + + @throw A RuntimeException in case any internal process indicates, that + the whole runtime can't be used any longer. + */ + bool waitWhileLoading(sal_uInt32 nTimeout = 0); + + /** TODO document me ... */ + css::uno::Reference< css::lang::XComponent > getTargetComponent() const; + +public: + + /** @short checks if the specified content can be handled by a + ContentHandler only and is not related to a target frame, + or if it can be loaded by a FrameLoader into a target frame + as "visible" component. + + @descr using: + switch(classifyContent(...)) + { + case E_CAN_BE_HANDLED : + handleIt(...); + break; + + case E_CAN_BE_LOADED : + xFrame = locateTargetFrame(); + loadIt(xFrame); + break; + + case E_NOT_A_CONTENT : + default : throw ...; + } + + @param sURL + describe the content. + + @param lMediaDescriptor + describe the content more detailed! + + @return A suitable enum value, which classify the specified content. + */ + static EContentType classifyContent(const OUString& sURL , + const css::uno::Sequence< css::beans::PropertyValue >& lMediaDescriptor); + + /** TODO document me ... */ + static void initializeUIDefaults( + const css::uno::Reference< css::uno::XComponentContext >& i_rxContext, + utl::MediaDescriptor& io_lMediaDescriptor, + const bool _bUIMode, + rtl::Reference<QuietInteraction>* o_ppQuiteInteraction + ); + + /** TODO document me ... */ + void impl_setResult(bool bResult); + + /** TODO document me ... */ + css::uno::Reference< css::uno::XInterface > impl_searchLoader(); + + /** @short it means; show the frame, bring it to front, + might set the right icon etcpp. in case loading was + successfully or reactivate a might existing old document or + close the frame if it was created before in case loading failed. + + @throw A LoadEnvException only in cases, where an internal error indicates, + that the complete load environment seems to be not usable in general. + In such cases a RuntimeException would be to hard for the outside code :-) + + @throw A RuntimeException in case any internal process indicates, that + the whole runtime can't be used any longer. + */ + void impl_reactForLoadingState(); + +private: + void start(); + + /** @short tries to detect the type and the filter of the specified content. + + @descr This method update the available media descriptor of this instance, + so it contains the right type, a corresponding filter, may a + valid frame loader etc. In case detection failed, this descriptor + is corrected first, before a suitable exception will be thrown. + (Excepting a RuntimeException occurrence!) + + @attention Not all types we know, are supported by filters. So it does not + indicates an error, if no suitable filter(loader etcpp will be found + for a type. But a type must be detected for the specified content. + Otherwise it's an error and loading can't be finished successfully. + + @throw A LoadEnvException if detection failed. + + @throw A RuntimeException in case any internal process indicates, that + the whole runtime can't be used any longer. + */ + void impl_detectTypeAndFilter(); + + /** @short tries to use ContentHandler objects for loading. + + @descr It searches for a suitable content handler object, registered + for the detected content type (must be done before by calling + impl_detectTypeAndFilter()). Because such handler does not depend + from a real target frame, location of such frame will be + suppressed here. + In case handle failed all new created resources will be + removed before a suitable exception is thrown. + (Excepting a RuntimeException occurrence!) + + @return TODO + + @throw A LoadEnvException if handling failed. + + @throw A RuntimeException in case any internal process indicates, that + the whole runtime can't be used any longer. + */ + bool impl_handleContent(); + + /** @short tries to use FrameLoader objects for loading. + + @descr First the target frame will be located. If it could be found + or new created a filter/frame loader will be instantiated and + used to load the content into this frame. + In case loading failed all new created resources will be + removed before a suitable exception is thrown. + (Excepting a RuntimeException occurrence!) + + @return TODO + + @throw A LoadEnvException if loading failed. + + @throw A RuntimeException in case any internal process indicates, that + the whole runtime can't be used any longer. + */ + bool impl_loadContent(); + + /** @short checks if the specified content is already loaded. + + @descr It depends from the set target information, if such + search is allowed or not! So this method checks first, + if the target is the special one "_default". + If not it returns with an empty result immediately! + In case search is allowed, an existing document with the + same URL is searched. If it could be found, the corresponding + view will get the focus and this method return the corresponding frame. + Optional jumpmarks will be accepted here too. So the + view of the document will be updated to show the position + inside the document, which is related to the jumpmark. + + @return A valid reference to the target frame, which contains the already loaded content + and could be activated successfully. An empty reference otherwise. + + @throw A LoadEnvException only in cases, where an internal error indicates, + that the complete load environment seems to be not usable in general. + In such cases a RuntimeException would be to hard for the outside code :-) + + @throw A RuntimeException in case any internal process indicates, that + the whole runtime can't be used any longer. + */ + css::uno::Reference< css::frame::XFrame > impl_searchAlreadyLoaded(); + + /** @short search for any target frame, which seems to be usable + for this load request. + + @descr Because this special feature is bound to the target specifier "_default" + its checked inside first. If it's not set => this method return an empty + reference. Otherwise any currently existing frame will be analyzed, if + it can be used here. The following rules exists: + + <ul> + <li>The frame must be empty ...</li> + <li>or contains an empty document of the same application module + which the new document will have (Note: the filter of the new content + must be well known here!)</li> + <li>and(!) this target must not be already used by any other load request.</li> + </ul> + + If a suitable target is located it will be locked. That's why the last rule + exists! If this method returns a valid frame reference, it was locked to be usable + for this load request only. (Don't forget to reset this state later!) + Concurrent LoadEnv instances can synchronize her work be using such locks :-) HOPEFULLY + + @throw A LoadEnvException only in cases, where an internal error indicates, + that the complete load environment seems to be not usable in general. + In such cases a RuntimeException would be to hard for the outside code :-) + + @throw A RuntimeException in case any internal process indicates, that + the whole runtime can't be used any longer. + */ + css::uno::Reference< css::frame::XFrame > impl_searchRecycleTarget(); + + /** @short because showing of a frame is needed more than once... + it's implemented as a separate method .-) + + @descr Note: Showing of a frame is bound to a special feature... + a) If we recycle any existing frame, we must bring it to front. + Showing of such frame is not needed really... because we recycle + visible frames only! + b) If the document was already shown (e.g. by our progress implementation) + we do nothing here. The reason behind: The document was already shown... + and it was already make a top window... + If the user activated another frame inbetween (because loading needed some time) + it's not allowed to disturb the user again. Then the frame must resists in the background. + c) If the frame was not shown before... but loading of a visible document into this frame + was finished... we need both actions: setVisible() and toFront(). + + @param xWindow + points to the container window of a frame. + + @param bForceToFront + if it's set to sal_False... showing of the window is done more intelligent. + setVisible() is called only if the window was not shown before. + This mode is needed by b) and c) + If it's set to sal_True... both actions has to be done: setVisible(), toFront()! + This mode is needed by a) + */ + void impl_makeFrameWindowVisible(const css::uno::Reference< css::awt::XWindow >& xWindow , + bool bForceToFront); + + /** @short checks whether a frame is already used for another load request or not. + + @descr Such frames can't be used for our "recycle feature"! + + @param xFrame + the frame, which should be checked. + + @return [sal_Bool] + sal_True if this frame is already used for loading, + sal_False otherwise. + */ + bool impl_isFrameAlreadyUsedForLoading(const css::uno::Reference< css::frame::XFrame >& xFrame) const; + + /** @short try to determine the used application module + of this load request and apply right position and size + for this document window... hopefully before we show it .-) + */ + void impl_applyPersistentWindowState(const css::uno::Reference< css::awt::XWindow >& xWindow); + + /** @short determine if it's allowed to open new document frames. + */ + bool impl_furtherDocsAllowed(); + + /** @short jumps to the requested bookmark inside a given document. + */ + void impl_jumpToMark(const css::uno::Reference< css::frame::XFrame >& xFrame, + const css::util::URL& aURL ); + + /** @short determine if this loader has an interactive dialog shown before + loading the document. + */ + bool impl_filterHasInteractiveDialog() const; +}; + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/inc/loadenv/loadenvexception.hxx b/framework/source/inc/loadenv/loadenvexception.hxx new file mode 100644 index 000000000..62a17d2ac --- /dev/null +++ b/framework/source/inc/loadenv/loadenvexception.hxx @@ -0,0 +1,87 @@ +/* -*- 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/uno/Any.hxx> +#include <utility> + +namespace framework{ + +/** @short specify an exception, which can be used inside the + load environment only. + + @descr Of course outside code must wrap it, to transport + the occurred information to its caller. + */ +class LoadEnvException +{ + public: + /** @short Can be used as an ID for an instance of a LoadEnvException. + @descr To prevent errors on adding/removing/changing such IDs here, + an enum field is used. Its int values are self organized... + */ + enum EIDs + { + /** @short The specified URL/Stream/etcpp. can not be handled by a LoadEnv instance. */ + ID_UNSUPPORTED_CONTENT, + + /** @short indicates a corrupted media descriptor. + @descr Some parts are required - some other ones are optional. Such exception + should be thrown, if a required item does not exists. */ + ID_INVALID_MEDIADESCRIPTOR, + + /** @short Its similar to a uno::RuntimeException... + @descr But such runtime exception can break the whole office code. + So its capsulated to this specialized load environment only. + Mostly it indicates a missing but needed resource ... e.g the + global desktop reference! */ + ID_INVALID_ENVIRONMENT, + + /** @short indicates a failed search for the right target frame. */ + ID_NO_TARGET_FOUND, + + /** @short TODO */ + ID_COULD_NOT_REACTIVATE_CONTROLLER, + + /** @short indicates an already running load operation. Of course the same + instance can't be used for multiple load requests at the same time. + */ + ID_STILL_RUNNING, + + /** @short sometimes we can't specify the reason for an error, because we + was interrupted by a called code in an unexpected way ... + */ + ID_GENERAL_ERROR + }; + + sal_Int32 m_nID; + OUString m_sMessage; + css::uno::Any m_exOriginal; + + LoadEnvException( + sal_Int32 id, OUString message = OUString(), + css::uno::Any original = css::uno::Any()): + m_nID(id), m_sMessage(std::move(message)), m_exOriginal(std::move(original)) + {} +}; + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/inc/loadenv/targethelper.hxx b/framework/source/inc/loadenv/targethelper.hxx new file mode 100644 index 000000000..1f0d93d7e --- /dev/null +++ b/framework/source/inc/loadenv/targethelper.hxx @@ -0,0 +1,90 @@ +/* -*- 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> + +namespace framework{ + +/** @short can be used to detect, if a target name (used e.g. for XFrame.findFrame()) + has a special meaning or can be used as normal frame name (e.g. for XFrame.setName()). + */ +class TargetHelper +{ + + public: + + /** @short it's used at the following interfaces to classify + target names. + */ + enum class ESpecialTarget + { + Blank, + Default, + Beamer, + HelpTask + }; + + // interface + + public: + + /** @short it checks the given unknown target name, + if it's the expected special one. + + @note An empty target is similar to "_self"! + + @param sCheckTarget + must be the unknown target name, which should be checked. + + @param eSpecialTarget + represent the expected target. + + @return It returns <TRUE/> if <var>sCheckTarget</var> represent + the expected <var>eSpecialTarget</var> value; <FALSE/> otherwise. + */ + static bool matchSpecialTarget(std::u16string_view sCheckTarget , + ESpecialTarget eSpecialTarget); + + /** @short it checks, if the given name can be used + to set it at a frame using XFrame.setName() method. + + @descr Because we handle special targets in a hard coded way + (means we do not check the real name of a frame then) + such named frames will never be found! + + And in case such special names can exists one times only + by definition inside the same frame tree (e.g. _beamer and + OFFICE_HELP_TASK) it's not a good idea to allow anything here :-) + + Of course we can't check unknown names, which are not special ones. + But we decide, that it's not allowed to use "_" as first sign + (because we reserve this letter for our own purposes!) + and the value must not a well known special target. + + @param sName + the new frame name, which should be checked. + */ + static bool isValidNameForFrame(std::u16string_view sName); +}; + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/inc/pattern/frame.hxx b/framework/source/inc/pattern/frame.hxx new file mode 100644 index 000000000..947a03668 --- /dev/null +++ b/framework/source/inc/pattern/frame.hxx @@ -0,0 +1,79 @@ +/* -*- 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/lang/XComponent.hpp> +#include <com/sun/star/lang/DisposedException.hpp> +#include <com/sun/star/util/CloseVetoException.hpp> +#include <com/sun/star/util/XCloseable.hpp> + +// namespaces + +namespace framework::pattern::frame{ + +/** @short close (or dispose) the given resource. + + @descr It try to close the given resource first. + Delegating of the ownership can be influenced from + outside. If closing isn't possible (because the + needed interface isn't available) dispose() is tried instead. + All possible exceptions are handled inside. + So the user of this method has to look for the return value only. + + @attention The given resource will not be cleared. + But later using of it can produce an exception! + + @param xResource + the object, which should be closed here. + + @return [bool] + sal_True if closing failed. + */ +inline bool closeIt(const css::uno::Reference< css::uno::XInterface >& xResource) +{ + css::uno::Reference< css::util::XCloseable > xClose (xResource, css::uno::UNO_QUERY); + css::uno::Reference< css::lang::XComponent > xDispose(xResource, css::uno::UNO_QUERY); + + try + { + if (xClose.is()) + xClose->close(false/*bDelegateOwnership*/); + else + if (xDispose.is()) + xDispose->dispose(); + else + return false; + } + catch(const css::util::CloseVetoException&) + { return false; } + catch(const css::lang::DisposedException&) + {} // disposed is closed is ... + catch(const css::uno::RuntimeException&) + { throw; } // should not be suppressed! + catch(const css::uno::Exception&) + { return false; } // ??? We defined to return a boolean value instead of throwing exceptions... + // (OK: RuntimeExceptions should not be caught inside the core..) + + return true; +} + +} // namespace framework::pattern::frame + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/framework/source/inc/pattern/window.hxx b/framework/source/inc/pattern/window.hxx new file mode 100644 index 000000000..92134915d --- /dev/null +++ b/framework/source/inc/pattern/window.hxx @@ -0,0 +1,62 @@ +/* -*- 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/awt/XWindow.hpp> +#include <com/sun/star/awt/XTopWindow.hpp> + +#include <toolkit/helper/vclunohelper.hxx> +#include <vcl/window.hxx> +#include <vcl/svapp.hxx> + +// namespaces + +namespace framework{ + +class WindowHelper +{ + public: + + +static bool isTopWindow(const css::uno::Reference< css::awt::XWindow >& xWindow) +{ + // even child frame containing top level windows (e.g. query designer of database) will be closed + css::uno::Reference< css::awt::XTopWindow > xTopWindowCheck(xWindow, css::uno::UNO_QUERY); + if (xTopWindowCheck.is()) + { + // Note: Toolkit interface XTopWindow sometimes is used by real VCL-child-windows also .-) + // Be sure that these window is really a "top system window". + // Attention ! Checking Window->GetParent() is not the right approach here. + // Because sometimes VCL create "implicit border windows" as parents even we created + // a simple XWindow using the toolkit only .-( + SolarMutexGuard aSolarGuard; + VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); + if ( pWindow && pWindow->IsSystemWindow() ) + return true; + } + + return false; +} + +}; + +} // namespace framework + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |