1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: presethandler.cxx,v $
10 * $Revision: 1.17.82.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_framework.hxx"
33 #include <accelerators/presethandler.hxx>
35 //_______________________________________________
37 #include <classes/fwkresid.hxx>
39 #include "classes/resource.hrc"
40 #include <threadhelp/readguard.hxx>
41 #include <threadhelp/writeguard.hxx>
44 //_______________________________________________
47 #ifndef __COM_SUN_STAR_CONFIGURATION_CORRUPTEDUICONFIGURATIONEXCEPTION_HPP_
48 #include <com/sun/star/configuration/CorruptedUIConfigurationException.hpp>
51 #ifndef __COM_SUN_STAR_CONTAINER_NOSUCHELEMENTEXCEPTION_HPP_
52 #include <com/sun/star/container/NoSuchElementException.hpp>
55 #ifndef __COM_SUN_STAR_CONTAINER_XNAMEACCESS_HPP_
56 #include <com/sun/star/container/XNameAccess.hpp>
59 #ifndef __COM_SUN_STAR_BEANS_XPROPERTYSET_HPP_
60 #include <com/sun/star/beans/XPropertySet.hpp>
63 #ifndef __COM_SUN_STAR_EMBED_ELEMENTMODES_HPP_
64 #include <com/sun/star/embed/ElementModes.hpp>
67 #ifndef __COM_SUN_STAR_EMBED_XTRANSACTEDOBJECT_HPP_
68 #include <com/sun/star/embed/XTransactedObject.hpp>
71 #ifndef __COM_SUN_STAR_LANG_XSINGLESERVICEFACTORY_HPP_
72 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
75 //_______________________________________________
77 #include <vcl/svapp.hxx>
79 #ifndef _RTL_USTRBUF_HXX
80 #include <rtl/ustrbuf.hxx>
83 //_______________________________________________
86 #define SUBSTORAGE_GLOBAL DECLARE_ASCII("global" )
87 #define SUBSTORAGE_MODULES DECLARE_ASCII("modules")
89 #define BASEPATH_SHARE_LAYER DECLARE_ASCII("UIConfig" )
90 #define BASEPATH_USER_LAYER DECLARE_ASCII("UserConfig")
92 #define RELPATH_SHARE_LAYER DECLARE_ASCII("soffice.cfg")
93 #define RELPATH_USER_LAYER DECLARE_ASCII("soffice.cfg")
94 // #define RELPATH_SHARE_LAYER DECLARE_ASCII("soffice.cfg/uiconfig.zip")
95 // #define RELPATH_USER_LAYER DECLARE_ASCII("soffice.cfg/uiconfig.zip")
97 #define FILE_EXTENSION DECLARE_ASCII(".xml")
99 #define PATH_SEPERATOR DECLARE_ASCII("/")
101 static const ::sal_Int32 ID_CORRUPT_UICONFIG_SHARE
= 1;
102 static const ::sal_Int32 ID_CORRUPT_UICONFIG_USER
= 2;
103 static const ::sal_Int32 ID_CORRUPT_UICONFIG_GENERAL
= 3;
105 //_______________________________________________
111 //-----------------------------------------------
112 ::rtl::OUString
PresetHandler::PRESET_DEFAULT()
114 static ::rtl::OUString RSTYPE
= DECLARE_ASCII("default");
118 //-----------------------------------------------
119 ::rtl::OUString
PresetHandler::TARGET_CURRENT()
121 static ::rtl::OUString RSTYPE
= DECLARE_ASCII("current");
125 //-----------------------------------------------
126 ::rtl::OUString
PresetHandler::RESOURCETYPE_MENUBAR()
128 static ::rtl::OUString RSTYPE
= DECLARE_ASCII("menubar");
132 //-----------------------------------------------
133 ::rtl::OUString
PresetHandler::RESOURCETYPE_TOOLBAR()
135 static ::rtl::OUString RSTYPE
= DECLARE_ASCII("toolbar");
139 //-----------------------------------------------
140 ::rtl::OUString
PresetHandler::RESOURCETYPE_ACCELERATOR()
142 static ::rtl::OUString RSTYPE
= DECLARE_ASCII("accelerator");
146 //-----------------------------------------------
147 ::rtl::OUString
PresetHandler::RESOURCETYPE_STATUSBAR()
149 static ::rtl::OUString RSTYPE
= DECLARE_ASCII("statusbar");
153 //-----------------------------------------------
154 PresetHandler::PresetHandler(const css::uno::Reference
< css::lang::XMultiServiceFactory
>& xSMGR
)
155 : ThreadHelpBase (&Application::GetSolarMutex() )
157 , m_aSharedStorages ( )
158 , m_lDocumentStorages(xSMGR
)
159 , m_aLocale (::comphelper::Locale::X_NOTRANSLATE())
163 //-----------------------------------------------
164 PresetHandler::PresetHandler(const PresetHandler
& rCopy
)
165 : ThreadHelpBase (&Application::GetSolarMutex() )
167 m_xSMGR
= rCopy
.m_xSMGR
;
168 m_eConfigType
= rCopy
.m_eConfigType
;
169 m_sResourceType
= rCopy
.m_sResourceType
;
170 m_sModule
= rCopy
.m_sModule
;
171 m_aSharedStorages
= rCopy
.m_aSharedStorages
;
172 m_xWorkingStorageShare
= rCopy
.m_xWorkingStorageShare
;
173 m_xWorkingStorageNoLang
= rCopy
.m_xWorkingStorageNoLang
;
174 m_xWorkingStorageUser
= rCopy
.m_xWorkingStorageUser
;
175 m_lPresets
= rCopy
.m_lPresets
;
176 m_lTargets
= rCopy
.m_lTargets
;
177 m_aLocale
= rCopy
.m_aLocale
;
178 m_lDocumentStorages
= rCopy
.m_lDocumentStorages
;
179 m_sRelPathShare
= rCopy
.m_sRelPathShare
;
180 m_sRelPathNoLang
= rCopy
.m_sRelPathNoLang
;
181 m_sRelPathUser
= rCopy
.m_sRelPathUser
;
184 //-----------------------------------------------
185 PresetHandler::~PresetHandler()
187 m_xWorkingStorageShare
.clear();
188 m_xWorkingStorageNoLang
.clear();
189 m_xWorkingStorageUser
.clear();
192 Dont call forgetCachedStorages() here for shared storages.
193 Because we opened different sub storages by using openPath().
194 And every already open path was reused and referenced (means it's
195 ref count was increased!)
196 So now we have to release our ref counts to these shared storages
197 only ... and not to free all used storages.
198 Otherwise we will disconnect all other open configuration access
199 objects which base on these storages.
201 m_aSharedStorages
->m_lStoragesShare
.closePath(m_sRelPathShare
);
202 m_aSharedStorages
->m_lStoragesUser
.closePath (m_sRelPathUser
);
204 /* On the other side closePath() is not needed for our special handled
205 document storage. Because it's not shared with others ... so we can
208 m_lDocumentStorages
.forgetCachedStorages();
211 //-----------------------------------------------
212 void PresetHandler::forgetCachedStorages()
214 // SAFE -> ----------------------------------
215 WriteGuard
aWriteLock(m_aLock
);
217 if (m_eConfigType
== E_DOCUMENT
)
219 m_xWorkingStorageShare
.clear();
220 m_xWorkingStorageNoLang
.clear();
221 m_xWorkingStorageUser
.clear();
224 m_lDocumentStorages
.forgetCachedStorages();
227 // <- SAFE ----------------------------------
230 //-----------------------------------------------
231 ::rtl::OUString
lcl_getLocalizedMessage(::sal_Int32 nID
)
233 ::rtl::OUString sMessage
= ::rtl::OUString::createFromAscii("Unknown error.");
237 case ID_CORRUPT_UICONFIG_SHARE
:
238 sMessage
= ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_SHARE
)));
241 case ID_CORRUPT_UICONFIG_USER
:
242 sMessage
= ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_USER
)));
245 case ID_CORRUPT_UICONFIG_GENERAL
:
246 sMessage
= ::rtl::OUString( String( FwkResId( STR_CORRUPT_UICFG_GENERAL
)));
253 //-----------------------------------------------
254 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getOrCreateRootStorageShare()
256 css::uno::Reference
< css::embed::XStorage
> xRoot
= m_aSharedStorages
->m_lStoragesShare
.getRootStorage();
260 // SAFE -> ----------------------------------
261 ReadGuard
aReadLock(m_aLock
);
262 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xSMGR
;
264 // <- SAFE ----------------------------------
266 css::uno::Reference
< css::beans::XPropertySet
> xPathSettings(
267 xSMGR
->createInstance(SERVICENAME_PATHSETTINGS
),
268 css::uno::UNO_QUERY_THROW
);
270 ::rtl::OUString sShareLayer
;
271 xPathSettings
->getPropertyValue(BASEPATH_SHARE_LAYER
) >>= sShareLayer
;
273 // "UIConfig" is a "multi path" ... use first part only here!
274 sal_Int32 nPos
= sShareLayer
.indexOf(';');
276 sShareLayer
= sShareLayer
.copy(0, nPos
);
278 // Note: May be an user uses URLs without a final slash! Check it ...
279 nPos
= sShareLayer
.lastIndexOf('/');
280 if (nPos
!= sShareLayer
.getLength()-1)
281 sShareLayer
+= ::rtl::OUString::createFromAscii("/");
283 sShareLayer
+= RELPATH_SHARE_LAYER
; // folder
286 // Attention: This is temp. workaround ... We create a temp. storage file
287 // based of a sytem directory. This must be used so, till the storage implementation
288 // can work on directories too.
290 css::uno::Sequence
< css::uno::Any
> lArgs(2);
291 lArgs
[0] <<= sShareLayer
;
292 lArgs
[1] <<= css::embed::ElementModes::READ
| css::embed::ElementModes::NOCREATE
;
294 css::uno::Reference
< css::lang::XSingleServiceFactory
> xStorageFactory(xSMGR
->createInstance(SERVICENAME_FILESYSTEMSTORAGEFACTORY
) , css::uno::UNO_QUERY_THROW
);
295 css::uno::Reference
< css::embed::XStorage
> xStorage
;
299 xStorage
= css::uno::Reference
< css::embed::XStorage
>(xStorageFactory
->createInstanceWithArguments(lArgs
), css::uno::UNO_QUERY_THROW
);
301 catch(const css::uno::Exception
& ex
)
303 throw css::configuration::CorruptedUIConfigurationException(
304 lcl_getLocalizedMessage(ID_CORRUPT_UICONFIG_SHARE
),
305 css::uno::Reference
< css::uno::XInterface
>(),
309 m_aSharedStorages
->m_lStoragesShare
.setRootStorage(xStorage
);
314 //-----------------------------------------------
315 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getOrCreateRootStorageUser()
317 css::uno::Reference
< css::embed::XStorage
> xRoot
= m_aSharedStorages
->m_lStoragesUser
.getRootStorage();
321 // SAFE -> ----------------------------------
322 ReadGuard
aReadLock(m_aLock
);
323 css::uno::Reference
< css::lang::XMultiServiceFactory
> xSMGR
= m_xSMGR
;
325 // <- SAFE ----------------------------------
327 css::uno::Reference
< css::beans::XPropertySet
> xPathSettings(
328 xSMGR
->createInstance(SERVICENAME_PATHSETTINGS
),
329 css::uno::UNO_QUERY_THROW
);
331 ::rtl::OUString sUserLayer
;
332 xPathSettings
->getPropertyValue(BASEPATH_USER_LAYER
) >>= sUserLayer
;
334 // Note: May be an user uses URLs without a final slash! Check it ...
335 sal_Int32 nPos
= sUserLayer
.lastIndexOf('/');
336 if (nPos
!= sUserLayer
.getLength()-1)
337 sUserLayer
+= ::rtl::OUString::createFromAscii("/");
339 sUserLayer
+= RELPATH_USER_LAYER
; // storage file
341 css::uno::Sequence
< css::uno::Any
> lArgs(2);
342 lArgs
[0] <<= sUserLayer
;
343 lArgs
[1] <<= css::embed::ElementModes::READWRITE
;
345 css::uno::Reference
< css::lang::XSingleServiceFactory
> xStorageFactory(xSMGR
->createInstance(SERVICENAME_FILESYSTEMSTORAGEFACTORY
) , css::uno::UNO_QUERY_THROW
);
346 css::uno::Reference
< css::embed::XStorage
> xStorage
;
350 xStorage
= css::uno::Reference
< css::embed::XStorage
>(xStorageFactory
->createInstanceWithArguments(lArgs
), css::uno::UNO_QUERY_THROW
);
352 catch(const css::uno::Exception
& ex
)
354 throw css::configuration::CorruptedUIConfigurationException(
355 lcl_getLocalizedMessage(ID_CORRUPT_UICONFIG_USER
),
356 css::uno::Reference
< css::uno::XInterface
>(),
360 m_aSharedStorages
->m_lStoragesUser
.setRootStorage(xStorage
);
365 //-----------------------------------------------
366 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getWorkingStorageShare()
368 // SAFE -> ----------------------------------
369 ReadGuard
aReadLock(m_aLock
);
370 return m_xWorkingStorageShare
;
371 // <- SAFE ----------------------------------
374 //-----------------------------------------------
375 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getWorkingStorageUser()
377 // SAFE -> ----------------------------------
378 ReadGuard
aReadLock(m_aLock
);
379 return m_xWorkingStorageUser
;
380 // <- SAFE ----------------------------------
383 //-----------------------------------------------
384 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getParentStorageShare(const css::uno::Reference
< css::embed::XStorage
>& /*xChild*/)
386 // SAFE -> ----------------------------------
387 ReadGuard
aReadLock(m_aLock
);
388 css::uno::Reference
< css::embed::XStorage
> xWorking
= m_xWorkingStorageShare
;
390 // <- SAFE ----------------------------------
392 return m_aSharedStorages
->m_lStoragesShare
.getParentStorage(xWorking
);
395 //-----------------------------------------------
396 css::uno::Reference
< css::embed::XStorage
> PresetHandler::getParentStorageUser(const css::uno::Reference
< css::embed::XStorage
>& /*xChild*/)
398 // SAFE -> ----------------------------------
399 ReadGuard
aReadLock(m_aLock
);
400 css::uno::Reference
< css::embed::XStorage
> xWorking
= m_xWorkingStorageUser
;
402 // <- SAFE ----------------------------------
404 return m_aSharedStorages
->m_lStoragesUser
.getParentStorage(xWorking
);
407 //-----------------------------------------------
408 void PresetHandler::connectToResource( PresetHandler::EConfigType eConfigType
,
409 const ::rtl::OUString
& sResource
,
410 const ::rtl::OUString
& sModule
,
411 const css::uno::Reference
< css::embed::XStorage
>& xDocumentRoot
,
412 const ::comphelper::Locale
& aLocale
)
414 // TODO free all current open storages!
416 // SAFE -> ----------------------------------
417 WriteGuard
aWriteLock(m_aLock
);
419 m_eConfigType
= eConfigType
;
420 m_sResourceType
= sResource
;
421 m_sModule
= sModule
;
422 m_aLocale
= aLocale
;
425 // <- SAFE ----------------------------------
427 css::uno::Reference
< css::embed::XStorage
> xShare
;
428 css::uno::Reference
< css::embed::XStorage
> xNoLang
;
429 css::uno::Reference
< css::embed::XStorage
> xUser
;
431 // special case for documents
432 // use outside root storage, if we run in E_DOCUMENT mode!
433 if (eConfigType
== E_DOCUMENT
)
435 if (!xDocumentRoot
.is())
436 throw css::uno::RuntimeException(
437 ::rtl::OUString::createFromAscii("There is valid root storage, where the UI configuration can work on."),
438 css::uno::Reference
< css::uno::XInterface
>());
439 m_lDocumentStorages
.setRootStorage(xDocumentRoot
);
440 xShare
= xDocumentRoot
;
441 xUser
= xDocumentRoot
;
445 xShare
= getOrCreateRootStorageShare();
446 xUser
= getOrCreateRootStorageUser();
453 // a) inside share layer we should not create any new structures ... We jave to use
454 // existing ones only!
455 // b) inside user layer we can (SOFT mode!) but sometimes we shouldnt (HARD mode!)
456 // create new empty structures. We should preferr using of any existing structure.
457 sal_Int32 eShareMode
= (css::embed::ElementModes::READ
| css::embed::ElementModes::NOCREATE
);
458 sal_Int32 eUserMode
= (css::embed::ElementModes::READWRITE
);
460 ::rtl::OUStringBuffer
sRelPathBuf(1024);
461 ::rtl::OUString sRelPathShare
;
462 ::rtl::OUString sRelPathNoLang
;
463 ::rtl::OUString sRelPathUser
;
468 sRelPathBuf
.append(SUBSTORAGE_GLOBAL
);
469 sRelPathBuf
.append(PATH_SEPERATOR
);
470 sRelPathBuf
.append(sResource
);
471 sRelPathShare
= sRelPathBuf
.makeStringAndClear();
472 sRelPathUser
= sRelPathShare
;
474 xShare
= impl_openPathIgnoringErrors(sRelPathShare
, eShareMode
, sal_True
);
475 xUser
= impl_openPathIgnoringErrors(sRelPathUser
, eUserMode
, sal_False
);
481 sRelPathBuf
.append(SUBSTORAGE_MODULES
);
482 sRelPathBuf
.append(PATH_SEPERATOR
);
483 sRelPathBuf
.append(sModule
);
484 sRelPathBuf
.append(PATH_SEPERATOR
);
485 sRelPathBuf
.append(sResource
);
486 sRelPathShare
= sRelPathBuf
.makeStringAndClear();
487 sRelPathUser
= sRelPathShare
;
489 xShare
= impl_openPathIgnoringErrors(sRelPathShare
, eShareMode
, sal_True
);
490 xUser
= impl_openPathIgnoringErrors(sRelPathUser
, eUserMode
, sal_False
);
496 // A document does not have a share layer in real.
497 // It has one layer only, and this one should be opened READ_WRITE.
498 // So we open the user layer here only and set the share layer equals to it .-)
500 sRelPathBuf
.append(sResource
);
501 sRelPathUser
= sRelPathBuf
.makeStringAndClear();
502 sRelPathShare
= sRelPathUser
;
506 xUser
= m_lDocumentStorages
.openPath(sRelPathUser
, eUserMode
);
509 catch(const css::uno::RuntimeException
& exRun
)
511 catch(const css::uno::Exception
&)
512 { xShare
.clear(); xUser
.clear(); }
517 // Non-localized global share
519 sRelPathNoLang
= sRelPathShare
;
522 (aLocale
!= ::comphelper::Locale::X_NOTRANSLATE()) && // localized level?
523 (eConfigType
!= E_DOCUMENT
) // no localization in document mode!
526 // First try to find the right localized set inside share layer.
527 // Fallbacks are allowed there.
528 ::comphelper::Locale aShareLocale
= aLocale
;
529 ::rtl::OUString
sLocalizedSharePath(sRelPathShare
);
530 sal_Bool bAllowFallbacks
= sal_True
;
531 xShare
= impl_openLocalizedPathIgnoringErrors(sLocalizedSharePath
, eShareMode
, sal_True
, aShareLocale
, bAllowFallbacks
);
533 // The try to locate the right sub dir inside user layer ... without using fallbacks!
534 // Normaly the corresponding sub dir should be created matching the specified locale.
535 // Because we allow creation of storages inside user layer by default.
536 ::comphelper::Locale aUserLocale
= aLocale
;
537 ::rtl::OUString
sLocalizedUserPath(sRelPathUser
);
538 bAllowFallbacks
= sal_False
;
539 xUser
= impl_openLocalizedPathIgnoringErrors(sLocalizedUserPath
, eUserMode
, sal_False
, aUserLocale
, bAllowFallbacks
);
541 sRelPathShare
= sLocalizedSharePath
;
542 sRelPathUser
= sLocalizedUserPath
;
545 // read content of level 3 (presets, targets)
546 css::uno::Reference
< css::container::XNameAccess
> xAccess
;
547 css::uno::Sequence
< ::rtl::OUString
> lNames
;
548 const ::rtl::OUString
* pNames
;
551 OUStringList lPresets
;
552 OUStringList lTargets
;
554 // read preset names of share layer
555 xAccess
= css::uno::Reference
< css::container::XNameAccess
>(xShare
, css::uno::UNO_QUERY
);
558 lNames
= xAccess
->getElementNames();
559 pNames
= lNames
.getConstArray();
560 c
= lNames
.getLength();
564 ::rtl::OUString sTemp
= pNames
[i
];
565 sal_Int32 nPos
= sTemp
.indexOf(FILE_EXTENSION
);
567 sTemp
= sTemp
.copy(0,nPos
);
568 lPresets
.push_back(sTemp
);
572 // read preset names of user layer
573 xAccess
= css::uno::Reference
< css::container::XNameAccess
>(xUser
, css::uno::UNO_QUERY
);
576 lNames
= xAccess
->getElementNames();
577 pNames
= lNames
.getConstArray();
578 c
= lNames
.getLength();
582 ::rtl::OUString sTemp
= pNames
[i
];
583 sal_Int32 nPos
= sTemp
.indexOf(FILE_EXTENSION
);
585 sTemp
= sTemp
.copy(0,nPos
);
586 lTargets
.push_back(sTemp
);
590 // SAFE -> ----------------------------------
593 m_xWorkingStorageShare
= xShare
;
594 m_xWorkingStorageNoLang
= xNoLang
;
595 m_xWorkingStorageUser
= xUser
;
596 m_lPresets
= lPresets
;
597 m_lTargets
= lTargets
;
598 m_sRelPathShare
= sRelPathShare
;
599 m_sRelPathNoLang
= sRelPathNoLang
;
600 m_sRelPathUser
= sRelPathUser
;
603 // <- SAFE ----------------------------------
606 catch(const css::uno::Exception
& ex
)
608 throw css::configuration::CorruptedUIConfigurationException(
609 lcl_getLocalizedMessage(ID_CORRUPT_UICONFIG_GENERAL
),
610 css::uno::Reference
< css::uno::XInterface
>(),
615 //-----------------------------------------------
616 void PresetHandler::copyPresetToTarget(const ::rtl::OUString
& sPreset
,
617 const ::rtl::OUString
& sTarget
)
619 // dont check our preset list, if element exists
620 // We try to open it and forward all errors to the user!
622 // SAFE -> ----------------------------------
623 ReadGuard
aReadLock(m_aLock
);
624 css::uno::Reference
< css::embed::XStorage
> xWorkingShare
= m_xWorkingStorageShare
;
625 css::uno::Reference
< css::embed::XStorage
> xWorkingNoLang
= m_xWorkingStorageNoLang
;
626 css::uno::Reference
< css::embed::XStorage
> xWorkingUser
= m_xWorkingStorageUser
;
628 // <- SAFE ----------------------------------
630 // e.g. module without any config data ?!
632 (!xWorkingShare
.is()) ||
633 (!xWorkingUser
.is() )
639 ::rtl::OUString
sPresetFile(sPreset
);
640 sPresetFile
+= FILE_EXTENSION
;
642 ::rtl::OUString
sTargetFile(sTarget
);
643 sTargetFile
+= FILE_EXTENSION
;
645 // remove existing elements before you try to copy the preset to that location ...
646 // Otherwise w will get an ElementExistException inside copyElementTo()!
647 css::uno::Reference
< css::container::XNameAccess
> xCheckingUser(xWorkingUser
, css::uno::UNO_QUERY_THROW
);
648 if (xCheckingUser
->hasByName(sTargetFile
))
649 xWorkingUser
->removeElement(sTargetFile
);
651 xWorkingShare
->copyElementTo(sPresetFile
, xWorkingUser
, sTargetFile
);
653 // If our storages work in transacted mode, we have
654 // to commit all changes from bottom to top!
658 //-----------------------------------------------
659 css::uno::Reference
< css::io::XStream
> PresetHandler::openPreset(const ::rtl::OUString
& sPreset
,
660 sal_Bool bUseNoLangGlobal
)
662 // SAFE -> ----------------------------------
663 ReadGuard
aReadLock(m_aLock
);
664 css::uno::Reference
< css::embed::XStorage
> xFolder
= bUseNoLangGlobal
? m_xWorkingStorageNoLang
: m_xWorkingStorageShare
;
666 // <- SAFE ----------------------------------
668 // e.g. module without any config data ?!
670 return css::uno::Reference
< css::io::XStream
>();
672 ::rtl::OUString
sFile(sPreset
);
673 sFile
+= FILE_EXTENSION
;
675 // inform user about errors (use original exceptions!)
676 css::uno::Reference
< css::io::XStream
> xStream
= xFolder
->openStreamElement(sFile
, css::embed::ElementModes::READ
);
680 //-----------------------------------------------
681 css::uno::Reference
< css::io::XStream
> PresetHandler::openTarget(const ::rtl::OUString
& sTarget
,
682 sal_Bool bCreateIfMissing
)
684 // SAFE -> ----------------------------------
685 ReadGuard
aReadLock(m_aLock
);
686 css::uno::Reference
< css::embed::XStorage
> xFolder
= m_xWorkingStorageUser
;
688 // <- SAFE ----------------------------------
690 // e.g. module without any config data ?!
692 return css::uno::Reference
< css::io::XStream
>();
694 ::rtl::OUString
sFile(sTarget
);
695 sFile
+= FILE_EXTENSION
;
697 sal_Int32 nOpenMode
= css::embed::ElementModes::READWRITE
;
698 if (!bCreateIfMissing
)
699 nOpenMode
|= css::embed::ElementModes::NOCREATE
;
701 // try it in read/write mode first and ignore errors.
702 css::uno::Reference
< css::io::XStream
> xStream
;
705 xStream
= xFolder
->openStreamElement(sFile
, nOpenMode
);
708 catch(const css::uno::RuntimeException
&)
710 catch(const css::uno::Exception
&)
713 // try it readonly if it failed before.
714 // inform user about errors (use original exceptions!)
715 nOpenMode
&= ~css::embed::ElementModes::WRITE
;
716 xStream
= xFolder
->openStreamElement(sFile
, nOpenMode
);
721 //-----------------------------------------------
722 void PresetHandler::commitUserChanges()
724 // SAFE -> ----------------------------------
725 ReadGuard
aReadLock(m_aLock
);
726 css::uno::Reference
< css::embed::XStorage
> xWorking
= m_xWorkingStorageUser
;
727 EConfigType eCfgType
= m_eConfigType
;
729 // <- SAFE ----------------------------------
731 // e.g. module without any config data ?!
735 ::rtl::OUString sPath
;
742 sPath
= m_aSharedStorages
->m_lStoragesUser
.getPathOfStorage(xWorking
);
743 m_aSharedStorages
->m_lStoragesUser
.commitPath(sPath
);
744 m_aSharedStorages
->m_lStoragesUser
.notifyPath(sPath
);
750 sPath
= m_lDocumentStorages
.getPathOfStorage(xWorking
);
751 m_lDocumentStorages
.commitPath(sPath
);
752 m_lDocumentStorages
.notifyPath(sPath
);
758 //-----------------------------------------------
759 void PresetHandler::addStorageListener(IStorageListener
* pListener
)
761 // SAFE -> ----------------------------------
762 ReadGuard
aReadLock(m_aLock
);
763 ::rtl::OUString sRelPath
= m_sRelPathUser
; // use user path ... because we dont work directly on the share layer!
764 EConfigType eCfgType
= m_eConfigType
;
766 // <- SAFE ----------------------------------
768 if (!sRelPath
.getLength())
776 m_aSharedStorages
->m_lStoragesUser
.addStorageListener(pListener
, sRelPath
);
782 m_lDocumentStorages
.addStorageListener(pListener
, sRelPath
);
788 //-----------------------------------------------
789 void PresetHandler::removeStorageListener(IStorageListener
* pListener
)
791 // SAFE -> ----------------------------------
792 ReadGuard
aReadLock(m_aLock
);
793 ::rtl::OUString sRelPath
= m_sRelPathUser
; // use user path ... because we dont work directly on the share layer!
794 EConfigType eCfgType
= m_eConfigType
;
796 // <- SAFE ----------------------------------
798 if (!sRelPath
.getLength())
806 m_aSharedStorages
->m_lStoragesUser
.removeStorageListener(pListener
, sRelPath
);
812 m_lDocumentStorages
.removeStorageListener(pListener
, sRelPath
);
818 //-----------------------------------------------
819 css::uno::Reference
< css::embed::XStorage
> PresetHandler::impl_openPathIgnoringErrors(const ::rtl::OUString
& sPath
,
823 css::uno::Reference
< css::embed::XStorage
> xPath
;
827 xPath
= m_aSharedStorages
->m_lStoragesShare
.openPath(sPath
, eMode
);
829 xPath
= m_aSharedStorages
->m_lStoragesUser
.openPath(sPath
, eMode
);
831 catch(const css::uno::RuntimeException
& exRun
)
833 catch(const css::uno::Exception
&)
838 //-----------------------------------------------
839 ::std::vector
< ::rtl::OUString
>::const_iterator
PresetHandler::impl_findMatchingLocalizedValue(const ::std::vector
< ::rtl::OUString
>& lLocalizedValues
,
840 ::comphelper::Locale
& aLocale
,
841 sal_Bool bAllowFallbacks
)
843 ::std::vector
< ::rtl::OUString
>::const_iterator pFound
= lLocalizedValues
.end();
846 pFound
= ::comphelper::Locale::getFallback(lLocalizedValues
, aLocale
.toISO());
850 for ( pFound
= lLocalizedValues
.begin();
851 pFound
!= lLocalizedValues
.end() ;
854 const ::rtl::OUString
& sCheckISO
= *pFound
;
855 ::comphelper::Locale
aCheckLocale(sCheckISO
);
856 if (aCheckLocale
.equals(aLocale
))
861 // if we found a valid locale ... take it over to our in/out parameter aLocale
862 if (pFound
!= lLocalizedValues
.end())
864 const ::rtl::OUString
& sISOLocale
= *pFound
;
865 aLocale
.fromISO(sISOLocale
);
871 //-----------------------------------------------
872 css::uno::Reference
< css::embed::XStorage
> PresetHandler::impl_openLocalizedPathIgnoringErrors(::rtl::OUString
& sPath
,
875 ::comphelper::Locale
& aLocale
,
876 sal_Bool bAllowFallback
)
878 css::uno::Reference
< css::embed::XStorage
> xPath
= impl_openPathIgnoringErrors(sPath
, eMode
, bShare
);
879 ::std::vector
< ::rtl::OUString
> lSubFolders
= impl_getSubFolderNames(xPath
);
880 ::std::vector
< ::rtl::OUString
>::const_iterator pLocaleFolder
= impl_findMatchingLocalizedValue(lSubFolders
, aLocale
, bAllowFallback
);
882 // no fallback ... creation not allowed => no storage
884 (pLocaleFolder
== lSubFolders
.end() ) &&
885 ((eMode
& css::embed::ElementModes::NOCREATE
) == css::embed::ElementModes::NOCREATE
)
887 return css::uno::Reference
< css::embed::XStorage
>();
889 // it doesnt matter, if there is a locale fallback or not
890 // If creation of storages is allowed, we do it anyway.
891 // Otherwhise we have no acc config at all, which can make other trouble.
892 ::rtl::OUString sLocalizedPath
;
893 sLocalizedPath
= sPath
;
894 sLocalizedPath
+= PATH_SEPERATOR
;
895 if (pLocaleFolder
!= lSubFolders
.end())
896 sLocalizedPath
+= *pLocaleFolder
;
898 sLocalizedPath
+= aLocale
.toISO();
900 css::uno::Reference
< css::embed::XStorage
> xLocalePath
= impl_openPathIgnoringErrors(sLocalizedPath
, eMode
, bShare
);
902 if (xLocalePath
.is())
903 sPath
= sLocalizedPath
;
905 sPath
= ::rtl::OUString();
910 //-----------------------------------------------
911 ::std::vector
< ::rtl::OUString
> PresetHandler::impl_getSubFolderNames(const css::uno::Reference
< css::embed::XStorage
>& xFolder
)
913 css::uno::Reference
< css::container::XNameAccess
> xAccess(xFolder
, css::uno::UNO_QUERY
);
915 return ::std::vector
< ::rtl::OUString
>();
917 ::std::vector
< ::rtl::OUString
> lSubFolders
;
918 const css::uno::Sequence
< ::rtl::OUString
> lNames
= xAccess
->getElementNames();
919 const ::rtl::OUString
* pNames
= lNames
.getConstArray();
920 sal_Int32 c
= lNames
.getLength();
927 if (xFolder
->isStorageElement(pNames
[i
]))
928 lSubFolders
.push_back(pNames
[i
]);
930 catch(const css::uno::RuntimeException
& exRun
)
932 catch(const css::uno::Exception
&)
939 //-----------------------------------------------
940 } // namespace framework