26#include <com/sun/star/configuration/CorruptedUIConfigurationException.hpp>
27#include <com/sun/star/container/XNameAccess.hpp>
28#include <com/sun/star/embed/ElementModes.hpp>
29#include <com/sun/star/embed/FileSystemStorageFactory.hpp>
30#include <com/sun/star/lang/XSingleServiceFactory.hpp>
31#include <com/sun/star/util/thePathSettings.hpp>
36#include <rtl/ustrbuf.hxx>
37#include <osl/diagnose.h>
55struct TSharedStorages final
68TSharedStorages& SharedStorages()
70 static TSharedStorages theStorages;
78 , m_eConfigType(E_GLOBAL)
110 auto & sharedStorages = SharedStorages();
137OUString lcl_getLocalizedMessage(::sal_Int32 nID)
139 OUString
sMessage(
"Unknown error.");
160void lcl_throwCorruptedUIConfigurationException(
161 css::uno::Any
const & exception, sal_Int32
id)
163 css::uno::Exception e;
164 bool ok = (exception >>= e);
166 throw css::configuration::CorruptedUIConfigurationException(
167 lcl_getLocalizedMessage(
id),
168 css::uno::Reference< css::uno::XInterface >(),
169 exception.getValueTypeName() +
": \"" + e.Message +
"\"");
176 auto & sharedStorages = SharedStorages();
177 css::uno::Reference< css::embed::XStorage > xRoot = sharedStorages.m_lStoragesShare.getRootStorage();
181 css::uno::Reference< css::uno::XComponentContext > xContext;
187 css::uno::Reference< css::util::XPathSettings > xPathSettings =
188 css::util::thePathSettings::get( xContext );
190 OUString sShareLayer = xPathSettings->getBasePathShareLayer();
193 sal_Int32
nPos = sShareLayer.indexOf(
';');
195 sShareLayer = sShareLayer.copy(0,
nPos);
198 nPos = sShareLayer.lastIndexOf(
'/');
199 if (
nPos != sShareLayer.getLength()-1)
202 sShareLayer +=
"soffice.cfg";
209 css::uno::Sequence< css::uno::Any > lArgs{
210 css::uno::Any(sShareLayer),
211 css::uno::Any(css::embed::ElementModes::READ | css::embed::ElementModes::NOCREATE)
214 css::uno::Reference< css::lang::XSingleServiceFactory > xStorageFactory = css::embed::FileSystemStorageFactory::create( xContext );
215 css::uno::Reference< css::embed::XStorage > xStorage;
219 xStorage.set(xStorageFactory->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
221 catch(
const css::uno::Exception&)
224 lcl_throwCorruptedUIConfigurationException(
228 sharedStorages.m_lStoragesShare.setRootStorage(xStorage);
235 auto & sharedStorages = SharedStorages();
236 css::uno::Reference< css::embed::XStorage > xRoot = sharedStorages.m_lStoragesUser.getRootStorage();
240 css::uno::Reference< css::uno::XComponentContext > xContext;
246 css::uno::Reference< css::util::XPathSettings > xPathSettings =
247 css::util::thePathSettings::get( xContext );
249 OUString sUserLayer = xPathSettings->getBasePathUserLayer();
252 sal_Int32
nPos = sUserLayer.lastIndexOf(
'/');
253 if (
nPos != sUserLayer.getLength()-1)
256 sUserLayer +=
"soffice.cfg";
258 css::uno::Sequence< css::uno::Any > lArgs{ css::uno::Any(sUserLayer),
259 css::uno::Any(css::embed::ElementModes::READWRITE) };
261 css::uno::Reference< css::lang::XSingleServiceFactory > xStorageFactory = css::embed::FileSystemStorageFactory::create( xContext );
262 css::uno::Reference< css::embed::XStorage > xStorage;
266 xStorage.set(xStorageFactory->createInstanceWithArguments(lArgs), css::uno::UNO_QUERY_THROW);
268 catch(
const css::uno::Exception&)
271 lcl_throwCorruptedUIConfigurationException(
275 sharedStorages.m_lStoragesUser.setRootStorage(xStorage);
288 css::uno::Reference< css::embed::XStorage > xWorking;
294 return SharedStorages().m_lStoragesShare.getParentStorage(xWorking);
299 css::uno::Reference< css::embed::XStorage > xWorking;
305 return SharedStorages().m_lStoragesUser.getParentStorage(xWorking);
309 std::u16string_view sResource ,
310 std::u16string_view sModule ,
311 const css::uno::Reference< css::embed::XStorage >& xDocumentRoot,
321 css::uno::Reference< css::embed::XStorage > xShare;
322 css::uno::Reference< css::embed::XStorage > xNoLang;
323 css::uno::Reference< css::embed::XStorage > xUser;
329 if (!xDocumentRoot.is())
330 throw css::uno::RuntimeException(
331 "There is valid root storage, where the UI configuration can work on.");
333 xShare = xDocumentRoot;
334 xUser = xDocumentRoot;
350 sal_Int32 eShareMode = (css::embed::ElementModes::READ | css::embed::ElementModes::NOCREATE);
351 sal_Int32 eUserMode = css::embed::ElementModes::READWRITE;
353 OUStringBuffer sRelPathBuf(1024);
354 OUString sRelPathShare;
355 OUString sRelPathUser;
360 sRelPathShare = OUString::Concat(
"global/") + sResource;
361 sRelPathUser = sRelPathShare;
370 sRelPathShare = OUString::Concat(
"modules/") + sModule +
"/" + sResource;
371 sRelPathUser = sRelPathShare;
384 sRelPathBuf.append(sResource);
385 sRelPathUser = sRelPathBuf.makeStringAndClear();
386 sRelPathShare = sRelPathUser;
393 catch(
const css::uno::RuntimeException&)
395 catch(
const css::uno::Exception&)
396 { xShare.clear(); xUser.clear(); }
411 OUString aShareLocale( rLanguageTag.
getBcp47());
412 OUString sLocalizedSharePath(sRelPathShare);
413 bool bAllowFallbacks =
true;
419 OUString aUserLocale( rLanguageTag.
getBcp47());
420 OUString sLocalizedUserPath(sRelPathUser);
421 bAllowFallbacks =
false;
424 sRelPathShare = sLocalizedSharePath;
425 sRelPathUser = sLocalizedUserPath;
438 catch(
const css::uno::Exception&)
441 lcl_throwCorruptedUIConfigurationException(
447 std::u16string_view sTarget)
452 css::uno::Reference< css::embed::XStorage > xWorkingShare;
453 css::uno::Reference< css::embed::XStorage > xWorkingNoLang;
454 css::uno::Reference< css::embed::XStorage > xWorkingUser;
464 (!xWorkingShare.is()) ||
465 (!xWorkingUser.is() )
471 OUString sPresetFile = OUString::Concat(sPreset) +
".xml";
472 OUString sTargetFile = OUString::Concat(sTarget) +
".xml";
476 css::uno::Reference< css::container::XNameAccess > xCheckingUser(xWorkingUser, css::uno::UNO_QUERY_THROW);
477 if (xCheckingUser->hasByName(sTargetFile))
478 xWorkingUser->removeElement(sTargetFile);
480 xWorkingShare->copyElementTo(sPresetFile, xWorkingUser, sTargetFile);
489 css::uno::Reference< css::embed::XStorage > xFolder;
497 return css::uno::Reference< css::io::XStream >();
499 OUString sFile = OUString::Concat(sPreset) +
".xml";
502 css::uno::Reference< css::io::XStream >
xStream = xFolder->openStreamElement(sFile, css::embed::ElementModes::READ);
507 std::u16string_view sTarget, sal_Int32
const nMode)
509 css::uno::Reference< css::embed::XStorage > xFolder;
517 return css::uno::Reference< css::io::XStream >();
519 OUString
const sFile(OUString::Concat(sTarget) +
".xml");
521 return xFolder->openStreamElement(sFile, nMode);
526 css::uno::Reference< css::embed::XStorage > xWorking;
545 auto & sharedStorages = SharedStorages();
546 sPath = sharedStorages.m_lStoragesUser.getPathOfStorage(xWorking);
547 sharedStorages.m_lStoragesUser.commitPath(sPath);
548 sharedStorages.m_lStoragesUser.notifyPath(sPath);
572 if (sRelPath.isEmpty())
580 SharedStorages().m_lStoragesUser.addStorageListener(pListener, sRelPath);
602 if (sRelPath.isEmpty())
610 SharedStorages().m_lStoragesUser.removeStorageListener(pListener, sRelPath);
626 css::uno::Reference< css::embed::XStorage > xPath;
630 xPath = SharedStorages().m_lStoragesShare.openPath(sPath,
eMode);
632 xPath = SharedStorages().m_lStoragesUser.openPath(sPath,
eMode);
634 catch(
const css::uno::RuntimeException&)
636 catch(
const css::uno::Exception&)
642 const ::std::vector< OUString >& lLocalizedValues,
643 OUString& rLanguageTag,
644 bool bAllowFallbacks )
646 ::std::vector< OUString >::const_iterator pFound = lLocalizedValues.end();
652 if (pFound != lLocalizedValues.end())
654 rLanguageTag = *pFound;
659 pFound = std::find(lLocalizedValues.begin(), lLocalizedValues.end(), rLanguageTag);
669 OUString& rLanguageTag ,
678 (pLocaleFolder == lSubFolders.end() ) &&
679 ((
eMode & css::embed::ElementModes::NOCREATE) == css::embed::ElementModes::NOCREATE)
681 return css::uno::Reference< css::embed::XStorage >();
686 OUString sLocalizedPath = sPath +
"/";
687 if (pLocaleFolder != lSubFolders.end())
688 sLocalizedPath += *pLocaleFolder;
690 sLocalizedPath += rLanguageTag;
694 if (xLocalePath.is())
695 sPath = sLocalizedPath;
705 return ::std::vector< OUString >();
707 ::std::vector< OUString > lSubFolders;
708 const css::uno::Sequence< OUString > lNames = xFolder->getElementNames();
709 const OUString* pNames = lNames.getConstArray();
710 sal_Int32 c = lNames.getLength();
717 if (xFolder->isStorageElement(pNames[
i]))
718 lSubFolders.push_back(pNames[
i]);
720 catch(
const css::uno::RuntimeException&)
722 catch(
const css::uno::Exception&)
const OUString & getBcp47(bool bResolveSystem=true) const
::std::vector< OUString >::const_iterator getFallback(const ::std::vector< OUString > &rList, const OUString &rReference)
::std::vector< OUString > impl_getSubFolderNames(const css::uno::Reference< css::embed::XStorage > &xFolder)
returns the names of all sub storages of specified storage.
css::uno::Reference< css::io::XStream > openPreset(std::u16string_view sPreset)
open the specified preset as stream object and return it.
PresetHandler(css::uno::Reference< css::uno::XComponentContext > xContext)
does nothing real.
css::uno::Reference< css::embed::XStorage > m_xWorkingStorageUser
holds the folder storage of the user layer alive, where the current configuration set exists.
css::uno::Reference< css::embed::XStorage > getOrCreateRootStorageShare()
return access to the internally used and cached root storage.
css::uno::Reference< css::embed::XStorage > getParentStorageShare()
check if there is a parent storage well known for the specified child storage and return it.
css::uno::Reference< css::embed::XStorage > getWorkingStorageUser() const
provides access to the current working storages.
css::uno::Reference< css::uno::XComponentContext > m_xContext
can be used to create on needed uno resources.
void removeStorageListener(XMLBasedAcceleratorConfiguration *pListener)
css::uno::Reference< css::embed::XStorage > m_xWorkingStorageShare
holds the folder storage of the share layer alive, where the current configuration set exists.
void commitUserChanges()
do anything which is necessary to flush all changes back to disk.
StorageHolder m_lDocumentStorages
if we run in document mode, we can't use the global root storages! We have to use a special document ...
OUString m_sRelPathShare
knows the relative path from the root.
void copyPresetToTarget(std::u16string_view sPreset, std::u16string_view sTarget)
try to copy the specified preset from the share layer to the user layer and establish it as the speci...
EConfigType
this handler can provide different types of configuration.
css::uno::Reference< css::embed::XStorage > impl_openLocalizedPathIgnoringErrors(OUString &sPath, sal_Int32 eMode, bool bShare, OUString &rLanguageTag, bool bAllowFallback)
open a config path ignoring errors (catching exceptions).
~PresetHandler()
closes all open storages ... if user forgot that .
void forgetCachedStorages()
free all currently cache(!) storages.
css::uno::Reference< css::embed::XStorage > getOrCreateRootStorageUser()
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))
free all internal structures and let this handler work on a new type of configuration sets.
css::uno::Reference< css::embed::XStorage > impl_openPathIgnoringErrors(const OUString &sPath, sal_Int32 eMode, bool bShare)
open a config path ignoring errors (catching exceptions).
EConfigType m_eConfigType
knows the type of provided configuration.
css::uno::Reference< css::embed::XStorage > getParentStorageUser()
void addStorageListener(XMLBasedAcceleratorConfiguration *pListener)
TODO.
::std::vector< OUString >::const_iterator impl_findMatchingLocalizedValue(const ::std::vector< OUString > &lLocalizedValues, OUString &rLanguageTag, bool bAllowFallbacks)
try to find the specified locale inside list of possible ones.
css::uno::Reference< css::io::XStream > openTarget(std::u16string_view sTarget, sal_Int32 nMode)
open the specified target as stream object and return it.
css::uno::Reference< css::embed::XStorage > m_xWorkingStorageNoLang
global language-independent storage
void removeStorageListener(XMLBasedAcceleratorConfiguration *pListener, const OUString &sPath)
TODO.
void commitPath(const OUString &sPath)
TODO.
OUString getPathOfStorage(const css::uno::Reference< css::embed::XStorage > &xStorage)
TODO.
void forgetCachedStorages()
TODO.
void setRootStorage(const css::uno::Reference< css::embed::XStorage > &xRoot)
TODO.
void notifyPath(const OUString &sPath)
TODO.
void addStorageListener(XMLBasedAcceleratorConfiguration *pListener, const OUString &sPath)
TODO.
css::uno::Reference< css::embed::XStorage > openPath(const OUString &sPath, sal_Int32 nOpenMode)
TODO open or get!
implements a read/write access to the accelerator configuration.
OUString FwkResId(TranslateId aId)
css::uno::Reference< css::uno::XComponentContext > m_xContext
#define LANGUAGE_USER_PRIV_NOTRANSLATE
Any SAL_CALL getCaughtException()
const ::sal_Int32 ID_CORRUPT_UICONFIG_GENERAL
const ::sal_Int32 ID_CORRUPT_UICONFIG_USER
StorageHolder m_lStoragesShare
const ::sal_Int32 ID_CORRUPT_UICONFIG_SHARE
StorageHolder m_lStoragesUser