summaryrefslogtreecommitdiff
path: root/framework/source/accelerators/presethandler.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'framework/source/accelerators/presethandler.cxx')
-rw-r--r--framework/source/accelerators/presethandler.cxx937
1 files changed, 937 insertions, 0 deletions
diff --git a/framework/source/accelerators/presethandler.cxx b/framework/source/accelerators/presethandler.cxx
new file mode 100644
index 000000000000..ecfe6d2a0a5f
--- /dev/null
+++ b/framework/source/accelerators/presethandler.cxx
@@ -0,0 +1,937 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_framework.hxx"
+#include <accelerators/presethandler.hxx>
+
+//_______________________________________________
+// own includes
+#include <classes/fwkresid.hxx>
+
+#include "classes/resource.hrc"
+#include <threadhelp/readguard.hxx>
+#include <threadhelp/writeguard.hxx>
+#include <services.h>
+
+//_______________________________________________
+// interface includes
+
+#ifndef __COM_SUN_STAR_CONFIGURATION_CORRUPTEDUICONFIGURATIONEXCEPTION_HPP_
+#include <com/sun/star/configuration/CorruptedUIConfigurationException.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_CONTAINER_NOSUCHELEMENTEXCEPTION_HPP_
+#include <com/sun/star/container/NoSuchElementException.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
+#include <com/sun/star/container/XNameAccess.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
+#include <com/sun/star/beans/XPropertySet.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
+#include <com/sun/star/embed/ElementModes.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
+#include <com/sun/star/embed/XTransactedObject.hpp>
+#endif
+
+#ifndef __COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
+#include <com/sun/star/lang/XSingleServiceFactory.hpp>
+#endif
+
+//_______________________________________________
+// other includes
+#include <vcl/svapp.hxx>
+
+#ifndef _RTL_USTRBUF_HXX
+#include <rtl/ustrbuf.hxx>
+#endif
+
+//_______________________________________________
+// const
+
+#define SUBSTORAGE_GLOBAL DECLARE_ASCII("global" )
+#define SUBSTORAGE_MODULES DECLARE_ASCII("modules")
+
+#define BASEPATH_SHARE_LAYER DECLARE_ASCII("UIConfig" )
+#define BASEPATH_USER_LAYER DECLARE_ASCII("UserConfig")
+
+#define RELPATH_SHARE_LAYER DECLARE_ASCII("soffice.cfg")
+#define RELPATH_USER_LAYER DECLARE_ASCII("soffice.cfg")
+// #define RELPATH_SHARE_LAYER DECLARE_ASCII("soffice.cfg/uiconfig.zip")
+// #define RELPATH_USER_LAYER DECLARE_ASCII("soffice.cfg/uiconfig.zip")
+
+#define FILE_EXTENSION DECLARE_ASCII(".xml")
+
+#define PATH_SEPERATOR DECLARE_ASCII("/")
+
+static const ::sal_Int32 ID_CORRUPT_UICONFIG_SHARE = 1;
+static const ::sal_Int32 ID_CORRUPT_UICONFIG_USER = 2;
+static const ::sal_Int32 ID_CORRUPT_UICONFIG_GENERAL = 3;
+
+//_______________________________________________
+// namespace
+
+namespace framework
+{
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::PRESET_DEFAULT()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("default");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::TARGET_CURRENT()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("current");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::RESOURCETYPE_MENUBAR()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("menubar");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::RESOURCETYPE_TOOLBAR()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("toolbar");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::RESOURCETYPE_ACCELERATOR()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("accelerator");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+::rtl::OUString PresetHandler::RESOURCETYPE_STATUSBAR()
+{
+ static ::rtl::OUString RSTYPE = DECLARE_ASCII("statusbar");
+ return RSTYPE;
+}
+
+//-----------------------------------------------
+PresetHandler::PresetHandler(const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR)
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+ , m_xSMGR (xSMGR )
+ , m_aSharedStorages ( )
+ , m_lDocumentStorages(xSMGR )
+ , m_aLocale (::comphelper::Locale::X_NOTRANSLATE())
+{
+}
+
+//-----------------------------------------------
+PresetHandler::PresetHandler(const PresetHandler& rCopy)
+ : ThreadHelpBase (&Application::GetSolarMutex() )
+{
+ m_xSMGR = rCopy.m_xSMGR;
+ m_eConfigType = rCopy.m_eConfigType;
+ m_sResourceType = rCopy.m_sResourceType;
+ m_sModule = rCopy.m_sModule;
+ m_aSharedStorages = rCopy.m_aSharedStorages;
+ m_xWorkingStorageShare = rCopy.m_xWorkingStorageShare;
+ m_xWorkingStorageNoLang = rCopy.m_xWorkingStorageNoLang;
+ m_xWorkingStorageUser = rCopy.m_xWorkingStorageUser;
+ m_lPresets = rCopy.m_lPresets;
+ m_lTargets = rCopy.m_lTargets;
+ m_aLocale = rCopy.m_aLocale;
+ m_lDocumentStorages = rCopy.m_lDocumentStorages;
+ m_sRelPathShare = rCopy.m_sRelPathShare;
+ m_sRelPathNoLang = rCopy.m_sRelPathNoLang;
+ m_sRelPathUser = rCopy.m_sRelPathUser;
+}
+
+//-----------------------------------------------
+PresetHandler::~PresetHandler()
+{
+ m_xWorkingStorageShare.clear();
+ m_xWorkingStorageNoLang.clear();
+ m_xWorkingStorageUser.clear();
+
+ /* #i46497#
+ Dont call forgetCachedStorages() here for shared storages.
+ Because we opened different sub storages by using openPath().
+ And every already open path was reused and referenced (means it's
+ ref count was increased!)
+ So now we have to release our ref counts to these shared storages
+ only ... and not to free all used storages.
+ Otherwise we will disconnect all other open configuration access
+ objects which base on these storages.
+ */
+ m_aSharedStorages->m_lStoragesShare.closePath(m_sRelPathShare);
+ m_aSharedStorages->m_lStoragesUser.closePath (m_sRelPathUser );
+
+ /* On the other side closePath() is not needed for our special handled
+ document storage. Because it's not shared with others ... so we can
+ free it.
+ */
+ m_lDocumentStorages.forgetCachedStorages();
+}
+
+//-----------------------------------------------
+void PresetHandler::forgetCachedStorages()
+{
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ if (m_eConfigType == E_DOCUMENT)
+ {
+ m_xWorkingStorageShare.clear();
+ m_xWorkingStorageNoLang.clear();
+ m_xWorkingStorageUser.clear();
+ }
+
+ m_lDocumentStorages.forgetCachedStorages();
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+::rtl::OUString lcl_getLocalizedMessage(::sal_Int32 nID)
+{
+ ::rtl::OUString sMessage = ::rtl::OUString::createFromAscii("Unknown error.");
+
+ switch(nID)
+ {
+ case ID_CORRUPT_UICONFIG_SHARE :
+ sMessage = ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_SHARE )));
+ break;
+
+ case ID_CORRUPT_UICONFIG_USER :
+ sMessage = ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_USER )));
+ break;
+
+ case ID_CORRUPT_UICONFIG_GENERAL :
+ sMessage = ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_GENERAL )));
+ break;
+ }
+
+ return sMessage;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getOrCreateRootStorageShare()
+{
+ css::uno::Reference< css::embed::XStorage > xRoot = m_aSharedStorages->m_lStoragesShare.getRootStorage();
+ if (xRoot.is())
+ return xRoot;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::beans::XPropertySet > xPathSettings(
+ xSMGR->createInstance(SERVICENAME_PATHSETTINGS),
+ css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString sShareLayer;
+ xPathSettings->getPropertyValue(BASEPATH_SHARE_LAYER) >>= sShareLayer;
+
+ // "UIConfig" is a "multi path" ... use first part only here!
+ sal_Int32 nPos = sShareLayer.indexOf(';');
+ if (nPos > 0)
+ sShareLayer = sShareLayer.copy(0, nPos);
+
+ // Note: May be an user uses URLs without a final slash! Check it ...
+ nPos = sShareLayer.lastIndexOf('/');
+ if (nPos != sShareLayer.getLength()-1)
+ sShareLayer += ::rtl::OUString::createFromAscii("/");
+
+ sShareLayer += RELPATH_SHARE_LAYER; // folder
+ /*
+ // TODO remove me!
+ // Attention: This is temp. workaround ... We create a temp. storage file
+ // based of a sytem directory. This must be used so, till the storage implementation
+ // can work on directories too.
+ */
+ css::uno::Sequence< css::uno::Any > lArgs(2);
+ lArgs[0] <<= sShareLayer;
+ lArgs[1] <<= css::embed::ElementModes::READ | css::embed::ElementModes::NOCREATE;
+
+ css::uno::Reference< css::lang::XSingleServiceFactory > xStorageFactory(xSMGR->createInstance(SERVICENAME_FILESYSTEMSTORAGEFACTORY) , css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::embed::XStorage > xStorage;
+
+ try
+ {
+ xStorage = css::uno::Reference< css::embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::configuration::CorruptedUIConfigurationException(
+ lcl_getLocalizedMessage(ID_CORRUPT_UICONFIG_SHARE),
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+
+ m_aSharedStorages->m_lStoragesShare.setRootStorage(xStorage);
+
+ return xStorage;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getOrCreateRootStorageUser()
+{
+ css::uno::Reference< css::embed::XStorage > xRoot = m_aSharedStorages->m_lStoragesUser.getRootStorage();
+ if (xRoot.is())
+ return xRoot;
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::beans::XPropertySet > xPathSettings(
+ xSMGR->createInstance(SERVICENAME_PATHSETTINGS),
+ css::uno::UNO_QUERY_THROW);
+
+ ::rtl::OUString sUserLayer;
+ xPathSettings->getPropertyValue(BASEPATH_USER_LAYER) >>= sUserLayer ;
+
+ // Note: May be an user uses URLs without a final slash! Check it ...
+ sal_Int32 nPos = sUserLayer.lastIndexOf('/');
+ if (nPos != sUserLayer.getLength()-1)
+ sUserLayer += ::rtl::OUString::createFromAscii("/");
+
+ sUserLayer += RELPATH_USER_LAYER; // storage file
+
+ css::uno::Sequence< css::uno::Any > lArgs(2);
+ lArgs[0] <<= sUserLayer;
+ lArgs[1] <<= css::embed::ElementModes::READWRITE;
+
+ css::uno::Reference< css::lang::XSingleServiceFactory > xStorageFactory(xSMGR->createInstance(SERVICENAME_FILESYSTEMSTORAGEFACTORY) , css::uno::UNO_QUERY_THROW);
+ css::uno::Reference< css::embed::XStorage > xStorage;
+
+ try
+ {
+ xStorage = css::uno::Reference< css::embed::XStorage >(xStorageFactory->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::configuration::CorruptedUIConfigurationException(
+ lcl_getLocalizedMessage(ID_CORRUPT_UICONFIG_USER),
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+
+ m_aSharedStorages->m_lStoragesUser.setRootStorage(xStorage);
+
+ return xStorage;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getWorkingStorageShare()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ return m_xWorkingStorageShare;
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getWorkingStorageUser()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ return m_xWorkingStorageUser;
+ // <- SAFE ----------------------------------
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getParentStorageShare(const css::uno::Reference< css::embed::XStorage >& /*xChild*/)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xWorking = m_xWorkingStorageShare;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return m_aSharedStorages->m_lStoragesShare.getParentStorage(xWorking);
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::getParentStorageUser(const css::uno::Reference< css::embed::XStorage >& /*xChild*/)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xWorking = m_xWorkingStorageUser;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ return m_aSharedStorages->m_lStoragesUser.getParentStorage(xWorking);
+}
+
+//-----------------------------------------------
+void PresetHandler::connectToResource( PresetHandler::EConfigType eConfigType ,
+ const ::rtl::OUString& sResource ,
+ const ::rtl::OUString& sModule ,
+ const css::uno::Reference< css::embed::XStorage >& xDocumentRoot,
+ const ::comphelper::Locale& aLocale )
+{
+ // TODO free all current open storages!
+
+ // SAFE -> ----------------------------------
+ WriteGuard aWriteLock(m_aLock);
+
+ m_eConfigType = eConfigType ;
+ m_sResourceType = sResource ;
+ m_sModule = sModule ;
+ m_aLocale = aLocale ;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ css::uno::Reference< css::embed::XStorage > xShare;
+ css::uno::Reference< css::embed::XStorage > xNoLang;
+ css::uno::Reference< css::embed::XStorage > xUser;
+
+ // special case for documents
+ // use outside root storage, if we run in E_DOCUMENT mode!
+ if (eConfigType == E_DOCUMENT)
+ {
+ if (!xDocumentRoot.is())
+ throw css::uno::RuntimeException(
+ ::rtl::OUString::createFromAscii("There is valid root storage, where the UI configuration can work on."),
+ css::uno::Reference< css::uno::XInterface >());
+ m_lDocumentStorages.setRootStorage(xDocumentRoot);
+ xShare = xDocumentRoot;
+ xUser = xDocumentRoot;
+ }
+ else
+ {
+ xShare = getOrCreateRootStorageShare();
+ xUser = getOrCreateRootStorageUser();
+ }
+
+ // #...#
+ try
+ {
+
+ // a) inside share layer we should not create any new structures ... We jave to use
+ // existing ones only!
+ // b) inside user layer we can (SOFT mode!) but sometimes we shouldnt (HARD mode!)
+ // create new empty structures. We should preferr using of any existing structure.
+ sal_Int32 eShareMode = (css::embed::ElementModes::READ | css::embed::ElementModes::NOCREATE);
+ sal_Int32 eUserMode = (css::embed::ElementModes::READWRITE );
+
+ ::rtl::OUStringBuffer sRelPathBuf(1024);
+ ::rtl::OUString sRelPathShare;
+ ::rtl::OUString sRelPathNoLang;
+ ::rtl::OUString sRelPathUser;
+ switch(eConfigType)
+ {
+ case E_GLOBAL :
+ {
+ sRelPathBuf.append(SUBSTORAGE_GLOBAL);
+ sRelPathBuf.append(PATH_SEPERATOR );
+ sRelPathBuf.append(sResource );
+ sRelPathShare = sRelPathBuf.makeStringAndClear();
+ sRelPathUser = sRelPathShare;
+
+ xShare = impl_openPathIgnoringErrors(sRelPathShare, eShareMode, sal_True );
+ xUser = impl_openPathIgnoringErrors(sRelPathUser , eUserMode , sal_False);
+ }
+ break;
+
+ case E_MODULES :
+ {
+ sRelPathBuf.append(SUBSTORAGE_MODULES);
+ sRelPathBuf.append(PATH_SEPERATOR );
+ sRelPathBuf.append(sModule );
+ sRelPathBuf.append(PATH_SEPERATOR );
+ sRelPathBuf.append(sResource );
+ sRelPathShare = sRelPathBuf.makeStringAndClear();
+ sRelPathUser = sRelPathShare;
+
+ xShare = impl_openPathIgnoringErrors(sRelPathShare, eShareMode, sal_True );
+ xUser = impl_openPathIgnoringErrors(sRelPathUser , eUserMode , sal_False);
+ }
+ break;
+
+ case E_DOCUMENT :
+ {
+ // A document does not have a share layer in real.
+ // It has one layer only, and this one should be opened READ_WRITE.
+ // So we open the user layer here only and set the share layer equals to it .-)
+
+ sRelPathBuf.append(sResource);
+ sRelPathUser = sRelPathBuf.makeStringAndClear();
+ sRelPathShare = sRelPathUser;
+
+ try
+ {
+ xUser = m_lDocumentStorages.openPath(sRelPathUser , eUserMode );
+ xShare = xUser;
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { xShare.clear(); xUser.clear(); }
+ }
+ break;
+ }
+
+ // Non-localized global share
+ xNoLang = xShare;
+ sRelPathNoLang = sRelPathShare;
+
+ if (
+ (aLocale != ::comphelper::Locale::X_NOTRANSLATE()) && // localized level?
+ (eConfigType != E_DOCUMENT ) // no localization in document mode!
+ )
+ {
+ // First try to find the right localized set inside share layer.
+ // Fallbacks are allowed there.
+ ::comphelper::Locale aShareLocale = aLocale ;
+ ::rtl::OUString sLocalizedSharePath(sRelPathShare);
+ sal_Bool bAllowFallbacks = sal_True ;
+ xShare = impl_openLocalizedPathIgnoringErrors(sLocalizedSharePath, eShareMode, sal_True , aShareLocale, bAllowFallbacks);
+
+ // The try to locate the right sub dir inside user layer ... without using fallbacks!
+ // Normaly the corresponding sub dir should be created matching the specified locale.
+ // Because we allow creation of storages inside user layer by default.
+ ::comphelper::Locale aUserLocale = aLocale ;
+ ::rtl::OUString sLocalizedUserPath(sRelPathUser);
+ bAllowFallbacks = sal_False ;
+ xUser = impl_openLocalizedPathIgnoringErrors(sLocalizedUserPath, eUserMode , sal_False, aUserLocale, bAllowFallbacks);
+
+ sRelPathShare = sLocalizedSharePath;
+ sRelPathUser = sLocalizedUserPath ;
+ }
+
+ // read content of level 3 (presets, targets)
+ css::uno::Reference< css::container::XNameAccess > xAccess ;
+ css::uno::Sequence< ::rtl::OUString > lNames ;
+ const ::rtl::OUString* pNames ;
+ sal_Int32 c ;
+ sal_Int32 i ;
+ OUStringList lPresets;
+ OUStringList lTargets;
+
+ // read preset names of share layer
+ xAccess = css::uno::Reference< css::container::XNameAccess >(xShare, css::uno::UNO_QUERY);
+ if (xAccess.is())
+ {
+ lNames = xAccess->getElementNames();
+ pNames = lNames.getConstArray();
+ c = lNames.getLength();
+
+ for (i=0; i<c; ++i)
+ {
+ ::rtl::OUString sTemp = pNames[i];
+ sal_Int32 nPos = sTemp.indexOf(FILE_EXTENSION);
+ if (nPos > -1)
+ sTemp = sTemp.copy(0,nPos);
+ lPresets.push_back(sTemp);
+ }
+ }
+
+ // read preset names of user layer
+ xAccess = css::uno::Reference< css::container::XNameAccess >(xUser, css::uno::UNO_QUERY);
+ if (xAccess.is())
+ {
+ lNames = xAccess->getElementNames();
+ pNames = lNames.getConstArray();
+ c = lNames.getLength();
+
+ for (i=0; i<c; ++i)
+ {
+ ::rtl::OUString sTemp = pNames[i];
+ sal_Int32 nPos = sTemp.indexOf(FILE_EXTENSION);
+ if (nPos > -1)
+ sTemp = sTemp.copy(0,nPos);
+ lTargets.push_back(sTemp);
+ }
+ }
+
+ // SAFE -> ----------------------------------
+ aWriteLock.lock();
+
+ m_xWorkingStorageShare = xShare ;
+ m_xWorkingStorageNoLang= xNoLang;
+ m_xWorkingStorageUser = xUser ;
+ m_lPresets = lPresets;
+ m_lTargets = lTargets;
+ m_sRelPathShare = sRelPathShare;
+ m_sRelPathNoLang = sRelPathNoLang;
+ m_sRelPathUser = sRelPathUser;
+
+ aWriteLock.unlock();
+ // <- SAFE ----------------------------------
+
+ }
+ catch(const css::uno::Exception& ex)
+ {
+ throw css::configuration::CorruptedUIConfigurationException(
+ lcl_getLocalizedMessage(ID_CORRUPT_UICONFIG_GENERAL),
+ css::uno::Reference< css::uno::XInterface >(),
+ ex.Message);
+ }
+}
+
+//-----------------------------------------------
+void PresetHandler::copyPresetToTarget(const ::rtl::OUString& sPreset,
+ const ::rtl::OUString& sTarget)
+{
+ // dont check our preset list, if element exists
+ // We try to open it and forward all errors to the user!
+
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xWorkingShare = m_xWorkingStorageShare;
+ css::uno::Reference< css::embed::XStorage > xWorkingNoLang= m_xWorkingStorageNoLang;
+ css::uno::Reference< css::embed::XStorage > xWorkingUser = m_xWorkingStorageUser ;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // e.g. module without any config data ?!
+ if (
+ (!xWorkingShare.is()) ||
+ (!xWorkingUser.is() )
+ )
+ {
+ return;
+ }
+
+ ::rtl::OUString sPresetFile(sPreset);
+ sPresetFile += FILE_EXTENSION;
+
+ ::rtl::OUString sTargetFile(sTarget);
+ sTargetFile += FILE_EXTENSION;
+
+ // remove existing elements before you try to copy the preset to that location ...
+ // Otherwise w will get an ElementExistException inside copyElementTo()!
+ css::uno::Reference< css::container::XNameAccess > xCheckingUser(xWorkingUser, css::uno::UNO_QUERY_THROW);
+ if (xCheckingUser->hasByName(sTargetFile))
+ xWorkingUser->removeElement(sTargetFile);
+
+ xWorkingShare->copyElementTo(sPresetFile, xWorkingUser, sTargetFile);
+
+ // If our storages work in transacted mode, we have
+ // to commit all changes from bottom to top!
+ commitUserChanges();
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::io::XStream > PresetHandler::openPreset(const ::rtl::OUString& sPreset,
+ sal_Bool bUseNoLangGlobal)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xFolder = bUseNoLangGlobal? m_xWorkingStorageNoLang: m_xWorkingStorageShare;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // e.g. module without any config data ?!
+ if (!xFolder.is())
+ return css::uno::Reference< css::io::XStream >();
+
+ ::rtl::OUString sFile(sPreset);
+ sFile += FILE_EXTENSION;
+
+ // inform user about errors (use original exceptions!)
+ css::uno::Reference< css::io::XStream > xStream = xFolder->openStreamElement(sFile, css::embed::ElementModes::READ);
+ return xStream;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::io::XStream > PresetHandler::openTarget(const ::rtl::OUString& sTarget ,
+ sal_Bool bCreateIfMissing)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xFolder = m_xWorkingStorageUser;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // e.g. module without any config data ?!
+ if (!xFolder.is())
+ return css::uno::Reference< css::io::XStream >();
+
+ ::rtl::OUString sFile(sTarget);
+ sFile += FILE_EXTENSION;
+
+ sal_Int32 nOpenMode = css::embed::ElementModes::READWRITE;
+ if (!bCreateIfMissing)
+ nOpenMode |= css::embed::ElementModes::NOCREATE;
+
+ // try it in read/write mode first and ignore errors.
+ css::uno::Reference< css::io::XStream > xStream;
+ try
+ {
+ xStream = xFolder->openStreamElement(sFile, nOpenMode);
+ return xStream;
+ }
+ catch(const css::uno::RuntimeException&)
+ { throw; }
+ catch(const css::uno::Exception&)
+ { xStream.clear(); }
+
+ // try it readonly if it failed before.
+ // inform user about errors (use original exceptions!)
+ nOpenMode &= ~css::embed::ElementModes::WRITE;
+ xStream = xFolder->openStreamElement(sFile, nOpenMode);
+
+ return xStream;
+}
+
+//-----------------------------------------------
+void PresetHandler::commitUserChanges()
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ css::uno::Reference< css::embed::XStorage > xWorking = m_xWorkingStorageUser;
+ EConfigType eCfgType = m_eConfigType;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ // e.g. module without any config data ?!
+ if (!xWorking.is())
+ return;
+
+ ::rtl::OUString sPath;
+
+ switch(eCfgType)
+ {
+ case E_GLOBAL :
+ case E_MODULES :
+ {
+ sPath = m_aSharedStorages->m_lStoragesUser.getPathOfStorage(xWorking);
+ m_aSharedStorages->m_lStoragesUser.commitPath(sPath);
+ m_aSharedStorages->m_lStoragesUser.notifyPath(sPath);
+ }
+ break;
+
+ case E_DOCUMENT :
+ {
+ sPath = m_lDocumentStorages.getPathOfStorage(xWorking);
+ m_lDocumentStorages.commitPath(sPath);
+ m_lDocumentStorages.notifyPath(sPath);
+ }
+ break;
+ }
+}
+
+//-----------------------------------------------
+void PresetHandler::addStorageListener(IStorageListener* pListener)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ ::rtl::OUString sRelPath = m_sRelPathUser; // use user path ... because we dont work directly on the share layer!
+ EConfigType eCfgType = m_eConfigType;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (!sRelPath.getLength())
+ return;
+
+ switch(eCfgType)
+ {
+ case E_GLOBAL :
+ case E_MODULES :
+ {
+ m_aSharedStorages->m_lStoragesUser.addStorageListener(pListener, sRelPath);
+ }
+ break;
+
+ case E_DOCUMENT :
+ {
+ m_lDocumentStorages.addStorageListener(pListener, sRelPath);
+ }
+ break;
+ }
+}
+
+//-----------------------------------------------
+void PresetHandler::removeStorageListener(IStorageListener* pListener)
+{
+ // SAFE -> ----------------------------------
+ ReadGuard aReadLock(m_aLock);
+ ::rtl::OUString sRelPath = m_sRelPathUser; // use user path ... because we dont work directly on the share layer!
+ EConfigType eCfgType = m_eConfigType;
+ aReadLock.unlock();
+ // <- SAFE ----------------------------------
+
+ if (!sRelPath.getLength())
+ return;
+
+ switch(eCfgType)
+ {
+ case E_GLOBAL :
+ case E_MODULES :
+ {
+ m_aSharedStorages->m_lStoragesUser.removeStorageListener(pListener, sRelPath);
+ }
+ break;
+
+ case E_DOCUMENT :
+ {
+ m_lDocumentStorages.removeStorageListener(pListener, sRelPath);
+ }
+ break;
+ }
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::impl_openPathIgnoringErrors(const ::rtl::OUString& sPath ,
+ sal_Int32 eMode ,
+ sal_Bool bShare)
+{
+ css::uno::Reference< css::embed::XStorage > xPath;
+ try
+ {
+ if (bShare)
+ xPath = m_aSharedStorages->m_lStoragesShare.openPath(sPath, eMode);
+ else
+ xPath = m_aSharedStorages->m_lStoragesUser.openPath(sPath, eMode);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ { xPath.clear(); }
+ return xPath;
+}
+
+//-----------------------------------------------
+::std::vector< ::rtl::OUString >::const_iterator PresetHandler::impl_findMatchingLocalizedValue(const ::std::vector< ::rtl::OUString >& lLocalizedValues,
+ ::comphelper::Locale& aLocale ,
+ sal_Bool bAllowFallbacks )
+{
+ ::std::vector< ::rtl::OUString >::const_iterator pFound = lLocalizedValues.end();
+ if (bAllowFallbacks)
+ {
+ pFound = ::comphelper::Locale::getFallback(lLocalizedValues, aLocale.toISO());
+ }
+ else
+ {
+ for ( pFound = lLocalizedValues.begin();
+ pFound != lLocalizedValues.end() ;
+ ++pFound )
+ {
+ const ::rtl::OUString& sCheckISO = *pFound;
+ ::comphelper::Locale aCheckLocale(sCheckISO);
+ if (aCheckLocale.equals(aLocale))
+ break;
+ }
+ }
+
+ // if we found a valid locale ... take it over to our in/out parameter aLocale
+ if (pFound != lLocalizedValues.end())
+ {
+ const ::rtl::OUString& sISOLocale = *pFound;
+ aLocale.fromISO(sISOLocale);
+ }
+
+ return pFound;
+}
+
+//-----------------------------------------------
+css::uno::Reference< css::embed::XStorage > PresetHandler::impl_openLocalizedPathIgnoringErrors(::rtl::OUString& sPath ,
+ sal_Int32 eMode ,
+ sal_Bool bShare ,
+ ::comphelper::Locale& aLocale ,
+ sal_Bool bAllowFallback)
+{
+ css::uno::Reference< css::embed::XStorage > xPath = impl_openPathIgnoringErrors(sPath, eMode, bShare);
+ ::std::vector< ::rtl::OUString > lSubFolders = impl_getSubFolderNames(xPath);
+ ::std::vector< ::rtl::OUString >::const_iterator pLocaleFolder = impl_findMatchingLocalizedValue(lSubFolders, aLocale, bAllowFallback);
+
+ // no fallback ... creation not allowed => no storage
+ if (
+ (pLocaleFolder == lSubFolders.end() ) &&
+ ((eMode & css::embed::ElementModes::NOCREATE) == css::embed::ElementModes::NOCREATE)
+ )
+ return css::uno::Reference< css::embed::XStorage >();
+
+ // it doesnt matter, if there is a locale fallback or not
+ // If creation of storages is allowed, we do it anyway.
+ // Otherwhise we have no acc config at all, which can make other trouble.
+ ::rtl::OUString sLocalizedPath;
+ sLocalizedPath = sPath;
+ sLocalizedPath += PATH_SEPERATOR;
+ if (pLocaleFolder != lSubFolders.end())
+ sLocalizedPath += *pLocaleFolder;
+ else
+ sLocalizedPath += aLocale.toISO();
+
+ css::uno::Reference< css::embed::XStorage > xLocalePath = impl_openPathIgnoringErrors(sLocalizedPath, eMode, bShare);
+
+ if (xLocalePath.is())
+ sPath = sLocalizedPath;
+ else
+ sPath = ::rtl::OUString();
+
+ return xLocalePath;
+}
+
+//-----------------------------------------------
+::std::vector< ::rtl::OUString > PresetHandler::impl_getSubFolderNames(const css::uno::Reference< css::embed::XStorage >& xFolder)
+{
+ css::uno::Reference< css::container::XNameAccess > xAccess(xFolder, css::uno::UNO_QUERY);
+ if (!xAccess.is())
+ return ::std::vector< ::rtl::OUString >();
+
+ ::std::vector< ::rtl::OUString > lSubFolders;
+ const css::uno::Sequence< ::rtl::OUString > lNames = xAccess->getElementNames();
+ const ::rtl::OUString* pNames = lNames.getConstArray();
+ sal_Int32 c = lNames.getLength();
+ sal_Int32 i = 0;
+
+ for (i=0; i<c; ++i)
+ {
+ try
+ {
+ if (xFolder->isStorageElement(pNames[i]))
+ lSubFolders.push_back(pNames[i]);
+ }
+ catch(const css::uno::RuntimeException& exRun)
+ { throw exRun; }
+ catch(const css::uno::Exception&)
+ {}
+ }
+
+ return lSubFolders;
+}
+
+//-----------------------------------------------
+} // namespace framework