update dev300-m58
[ooovba.git] / unotools / source / config / configitem.cxx
blob5e6b3320af3bbe12d7955264449e8abf4b3e4e54
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: configitem.cxx,v $
10 * $Revision: 1.52 $
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_unotools.hxx"
33 #include "unotools/configitem.hxx"
34 #include "unotools/configmgr.hxx"
35 #include "unotools/configpathes.hxx"
36 #include <com/sun/star/beans/XMultiPropertySet.hpp>
37 #include <com/sun/star/beans/XPropertySet.hpp>
38 #include <com/sun/star/util/XChangesListener.hpp>
39 #include <com/sun/star/util/XChangesNotifier.hpp>
40 #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
41 #include <com/sun/star/container/XHierarchicalName.hpp>
42 #include <com/sun/star/configuration/XTemplateContainer.hpp>
43 #include <com/sun/star/container/XNameContainer.hpp>
44 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
45 #include <com/sun/star/lang/XServiceInfo.hpp>
46 #include <com/sun/star/beans/PropertyValue.hpp>
47 #include <com/sun/star/beans/PropertyAttribute.hpp>
48 #include <com/sun/star/util/XStringEscape.hpp>
49 #include <com/sun/star/util/XChangesBatch.hpp>
50 #include <osl/diagnose.h>
52 #include <rtl/ustrbuf.hxx>
54 using namespace utl;
55 using rtl::OUString;
56 using rtl::OString;
57 using namespace com::sun::star::uno;
58 using namespace com::sun::star::util;
59 using namespace com::sun::star::lang;
60 using namespace com::sun::star::beans;
61 using namespace com::sun::star::container;
62 using namespace com::sun::star::configuration;
64 #define C2U(cChar) OUString::createFromAscii(cChar)
65 #include <cppuhelper/implbase1.hxx> // helper for implementations
67 #ifdef DBG_UTIL
68 inline void lcl_CFG_DBG_EXCEPTION(const sal_Char* cText, const Exception& rEx)
70 OString sMsg(cText);
71 sMsg += OString(rEx.Message.getStr(), rEx.Message.getLength(), RTL_TEXTENCODING_ASCII_US);
72 OSL_ENSURE(sal_False, sMsg.getStr());
74 #define CATCH_INFO(a) \
75 catch(Exception& rEx) \
76 { \
77 lcl_CFG_DBG_EXCEPTION(a, rEx);\
79 #else
80 #define lcl_CFG_DBG_EXCEPTION( a, b)
81 #define CATCH_INFO(a) catch(Exception& ){}
82 #endif
84 namespace utl{
85 class ConfigChangeListener_Impl : public cppu::WeakImplHelper1
87 com::sun::star::util::XChangesListener
90 ConfigItem* pParent;
91 const Sequence< OUString > aPropertyNames;
92 public:
93 ConfigChangeListener_Impl(ConfigItem& rItem, const Sequence< OUString >& rNames);
94 ~ConfigChangeListener_Impl();
96 //XChangesListener
97 virtual void SAL_CALL changesOccurred( const ChangesEvent& Event ) throw(RuntimeException);
99 //XEventListener
100 virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException);
103 /* -----------------------------12.02.01 11:38--------------------------------
105 ---------------------------------------------------------------------------*/
106 struct ConfigItem_Impl
108 utl::ConfigManager* pManager;
109 sal_Int16 nMode;
110 sal_Bool bIsModified;
111 sal_Bool bEnableInternalNotification;
113 sal_Int16 nInValueChange;
114 ConfigItem_Impl() :
115 pManager(0),
116 nMode(0),
117 bIsModified(sal_False),
118 bEnableInternalNotification(sal_False),
119 nInValueChange(0)
123 /* -----------------------------04.12.00 10:25--------------------------------
125 ---------------------------------------------------------------------------*/
126 class ValueCounter_Impl
128 sal_Int16& rCnt;
129 public:
130 ValueCounter_Impl(sal_Int16& rCounter):
131 rCnt(rCounter)
132 {rCnt++;}
133 ~ValueCounter_Impl()
135 OSL_ENSURE(rCnt>0, "RefCount < 0 ??");
136 rCnt--;
139 /* -----------------------------03.12.02 -------------------------------------
141 ---------------------------------------------------------------------------*/
142 namespace
144 // helper to achieve exception - safe handling of an Item under construction
145 template <class TYP>
146 class AutoDeleter // : Noncopyable
148 TYP* m_pItem;
149 public:
150 AutoDeleter(TYP * pItem)
151 : m_pItem(pItem)
155 ~AutoDeleter()
157 delete m_pItem;
160 void keep() { m_pItem = 0; }
163 /* -----------------------------29.08.00 16:34--------------------------------
165 ---------------------------------------------------------------------------*/
166 ConfigChangeListener_Impl::ConfigChangeListener_Impl(
167 ConfigItem& rItem, const Sequence< OUString >& rNames) :
168 pParent(&rItem),
169 aPropertyNames(rNames)
172 /* -----------------------------29.08.00 16:34--------------------------------
174 ---------------------------------------------------------------------------*/
175 ConfigChangeListener_Impl::~ConfigChangeListener_Impl()
178 /* -----------------------------29.08.00 16:34--------------------------------
180 ---------------------------------------------------------------------------*/
181 sal_Bool lcl_Find(
182 const rtl::OUString& rTemp,
183 const OUString* pCheckPropertyNames,
184 sal_Int32 nLength)
186 //return true if the path is completely correct or if it is longer
187 //i.e ...Print/Content/Graphic and .../Print
188 for(sal_Int32 nIndex = 0; nIndex < nLength; nIndex++)
189 if( isPrefixOfConfigurationPath(rTemp, pCheckPropertyNames[nIndex]) )
190 return sal_True;
191 return sal_False;
193 //-----------------------------------------------------------------------------
194 void ConfigChangeListener_Impl::changesOccurred( const ChangesEvent& rEvent ) throw(RuntimeException)
196 const ElementChange* pElementChanges = rEvent.Changes.getConstArray();
198 Sequence<OUString> aChangedNames(rEvent.Changes.getLength());
199 OUString* pNames = aChangedNames.getArray();
201 const OUString* pCheckPropertyNames = aPropertyNames.getConstArray();
203 sal_Int32 nNotify = 0;
204 for(int i = 0; i < aChangedNames.getLength(); i++)
206 OUString sTemp;
207 pElementChanges[i].Accessor >>= sTemp;
208 if(lcl_Find(sTemp, pCheckPropertyNames, aPropertyNames.getLength()))
209 pNames[nNotify++] = sTemp;
211 if(nNotify)
213 aChangedNames.realloc(nNotify);
214 pParent->CallNotify(aChangedNames);
217 /* -----------------------------29.08.00 16:34--------------------------------
219 ---------------------------------------------------------------------------*/
220 void ConfigChangeListener_Impl::disposing( const EventObject& /*rSource*/ ) throw(RuntimeException)
222 pParent->RemoveChangesListener();
224 /* -----------------------------29.08.00 12:50--------------------------------
226 ---------------------------------------------------------------------------*/
227 ConfigItem::ConfigItem(const OUString rSubTree, sal_Int16 nSetMode ) :
228 sSubTree(rSubTree),
229 pImpl(new ConfigItem_Impl)
231 AutoDeleter<ConfigItem_Impl> aNewImpl(pImpl);
233 pImpl->pManager = ConfigManager::GetConfigManager();
234 pImpl->nMode = nSetMode;
235 if(0 != (nSetMode&CONFIG_MODE_RELEASE_TREE))
236 pImpl->pManager->AddConfigItem(*this);
237 else
238 m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this);
240 // no more exceptions after c'tor has finished
241 aNewImpl.keep();
242 pImpl->nMode &= ~CONFIG_MODE_PROPAGATE_ERRORS;
244 /* -----------------------------17.11.00 13:53--------------------------------
246 ---------------------------------------------------------------------------*/
247 ConfigItem::ConfigItem(utl::ConfigManager& rManager, const rtl::OUString rSubTree) :
248 sSubTree(rSubTree),
249 pImpl(new ConfigItem_Impl)
251 pImpl->pManager = &rManager;
252 pImpl->nMode = CONFIG_MODE_IMMEDIATE_UPDATE; // does not allow exceptions
253 m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this);
255 //---------------------------------------------------------------------
256 //--- 02.08.2002 16:33:23 -----------------------------------------------
257 sal_Bool ConfigItem::IsValidConfigMgr() const
259 return ( pImpl->pManager && pImpl->pManager->GetConfigurationProvider().is() );
262 /* -----------------------------29.08.00 12:52--------------------------------
264 ---------------------------------------------------------------------------*/
265 ConfigItem::~ConfigItem()
267 if(pImpl->pManager)
269 RemoveChangesListener();
270 pImpl->pManager->RemoveConfigItem(*this);
272 delete pImpl;
274 /* -----------------------------29.08.00 12:52--------------------------------
276 ---------------------------------------------------------------------------*/
277 void ConfigItem::Commit()
279 OSL_ENSURE(sal_False, "Base class called");
281 /* -----------------------------29.08.00 12:52--------------------------------
283 ---------------------------------------------------------------------------*/
284 void ConfigItem::ReleaseConfigMgr()
286 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
287 if(xHierarchyAccess.is())
291 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
292 xBatch->commitChanges();
294 CATCH_INFO("Exception from commitChanges(): ")
296 RemoveChangesListener();
297 OSL_ENSURE(pImpl->pManager, "ConfigManager already released");
298 pImpl->pManager = 0;
300 /* -----------------------------29.08.00 12:52--------------------------------
302 ---------------------------------------------------------------------------*/
303 void ConfigItem::CallNotify( const com::sun::star::uno::Sequence<OUString>& rPropertyNames )
305 if(!IsInValueChange() || pImpl->bEnableInternalNotification)
306 Notify(rPropertyNames);
308 /* -----------------------------29.08.00 12:52--------------------------------
310 ---------------------------------------------------------------------------*/
311 void ConfigItem::Notify( const com::sun::star::uno::Sequence<OUString>& /*rPropertyNames*/)
313 OSL_ENSURE(sal_False, "Base class called");
315 /* -----------------------------12.12.00 17:09--------------------------------
317 ---------------------------------------------------------------------------*/
318 sal_Bool lcl_IsLocalProperty(const OUString& rSubTree, const OUString& rProperty)
320 static const sal_Char* aLocalProperties[] =
322 "Office.Common/Path/Current/Storage",
323 "Office.Common/Path/Current/Temp"
325 static const int aLocalPropLen[] =
330 OUString sProperty(rSubTree);
331 sProperty += C2U("/");
332 sProperty += rProperty;
334 if(sProperty.equalsAsciiL( aLocalProperties[0], aLocalPropLen[0]) ||
335 sProperty.equalsAsciiL( aLocalProperties[1], aLocalPropLen[1]))
336 return sal_True;
338 return sal_False;
340 /* -----------------------------10.04.01 15:00--------------------------------
342 ---------------------------------------------------------------------------*/
343 void ConfigItem::impl_packLocalizedProperties( const Sequence< OUString >& lInNames ,
344 const Sequence< Any >& lInValues ,
345 Sequence< Any >& lOutValues )
347 // Safe impossible cases.
348 // This method should be called for special ConfigItem-mode only!
349 OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_packLocalizedProperties()\nWrong call of this method detected!\n" );
351 sal_Int32 nSourceCounter ; // used to step during input lists
352 sal_Int32 nSourceSize ; // marks end of loop over input lists
353 sal_Int32 nDestinationCounter ; // actual position in output lists
354 sal_Int32 nPropertyCounter ; // counter of inner loop for Sequence< PropertyValue >
355 sal_Int32 nPropertiesSize ; // marks end of inner loop
356 Sequence< OUString > lPropertyNames ; // list of all locales for localized entry
357 Sequence< PropertyValue > lProperties ; // localized values of an configuration entry packed for return
358 Reference< XInterface > xLocalizedNode ; // if cfg entry is localized ... lInValues contains an XInterface!
360 // Optimise follow algorithm ... A LITTLE BIT :-)
361 // There exist two different possibilities:
362 // i ) There exist no localized entries ... => size of lOutValues will be the same like lInNames/lInValues!
363 // ii) There exist some (mostly one or two) localized entries ... => size of lOutValues will be the same like lInNames/lInValues!
364 // ... Why? If a localized value exist - the any is filled with an XInterface object (is a SetNode-service).
365 // We read all his child nodes and pack it into Sequence< PropertyValue >.
366 // The result list we pack into the return any. We never change size of lists!
367 nSourceSize = lInNames.getLength();
368 lOutValues.realloc( nSourceSize );
370 // Algorithm:
371 // Copy all names and values from in to out lists.
372 // Look for special localized entries ... You can detect it as "XInterface" packed into an Any.
373 // Use this XInterface-object to read all localized values and pack it into Sequence< PropertValue >.
374 // Add this list to out lists then.
376 nDestinationCounter = 0;
377 for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
379 // If item a special localized one ... convert and pack it ...
380 if( lInValues[nSourceCounter].getValueTypeName() == C2U("com.sun.star.uno.XInterface") )
382 lInValues[nSourceCounter] >>= xLocalizedNode;
383 Reference< XNameContainer > xSetAccess( xLocalizedNode, UNO_QUERY );
384 if( xSetAccess.is() == sal_True )
386 lPropertyNames = xSetAccess->getElementNames() ;
387 nPropertiesSize = lPropertyNames.getLength() ;
388 lProperties.realloc( nPropertiesSize ) ;
390 for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
392 #if OSL_DEBUG_LEVEL > 1
393 // Sometimes it's better to see what's going on :-)
394 OUString sPropName = lInNames[nSourceCounter];
395 OUString sLocaleName = lPropertyNames[nPropertyCounter];
396 #endif
397 lProperties[nPropertyCounter].Name = lPropertyNames[nPropertyCounter] ;
398 OUString sLocaleValue;
399 xSetAccess->getByName( lPropertyNames[nPropertyCounter] ) >>= sLocaleValue ;
400 lProperties[nPropertyCounter].Value <<= sLocaleValue;
403 lOutValues[nDestinationCounter] <<= lProperties;
406 // ... or copy normal items to return lists directly.
407 else
409 lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
411 ++nDestinationCounter;
414 /* -----------------------------10.04.01 15:00--------------------------------
416 ---------------------------------------------------------------------------*/
417 void ConfigItem::impl_unpackLocalizedProperties( const Sequence< OUString >& lInNames ,
418 const Sequence< Any >& lInValues ,
419 Sequence< OUString >& lOutNames ,
420 Sequence< Any >& lOutValues )
422 // Safe impossible cases.
423 // This method should be called for special ConfigItem-mode only!
424 OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_unpackLocalizedProperties()\nWrong call of this method detected!\n" );
426 sal_Int32 nSourceCounter ; // used to step during input lists
427 sal_Int32 nSourceSize ; // marks end of loop over input lists
428 sal_Int32 nDestinationCounter ; // actual position in output lists
429 sal_Int32 nPropertyCounter ; // counter of inner loop for Sequence< PropertyValue >
430 sal_Int32 nPropertiesSize ; // marks end of inner loop
431 OUString sNodeName ; // base name of node ( e.g. "UIName/" ) ... expand to locale ( e.g. "UIName/de" )
432 Sequence< PropertyValue > lProperties ; // localized values of an configuration entry getted from lInValues-Any
434 // Optimise follow algorithm ... A LITTLE BIT :-)
435 // There exist two different possibilities:
436 // i ) There exist no localized entries ... => size of lOutNames/lOutValues will be the same like lInNames/lInValues!
437 // ii) There exist some (mostly one or two) localized entries ... => size of lOutNames/lOutValues will be some bytes greater then lInNames/lInValues.
438 // => I think we should make it fast for i). ii) is a special case and mustn't be SOOOO... fast.
439 // We should reserve same space for output list like input ones first.
440 // Follow algorithm looks for these borders and change it for ii) only!
441 // It will be faster then a "realloc()" call in every loop ...
442 nSourceSize = lInNames.getLength();
444 lOutNames.realloc ( nSourceSize );
445 lOutValues.realloc ( nSourceSize );
447 // Algorithm:
448 // Copy all names and values from const to return lists.
449 // Look for special localized entries ... You can detect it as Sequence< PropertyValue > packed into an Any.
450 // Split it ... insert PropertyValue.Name to lOutNames and PropertyValue.Value to lOutValues.
452 nDestinationCounter = 0;
453 for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
455 // If item a special localized one ... split it and insert his parts to output lists ...
456 if( lInValues[nSourceCounter].getValueType() == ::getCppuType( (const Sequence< PropertyValue >*)NULL ) )
458 lInValues[nSourceCounter] >>= lProperties ;
459 sNodeName = lInNames[nSourceCounter] ;
460 sNodeName += C2U("/") ;
461 nPropertiesSize = lProperties.getLength() ;
463 if( (nDestinationCounter+nPropertiesSize) > lOutNames.getLength() )
465 lOutNames.realloc ( nDestinationCounter+nPropertiesSize );
466 lOutValues.realloc ( nDestinationCounter+nPropertiesSize );
469 for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
471 lOutNames [nDestinationCounter] = sNodeName + lProperties[nPropertyCounter].Name ;
472 lOutValues[nDestinationCounter] = lProperties[nPropertyCounter].Value ;
473 ++nDestinationCounter;
476 // ... or copy normal items to return lists directly.
477 else
479 if( (nDestinationCounter+1) > lOutNames.getLength() )
481 lOutNames.realloc ( nDestinationCounter+1 );
482 lOutValues.realloc ( nDestinationCounter+1 );
485 lOutNames [nDestinationCounter] = lInNames [nSourceCounter];
486 lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
487 ++nDestinationCounter;
491 /* -----------------------------03.02.2003 14:44------------------------------
493 ---------------------------------------------------------------------------*/
494 Sequence< sal_Bool > ConfigItem::GetReadOnlyStates(const com::sun::star::uno::Sequence< rtl::OUString >& rNames)
496 sal_Int32 i;
498 // size of return list is fix!
499 // Every item must match to length of incoming name list.
500 sal_Int32 nCount = rNames.getLength();
501 Sequence< sal_Bool > lStates(nCount);
503 // We must be shure to return a valid information everytime!
504 // Set default to non readonly ... similar to the configuration handling of this property.
505 for ( i=0; i<nCount; ++i)
506 lStates[i] = sal_False;
508 // no access - no informations ...
509 Reference< XHierarchicalNameAccess > xHierarchyAccess = GetTree();
510 if (!xHierarchyAccess.is())
511 return lStates;
513 for (i=0; i<nCount; ++i)
517 if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, rNames[i]))
519 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nlocal mode seams to be used!?\n");
520 continue;
523 OUString sName = rNames[i];
524 OUString sPath;
525 OUString sProperty;
527 ::utl::splitLastFromConfigurationPath(sName,sPath,sProperty);
528 if (!sPath.getLength() && !sProperty.getLength())
530 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nsplitt failed\n");
531 continue;
534 Reference< XInterface > xNode;
535 Reference< XPropertySet > xSet ;
536 Reference< XPropertySetInfo > xInfo;
537 if (sPath.getLength())
539 Any aNode = xHierarchyAccess->getByHierarchicalName(sPath);
540 if (!(aNode >>= xNode) || !xNode.is())
542 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno set available\n");
543 continue;
546 else
548 xNode = Reference< XInterface >(xHierarchyAccess, UNO_QUERY);
551 xSet = Reference< XPropertySet >(xNode, UNO_QUERY);
552 if (xSet.is())
554 xInfo = xSet->getPropertySetInfo();
555 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\ngetPropertySetInfo failed ...\n");
557 else
559 xInfo = Reference< XPropertySetInfo >(xNode, UNO_QUERY);
560 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\nUNO_QUERY failed ...\n");
563 if (!xInfo.is())
565 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno prop info available\n");
566 continue;
569 Property aProp = xInfo->getPropertyByName(sProperty);
570 lStates[i] = ((aProp.Attributes & PropertyAttribute::READONLY) == PropertyAttribute::READONLY);
572 catch(Exception&){}
575 return lStates;
578 /* -----------------------------29.08.00 15:10--------------------------------
580 ---------------------------------------------------------------------------*/
581 Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames)
583 Sequence< Any > aRet(rNames.getLength());
584 const OUString* pNames = rNames.getConstArray();
585 Any* pRet = aRet.getArray();
586 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
587 if(xHierarchyAccess.is())
589 for(int i = 0; i < rNames.getLength(); i++)
593 if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i]))
595 OUString sProperty(sSubTree);
596 sProperty += C2U("/");
597 sProperty += pNames[i];
598 pRet[i] = pImpl->pManager->GetLocalProperty(sProperty);
600 else
601 pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]);
603 #ifdef DBG_UTIL
604 catch(Exception& rEx)
606 OString sMsg("XHierarchicalNameAccess: ");
607 sMsg += OString(rEx.Message.getStr(),
608 rEx.Message.getLength(),
609 RTL_TEXTENCODING_ASCII_US);
610 sMsg += OString("\n");
611 sMsg += OString(ConfigManager::GetConfigBaseURL().getStr(),
612 ConfigManager::GetConfigBaseURL().getLength(),
613 RTL_TEXTENCODING_ASCII_US);
614 sMsg += OString(sSubTree.getStr(),
615 sSubTree.getLength(),
616 RTL_TEXTENCODING_ASCII_US);
617 sMsg += OString("/");
618 sMsg += OString(pNames[i].getStr(),
619 pNames[i].getLength(),
620 RTL_TEXTENCODING_ASCII_US);
621 OSL_ENSURE(sal_False, sMsg.getStr());
623 #else
624 catch(Exception&){}
625 #endif
628 // In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >.
629 if((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES)
631 Sequence< Any > lValues;
632 impl_packLocalizedProperties( rNames, aRet, lValues );
633 aRet = lValues;
636 return aRet;
638 /* -----------------------------29.08.00 17:28--------------------------------
640 ---------------------------------------------------------------------------*/
641 sal_Bool ConfigItem::PutProperties( const Sequence< OUString >& rNames,
642 const Sequence< Any>& rValues)
644 ValueCounter_Impl aCounter(pImpl->nInValueChange);
645 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
646 Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY);
647 sal_Bool bRet = xHierarchyAccess.is() && xTopNodeReplace.is();
648 if(bRet)
650 Sequence< OUString > lNames ;
651 Sequence< Any > lValues ;
652 const OUString* pNames = NULL ;
653 const Any* pValues = NULL ;
654 sal_Int32 nNameCount ;
655 if(( pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES )
657 // If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue >
658 // as value of an localized configuration entry!
659 // How we can do that?
660 // We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"!
661 impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues );
662 pNames = lNames.getConstArray ();
663 pValues = lValues.getConstArray ();
664 nNameCount = lNames.getLength ();
666 else
668 // This is the normal mode ...
669 // Use given input lists directly.
670 pNames = rNames.getConstArray ();
671 pValues = rValues.getConstArray ();
672 nNameCount = rNames.getLength ();
674 for(int i = 0; i < nNameCount; i++)
676 if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i]))
678 OUString sProperty(sSubTree);
679 sProperty += C2U("/");
680 sProperty += pNames[i];
681 pImpl->pManager->PutLocalProperty(sProperty, pValues[i]);
683 else
687 OUString sNode, sProperty;
688 if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty))
690 Any aNode = xHierarchyAccess->getByHierarchicalName(sNode);
692 Reference<XNameAccess> xNodeAcc;
693 aNode >>= xNodeAcc;
694 Reference<XNameReplace> xNodeReplace(xNodeAcc, UNO_QUERY);
695 Reference<XNameContainer> xNodeCont (xNodeAcc, UNO_QUERY);
697 sal_Bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty));
698 if (bExist && xNodeReplace.is())
699 xNodeReplace->replaceByName(sProperty, pValues[i]);
700 else
701 if (!bExist && xNodeCont.is())
702 xNodeCont->insertByName(sProperty, pValues[i]);
703 else
704 bRet = sal_False;
706 else //direct value
708 xTopNodeReplace->replaceByName(sProperty, pValues[i]);
711 CATCH_INFO("Exception from PutProperties: ");
716 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
717 xBatch->commitChanges();
719 CATCH_INFO("Exception from commitChanges(): ")
722 return bRet;
724 /* -----------------------------08.12.05 15:27--------------------------------
726 ---------------------------------------------------------------------------*/
727 void ConfigItem::DisableNotification()
729 OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" );
730 RemoveChangesListener();
732 /* -----------------------------29.08.00 16:19--------------------------------
734 ---------------------------------------------------------------------------*/
735 sal_Bool ConfigItem::EnableNotification(const Sequence< OUString >& rNames,
736 sal_Bool bEnableInternalNotification )
739 OSL_ENSURE(0 == (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "notification in CONFIG_MODE_RELEASE_TREE mode not possible");
740 pImpl->bEnableInternalNotification = bEnableInternalNotification;
741 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
742 Reference<XChangesNotifier> xChgNot(xHierarchyAccess, UNO_QUERY);
743 if(!xChgNot.is())
744 return sal_False;
746 OSL_ENSURE(!xChangeLstnr.is(), "EnableNotification already called");
747 if(xChangeLstnr.is())
748 xChgNot->removeChangesListener( xChangeLstnr );
749 sal_Bool bRet = sal_True;
753 xChangeLstnr = new ConfigChangeListener_Impl(*this, rNames);
754 xChgNot->addChangesListener( xChangeLstnr );
756 catch(RuntimeException& )
758 bRet = sal_False;
760 return bRet;
762 /* -----------------------------29.08.00 16:47--------------------------------
764 ---------------------------------------------------------------------------*/
765 void ConfigItem::RemoveChangesListener()
767 Reference<XChangesNotifier> xChgNot(m_xHierarchyAccess, UNO_QUERY);
768 if(xChgNot.is() && xChangeLstnr.is())
772 xChgNot->removeChangesListener( xChangeLstnr );
773 xChangeLstnr = 0;
775 catch(Exception & )
780 /* -----------------------------10.07.00 --------------------------------
782 ---------------------------------------------------------------------------*/
783 void lcl_normalizeLocalNames(Sequence< OUString >& _rNames, ConfigNameFormat _eFormat, Reference<XInterface> const& _xParentNode)
785 switch (_eFormat)
787 case CONFIG_NAME_LOCAL_NAME:
788 // unaltered - this is our input format
789 break;
791 case CONFIG_NAME_FULL_PATH:
793 Reference<XHierarchicalName> xFormatter(_xParentNode, UNO_QUERY);
794 if (xFormatter.is())
796 OUString * pNames = _rNames.getArray();
797 for(int i = 0; i<_rNames.getLength(); ++i)
800 pNames[i] = xFormatter->composeHierarchicalName(pNames[i]);
802 CATCH_INFO("Exception from composeHierarchicalName(): ")
803 break;
806 OSL_ENSURE(false, "Cannot create absolute pathes: missing interface");
807 // make local pathes instaed
809 case CONFIG_NAME_LOCAL_PATH:
811 Reference<XTemplateContainer> xTypeContainer(_xParentNode, UNO_QUERY);
812 if (xTypeContainer.is())
814 OUString sTypeName = xTypeContainer->getElementTemplateName();
815 sTypeName = sTypeName.copy(sTypeName.lastIndexOf('/')+1);
817 OUString * pNames = _rNames.getArray();
818 for(int i = 0; i<_rNames.getLength(); ++i)
820 pNames[i] = wrapConfigurationElementName(pNames[i],sTypeName);
823 else
825 static const OUString sSetService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.SetAccess"));
826 Reference<XServiceInfo> xSVI(_xParentNode, UNO_QUERY);
827 if (xSVI.is() && xSVI->supportsService(sSetService))
829 OUString * pNames = _rNames.getArray();
830 for(int i = 0; i<_rNames.getLength(); ++i)
832 pNames[i] = wrapConfigurationElementName(pNames[i]);
837 break;
839 case CONFIG_NAME_PLAINTEXT_NAME:
841 Reference<XStringEscape> xEscaper(_xParentNode, UNO_QUERY);
842 if (xEscaper.is())
844 OUString * pNames = _rNames.getArray();
845 for(int i = 0; i<_rNames.getLength(); ++i)
848 pNames[i] = xEscaper->unescapeString(pNames[i]);
850 CATCH_INFO("Exception from unescapeString(): ")
853 break;
857 /* -----------------------------10.07.00 --------------------------------
859 ---------------------------------------------------------------------------*/
860 Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode)
862 ConfigNameFormat const eDefaultFormat = CONFIG_NAME_LOCAL_NAME; // CONFIG_NAME_DEFAULT;
864 return GetNodeNames(rNode, eDefaultFormat);
866 /* -----------------------------15.09.00 12:06--------------------------------
868 ---------------------------------------------------------------------------*/
869 Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat)
871 Sequence< OUString > aRet;
872 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
873 if(xHierarchyAccess.is())
877 Reference<XNameAccess> xCont;
878 if(rNode.getLength())
880 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
881 aNode >>= xCont;
883 else
884 xCont = Reference<XNameAccess> (xHierarchyAccess, UNO_QUERY);
885 if(xCont.is())
887 aRet = xCont->getElementNames();
888 lcl_normalizeLocalNames(aRet,eFormat,xCont);
892 CATCH_INFO("Exception from GetNodeNames: ");
894 return aRet;
896 /* -----------------------------15.09.00 15:52--------------------------------
898 ---------------------------------------------------------------------------*/
899 sal_Bool ConfigItem::ClearNodeSet(const OUString& rNode)
901 ValueCounter_Impl aCounter(pImpl->nInValueChange);
902 sal_Bool bRet = sal_False;
903 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
904 if(xHierarchyAccess.is())
908 Reference<XNameContainer> xCont;
909 if(rNode.getLength())
911 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
912 aNode >>= xCont;
914 else
915 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
916 if(!xCont.is())
917 return sal_False;
918 Sequence< OUString > aNames = xCont->getElementNames();
919 const OUString* pNames = aNames.getConstArray();
920 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
921 for(sal_Int32 i = 0; i < aNames.getLength(); i++)
925 xCont->removeByName(pNames[i]);
927 CATCH_INFO("Exception from removeByName(): ")
929 xBatch->commitChanges();
930 bRet = sal_True;
932 CATCH_INFO("Exception from ClearNodeSet")
934 return bRet;
936 /* -----------------------------24.11.00 10:58--------------------------------
938 ---------------------------------------------------------------------------*/
939 sal_Bool ConfigItem::ClearNodeElements(const OUString& rNode, Sequence< OUString >& rElements)
941 ValueCounter_Impl aCounter(pImpl->nInValueChange);
942 sal_Bool bRet = sal_False;
943 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
944 if(xHierarchyAccess.is())
946 const OUString* pElements = rElements.getConstArray();
949 Reference<XNameContainer> xCont;
950 if(rNode.getLength())
952 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
953 aNode >>= xCont;
955 else
956 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
957 if(!xCont.is())
958 return sal_False;
961 for(sal_Int32 nElement = 0; nElement < rElements.getLength(); nElement++)
963 xCont->removeByName(pElements[nElement]);
965 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
966 xBatch->commitChanges();
968 CATCH_INFO("Exception from commitChanges(): ")
969 bRet = sal_True;
971 CATCH_INFO("Exception from GetNodeNames: ")
973 return bRet;
975 //----------------------------------------------------------------------------
976 static inline
977 OUString lcl_extractSetPropertyName( const OUString& rInPath, const OUString& rPrefix )
979 OUString const sSubPath = dropPrefixFromConfigurationPath( rInPath, rPrefix);
980 return extractFirstFromConfigurationPath( sSubPath );
982 //----------------------------------------------------------------------------
983 static
984 Sequence< OUString > lcl_extractSetPropertyNames( const Sequence< PropertyValue >& rValues, const OUString& rPrefix )
986 const PropertyValue* pProperties = rValues.getConstArray();
988 Sequence< OUString > aSubNodeNames(rValues.getLength());
989 OUString* pSubNodeNames = aSubNodeNames.getArray();
991 OUString sLastSubNode;
992 sal_Int32 nSubIndex = 0;
994 for(sal_Int32 i = 0; i < rValues.getLength(); i++)
996 OUString const sSubPath = dropPrefixFromConfigurationPath( pProperties[i].Name, rPrefix);
997 OUString const sSubNode = extractFirstFromConfigurationPath( sSubPath );
999 if(sLastSubNode != sSubNode)
1001 pSubNodeNames[nSubIndex++] = sSubNode;
1004 sLastSubNode = sSubNode;
1006 aSubNodeNames.realloc(nSubIndex);
1008 return aSubNodeNames;
1010 /* -----------------------------15.09.00 15:52--------------------------------
1011 add or change properties
1012 ---------------------------------------------------------------------------*/
1013 sal_Bool ConfigItem::SetSetProperties(
1014 const OUString& rNode, Sequence< PropertyValue > rValues)
1016 ValueCounter_Impl aCounter(pImpl->nInValueChange);
1017 sal_Bool bRet = sal_True;
1018 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1019 if(xHierarchyAccess.is())
1021 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
1024 Reference<XNameContainer> xCont;
1025 if(rNode.getLength())
1027 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
1028 aNode >>= xCont;
1030 else
1031 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
1032 if(!xCont.is())
1033 return sal_False;
1035 Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
1037 if(xFac.is())
1039 const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
1041 const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
1043 for(sal_Int32 j = 0; j <nSubNodeCount ; j++)
1045 if(!xCont->hasByName(aSubNodeNames[j]))
1047 Reference<XInterface> xInst = xFac->createInstance();
1048 Any aVal; aVal <<= xInst;
1049 xCont->insertByName(aSubNodeNames[j], aVal);
1051 //set values
1055 xBatch->commitChanges();
1057 CATCH_INFO("Exception from commitChanges(): ")
1059 const PropertyValue* pProperties = rValues.getConstArray();
1061 Sequence< OUString > aSetNames(rValues.getLength());
1062 OUString* pSetNames = aSetNames.getArray();
1064 Sequence< Any> aSetValues(rValues.getLength());
1065 Any* pSetValues = aSetValues.getArray();
1067 sal_Bool bEmptyNode = rNode.getLength() == 0;
1068 for(sal_Int32 k = 0; k < rValues.getLength(); k++)
1070 pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
1071 pSetValues[k] = pProperties[k].Value;
1073 bRet = PutProperties(aSetNames, aSetValues);
1075 else
1077 //if no factory is available then the node contains basic data elements
1078 const PropertyValue* pValues = rValues.getConstArray();
1079 for(int nValue = 0; nValue < rValues.getLength();nValue++)
1083 OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
1085 if(xCont->hasByName(sSubNode))
1086 xCont->replaceByName(sSubNode, pValues[nValue].Value);
1087 else
1088 xCont->insertByName(sSubNode, pValues[nValue].Value);
1090 OSL_ENSURE( xHierarchyAccess->hasByHierarchicalName(pValues[nValue].Name),
1091 "Invalid config path" );
1093 CATCH_INFO("Exception form insert/replaceByName(): ")
1095 xBatch->commitChanges();
1098 #ifdef DBG_UTIL
1099 catch(Exception& rEx)
1101 lcl_CFG_DBG_EXCEPTION("Exception from SetSetProperties: ", rEx);
1102 #else
1103 catch(Exception&)
1105 #endif
1106 bRet = sal_False;
1109 return bRet;
1111 /* -----------------------------15.09.00 15:52--------------------------------
1113 ---------------------------------------------------------------------------*/
1114 sal_Bool ConfigItem::ReplaceSetProperties(
1115 const OUString& rNode, Sequence< PropertyValue > rValues)
1117 ValueCounter_Impl aCounter(pImpl->nInValueChange);
1118 sal_Bool bRet = sal_True;
1119 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1120 if(xHierarchyAccess.is())
1122 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
1125 Reference<XNameContainer> xCont;
1126 if(rNode.getLength())
1128 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
1129 aNode >>= xCont;
1131 else
1132 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
1133 if(!xCont.is())
1134 return sal_False;
1136 // JB: Change: now the same name handling for sets of simple values
1137 const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
1138 const OUString* pSubNodeNames = aSubNodeNames.getConstArray();
1139 const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
1141 Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
1142 const bool isSimpleValueSet = !xFac.is();
1144 //remove unknown members first
1146 const Sequence<OUString> aContainerSubNodes = xCont->getElementNames();
1147 const OUString* pContainerSubNodes = aContainerSubNodes.getConstArray();
1149 for(sal_Int32 nContSub = 0; nContSub < aContainerSubNodes.getLength(); nContSub++)
1151 sal_Bool bFound = sal_False;
1152 for(sal_Int32 j = 0; j < nSubNodeCount; j++)
1154 if(pSubNodeNames[j] == pContainerSubNodes[nContSub])
1156 bFound = sal_True;
1157 break;
1160 if(!bFound)
1163 xCont->removeByName(pContainerSubNodes[nContSub]);
1165 catch (Exception & )
1167 if (isSimpleValueSet)
1170 // #i37322#: fallback action: replace with <void/>
1171 xCont->replaceByName(pContainerSubNodes[nContSub], Any());
1172 // fallback successfull: continue looping
1173 continue;
1175 catch (Exception &)
1176 {} // propagate original exception, if fallback fails
1178 throw;
1181 try { xBatch->commitChanges(); }
1182 CATCH_INFO("Exception from commitChanges(): ")
1185 if(xFac.is()) // !isSimpleValueSet
1187 for(sal_Int32 j = 0; j < nSubNodeCount; j++)
1189 if(!xCont->hasByName(pSubNodeNames[j]))
1191 //create if not available
1192 Reference<XInterface> xInst = xFac->createInstance();
1193 Any aVal; aVal <<= xInst;
1194 xCont->insertByName(pSubNodeNames[j], aVal);
1197 try { xBatch->commitChanges(); }
1198 CATCH_INFO("Exception from commitChanges(): ")
1200 const PropertyValue* pProperties = rValues.getConstArray();
1202 Sequence< OUString > aSetNames(rValues.getLength());
1203 OUString* pSetNames = aSetNames.getArray();
1205 Sequence< Any> aSetValues(rValues.getLength());
1206 Any* pSetValues = aSetValues.getArray();
1208 sal_Bool bEmptyNode = rNode.getLength() == 0;
1209 for(sal_Int32 k = 0; k < rValues.getLength(); k++)
1211 pSetNames[k] = pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
1212 pSetValues[k] = pProperties[k].Value;
1214 bRet = PutProperties(aSetNames, aSetValues);
1216 else
1218 const PropertyValue* pValues = rValues.getConstArray();
1220 //if no factory is available then the node contains basic data elements
1221 for(int nValue = 0; nValue < rValues.getLength();nValue++)
1225 OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
1227 if(xCont->hasByName(sSubNode))
1228 xCont->replaceByName(sSubNode, pValues[nValue].Value);
1229 else
1230 xCont->insertByName(sSubNode, pValues[nValue].Value);
1232 CATCH_INFO("Exception from insert/replaceByName(): ");
1234 xBatch->commitChanges();
1237 #ifdef DBG_UTIL
1238 catch(Exception& rEx)
1240 lcl_CFG_DBG_EXCEPTION("Exception from ReplaceSetProperties: ", rEx);
1241 #else
1242 catch(Exception&)
1244 #endif
1245 bRet = sal_False;
1248 return bRet;
1250 /* -----------------------------07.05.01 12:15--------------------------------
1252 ---------------------------------------------------------------------------*/
1253 sal_Bool ConfigItem::getUniqueSetElementName( const ::rtl::OUString& _rSetNode, ::rtl::OUString& _rName)
1255 ::rtl::OUString sNewElementName;
1256 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1257 sal_Bool bRet = sal_False;
1258 if(xHierarchyAccess.is())
1262 Reference< XNameAccess > xSetNode;
1263 xHierarchyAccess->getByHierarchicalName(_rSetNode) >>= xSetNode;
1264 if (xSetNode.is())
1266 const sal_uInt32 nPrime = 65521; // a prime number
1267 const sal_uInt32 nPrimeLess2 = nPrime - 2;
1268 sal_uInt32 nEngendering = (rand() % nPrimeLess2) + 2; // the engendering of the field
1270 // the element which will loop through the field
1271 sal_uInt32 nFieldElement = nEngendering;
1273 for (; 1 != nFieldElement; nFieldElement = (nFieldElement * nEngendering) % nPrime)
1275 ::rtl::OUString sThisRoundTrial = _rName;
1276 sThisRoundTrial += ::rtl::OUString::valueOf((sal_Int32)nFieldElement);
1278 if (!xSetNode->hasByName(sThisRoundTrial))
1280 _rName = sThisRoundTrial;
1281 bRet = sal_True;
1282 break;
1287 CATCH_INFO("Exception from getUniqueSetElementName(): ")
1289 return bRet;
1291 /* -----------------------------23.01.01 12:49--------------------------------
1293 ---------------------------------------------------------------------------*/
1294 sal_Bool ConfigItem::AddNode(const rtl::OUString& rNode, const rtl::OUString& rNewNode)
1296 ValueCounter_Impl aCounter(pImpl->nInValueChange);
1297 sal_Bool bRet = sal_True;
1298 Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1299 if(xHierarchyAccess.is())
1301 Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
1304 Reference<XNameContainer> xCont;
1305 if(rNode.getLength())
1307 Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
1308 aNode >>= xCont;
1310 else
1311 xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
1312 if(!xCont.is())
1313 return sal_False;
1315 Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
1317 if(xFac.is())
1319 if(!xCont->hasByName(rNewNode))
1321 Reference<XInterface> xInst = xFac->createInstance();
1322 Any aVal; aVal <<= xInst;
1323 xCont->insertByName(rNewNode, aVal);
1327 xBatch->commitChanges();
1329 CATCH_INFO("Exception from commitChanges(): ")
1331 else
1333 //if no factory is available then the node contains basic data elements
1336 if(!xCont->hasByName(rNewNode))
1337 xCont->insertByName(rNewNode, Any());
1339 CATCH_INFO("Exception from AddNode(): ")
1341 xBatch->commitChanges();
1343 #ifdef DBG_UTIL
1344 catch(Exception& rEx)
1346 lcl_CFG_DBG_EXCEPTION("Exception from AddNode(): ", rEx);
1347 #else
1348 catch(Exception&)
1350 #endif
1351 bRet = sal_False;
1354 return bRet;
1356 /* -----------------------------12.02.01 11:38--------------------------------
1358 ---------------------------------------------------------------------------*/
1359 sal_Int16 ConfigItem::GetMode() const
1361 return pImpl->nMode;
1363 /* -----------------------------12.02.01 13:31--------------------------------
1365 ---------------------------------------------------------------------------*/
1366 void ConfigItem::SetModified()
1368 pImpl->bIsModified = sal_True;
1370 /* -----------------------------05.05.01 14:07--------------------------------
1372 ---------------------------------------------------------------------------*/
1373 void ConfigItem::ClearModified()
1375 pImpl->bIsModified = sal_False;
1377 /* -----------------------------12.02.01 13:31--------------------------------
1379 ---------------------------------------------------------------------------*/
1380 sal_Bool ConfigItem::IsModified() const
1382 return pImpl->bIsModified;
1384 /* -----------------------------12.02.01 13:33--------------------------------
1386 ---------------------------------------------------------------------------*/
1387 sal_Bool ConfigItem::IsInValueChange() const
1389 return pImpl->nInValueChange > 0;
1391 /* -----------------------------21.06.01 12:26--------------------------------
1393 ---------------------------------------------------------------------------*/
1394 Reference< XHierarchicalNameAccess> ConfigItem::GetTree()
1396 Reference< XHierarchicalNameAccess> xRet;
1397 if(!m_xHierarchyAccess.is())
1398 xRet = pImpl->pManager->AcquireTree(*this);
1399 else
1400 xRet = m_xHierarchyAccess;
1401 OSL_ENSURE(xRet.is(), "AcquireTree failed");
1402 return xRet;
1404 /* -----------------------------22.06.01 08:42--------------------------------
1406 ---------------------------------------------------------------------------*/
1407 void ConfigItem::LockTree()
1409 OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call LockTree in CONFIG_MODE_RELEASE_TREE mode, only");
1410 m_xHierarchyAccess = GetTree();
1412 /* -----------------------------22.06.01 08:42--------------------------------
1414 ---------------------------------------------------------------------------*/
1415 void ConfigItem::UnlockTree()
1417 OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call UnlockTree in CONFIG_MODE_RELEASE_TREE mode, only");
1418 if(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE))
1419 m_xHierarchyAccess = 0;