1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <accelerators/presethandler.hxx>
22 #include <classes/fwkresid.hxx>
24 #include "classes/resource.hrc"
27 #include <com/sun/star/beans/XPropertySet.hpp>
28 #include <com/sun/star/configuration/CorruptedUIConfigurationException.hpp>
29 #include <com/sun/star/container/NoSuchElementException.hpp>
30 #include <com/sun/star/container/XNameAccess.hpp>
31 #include <com/sun/star/embed/ElementModes.hpp>
32 #include <com/sun/star/embed/XTransactedObject.hpp>
33 #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
34 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
35 #include <com/sun/star/util/thePathSettings.hpp>
37 #include <vcl/svapp.hxx>
38 #include <cppuhelper/exc_hlp.hxx>
39 #include <rtl/ustrbuf.hxx>
40 #include <i18nlangtag/languagetag.hxx>
42 static const ::sal_Int32 ID_CORRUPT_UICONFIG_SHARE
= 1;
43 static const ::sal_Int32 ID_CORRUPT_UICONFIG_USER
= 2;
44 static const ::sal_Int32 ID_CORRUPT_UICONFIG_GENERAL
= 3;
49 PresetHandler::PresetHandler(const css::uno::Reference
< css::uno::XComponentContext
>& xContext
)
50 : m_xContext(xContext
)
51 , m_eConfigType(E_GLOBAL
)
53 , m_lDocumentStorages()
54 , m_aLanguageTag(LANGUAGE_USER_PRIV_NOTRANSLATE
)
58 PresetHandler::PresetHandler(const PresetHandler
& rCopy
)
59 : m_aLanguageTag( rCopy
.m_aLanguageTag
)
61 m_xContext
= rCopy
.m_xContext
;
62 m_eConfigType
= rCopy
.m_eConfigType
;
63 m_sResourceType
= rCopy
.m_sResourceType
;
64 m_sModule
= rCopy
.m_sModule
;
65 m_aSharedStorages
= rCopy
.m_aSharedStorages
;
66 m_xWorkingStorageShare
= rCopy
.m_xWorkingStorageShare
;
67 m_xWorkingStorageNoLang
= rCopy
.m_xWorkingStorageNoLang
;
68 m_xWorkingStorageUser
= rCopy
.m_xWorkingStorageUser
;
69 m_lPresets
= rCopy
.m_lPresets
;
70 m_lTargets
= rCopy
.m_lTargets
;
71 m_lDocumentStorages
= rCopy
.m_lDocumentStorages
;
72 m_sRelPathShare
= rCopy
.m_sRelPathShare
;
73 m_sRelPathNoLang
= rCopy
.m_sRelPathNoLang
;
74 m_sRelPathUser
= rCopy
.m_sRelPathUser
;
77 PresetHandler::~PresetHandler()
79 m_xWorkingStorageShare
.clear();
80 m_xWorkingStorageNoLang
.clear();
81 m_xWorkingStorageUser
.clear();
84 Dont call forgetCachedStorages() here for shared storages.
85 Because we opened different sub storages by using openPath().
86 And every already open path was reused and referenced (means it's
87 ref count was increased!)
88 So now we have to release our ref counts to these shared storages
89 only ... and not to free all used storages.
90 Otherwise we will disconnect all other open configuration access
91 objects which base on these storages.
93 m_aSharedStorages
->m_lStoragesShare
.closePath(m_sRelPathShare
);
94 m_aSharedStorages
->m_lStoragesUser
.closePath (m_sRelPathUser
);
96 /* On the other side closePath() is not needed for our special handled
97 document storage. Because it's not shared with others ... so we can
100 m_lDocumentStorages
.forgetCachedStorages();
103 void PresetHandler::forgetCachedStorages()
107 if (m_eConfigType
== E_DOCUMENT
)
109 m_xWorkingStorageShare
.clear();
110 m_xWorkingStorageNoLang
.clear();
111 m_xWorkingStorageUser
.clear();
114 m_lDocumentStorages
.forgetCachedStorages();
119 OUString
lcl_getLocalizedMessage(::sal_Int32 nID
)
121 OUString
sMessage("Unknown error.");
125 case ID_CORRUPT_UICONFIG_SHARE
:
126 sMessage
= FWK_RESSTR(STR_CORRUPT_UICFG_SHARE
);
130 case ID_CORRUPT_UICONFIG_USER
:
131 sMessage
= FWK_RESSTR(STR_CORRUPT_UICFG_USER
);
134 case ID_CORRUPT_UICONFIG_GENERAL
:
135 sMessage
= FWK_RESSTR(STR_CORRUPT_UICFG_GENERAL
);
142 void lcl_throwCorruptedUIConfigurationException(
143 css::uno::Any
const & exception
, sal_Int32 id
)
145 css::uno::Exception e
;
146 bool ok
= (exception
>>= e
);
147 OSL_ASSERT(ok
); (void) ok
; // avoid warnings
148 throw css::configuration::CorruptedUIConfigurationException(
149 lcl_getLocalizedMessage(id
),
150 css::uno::Reference
< css::uno::XInterface
>(),
151 exception
.getValueTypeName() + ": \"" + e
.Message
+ "\"");
156 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getOrCreateRootStorageShare()
158 css::uno::Reference
< css::embed::XStorage
> xRoot
= m_aSharedStorages
->m_lStoragesShare
.getRootStorage();
162 css::uno::Reference
< css::uno::XComponentContext
> xContext
;
165 xContext
= m_xContext
;
168 css::uno::Reference
< css::util::XPathSettings
> xPathSettings
=
169 css::util::thePathSettings::get( xContext
);
171 OUString sShareLayer
= xPathSettings
->getBasePathShareLayer();
173 // "UIConfig" is a "multi path" ... use first part only here!
174 sal_Int32 nPos
= sShareLayer
.indexOf(';');
176 sShareLayer
= sShareLayer
.copy(0, nPos
);
178 // Note: May be an user uses URLs without a final slash! Check it ...
179 nPos
= sShareLayer
.lastIndexOf('/');
180 if (nPos
!= sShareLayer
.getLength()-1)
183 sShareLayer
+= "soffice.cfg";
186 // Attention: This is temp. workaround ... We create a temp. storage file
187 // based of a system directory. This must be used so, till the storage implementation
188 // can work on directories too.
190 css::uno::Sequence
< css::uno::Any
> lArgs(2);
191 lArgs
[0] <<= sShareLayer
;
192 lArgs
[1] <<= css::embed::ElementModes::READ
| css::embed::ElementModes::NOCREATE
;
194 css::uno::Reference
< css::lang::XSingleServiceFactory
> xStorageFactory
= css::embed::FileSystemStorageFactory::create( xContext
);
195 css::uno::Reference
< css::embed::XStorage
> xStorage
;
199 xStorage
= css::uno::Reference
< css::embed::XStorage
>(xStorageFactory
->createInstanceWithArguments(lArgs
), css::uno::UNO_QUERY_THROW
);
201 catch(const css::uno::Exception
&)
203 css::uno::Any
ex(cppu::getCaughtException());
204 lcl_throwCorruptedUIConfigurationException(
205 ex
, ID_CORRUPT_UICONFIG_SHARE
);
208 m_aSharedStorages
->m_lStoragesShare
.setRootStorage(xStorage
);
213 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getOrCreateRootStorageUser()
215 css::uno::Reference
< css::embed::XStorage
> xRoot
= m_aSharedStorages
->m_lStoragesUser
.getRootStorage();
219 css::uno::Reference
< css::uno::XComponentContext
> xContext
;
222 xContext
= m_xContext
;
225 css::uno::Reference
< css::util::XPathSettings
> xPathSettings
=
226 css::util::thePathSettings::get( xContext
);
228 OUString sUserLayer
= xPathSettings
->getBasePathUserLayer();
230 // Note: May be an user uses URLs without a final slash! Check it ...
231 sal_Int32 nPos
= sUserLayer
.lastIndexOf('/');
232 if (nPos
!= sUserLayer
.getLength()-1)
235 sUserLayer
+= "soffice.cfg"; // storage file
237 css::uno::Sequence
< css::uno::Any
> lArgs(2);
238 lArgs
[0] <<= sUserLayer
;
239 lArgs
[1] <<= css::embed::ElementModes::READWRITE
;
241 css::uno::Reference
< css::lang::XSingleServiceFactory
> xStorageFactory
= css::embed::FileSystemStorageFactory::create( xContext
);
242 css::uno::Reference
< css::embed::XStorage
> xStorage
;
246 xStorage
= css::uno::Reference
< css::embed::XStorage
>(xStorageFactory
->createInstanceWithArguments(lArgs
), css::uno::UNO_QUERY_THROW
);
248 catch(const css::uno::Exception
&)
250 css::uno::Any
ex(cppu::getCaughtException());
251 lcl_throwCorruptedUIConfigurationException(
252 ex
, ID_CORRUPT_UICONFIG_USER
);
255 m_aSharedStorages
->m_lStoragesUser
.setRootStorage(xStorage
);
260 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getWorkingStorageShare()
263 return m_xWorkingStorageShare
;
266 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getWorkingStorageUser()
269 return m_xWorkingStorageUser
;
272 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getParentStorageShare(const css::uno::Reference
< css::embed::XStorage
>& /*xChild*/)
274 css::uno::Reference
< css::embed::XStorage
> xWorking
;
277 xWorking
= m_xWorkingStorageShare
;
280 return m_aSharedStorages
->m_lStoragesShare
.getParentStorage(xWorking
);
283 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getParentStorageUser(const css::uno::Reference
< css::embed::XStorage
>& /*xChild*/)
285 css::uno::Reference
< css::embed::XStorage
> xWorking
;
288 xWorking
= m_xWorkingStorageUser
;
291 return m_aSharedStorages
->m_lStoragesUser
.getParentStorage(xWorking
);
294 void PresetHandler::connectToResource( PresetHandler::EConfigType eConfigType
,
295 const OUString
& sResource
,
296 const OUString
& sModule
,
297 const css::uno::Reference
< css::embed::XStorage
>& xDocumentRoot
,
298 const LanguageTag
& rLanguageTag
)
300 // TODO free all current open storages!
304 m_eConfigType
= eConfigType
;
305 m_sResourceType
= sResource
;
307 m_aLanguageTag
= rLanguageTag
;
310 css::uno::Reference
< css::embed::XStorage
> xShare
;
311 css::uno::Reference
< css::embed::XStorage
> xNoLang
;
312 css::uno::Reference
< css::embed::XStorage
> xUser
;
314 // special case for documents
315 // use outside root storage, if we run in E_DOCUMENT mode!
316 if (eConfigType
== E_DOCUMENT
)
318 if (!xDocumentRoot
.is())
319 throw css::uno::RuntimeException(
320 "There is valid root storage, where the UI configuration can work on.");
321 m_lDocumentStorages
.setRootStorage(xDocumentRoot
);
322 xShare
= xDocumentRoot
;
323 xUser
= xDocumentRoot
;
327 xShare
= getOrCreateRootStorageShare();
328 xUser
= getOrCreateRootStorageUser();
335 // a) inside share layer we should not create any new structures ... We jave to use
336 // existing ones only!
337 // b) inside user layer we can (SOFT mode!) but sometimes we should not (HARD mode!)
338 // create new empty structures. We should preferr using of any existing structure.
339 sal_Int32 eShareMode
= (css::embed::ElementModes::READ
| css::embed::ElementModes::NOCREATE
);
340 sal_Int32 eUserMode
= (css::embed::ElementModes::READWRITE
);
342 OUStringBuffer
sRelPathBuf(1024);
343 OUString sRelPathShare
;
344 OUString sRelPathNoLang
;
345 OUString sRelPathUser
;
350 sRelPathBuf
.append("global");
351 sRelPathBuf
.append("/");
352 sRelPathBuf
.append(sResource
);
353 sRelPathShare
= sRelPathBuf
.makeStringAndClear();
354 sRelPathUser
= sRelPathShare
;
356 xShare
= impl_openPathIgnoringErrors(sRelPathShare
, eShareMode
, true );
357 xUser
= impl_openPathIgnoringErrors(sRelPathUser
, eUserMode
, false);
363 sRelPathBuf
.append("modules");
364 sRelPathBuf
.append("/");
365 sRelPathBuf
.append(sModule
);
366 sRelPathBuf
.append("/");
367 sRelPathBuf
.append(sResource
);
368 sRelPathShare
= sRelPathBuf
.makeStringAndClear();
369 sRelPathUser
= sRelPathShare
;
371 xShare
= impl_openPathIgnoringErrors(sRelPathShare
, eShareMode
, true );
372 xUser
= impl_openPathIgnoringErrors(sRelPathUser
, eUserMode
, false);
378 // A document does not have a share layer in real.
379 // It has one layer only, and this one should be opened READ_WRITE.
380 // So we open the user layer here only and set the share layer equals to it .-)
382 sRelPathBuf
.append(sResource
);
383 sRelPathUser
= sRelPathBuf
.makeStringAndClear();
384 sRelPathShare
= sRelPathUser
;
388 xUser
= m_lDocumentStorages
.openPath(sRelPathUser
, eUserMode
);
391 catch(const css::uno::RuntimeException
&)
393 catch(const css::uno::Exception
&)
394 { xShare
.clear(); xUser
.clear(); }
399 // Non-localized global share
401 sRelPathNoLang
= sRelPathShare
;
404 (rLanguageTag
!= LanguageTag(LANGUAGE_USER_PRIV_NOTRANSLATE
)) && // localized level?
405 (eConfigType
!= E_DOCUMENT
) // no localization in document mode!
408 // First try to find the right localized set inside share layer.
409 // Fallbacks are allowed there.
410 OUString
aShareLocale( rLanguageTag
.getBcp47());
411 OUString
sLocalizedSharePath(sRelPathShare
);
412 bool bAllowFallbacks
= true;
413 xShare
= impl_openLocalizedPathIgnoringErrors(sLocalizedSharePath
, eShareMode
, true , aShareLocale
, bAllowFallbacks
);
415 // The try to locate the right sub dir inside user layer ... without using fallbacks!
416 // Normally the corresponding sub dir should be created matching the specified locale.
417 // Because we allow creation of storages inside user layer by default.
418 OUString
aUserLocale( rLanguageTag
.getBcp47());
419 OUString
sLocalizedUserPath(sRelPathUser
);
420 bAllowFallbacks
= false;
421 xUser
= impl_openLocalizedPathIgnoringErrors(sLocalizedUserPath
, eUserMode
, false, aUserLocale
, bAllowFallbacks
);
423 sRelPathShare
= sLocalizedSharePath
;
424 sRelPathUser
= sLocalizedUserPath
;
427 // read content of level 3 (presets, targets)
428 css::uno::Reference
< css::container::XNameAccess
> xAccess
;
429 css::uno::Sequence
< OUString
> lNames
;
430 const OUString
* pNames
;
433 OUStringList lPresets
;
434 OUStringList lTargets
;
436 // read preset names of share layer
437 xAccess
= css::uno::Reference
< css::container::XNameAccess
>(xShare
, css::uno::UNO_QUERY
);
440 lNames
= xAccess
->getElementNames();
441 pNames
= lNames
.getConstArray();
442 c
= lNames
.getLength();
446 OUString sTemp
= pNames
[i
];
447 sal_Int32 nPos
= sTemp
.indexOf(".xml");
449 sTemp
= sTemp
.copy(0,nPos
);
450 lPresets
.push_back(sTemp
);
454 // read preset names of user layer
455 xAccess
= css::uno::Reference
< css::container::XNameAccess
>(xUser
, css::uno::UNO_QUERY
);
458 lNames
= xAccess
->getElementNames();
459 pNames
= lNames
.getConstArray();
460 c
= lNames
.getLength();
464 OUString sTemp
= pNames
[i
];
465 sal_Int32 nPos
= sTemp
.indexOf(".xml");
467 sTemp
= sTemp
.copy(0,nPos
);
468 lTargets
.push_back(sTemp
);
474 m_xWorkingStorageShare
= xShare
;
475 m_xWorkingStorageNoLang
= xNoLang
;
476 m_xWorkingStorageUser
= xUser
;
477 m_lPresets
= lPresets
;
478 m_lTargets
= lTargets
;
479 m_sRelPathShare
= sRelPathShare
;
480 m_sRelPathNoLang
= sRelPathNoLang
;
481 m_sRelPathUser
= sRelPathUser
;
485 catch(const css::uno::Exception
&)
487 css::uno::Any
ex(cppu::getCaughtException());
488 lcl_throwCorruptedUIConfigurationException(
489 ex
, ID_CORRUPT_UICONFIG_GENERAL
);
493 void PresetHandler::copyPresetToTarget(const OUString
& sPreset
,
494 const OUString
& sTarget
)
496 // dont check our preset list, if element exists
497 // We try to open it and forward all errors to the user!
499 css::uno::Reference
< css::embed::XStorage
> xWorkingShare
;
500 css::uno::Reference
< css::embed::XStorage
> xWorkingNoLang
;
501 css::uno::Reference
< css::embed::XStorage
> xWorkingUser
;
504 xWorkingShare
= m_xWorkingStorageShare
;
505 xWorkingNoLang
= m_xWorkingStorageNoLang
;
506 xWorkingUser
= m_xWorkingStorageUser
;
509 // e.g. module without any config data ?!
511 (!xWorkingShare
.is()) ||
512 (!xWorkingUser
.is() )
518 OUString
sPresetFile(sPreset
);
519 sPresetFile
+= ".xml";
521 OUString
sTargetFile(sTarget
);
522 sTargetFile
+= ".xml";
524 // remove existing elements before you try to copy the preset to that location ...
525 // Otherwise w will get an ElementExistException inside copyElementTo()!
526 css::uno::Reference
< css::container::XNameAccess
> xCheckingUser(xWorkingUser
, css::uno::UNO_QUERY_THROW
);
527 if (xCheckingUser
->hasByName(sTargetFile
))
528 xWorkingUser
->removeElement(sTargetFile
);
530 xWorkingShare
->copyElementTo(sPresetFile
, xWorkingUser
, sTargetFile
);
532 // If our storages work in transacted mode, we have
533 // to commit all changes from bottom to top!
537 css::uno::Reference
< css::io::XStream
> PresetHandler::openPreset(const OUString
& sPreset
,
538 bool bUseNoLangGlobal
)
540 css::uno::Reference
< css::embed::XStorage
> xFolder
;
543 xFolder
= bUseNoLangGlobal
? m_xWorkingStorageNoLang
: m_xWorkingStorageShare
;
546 // e.g. module without any config data ?!
548 return css::uno::Reference
< css::io::XStream
>();
550 OUString
sFile(sPreset
);
553 // inform user about errors (use original exceptions!)
554 css::uno::Reference
< css::io::XStream
> xStream
= xFolder
->openStreamElement(sFile
, css::embed::ElementModes::READ
);
558 css::uno::Reference
< css::io::XStream
> PresetHandler::openTarget(const OUString
& sTarget
,
559 bool bCreateIfMissing
)
561 css::uno::Reference
< css::embed::XStorage
> xFolder
;
564 xFolder
= m_xWorkingStorageUser
;
567 // e.g. module without any config data ?!
569 return css::uno::Reference
< css::io::XStream
>();
571 OUString
sFile(sTarget
);
574 sal_Int32 nOpenMode
= css::embed::ElementModes::READWRITE
;
575 if (!bCreateIfMissing
)
576 nOpenMode
|= css::embed::ElementModes::NOCREATE
;
578 // try it in read/write mode first and ignore errors.
579 css::uno::Reference
< css::io::XStream
> xStream
;
582 xStream
= xFolder
->openStreamElement(sFile
, nOpenMode
);
585 catch(const css::uno::RuntimeException
&)
587 catch(const css::uno::Exception
&)
590 // try it readonly if it failed before.
591 // inform user about errors (use original exceptions!)
592 nOpenMode
&= ~css::embed::ElementModes::WRITE
;
593 xStream
= xFolder
->openStreamElement(sFile
, nOpenMode
);
598 void PresetHandler::commitUserChanges()
600 css::uno::Reference
< css::embed::XStorage
> xWorking
;
601 EConfigType eCfgType
;
604 xWorking
= m_xWorkingStorageUser
;
605 eCfgType
= m_eConfigType
;
608 // e.g. module without any config data ?!
619 sPath
= m_aSharedStorages
->m_lStoragesUser
.getPathOfStorage(xWorking
);
620 m_aSharedStorages
->m_lStoragesUser
.commitPath(sPath
);
621 m_aSharedStorages
->m_lStoragesUser
.notifyPath(sPath
);
627 sPath
= m_lDocumentStorages
.getPathOfStorage(xWorking
);
628 m_lDocumentStorages
.commitPath(sPath
);
629 m_lDocumentStorages
.notifyPath(sPath
);
635 void PresetHandler::addStorageListener(IStorageListener
* pListener
)
638 EConfigType eCfgType
;
641 sRelPath
= m_sRelPathUser
; // use user path ... because we dont work directly on the share layer!
642 eCfgType
= m_eConfigType
;
645 if (sRelPath
.isEmpty())
653 m_aSharedStorages
->m_lStoragesUser
.addStorageListener(pListener
, sRelPath
);
659 m_lDocumentStorages
.addStorageListener(pListener
, sRelPath
);
665 void PresetHandler::removeStorageListener(IStorageListener
* pListener
)
668 EConfigType eCfgType
;
671 sRelPath
= m_sRelPathUser
; // use user path ... because we dont work directly on the share layer!
672 eCfgType
= m_eConfigType
;
675 if (sRelPath
.isEmpty())
683 m_aSharedStorages
->m_lStoragesUser
.removeStorageListener(pListener
, sRelPath
);
689 m_lDocumentStorages
.removeStorageListener(pListener
, sRelPath
);
695 css::uno::Reference
< css::embed::XStorage
> PresetHandler::impl_openPathIgnoringErrors(const OUString
& sPath
,
699 css::uno::Reference
< css::embed::XStorage
> xPath
;
703 xPath
= m_aSharedStorages
->m_lStoragesShare
.openPath(sPath
, eMode
);
705 xPath
= m_aSharedStorages
->m_lStoragesUser
.openPath(sPath
, eMode
);
707 catch(const css::uno::RuntimeException
&)
709 catch(const css::uno::Exception
&)
714 ::std::vector
< OUString
>::const_iterator
PresetHandler::impl_findMatchingLocalizedValue(
715 const ::std::vector
< OUString
>& lLocalizedValues
,
716 OUString
& rLanguageTag
,
717 bool bAllowFallbacks
)
719 ::std::vector
< OUString
>::const_iterator pFound
= lLocalizedValues
.end();
722 pFound
= LanguageTag::getFallback(lLocalizedValues
, rLanguageTag
);
723 // if we found a valid locale ... take it over to our in/out parameter
725 if (pFound
!= lLocalizedValues
.end())
727 rLanguageTag
= *pFound
;
732 for ( pFound
= lLocalizedValues
.begin();
733 pFound
!= lLocalizedValues
.end();
736 if (*pFound
== rLanguageTag
)
744 css::uno::Reference
< css::embed::XStorage
> PresetHandler::impl_openLocalizedPathIgnoringErrors(
748 OUString
& rLanguageTag
,
751 css::uno::Reference
< css::embed::XStorage
> xPath
= impl_openPathIgnoringErrors(sPath
, eMode
, bShare
);
752 ::std::vector
< OUString
> lSubFolders
= impl_getSubFolderNames(xPath
);
753 ::std::vector
< OUString
>::const_iterator pLocaleFolder
= impl_findMatchingLocalizedValue(lSubFolders
, rLanguageTag
, bAllowFallback
);
755 // no fallback ... creation not allowed => no storage
757 (pLocaleFolder
== lSubFolders
.end() ) &&
758 ((eMode
& css::embed::ElementModes::NOCREATE
) == css::embed::ElementModes::NOCREATE
)
760 return css::uno::Reference
< css::embed::XStorage
>();
762 // it doesn't matter, if there is a locale fallback or not
763 // If creation of storages is allowed, we do it anyway.
764 // Otherwhise we have no acc config at all, which can make other trouble.
765 OUString sLocalizedPath
;
766 sLocalizedPath
= sPath
;
767 sLocalizedPath
+= "/";
768 if (pLocaleFolder
!= lSubFolders
.end())
769 sLocalizedPath
+= *pLocaleFolder
;
771 sLocalizedPath
+= rLanguageTag
;
773 css::uno::Reference
< css::embed::XStorage
> xLocalePath
= impl_openPathIgnoringErrors(sLocalizedPath
, eMode
, bShare
);
775 if (xLocalePath
.is())
776 sPath
= sLocalizedPath
;
783 ::std::vector
< OUString
> PresetHandler::impl_getSubFolderNames(const css::uno::Reference
< css::embed::XStorage
>& xFolder
)
785 css::uno::Reference
< css::container::XNameAccess
> xAccess(xFolder
, css::uno::UNO_QUERY
);
787 return ::std::vector
< OUString
>();
789 ::std::vector
< OUString
> lSubFolders
;
790 const css::uno::Sequence
< OUString
> lNames
= xAccess
->getElementNames();
791 const OUString
* pNames
= lNames
.getConstArray();
792 sal_Int32 c
= lNames
.getLength();
799 if (xFolder
->isStorageElement(pNames
[i
]))
800 lSubFolders
.push_back(pNames
[i
]);
802 catch(const css::uno::RuntimeException
&)
804 catch(const css::uno::Exception
&)
811 } // namespace framework
813 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */