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"
25 #include <threadhelp/readguard.hxx>
26 #include <threadhelp/writeguard.hxx>
29 #include <com/sun/star/beans/XPropertySet.hpp>
30 #include <com/sun/star/configuration/CorruptedUIConfigurationException.hpp>
31 #include <com/sun/star/container/NoSuchElementException.hpp>
32 #include <com/sun/star/container/XNameAccess.hpp>
33 #include <com/sun/star/embed/ElementModes.hpp>
34 #include <com/sun/star/embed/XTransactedObject.hpp>
35 #include <com/sun/star/embed/FileSystemStorageFactory.hpp>
36 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
37 #include <com/sun/star/util/PathSettings.hpp>
39 #include <vcl/svapp.hxx>
40 #include <cppuhelper/exc_hlp.hxx>
41 #include <rtl/ustrbuf.hxx>
42 #include <i18nlangtag/languagetag.hxx>
45 #define SUBSTORAGE_GLOBAL DECLARE_ASCII("global" )
46 #define SUBSTORAGE_MODULES DECLARE_ASCII("modules")
48 #define RELPATH_SHARE_LAYER DECLARE_ASCII("soffice.cfg")
49 #define RELPATH_USER_LAYER DECLARE_ASCII("soffice.cfg")
51 #define FILE_EXTENSION DECLARE_ASCII(".xml")
53 #define PATH_SEPARATOR DECLARE_ASCII("/")
55 static const ::sal_Int32 ID_CORRUPT_UICONFIG_SHARE
= 1;
56 static const ::sal_Int32 ID_CORRUPT_UICONFIG_USER
= 2;
57 static const ::sal_Int32 ID_CORRUPT_UICONFIG_GENERAL
= 3;
63 //-----------------------------------------------
64 OUString
PresetHandler::PRESET_DEFAULT()
66 return OUString("default");
69 //-----------------------------------------------
70 OUString
PresetHandler::TARGET_CURRENT()
72 return OUString("current");
75 //-----------------------------------------------
76 OUString
PresetHandler::RESOURCETYPE_MENUBAR()
78 return OUString("menubar");
81 //-----------------------------------------------
82 OUString
PresetHandler::RESOURCETYPE_TOOLBAR()
84 return OUString("toolbar");
87 //-----------------------------------------------
88 OUString
PresetHandler::RESOURCETYPE_ACCELERATOR()
90 return OUString("accelerator");
93 //-----------------------------------------------
94 OUString
PresetHandler::RESOURCETYPE_STATUSBAR()
96 return OUString("statusbar");
99 //-----------------------------------------------
100 PresetHandler::PresetHandler(const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
)
101 : ThreadHelpBase (&Application::GetSolarMutex() )
103 , m_aSharedStorages ( )
104 , m_lDocumentStorages()
105 , m_aLanguageTag (LANGUAGE_USER_PRIV_NOTRANSLATE
)
109 //-----------------------------------------------
110 PresetHandler::PresetHandler(const PresetHandler
& rCopy
)
111 : ThreadHelpBase (&Application::GetSolarMutex() )
112 , m_aLanguageTag( rCopy
.m_aLanguageTag
)
114 m_xSMGR
= rCopy
.m_xSMGR
;
115 m_eConfigType
= rCopy
.m_eConfigType
;
116 m_sResourceType
= rCopy
.m_sResourceType
;
117 m_sModule
= rCopy
.m_sModule
;
118 m_aSharedStorages
= rCopy
.m_aSharedStorages
;
119 m_xWorkingStorageShare
= rCopy
.m_xWorkingStorageShare
;
120 m_xWorkingStorageNoLang
= rCopy
.m_xWorkingStorageNoLang
;
121 m_xWorkingStorageUser
= rCopy
.m_xWorkingStorageUser
;
122 m_lPresets
= rCopy
.m_lPresets
;
123 m_lTargets
= rCopy
.m_lTargets
;
124 m_lDocumentStorages
= rCopy
.m_lDocumentStorages
;
125 m_sRelPathShare
= rCopy
.m_sRelPathShare
;
126 m_sRelPathNoLang
= rCopy
.m_sRelPathNoLang
;
127 m_sRelPathUser
= rCopy
.m_sRelPathUser
;
130 //-----------------------------------------------
131 PresetHandler::~PresetHandler()
133 m_xWorkingStorageShare
.clear();
134 m_xWorkingStorageNoLang
.clear();
135 m_xWorkingStorageUser
.clear();
138 Dont call forgetCachedStorages() here for shared storages.
139 Because we opened different sub storages by using openPath().
140 And every already open path was reused and referenced (means it's
141 ref count was increased!)
142 So now we have to release our ref counts to these shared storages
143 only ... and not to free all used storages.
144 Otherwise we will disconnect all other open configuration access
145 objects which base on these storages.
147 m_aSharedStorages
->m_lStoragesShare
.closePath(m_sRelPathShare
);
148 m_aSharedStorages
->m_lStoragesUser
.closePath (m_sRelPathUser
);
150 /* On the other side closePath() is not needed for our special handled
151 document storage. Because it's not shared with others ... so we can
154 m_lDocumentStorages
.forgetCachedStorages();
157 //-----------------------------------------------
158 void PresetHandler::forgetCachedStorages()
160 // SAFE -> ----------------------------------
161 WriteGuard
aWriteLock(m_aLock
);
163 if (m_eConfigType
== E_DOCUMENT
)
165 m_xWorkingStorageShare
.clear();
166 m_xWorkingStorageNoLang
.clear();
167 m_xWorkingStorageUser
.clear();
170 m_lDocumentStorages
.forgetCachedStorages();
173 // <- SAFE ----------------------------------
178 OUString
lcl_getLocalizedMessage(::sal_Int32 nID
)
180 OUString
sMessage("Unknown error.");
184 case ID_CORRUPT_UICONFIG_SHARE
:
185 sMessage
= OUString( String( FwkResId( STR_CORRUPT_UICFG_SHARE
)));
189 case ID_CORRUPT_UICONFIG_USER
:
190 sMessage
= OUString( String( FwkResId( STR_CORRUPT_UICFG_USER
)));
193 case ID_CORRUPT_UICONFIG_GENERAL
:
194 sMessage
= OUString( String( FwkResId( STR_CORRUPT_UICFG_GENERAL
)));
201 void lcl_throwCorruptedUIConfigurationException(
202 css::uno::Any
const & exception
, sal_Int32 id
)
204 css::uno::Exception e
;
205 bool ok
= (exception
>>= e
);
206 OSL_ASSERT(ok
); (void) ok
; // avoid warnings
207 throw css::configuration::CorruptedUIConfigurationException(
208 lcl_getLocalizedMessage(id
),
209 css::uno::Reference
< css::uno::XInterface
>(),
210 (exception
.getValueTypeName() +
211 OUString(": \"") + e
.Message
+
217 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getOrCreateRootStorageShare()
219 css::uno::Reference
< css::embed::XStorage
> xRoot
= m_aSharedStorages
->m_lStoragesShare
.getRootStorage();
223 // SAFE -> ----------------------------------
224 ReadGuard
aReadLock(m_aLock
);
225 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xSMGR
;
227 // <- SAFE ----------------------------------
229 css::uno::Reference
< css::util::XPathSettings
> xPathSettings
=
230 css::util::PathSettings::create( comphelper::getComponentContext(xSMGR
) );
232 OUString sShareLayer
= xPathSettings
->getBasePathShareLayer();
234 // "UIConfig" is a "multi path" ... use first part only here!
235 sal_Int32 nPos
= sShareLayer
.indexOf(';');
237 sShareLayer
= sShareLayer
.copy(0, nPos
);
239 // Note: May be an user uses URLs without a final slash! Check it ...
240 nPos
= sShareLayer
.lastIndexOf('/');
241 if (nPos
!= sShareLayer
.getLength()-1)
242 sShareLayer
+= OUString("/");
244 sShareLayer
+= RELPATH_SHARE_LAYER
; // folder
247 // Attention: This is temp. workaround ... We create a temp. storage file
248 // based of a sytem directory. This must be used so, till the storage implementation
249 // can work on directories too.
251 css::uno::Sequence
< css::uno::Any
> lArgs(2);
252 lArgs
[0] <<= sShareLayer
;
253 lArgs
[1] <<= css::embed::ElementModes::READ
| css::embed::ElementModes::NOCREATE
;
255 css::uno::Reference
< css::lang::XSingleServiceFactory
> xStorageFactory
= css::embed::FileSystemStorageFactory::create( comphelper::getComponentContext(xSMGR
) );
256 css::uno::Reference
< css::embed::XStorage
> xStorage
;
260 xStorage
= css::uno::Reference
< css::embed::XStorage
>(xStorageFactory
->createInstanceWithArguments(lArgs
), css::uno::UNO_QUERY_THROW
);
262 catch(const css::uno::Exception
&)
264 css::uno::Any
ex(cppu::getCaughtException());
265 lcl_throwCorruptedUIConfigurationException(
266 ex
, ID_CORRUPT_UICONFIG_SHARE
);
269 m_aSharedStorages
->m_lStoragesShare
.setRootStorage(xStorage
);
274 //-----------------------------------------------
275 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getOrCreateRootStorageUser()
277 css::uno::Reference
< css::embed::XStorage
> xRoot
= m_aSharedStorages
->m_lStoragesUser
.getRootStorage();
281 // SAFE -> ----------------------------------
282 ReadGuard
aReadLock(m_aLock
);
283 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xSMGR
;
285 // <- SAFE ----------------------------------
287 css::uno::Reference
< css::util::XPathSettings
> xPathSettings
=
288 css::util::PathSettings::create( comphelper::getComponentContext(xSMGR
) );
290 OUString sUserLayer
= xPathSettings
->getBasePathUserLayer();
292 // Note: May be an user uses URLs without a final slash! Check it ...
293 sal_Int32 nPos
= sUserLayer
.lastIndexOf('/');
294 if (nPos
!= sUserLayer
.getLength()-1)
295 sUserLayer
+= OUString("/");
297 sUserLayer
+= RELPATH_USER_LAYER
; // storage file
299 css::uno::Sequence
< css::uno::Any
> lArgs(2);
300 lArgs
[0] <<= sUserLayer
;
301 lArgs
[1] <<= css::embed::ElementModes::READWRITE
;
303 css::uno::Reference
< css::lang::XSingleServiceFactory
> xStorageFactory
= css::embed::FileSystemStorageFactory::create( comphelper::getComponentContext(xSMGR
) );
304 css::uno::Reference
< css::embed::XStorage
> xStorage
;
308 xStorage
= css::uno::Reference
< css::embed::XStorage
>(xStorageFactory
->createInstanceWithArguments(lArgs
), css::uno::UNO_QUERY_THROW
);
310 catch(const css::uno::Exception
&)
312 css::uno::Any
ex(cppu::getCaughtException());
313 lcl_throwCorruptedUIConfigurationException(
314 ex
, ID_CORRUPT_UICONFIG_USER
);
317 m_aSharedStorages
->m_lStoragesUser
.setRootStorage(xStorage
);
322 //-----------------------------------------------
323 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getWorkingStorageShare()
325 // SAFE -> ----------------------------------
326 ReadGuard
aReadLock(m_aLock
);
327 return m_xWorkingStorageShare
;
328 // <- SAFE ----------------------------------
331 //-----------------------------------------------
332 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getWorkingStorageUser()
334 // SAFE -> ----------------------------------
335 ReadGuard
aReadLock(m_aLock
);
336 return m_xWorkingStorageUser
;
337 // <- SAFE ----------------------------------
340 //-----------------------------------------------
341 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getParentStorageShare(const css::uno::Reference
< css::embed::XStorage
>& /*xChild*/)
343 // SAFE -> ----------------------------------
344 ReadGuard
aReadLock(m_aLock
);
345 css::uno::Reference
< css::embed::XStorage
> xWorking
= m_xWorkingStorageShare
;
347 // <- SAFE ----------------------------------
349 return m_aSharedStorages
->m_lStoragesShare
.getParentStorage(xWorking
);
352 //-----------------------------------------------
353 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getParentStorageUser(const css::uno::Reference
< css::embed::XStorage
>& /*xChild*/)
355 // SAFE -> ----------------------------------
356 ReadGuard
aReadLock(m_aLock
);
357 css::uno::Reference
< css::embed::XStorage
> xWorking
= m_xWorkingStorageUser
;
359 // <- SAFE ----------------------------------
361 return m_aSharedStorages
->m_lStoragesUser
.getParentStorage(xWorking
);
364 //-----------------------------------------------
365 void PresetHandler::connectToResource( PresetHandler::EConfigType eConfigType
,
366 const OUString
& sResource
,
367 const OUString
& sModule
,
368 const css::uno::Reference
< css::embed::XStorage
>& xDocumentRoot
,
369 const LanguageTag
& rLanguageTag
)
371 // TODO free all current open storages!
373 // SAFE -> ----------------------------------
374 WriteGuard
aWriteLock(m_aLock
);
376 m_eConfigType
= eConfigType
;
377 m_sResourceType
= sResource
;
378 m_sModule
= sModule
;
379 m_aLanguageTag
= rLanguageTag
;
382 // <- SAFE ----------------------------------
384 css::uno::Reference
< css::embed::XStorage
> xShare
;
385 css::uno::Reference
< css::embed::XStorage
> xNoLang
;
386 css::uno::Reference
< css::embed::XStorage
> xUser
;
388 // special case for documents
389 // use outside root storage, if we run in E_DOCUMENT mode!
390 if (eConfigType
== E_DOCUMENT
)
392 if (!xDocumentRoot
.is())
393 throw css::uno::RuntimeException(
394 OUString("There is valid root storage, where the UI configuration can work on."),
395 css::uno::Reference
< css::uno::XInterface
>());
396 m_lDocumentStorages
.setRootStorage(xDocumentRoot
);
397 xShare
= xDocumentRoot
;
398 xUser
= xDocumentRoot
;
402 xShare
= getOrCreateRootStorageShare();
403 xUser
= getOrCreateRootStorageUser();
410 // a) inside share layer we should not create any new structures ... We jave to use
411 // existing ones only!
412 // b) inside user layer we can (SOFT mode!) but sometimes we shouldnt (HARD mode!)
413 // create new empty structures. We should preferr using of any existing structure.
414 sal_Int32 eShareMode
= (css::embed::ElementModes::READ
| css::embed::ElementModes::NOCREATE
);
415 sal_Int32 eUserMode
= (css::embed::ElementModes::READWRITE
);
417 OUStringBuffer
sRelPathBuf(1024);
418 OUString sRelPathShare
;
419 OUString sRelPathNoLang
;
420 OUString sRelPathUser
;
425 sRelPathBuf
.append(SUBSTORAGE_GLOBAL
);
426 sRelPathBuf
.append(PATH_SEPARATOR
);
427 sRelPathBuf
.append(sResource
);
428 sRelPathShare
= sRelPathBuf
.makeStringAndClear();
429 sRelPathUser
= sRelPathShare
;
431 xShare
= impl_openPathIgnoringErrors(sRelPathShare
, eShareMode
, sal_True
);
432 xUser
= impl_openPathIgnoringErrors(sRelPathUser
, eUserMode
, sal_False
);
438 sRelPathBuf
.append(SUBSTORAGE_MODULES
);
439 sRelPathBuf
.append(PATH_SEPARATOR
);
440 sRelPathBuf
.append(sModule
);
441 sRelPathBuf
.append(PATH_SEPARATOR
);
442 sRelPathBuf
.append(sResource
);
443 sRelPathShare
= sRelPathBuf
.makeStringAndClear();
444 sRelPathUser
= sRelPathShare
;
446 xShare
= impl_openPathIgnoringErrors(sRelPathShare
, eShareMode
, sal_True
);
447 xUser
= impl_openPathIgnoringErrors(sRelPathUser
, eUserMode
, sal_False
);
453 // A document does not have a share layer in real.
454 // It has one layer only, and this one should be opened READ_WRITE.
455 // So we open the user layer here only and set the share layer equals to it .-)
457 sRelPathBuf
.append(sResource
);
458 sRelPathUser
= sRelPathBuf
.makeStringAndClear();
459 sRelPathShare
= sRelPathUser
;
463 xUser
= m_lDocumentStorages
.openPath(sRelPathUser
, eUserMode
);
466 catch(const css::uno::RuntimeException
&)
468 catch(const css::uno::Exception
&)
469 { xShare
.clear(); xUser
.clear(); }
474 // Non-localized global share
476 sRelPathNoLang
= sRelPathShare
;
479 (rLanguageTag
!= LanguageTag(LANGUAGE_USER_PRIV_NOTRANSLATE
)) && // localized level?
480 (eConfigType
!= E_DOCUMENT
) // no localization in document mode!
483 // First try to find the right localized set inside share layer.
484 // Fallbacks are allowed there.
485 OUString
aShareLocale( rLanguageTag
.getBcp47());
486 OUString
sLocalizedSharePath(sRelPathShare
);
487 sal_Bool bAllowFallbacks
= sal_True
;
488 xShare
= impl_openLocalizedPathIgnoringErrors(sLocalizedSharePath
, eShareMode
, sal_True
, aShareLocale
, bAllowFallbacks
);
490 // The try to locate the right sub dir inside user layer ... without using fallbacks!
491 // Normaly the corresponding sub dir should be created matching the specified locale.
492 // Because we allow creation of storages inside user layer by default.
493 OUString
aUserLocale( rLanguageTag
.getBcp47());
494 OUString
sLocalizedUserPath(sRelPathUser
);
495 bAllowFallbacks
= sal_False
;
496 xUser
= impl_openLocalizedPathIgnoringErrors(sLocalizedUserPath
, eUserMode
, sal_False
, aUserLocale
, bAllowFallbacks
);
498 sRelPathShare
= sLocalizedSharePath
;
499 sRelPathUser
= sLocalizedUserPath
;
502 // read content of level 3 (presets, targets)
503 css::uno::Reference
< css::container::XNameAccess
> xAccess
;
504 css::uno::Sequence
< OUString
> lNames
;
505 const OUString
* pNames
;
508 OUStringList lPresets
;
509 OUStringList lTargets
;
511 // read preset names of share layer
512 xAccess
= css::uno::Reference
< css::container::XNameAccess
>(xShare
, css::uno::UNO_QUERY
);
515 lNames
= xAccess
->getElementNames();
516 pNames
= lNames
.getConstArray();
517 c
= lNames
.getLength();
521 OUString sTemp
= pNames
[i
];
522 sal_Int32 nPos
= sTemp
.indexOf(FILE_EXTENSION
);
524 sTemp
= sTemp
.copy(0,nPos
);
525 lPresets
.push_back(sTemp
);
529 // read preset names of user layer
530 xAccess
= css::uno::Reference
< css::container::XNameAccess
>(xUser
, css::uno::UNO_QUERY
);
533 lNames
= xAccess
->getElementNames();
534 pNames
= lNames
.getConstArray();
535 c
= lNames
.getLength();
539 OUString sTemp
= pNames
[i
];
540 sal_Int32 nPos
= sTemp
.indexOf(FILE_EXTENSION
);
542 sTemp
= sTemp
.copy(0,nPos
);
543 lTargets
.push_back(sTemp
);
547 // SAFE -> ----------------------------------
550 m_xWorkingStorageShare
= xShare
;
551 m_xWorkingStorageNoLang
= xNoLang
;
552 m_xWorkingStorageUser
= xUser
;
553 m_lPresets
= lPresets
;
554 m_lTargets
= lTargets
;
555 m_sRelPathShare
= sRelPathShare
;
556 m_sRelPathNoLang
= sRelPathNoLang
;
557 m_sRelPathUser
= sRelPathUser
;
560 // <- SAFE ----------------------------------
563 catch(const css::uno::Exception
&)
565 css::uno::Any
ex(cppu::getCaughtException());
566 lcl_throwCorruptedUIConfigurationException(
567 ex
, ID_CORRUPT_UICONFIG_GENERAL
);
571 //-----------------------------------------------
572 void PresetHandler::copyPresetToTarget(const OUString
& sPreset
,
573 const OUString
& sTarget
)
575 // dont check our preset list, if element exists
576 // We try to open it and forward all errors to the user!
578 // SAFE -> ----------------------------------
579 ReadGuard
aReadLock(m_aLock
);
580 css::uno::Reference
< css::embed::XStorage
> xWorkingShare
= m_xWorkingStorageShare
;
581 css::uno::Reference
< css::embed::XStorage
> xWorkingNoLang
= m_xWorkingStorageNoLang
;
582 css::uno::Reference
< css::embed::XStorage
> xWorkingUser
= m_xWorkingStorageUser
;
584 // <- SAFE ----------------------------------
586 // e.g. module without any config data ?!
588 (!xWorkingShare
.is()) ||
589 (!xWorkingUser
.is() )
595 OUString
sPresetFile(sPreset
);
596 sPresetFile
+= FILE_EXTENSION
;
598 OUString
sTargetFile(sTarget
);
599 sTargetFile
+= FILE_EXTENSION
;
601 // remove existing elements before you try to copy the preset to that location ...
602 // Otherwise w will get an ElementExistException inside copyElementTo()!
603 css::uno::Reference
< css::container::XNameAccess
> xCheckingUser(xWorkingUser
, css::uno::UNO_QUERY_THROW
);
604 if (xCheckingUser
->hasByName(sTargetFile
))
605 xWorkingUser
->removeElement(sTargetFile
);
607 xWorkingShare
->copyElementTo(sPresetFile
, xWorkingUser
, sTargetFile
);
609 // If our storages work in transacted mode, we have
610 // to commit all changes from bottom to top!
614 //-----------------------------------------------
615 css::uno::Reference
< css::io::XStream
> PresetHandler::openPreset(const OUString
& sPreset
,
616 sal_Bool bUseNoLangGlobal
)
618 // SAFE -> ----------------------------------
619 ReadGuard
aReadLock(m_aLock
);
620 css::uno::Reference
< css::embed::XStorage
> xFolder
= bUseNoLangGlobal
? m_xWorkingStorageNoLang
: m_xWorkingStorageShare
;
622 // <- SAFE ----------------------------------
624 // e.g. module without any config data ?!
626 return css::uno::Reference
< css::io::XStream
>();
628 OUString
sFile(sPreset
);
629 sFile
+= FILE_EXTENSION
;
631 // inform user about errors (use original exceptions!)
632 css::uno::Reference
< css::io::XStream
> xStream
= xFolder
->openStreamElement(sFile
, css::embed::ElementModes::READ
);
636 //-----------------------------------------------
637 css::uno::Reference
< css::io::XStream
> PresetHandler::openTarget(const OUString
& sTarget
,
638 sal_Bool bCreateIfMissing
)
640 // SAFE -> ----------------------------------
641 ReadGuard
aReadLock(m_aLock
);
642 css::uno::Reference
< css::embed::XStorage
> xFolder
= m_xWorkingStorageUser
;
644 // <- SAFE ----------------------------------
646 // e.g. module without any config data ?!
648 return css::uno::Reference
< css::io::XStream
>();
650 OUString
sFile(sTarget
);
651 sFile
+= FILE_EXTENSION
;
653 sal_Int32 nOpenMode
= css::embed::ElementModes::READWRITE
;
654 if (!bCreateIfMissing
)
655 nOpenMode
|= css::embed::ElementModes::NOCREATE
;
657 // try it in read/write mode first and ignore errors.
658 css::uno::Reference
< css::io::XStream
> xStream
;
661 xStream
= xFolder
->openStreamElement(sFile
, nOpenMode
);
664 catch(const css::uno::RuntimeException
&)
666 catch(const css::uno::Exception
&)
669 // try it readonly if it failed before.
670 // inform user about errors (use original exceptions!)
671 nOpenMode
&= ~css::embed::ElementModes::WRITE
;
672 xStream
= xFolder
->openStreamElement(sFile
, nOpenMode
);
677 //-----------------------------------------------
678 void PresetHandler::commitUserChanges()
680 // SAFE -> ----------------------------------
681 ReadGuard
aReadLock(m_aLock
);
682 css::uno::Reference
< css::embed::XStorage
> xWorking
= m_xWorkingStorageUser
;
683 EConfigType eCfgType
= m_eConfigType
;
685 // <- SAFE ----------------------------------
687 // e.g. module without any config data ?!
698 sPath
= m_aSharedStorages
->m_lStoragesUser
.getPathOfStorage(xWorking
);
699 m_aSharedStorages
->m_lStoragesUser
.commitPath(sPath
);
700 m_aSharedStorages
->m_lStoragesUser
.notifyPath(sPath
);
706 sPath
= m_lDocumentStorages
.getPathOfStorage(xWorking
);
707 m_lDocumentStorages
.commitPath(sPath
);
708 m_lDocumentStorages
.notifyPath(sPath
);
714 //-----------------------------------------------
715 void PresetHandler::addStorageListener(IStorageListener
* pListener
)
717 // SAFE -> ----------------------------------
718 ReadGuard
aReadLock(m_aLock
);
719 OUString sRelPath
= m_sRelPathUser
; // use user path ... because we dont work directly on the share layer!
720 EConfigType eCfgType
= m_eConfigType
;
722 // <- SAFE ----------------------------------
724 if (sRelPath
.isEmpty())
732 m_aSharedStorages
->m_lStoragesUser
.addStorageListener(pListener
, sRelPath
);
738 m_lDocumentStorages
.addStorageListener(pListener
, sRelPath
);
744 //-----------------------------------------------
745 void PresetHandler::removeStorageListener(IStorageListener
* pListener
)
747 // SAFE -> ----------------------------------
748 ReadGuard
aReadLock(m_aLock
);
749 OUString sRelPath
= m_sRelPathUser
; // use user path ... because we dont work directly on the share layer!
750 EConfigType eCfgType
= m_eConfigType
;
752 // <- SAFE ----------------------------------
754 if (sRelPath
.isEmpty())
762 m_aSharedStorages
->m_lStoragesUser
.removeStorageListener(pListener
, sRelPath
);
768 m_lDocumentStorages
.removeStorageListener(pListener
, sRelPath
);
774 //-----------------------------------------------
775 css::uno::Reference
< css::embed::XStorage
> PresetHandler::impl_openPathIgnoringErrors(const OUString
& sPath
,
779 css::uno::Reference
< css::embed::XStorage
> xPath
;
783 xPath
= m_aSharedStorages
->m_lStoragesShare
.openPath(sPath
, eMode
);
785 xPath
= m_aSharedStorages
->m_lStoragesUser
.openPath(sPath
, eMode
);
787 catch(const css::uno::RuntimeException
&)
789 catch(const css::uno::Exception
&)
794 //-----------------------------------------------
795 ::std::vector
< OUString
>::const_iterator
PresetHandler::impl_findMatchingLocalizedValue(
796 const ::std::vector
< OUString
>& lLocalizedValues
,
797 OUString
& rLanguageTag
,
798 sal_Bool bAllowFallbacks
)
800 ::std::vector
< OUString
>::const_iterator pFound
= lLocalizedValues
.end();
803 pFound
= LanguageTag::getFallback(lLocalizedValues
, rLanguageTag
);
804 // if we found a valid locale ... take it over to our in/out parameter
806 if (pFound
!= lLocalizedValues
.end())
808 rLanguageTag
= *pFound
;
813 for ( pFound
= lLocalizedValues
.begin();
814 pFound
!= lLocalizedValues
.end() ;
817 if (*pFound
== rLanguageTag
)
825 //-----------------------------------------------
826 css::uno::Reference
< css::embed::XStorage
> PresetHandler::impl_openLocalizedPathIgnoringErrors(
830 OUString
& rLanguageTag
,
831 sal_Bool bAllowFallback
)
833 css::uno::Reference
< css::embed::XStorage
> xPath
= impl_openPathIgnoringErrors(sPath
, eMode
, bShare
);
834 ::std::vector
< OUString
> lSubFolders
= impl_getSubFolderNames(xPath
);
835 ::std::vector
< OUString
>::const_iterator pLocaleFolder
= impl_findMatchingLocalizedValue(lSubFolders
, rLanguageTag
, bAllowFallback
);
837 // no fallback ... creation not allowed => no storage
839 (pLocaleFolder
== lSubFolders
.end() ) &&
840 ((eMode
& css::embed::ElementModes::NOCREATE
) == css::embed::ElementModes::NOCREATE
)
842 return css::uno::Reference
< css::embed::XStorage
>();
844 // it doesnt matter, if there is a locale fallback or not
845 // If creation of storages is allowed, we do it anyway.
846 // Otherwhise we have no acc config at all, which can make other trouble.
847 OUString sLocalizedPath
;
848 sLocalizedPath
= sPath
;
849 sLocalizedPath
+= PATH_SEPARATOR
;
850 if (pLocaleFolder
!= lSubFolders
.end())
851 sLocalizedPath
+= *pLocaleFolder
;
853 sLocalizedPath
+= rLanguageTag
;
855 css::uno::Reference
< css::embed::XStorage
> xLocalePath
= impl_openPathIgnoringErrors(sLocalizedPath
, eMode
, bShare
);
857 if (xLocalePath
.is())
858 sPath
= sLocalizedPath
;
865 //-----------------------------------------------
866 ::std::vector
< OUString
> PresetHandler::impl_getSubFolderNames(const css::uno::Reference
< css::embed::XStorage
>& xFolder
)
868 css::uno::Reference
< css::container::XNameAccess
> xAccess(xFolder
, css::uno::UNO_QUERY
);
870 return ::std::vector
< OUString
>();
872 ::std::vector
< OUString
> lSubFolders
;
873 const css::uno::Sequence
< OUString
> lNames
= xAccess
->getElementNames();
874 const OUString
* pNames
= lNames
.getConstArray();
875 sal_Int32 c
= lNames
.getLength();
882 if (xFolder
->isStorageElement(pNames
[i
]))
883 lSubFolders
.push_back(pNames
[i
]);
885 catch(const css::uno::RuntimeException
&)
887 catch(const css::uno::Exception
&)
894 //-----------------------------------------------
895 } // namespace framework
897 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */