1*b1cdbd2cSJim Jagielski /**************************************************************
2*b1cdbd2cSJim Jagielski  *
3*b1cdbd2cSJim Jagielski  * Licensed to the Apache Software Foundation (ASF) under one
4*b1cdbd2cSJim Jagielski  * or more contributor license agreements.  See the NOTICE file
5*b1cdbd2cSJim Jagielski  * distributed with this work for additional information
6*b1cdbd2cSJim Jagielski  * regarding copyright ownership.  The ASF licenses this file
7*b1cdbd2cSJim Jagielski  * to you under the Apache License, Version 2.0 (the
8*b1cdbd2cSJim Jagielski  * "License"); you may not use this file except in compliance
9*b1cdbd2cSJim Jagielski  * with the License.  You may obtain a copy of the License at
10*b1cdbd2cSJim Jagielski  *
11*b1cdbd2cSJim Jagielski  *   http://www.apache.org/licenses/LICENSE-2.0
12*b1cdbd2cSJim Jagielski  *
13*b1cdbd2cSJim Jagielski  * Unless required by applicable law or agreed to in writing,
14*b1cdbd2cSJim Jagielski  * software distributed under the License is distributed on an
15*b1cdbd2cSJim Jagielski  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*b1cdbd2cSJim Jagielski  * KIND, either express or implied.  See the License for the
17*b1cdbd2cSJim Jagielski  * specific language governing permissions and limitations
18*b1cdbd2cSJim Jagielski  * under the License.
19*b1cdbd2cSJim Jagielski  *
20*b1cdbd2cSJim Jagielski  *************************************************************/
21*b1cdbd2cSJim Jagielski 
22*b1cdbd2cSJim Jagielski 
23*b1cdbd2cSJim Jagielski 
24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove
25*b1cdbd2cSJim Jagielski #include "precompiled_unotools.hxx"
26*b1cdbd2cSJim Jagielski #include "unotools/configitem.hxx"
27*b1cdbd2cSJim Jagielski #include "unotools/configmgr.hxx"
28*b1cdbd2cSJim Jagielski #include "unotools/configpathes.hxx"
29*b1cdbd2cSJim Jagielski #include <comphelper/processfactory.hxx>
30*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/XMultiPropertySet.hpp>
31*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/XPropertySet.hpp>
32*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XChangesListener.hpp>
33*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XChangesNotifier.hpp>
34*b1cdbd2cSJim Jagielski #include <com/sun/star/container/XHierarchicalNameAccess.hpp>
35*b1cdbd2cSJim Jagielski #include <com/sun/star/container/XHierarchicalName.hpp>
36*b1cdbd2cSJim Jagielski #include <com/sun/star/configuration/XTemplateContainer.hpp>
37*b1cdbd2cSJim Jagielski #include <com/sun/star/container/XNameContainer.hpp>
38*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XSingleServiceFactory.hpp>
39*b1cdbd2cSJim Jagielski #include <com/sun/star/lang/XServiceInfo.hpp>
40*b1cdbd2cSJim Jagielski #include <com/sun/star/awt/XRequestCallback.hpp>
41*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/PropertyValue.hpp>
42*b1cdbd2cSJim Jagielski #include <com/sun/star/beans/PropertyAttribute.hpp>
43*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XStringEscape.hpp>
44*b1cdbd2cSJim Jagielski #include <com/sun/star/util/XChangesBatch.hpp>
45*b1cdbd2cSJim Jagielski #include <osl/diagnose.h>
46*b1cdbd2cSJim Jagielski #include <tools/solarmutex.hxx>
47*b1cdbd2cSJim Jagielski #include <rtl/ustrbuf.hxx>
48*b1cdbd2cSJim Jagielski 
49*b1cdbd2cSJim Jagielski using namespace utl;
50*b1cdbd2cSJim Jagielski using rtl::OUString;
51*b1cdbd2cSJim Jagielski using rtl::OString;
52*b1cdbd2cSJim Jagielski using namespace com::sun::star::uno;
53*b1cdbd2cSJim Jagielski using namespace com::sun::star::util;
54*b1cdbd2cSJim Jagielski using namespace com::sun::star::lang;
55*b1cdbd2cSJim Jagielski using namespace com::sun::star::beans;
56*b1cdbd2cSJim Jagielski using namespace com::sun::star::container;
57*b1cdbd2cSJim Jagielski using namespace com::sun::star::configuration;
58*b1cdbd2cSJim Jagielski 
59*b1cdbd2cSJim Jagielski #define C2U(cChar) OUString::createFromAscii(cChar)
60*b1cdbd2cSJim Jagielski #include <cppuhelper/implbase1.hxx> // helper for implementations
61*b1cdbd2cSJim Jagielski 
62*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL
lcl_CFG_DBG_EXCEPTION(const sal_Char * cText,const Exception & rEx)63*b1cdbd2cSJim Jagielski inline void lcl_CFG_DBG_EXCEPTION(const sal_Char* cText, const Exception& rEx)
64*b1cdbd2cSJim Jagielski {
65*b1cdbd2cSJim Jagielski 	OString sMsg(cText);
66*b1cdbd2cSJim Jagielski 	sMsg += OString(rEx.Message.getStr(), rEx.Message.getLength(), RTL_TEXTENCODING_ASCII_US);
67*b1cdbd2cSJim Jagielski 	OSL_ENSURE(sal_False, sMsg.getStr());
68*b1cdbd2cSJim Jagielski }
69*b1cdbd2cSJim Jagielski #define CATCH_INFO(a) \
70*b1cdbd2cSJim Jagielski catch(Exception& rEx)   \
71*b1cdbd2cSJim Jagielski {                       \
72*b1cdbd2cSJim Jagielski     lcl_CFG_DBG_EXCEPTION(a, rEx);\
73*b1cdbd2cSJim Jagielski }
74*b1cdbd2cSJim Jagielski #else
75*b1cdbd2cSJim Jagielski 	#define lcl_CFG_DBG_EXCEPTION( a, b)
76*b1cdbd2cSJim Jagielski     #define CATCH_INFO(a) catch(Exception& ){}
77*b1cdbd2cSJim Jagielski #endif
78*b1cdbd2cSJim Jagielski 
79*b1cdbd2cSJim Jagielski /*
80*b1cdbd2cSJim Jagielski 	The ConfigChangeListener_Impl receives notifications from the configuration about changes that
81*b1cdbd2cSJim Jagielski 	have happened. It forwards this notification to the ConfigItem it knows a pParent by calling its
82*b1cdbd2cSJim Jagielski 	"CallNotify" method. As ConfigItems are most probably not thread safe, the SolarMutex is acquired
83*b1cdbd2cSJim Jagielski 	before doing so.
84*b1cdbd2cSJim Jagielski */
85*b1cdbd2cSJim Jagielski 
86*b1cdbd2cSJim Jagielski namespace utl{
87*b1cdbd2cSJim Jagielski     class ConfigChangeListener_Impl : public cppu::WeakImplHelper1
88*b1cdbd2cSJim Jagielski 	<
89*b1cdbd2cSJim Jagielski         com::sun::star::util::XChangesListener
90*b1cdbd2cSJim Jagielski 	>
91*b1cdbd2cSJim Jagielski 	{
92*b1cdbd2cSJim Jagielski 		public:
93*b1cdbd2cSJim Jagielski 			ConfigItem* 				pParent;
94*b1cdbd2cSJim Jagielski 			const Sequence< OUString > 	aPropertyNames;
95*b1cdbd2cSJim Jagielski 			ConfigChangeListener_Impl(ConfigItem& rItem, const Sequence< OUString >& rNames);
96*b1cdbd2cSJim Jagielski 			~ConfigChangeListener_Impl();
97*b1cdbd2cSJim Jagielski 
98*b1cdbd2cSJim Jagielski 		//XChangesListener
99*b1cdbd2cSJim Jagielski     	virtual void SAL_CALL changesOccurred( const ChangesEvent& Event ) throw(RuntimeException);
100*b1cdbd2cSJim Jagielski 
101*b1cdbd2cSJim Jagielski 		//XEventListener
102*b1cdbd2cSJim Jagielski     	virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException);
103*b1cdbd2cSJim Jagielski 	};
104*b1cdbd2cSJim Jagielski /* -----------------------------12.02.01 11:38--------------------------------
105*b1cdbd2cSJim Jagielski 
106*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
107*b1cdbd2cSJim Jagielski struct ConfigItem_Impl
108*b1cdbd2cSJim Jagielski {
109*b1cdbd2cSJim Jagielski 	utl::ConfigManager* 		pManager;
110*b1cdbd2cSJim Jagielski    	sal_Int16 					nMode;
111*b1cdbd2cSJim Jagielski 	sal_Bool					bIsModified;
112*b1cdbd2cSJim Jagielski     sal_Bool                    bEnableInternalNotification;
113*b1cdbd2cSJim Jagielski 
114*b1cdbd2cSJim Jagielski 	sal_Int16					nInValueChange;
ConfigItem_Implutl::ConfigItem_Impl115*b1cdbd2cSJim Jagielski 	ConfigItem_Impl() :
116*b1cdbd2cSJim Jagielski 		pManager(0),
117*b1cdbd2cSJim Jagielski 		nMode(0),
118*b1cdbd2cSJim Jagielski 		bIsModified(sal_False),
119*b1cdbd2cSJim Jagielski         bEnableInternalNotification(sal_False),
120*b1cdbd2cSJim Jagielski 		nInValueChange(0)
121*b1cdbd2cSJim Jagielski     {}
122*b1cdbd2cSJim Jagielski };
123*b1cdbd2cSJim Jagielski }
124*b1cdbd2cSJim Jagielski /* -----------------------------04.12.00 10:25--------------------------------
125*b1cdbd2cSJim Jagielski 
126*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
127*b1cdbd2cSJim Jagielski class ValueCounter_Impl
128*b1cdbd2cSJim Jagielski {
129*b1cdbd2cSJim Jagielski 	sal_Int16& rCnt;
130*b1cdbd2cSJim Jagielski public:
ValueCounter_Impl(sal_Int16 & rCounter)131*b1cdbd2cSJim Jagielski 	ValueCounter_Impl(sal_Int16& rCounter):
132*b1cdbd2cSJim Jagielski 		rCnt(rCounter)
133*b1cdbd2cSJim Jagielski 			{rCnt++;}
~ValueCounter_Impl()134*b1cdbd2cSJim Jagielski 	~ValueCounter_Impl()
135*b1cdbd2cSJim Jagielski 			{
136*b1cdbd2cSJim Jagielski 				OSL_ENSURE(rCnt>0, "RefCount < 0 ??");
137*b1cdbd2cSJim Jagielski 				rCnt--;
138*b1cdbd2cSJim Jagielski 			}
139*b1cdbd2cSJim Jagielski };
140*b1cdbd2cSJim Jagielski /* -----------------------------03.12.02 -------------------------------------
141*b1cdbd2cSJim Jagielski 
142*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
143*b1cdbd2cSJim Jagielski namespace
144*b1cdbd2cSJim Jagielski {
145*b1cdbd2cSJim Jagielski     // helper to achieve exception - safe handling of an Item under construction
146*b1cdbd2cSJim Jagielski     template <class TYP>
147*b1cdbd2cSJim Jagielski     class AutoDeleter // : Noncopyable
148*b1cdbd2cSJim Jagielski     {
149*b1cdbd2cSJim Jagielski         TYP* m_pItem;
150*b1cdbd2cSJim Jagielski     public:
AutoDeleter(TYP * pItem)151*b1cdbd2cSJim Jagielski         AutoDeleter(TYP * pItem)
152*b1cdbd2cSJim Jagielski         : m_pItem(pItem)
153*b1cdbd2cSJim Jagielski         {
154*b1cdbd2cSJim Jagielski         }
155*b1cdbd2cSJim Jagielski 
~AutoDeleter()156*b1cdbd2cSJim Jagielski         ~AutoDeleter()
157*b1cdbd2cSJim Jagielski         {
158*b1cdbd2cSJim Jagielski             delete m_pItem;
159*b1cdbd2cSJim Jagielski         }
160*b1cdbd2cSJim Jagielski 
keep()161*b1cdbd2cSJim Jagielski         void keep() { m_pItem = 0; }
162*b1cdbd2cSJim Jagielski     };
163*b1cdbd2cSJim Jagielski }
164*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 16:34--------------------------------
165*b1cdbd2cSJim Jagielski 
166*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
ConfigChangeListener_Impl(ConfigItem & rItem,const Sequence<OUString> & rNames)167*b1cdbd2cSJim Jagielski ConfigChangeListener_Impl::ConfigChangeListener_Impl(
168*b1cdbd2cSJim Jagielski 			 ConfigItem& rItem, const Sequence< OUString >& rNames) :
169*b1cdbd2cSJim Jagielski 	pParent(&rItem),
170*b1cdbd2cSJim Jagielski 	aPropertyNames(rNames)
171*b1cdbd2cSJim Jagielski {
172*b1cdbd2cSJim Jagielski }
173*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 16:34--------------------------------
174*b1cdbd2cSJim Jagielski 
175*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
~ConfigChangeListener_Impl()176*b1cdbd2cSJim Jagielski ConfigChangeListener_Impl::~ConfigChangeListener_Impl()
177*b1cdbd2cSJim Jagielski {
178*b1cdbd2cSJim Jagielski }
179*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 16:34--------------------------------
180*b1cdbd2cSJim Jagielski 
181*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
lcl_Find(const rtl::OUString & rTemp,const OUString * pCheckPropertyNames,sal_Int32 nLength)182*b1cdbd2cSJim Jagielski sal_Bool lcl_Find(
183*b1cdbd2cSJim Jagielski 		const rtl::OUString& rTemp,
184*b1cdbd2cSJim Jagielski 		const OUString* pCheckPropertyNames,
185*b1cdbd2cSJim Jagielski 		sal_Int32 nLength)
186*b1cdbd2cSJim Jagielski {
187*b1cdbd2cSJim Jagielski 	//return true if the path is completely correct or if it is longer
188*b1cdbd2cSJim Jagielski 	//i.e ...Print/Content/Graphic and .../Print
189*b1cdbd2cSJim Jagielski 	for(sal_Int32 nIndex = 0; nIndex < nLength; nIndex++)
190*b1cdbd2cSJim Jagielski 		if( isPrefixOfConfigurationPath(rTemp, pCheckPropertyNames[nIndex]) )
191*b1cdbd2cSJim Jagielski 			return sal_True;
192*b1cdbd2cSJim Jagielski 	return sal_False;
193*b1cdbd2cSJim Jagielski }
194*b1cdbd2cSJim Jagielski //-----------------------------------------------------------------------------
changesOccurred(const ChangesEvent & rEvent)195*b1cdbd2cSJim Jagielski void ConfigChangeListener_Impl::changesOccurred( const ChangesEvent& rEvent ) throw(RuntimeException)
196*b1cdbd2cSJim Jagielski {
197*b1cdbd2cSJim Jagielski 	const ElementChange* pElementChanges = rEvent.Changes.getConstArray();
198*b1cdbd2cSJim Jagielski 
199*b1cdbd2cSJim Jagielski 	Sequence<OUString>	aChangedNames(rEvent.Changes.getLength());
200*b1cdbd2cSJim Jagielski 	OUString* pNames = aChangedNames.getArray();
201*b1cdbd2cSJim Jagielski 
202*b1cdbd2cSJim Jagielski 	const OUString* pCheckPropertyNames = aPropertyNames.getConstArray();
203*b1cdbd2cSJim Jagielski 
204*b1cdbd2cSJim Jagielski 	sal_Int32 nNotify = 0;
205*b1cdbd2cSJim Jagielski 	for(int i = 0; i < aChangedNames.getLength(); i++)
206*b1cdbd2cSJim Jagielski 	{
207*b1cdbd2cSJim Jagielski 		OUString sTemp;
208*b1cdbd2cSJim Jagielski 		pElementChanges[i].Accessor >>= sTemp;
209*b1cdbd2cSJim Jagielski 		if(lcl_Find(sTemp, pCheckPropertyNames, aPropertyNames.getLength()))
210*b1cdbd2cSJim Jagielski 			pNames[nNotify++] = sTemp;
211*b1cdbd2cSJim Jagielski 	}
212*b1cdbd2cSJim Jagielski 	if( nNotify )
213*b1cdbd2cSJim Jagielski 	{
214*b1cdbd2cSJim Jagielski 		if ( ::tools::SolarMutex::Acquire() )
215*b1cdbd2cSJim Jagielski 		{
216*b1cdbd2cSJim Jagielski 			aChangedNames.realloc(nNotify);
217*b1cdbd2cSJim Jagielski 			pParent->CallNotify(aChangedNames);
218*b1cdbd2cSJim Jagielski 			::tools::SolarMutex::Release();
219*b1cdbd2cSJim Jagielski 		}
220*b1cdbd2cSJim Jagielski 	}
221*b1cdbd2cSJim Jagielski }
222*b1cdbd2cSJim Jagielski 
223*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 16:34--------------------------------
224*b1cdbd2cSJim Jagielski 
225*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
disposing(const EventObject &)226*b1cdbd2cSJim Jagielski void ConfigChangeListener_Impl::disposing( const EventObject& /*rSource*/ ) throw(RuntimeException)
227*b1cdbd2cSJim Jagielski {
228*b1cdbd2cSJim Jagielski 	pParent->RemoveChangesListener();
229*b1cdbd2cSJim Jagielski }
230*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 12:50--------------------------------
231*b1cdbd2cSJim Jagielski 
232*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
ConfigItem(const OUString rSubTree,sal_Int16 nSetMode)233*b1cdbd2cSJim Jagielski ConfigItem::ConfigItem(const OUString rSubTree, sal_Int16 nSetMode ) :
234*b1cdbd2cSJim Jagielski 	sSubTree(rSubTree),
235*b1cdbd2cSJim Jagielski 	pImpl(new ConfigItem_Impl)
236*b1cdbd2cSJim Jagielski {
237*b1cdbd2cSJim Jagielski     AutoDeleter<ConfigItem_Impl> aNewImpl(pImpl);
238*b1cdbd2cSJim Jagielski 
239*b1cdbd2cSJim Jagielski 	pImpl->pManager = ConfigManager::GetConfigManager();
240*b1cdbd2cSJim Jagielski 	pImpl->nMode = nSetMode;
241*b1cdbd2cSJim Jagielski     if(0 != (nSetMode&CONFIG_MODE_RELEASE_TREE))
242*b1cdbd2cSJim Jagielski         pImpl->pManager->AddConfigItem(*this);
243*b1cdbd2cSJim Jagielski     else
244*b1cdbd2cSJim Jagielski         m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this);
245*b1cdbd2cSJim Jagielski 
246*b1cdbd2cSJim Jagielski     // no more exceptions after c'tor has finished
247*b1cdbd2cSJim Jagielski     aNewImpl.keep();
248*b1cdbd2cSJim Jagielski 	pImpl->nMode &= ~CONFIG_MODE_PROPAGATE_ERRORS;
249*b1cdbd2cSJim Jagielski }
250*b1cdbd2cSJim Jagielski /* -----------------------------17.11.00 13:53--------------------------------
251*b1cdbd2cSJim Jagielski 
252*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
ConfigItem(utl::ConfigManager & rManager,const rtl::OUString rSubTree)253*b1cdbd2cSJim Jagielski ConfigItem::ConfigItem(utl::ConfigManager& 	rManager, const rtl::OUString rSubTree) :
254*b1cdbd2cSJim Jagielski 	sSubTree(rSubTree),
255*b1cdbd2cSJim Jagielski 	pImpl(new ConfigItem_Impl)
256*b1cdbd2cSJim Jagielski {
257*b1cdbd2cSJim Jagielski 	pImpl->pManager = &rManager;
258*b1cdbd2cSJim Jagielski 	pImpl->nMode = CONFIG_MODE_IMMEDIATE_UPDATE; // does not allow exceptions
259*b1cdbd2cSJim Jagielski     m_xHierarchyAccess = pImpl->pManager->AddConfigItem(*this);
260*b1cdbd2cSJim Jagielski }
261*b1cdbd2cSJim Jagielski //---------------------------------------------------------------------
262*b1cdbd2cSJim Jagielski //--- 02.08.2002 16:33:23 -----------------------------------------------
IsValidConfigMgr() const263*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::IsValidConfigMgr() const
264*b1cdbd2cSJim Jagielski {
265*b1cdbd2cSJim Jagielski 	return ( pImpl->pManager && pImpl->pManager->GetConfigurationProvider().is() );
266*b1cdbd2cSJim Jagielski }
267*b1cdbd2cSJim Jagielski 
268*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 12:52--------------------------------
269*b1cdbd2cSJim Jagielski 
270*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
~ConfigItem()271*b1cdbd2cSJim Jagielski ConfigItem::~ConfigItem()
272*b1cdbd2cSJim Jagielski {
273*b1cdbd2cSJim Jagielski 	if(pImpl->pManager)
274*b1cdbd2cSJim Jagielski 	{
275*b1cdbd2cSJim Jagielski         RemoveChangesListener();
276*b1cdbd2cSJim Jagielski 		pImpl->pManager->RemoveConfigItem(*this);
277*b1cdbd2cSJim Jagielski 	}
278*b1cdbd2cSJim Jagielski 	delete pImpl;
279*b1cdbd2cSJim Jagielski }
280*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 12:52--------------------------------
281*b1cdbd2cSJim Jagielski 
282*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
ReleaseConfigMgr()283*b1cdbd2cSJim Jagielski void	ConfigItem::ReleaseConfigMgr()
284*b1cdbd2cSJim Jagielski {
285*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
286*b1cdbd2cSJim Jagielski     if(xHierarchyAccess.is())
287*b1cdbd2cSJim Jagielski 	{
288*b1cdbd2cSJim Jagielski 		try
289*b1cdbd2cSJim Jagielski 		{
290*b1cdbd2cSJim Jagielski 			Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
291*b1cdbd2cSJim Jagielski 			xBatch->commitChanges();
292*b1cdbd2cSJim Jagielski 		}
293*b1cdbd2cSJim Jagielski         CATCH_INFO("Exception from commitChanges(): ")
294*b1cdbd2cSJim Jagielski 	}
295*b1cdbd2cSJim Jagielski 	RemoveChangesListener();
296*b1cdbd2cSJim Jagielski 	OSL_ENSURE(pImpl->pManager, "ConfigManager already released");
297*b1cdbd2cSJim Jagielski 	pImpl->pManager = 0;
298*b1cdbd2cSJim Jagielski }
299*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 12:52--------------------------------
300*b1cdbd2cSJim Jagielski 
301*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
CallNotify(const com::sun::star::uno::Sequence<OUString> & rPropertyNames)302*b1cdbd2cSJim Jagielski void ConfigItem::CallNotify( const com::sun::star::uno::Sequence<OUString>& rPropertyNames )
303*b1cdbd2cSJim Jagielski {
304*b1cdbd2cSJim Jagielski 	// the call is forwarded to the virtual Notify() method
305*b1cdbd2cSJim Jagielski 	// it is pure virtual, so all classes deriving from ConfigItem have to decide how they
306*b1cdbd2cSJim Jagielski 	// want to notify listeners
307*b1cdbd2cSJim Jagielski     if(!IsInValueChange() || pImpl->bEnableInternalNotification)
308*b1cdbd2cSJim Jagielski 		Notify(rPropertyNames);
309*b1cdbd2cSJim Jagielski }
310*b1cdbd2cSJim Jagielski 
311*b1cdbd2cSJim Jagielski /* -----------------------------12.12.00 17:09--------------------------------
312*b1cdbd2cSJim Jagielski 
313*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
lcl_IsLocalProperty(const OUString & rSubTree,const OUString & rProperty)314*b1cdbd2cSJim Jagielski sal_Bool lcl_IsLocalProperty(const OUString& rSubTree, const OUString& rProperty)
315*b1cdbd2cSJim Jagielski {
316*b1cdbd2cSJim Jagielski 	static const sal_Char* aLocalProperties[] =
317*b1cdbd2cSJim Jagielski 	{
318*b1cdbd2cSJim Jagielski 		"Office.Common/Path/Current/Storage",
319*b1cdbd2cSJim Jagielski         "Office.Common/Path/Current/Temp"
320*b1cdbd2cSJim Jagielski 	};
321*b1cdbd2cSJim Jagielski 	static const int aLocalPropLen[] =
322*b1cdbd2cSJim Jagielski 	{
323*b1cdbd2cSJim Jagielski 		34,
324*b1cdbd2cSJim Jagielski         31
325*b1cdbd2cSJim Jagielski 	};
326*b1cdbd2cSJim Jagielski 	OUString sProperty(rSubTree);
327*b1cdbd2cSJim Jagielski 	sProperty += C2U("/");
328*b1cdbd2cSJim Jagielski 	sProperty += rProperty;
329*b1cdbd2cSJim Jagielski 
330*b1cdbd2cSJim Jagielski 	if(sProperty.equalsAsciiL( aLocalProperties[0], aLocalPropLen[0]) ||
331*b1cdbd2cSJim Jagielski         sProperty.equalsAsciiL( aLocalProperties[1], aLocalPropLen[1]))
332*b1cdbd2cSJim Jagielski 		return sal_True;
333*b1cdbd2cSJim Jagielski 
334*b1cdbd2cSJim Jagielski 	return sal_False;
335*b1cdbd2cSJim Jagielski }
336*b1cdbd2cSJim Jagielski /* -----------------------------10.04.01 15:00--------------------------------
337*b1cdbd2cSJim Jagielski 
338*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
impl_packLocalizedProperties(const Sequence<OUString> & lInNames,const Sequence<Any> & lInValues,Sequence<Any> & lOutValues)339*b1cdbd2cSJim Jagielski void ConfigItem::impl_packLocalizedProperties(	const	Sequence< OUString >&	lInNames	,
340*b1cdbd2cSJim Jagielski 												const	Sequence< Any >&		lInValues	,
341*b1cdbd2cSJim Jagielski 														Sequence< Any >&		lOutValues	)
342*b1cdbd2cSJim Jagielski {
343*b1cdbd2cSJim Jagielski 	// Safe impossible cases.
344*b1cdbd2cSJim Jagielski 	// This method should be called for special ConfigItem-mode only!
345*b1cdbd2cSJim Jagielski     OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_packLocalizedProperties()\nWrong call of this method detected!\n" );
346*b1cdbd2cSJim Jagielski 
347*b1cdbd2cSJim Jagielski 	sal_Int32					nSourceCounter		;	// used to step during input lists
348*b1cdbd2cSJim Jagielski 	sal_Int32					nSourceSize			;	// marks end of loop over input lists
349*b1cdbd2cSJim Jagielski 	sal_Int32					nDestinationCounter	;	// actual position in output lists
350*b1cdbd2cSJim Jagielski 	sal_Int32					nPropertyCounter	;	// counter of inner loop for Sequence< PropertyValue >
351*b1cdbd2cSJim Jagielski 	sal_Int32					nPropertiesSize		;	// marks end of inner loop
352*b1cdbd2cSJim Jagielski 	Sequence< OUString >		lPropertyNames		;	// list of all locales for localized entry
353*b1cdbd2cSJim Jagielski 	Sequence< PropertyValue >	lProperties			;	// localized values of an configuration entry packed for return
354*b1cdbd2cSJim Jagielski 	Reference< XInterface >		xLocalizedNode		;	// if cfg entry is localized ... lInValues contains an XInterface!
355*b1cdbd2cSJim Jagielski 
356*b1cdbd2cSJim Jagielski 	// Optimise follow algorithm ... A LITTLE BIT :-)
357*b1cdbd2cSJim Jagielski 	// There exist two different possibilities:
358*b1cdbd2cSJim Jagielski 	//	i )	There exist no localized entries ...						=>	size of lOutValues will be the same like lInNames/lInValues!
359*b1cdbd2cSJim Jagielski 	//	ii)	There exist some (mostly one or two) localized entries ...	=>	size of lOutValues will be the same like lInNames/lInValues!
360*b1cdbd2cSJim Jagielski 	//	... Why? If a localized value exist - the any is filled with an XInterface object (is a SetNode-service).
361*b1cdbd2cSJim Jagielski 	//		We read all his child nodes and pack it into Sequence< PropertyValue >.
362*b1cdbd2cSJim Jagielski 	//		The result list we pack into the return any. We never change size of lists!
363*b1cdbd2cSJim Jagielski 	nSourceSize = lInNames.getLength();
364*b1cdbd2cSJim Jagielski 	lOutValues.realloc( nSourceSize );
365*b1cdbd2cSJim Jagielski 
366*b1cdbd2cSJim Jagielski 	// Algorithm:
367*b1cdbd2cSJim Jagielski 	// Copy all names and values from in to out lists.
368*b1cdbd2cSJim Jagielski 	// Look for special localized entries ... You can detect it as "XInterface" packed into an Any.
369*b1cdbd2cSJim Jagielski 	// Use this XInterface-object to read all localized values and pack it into Sequence< PropertValue >.
370*b1cdbd2cSJim Jagielski 	// Add this list to out lists then.
371*b1cdbd2cSJim Jagielski 
372*b1cdbd2cSJim Jagielski 	nDestinationCounter = 0;
373*b1cdbd2cSJim Jagielski 	for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
374*b1cdbd2cSJim Jagielski 	{
375*b1cdbd2cSJim Jagielski 		// If item a special localized one ... convert and pack it ...
376*b1cdbd2cSJim Jagielski 		if( lInValues[nSourceCounter].getValueTypeName() == C2U("com.sun.star.uno.XInterface") )
377*b1cdbd2cSJim Jagielski 		{
378*b1cdbd2cSJim Jagielski 			lInValues[nSourceCounter] >>= xLocalizedNode;
379*b1cdbd2cSJim Jagielski 			Reference< XNameContainer > xSetAccess( xLocalizedNode, UNO_QUERY );
380*b1cdbd2cSJim Jagielski 			if( xSetAccess.is() == sal_True )
381*b1cdbd2cSJim Jagielski 			{
382*b1cdbd2cSJim Jagielski 				lPropertyNames	=	xSetAccess->getElementNames()	;
383*b1cdbd2cSJim Jagielski 				nPropertiesSize	=	lPropertyNames.getLength()		;
384*b1cdbd2cSJim Jagielski 				lProperties.realloc( nPropertiesSize )				;
385*b1cdbd2cSJim Jagielski 
386*b1cdbd2cSJim Jagielski 				for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
387*b1cdbd2cSJim Jagielski 				{
388*b1cdbd2cSJim Jagielski                     #if OSL_DEBUG_LEVEL > 1
389*b1cdbd2cSJim Jagielski 					// Sometimes it's better to see what's going on :-)
390*b1cdbd2cSJim Jagielski                     OUString sPropName   = lInNames[nSourceCounter];
391*b1cdbd2cSJim Jagielski                     OUString sLocaleName = lPropertyNames[nPropertyCounter];
392*b1cdbd2cSJim Jagielski 					#endif
393*b1cdbd2cSJim Jagielski 					lProperties[nPropertyCounter].Name	=	lPropertyNames[nPropertyCounter]							;
394*b1cdbd2cSJim Jagielski 					OUString sLocaleValue;
395*b1cdbd2cSJim Jagielski 					xSetAccess->getByName( lPropertyNames[nPropertyCounter] ) >>= sLocaleValue	;
396*b1cdbd2cSJim Jagielski 					lProperties[nPropertyCounter].Value	<<=	sLocaleValue;
397*b1cdbd2cSJim Jagielski 				}
398*b1cdbd2cSJim Jagielski 
399*b1cdbd2cSJim Jagielski 				lOutValues[nDestinationCounter] <<= lProperties;
400*b1cdbd2cSJim Jagielski 			}
401*b1cdbd2cSJim Jagielski 		}
402*b1cdbd2cSJim Jagielski 		// ... or copy normal items to return lists directly.
403*b1cdbd2cSJim Jagielski 		else
404*b1cdbd2cSJim Jagielski 		{
405*b1cdbd2cSJim Jagielski 			lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
406*b1cdbd2cSJim Jagielski 		}
407*b1cdbd2cSJim Jagielski 		++nDestinationCounter;
408*b1cdbd2cSJim Jagielski 	}
409*b1cdbd2cSJim Jagielski }
410*b1cdbd2cSJim Jagielski /* -----------------------------10.04.01 15:00--------------------------------
411*b1cdbd2cSJim Jagielski 
412*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
impl_unpackLocalizedProperties(const Sequence<OUString> & lInNames,const Sequence<Any> & lInValues,Sequence<OUString> & lOutNames,Sequence<Any> & lOutValues)413*b1cdbd2cSJim Jagielski void ConfigItem::impl_unpackLocalizedProperties(	const	Sequence< OUString >&	lInNames	,
414*b1cdbd2cSJim Jagielski 													const	Sequence< Any >&		lInValues	,
415*b1cdbd2cSJim Jagielski 															Sequence< OUString >&	lOutNames	,
416*b1cdbd2cSJim Jagielski 															Sequence< Any >&		lOutValues	)
417*b1cdbd2cSJim Jagielski {
418*b1cdbd2cSJim Jagielski 	// Safe impossible cases.
419*b1cdbd2cSJim Jagielski 	// This method should be called for special ConfigItem-mode only!
420*b1cdbd2cSJim Jagielski     OSL_ENSURE( ((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES), "ConfigItem::impl_unpackLocalizedProperties()\nWrong call of this method detected!\n" );
421*b1cdbd2cSJim Jagielski 
422*b1cdbd2cSJim Jagielski 	sal_Int32					nSourceCounter		;	// used to step during input lists
423*b1cdbd2cSJim Jagielski 	sal_Int32					nSourceSize			;	// marks end of loop over input lists
424*b1cdbd2cSJim Jagielski 	sal_Int32					nDestinationCounter	;	// actual position in output lists
425*b1cdbd2cSJim Jagielski 	sal_Int32					nPropertyCounter	;	// counter of inner loop for Sequence< PropertyValue >
426*b1cdbd2cSJim Jagielski 	sal_Int32					nPropertiesSize		;	// marks end of inner loop
427*b1cdbd2cSJim Jagielski 	OUString					sNodeName			;	// base name of node ( e.g. "UIName/" ) ... expand to locale ( e.g. "UIName/de" )
428*b1cdbd2cSJim Jagielski 	Sequence< PropertyValue >	lProperties			;	// localized values of an configuration entry getted from lInValues-Any
429*b1cdbd2cSJim Jagielski 
430*b1cdbd2cSJim Jagielski 	// Optimise follow algorithm ... A LITTLE BIT :-)
431*b1cdbd2cSJim Jagielski 	// There exist two different possibilities:
432*b1cdbd2cSJim Jagielski 	//	i )	There exist no localized entries ...						=>	size of lOutNames/lOutValues will be the same like lInNames/lInValues!
433*b1cdbd2cSJim Jagielski 	//	ii)	There exist some (mostly one or two) localized entries ...	=>	size of lOutNames/lOutValues will be some bytes greater then lInNames/lInValues.
434*b1cdbd2cSJim Jagielski 	//	=>	I think we should make it fast for i). ii) is a special case and mustn't be SOOOO... fast.
435*b1cdbd2cSJim Jagielski 	//		We should reserve same space for output list like input ones first.
436*b1cdbd2cSJim Jagielski 	//		Follow algorithm looks for these borders and change it for ii) only!
437*b1cdbd2cSJim Jagielski 	//		It will be faster then a "realloc()" call in every loop ...
438*b1cdbd2cSJim Jagielski 	nSourceSize = lInNames.getLength();
439*b1cdbd2cSJim Jagielski 
440*b1cdbd2cSJim Jagielski 	lOutNames.realloc	( nSourceSize );
441*b1cdbd2cSJim Jagielski 	lOutValues.realloc	( nSourceSize );
442*b1cdbd2cSJim Jagielski 
443*b1cdbd2cSJim Jagielski 	// Algorithm:
444*b1cdbd2cSJim Jagielski 	// Copy all names and values from const to return lists.
445*b1cdbd2cSJim Jagielski 	// Look for special localized entries ... You can detect it as Sequence< PropertyValue > packed into an Any.
446*b1cdbd2cSJim Jagielski 	// Split it ... insert PropertyValue.Name to lOutNames and PropertyValue.Value to lOutValues.
447*b1cdbd2cSJim Jagielski 
448*b1cdbd2cSJim Jagielski 	nDestinationCounter = 0;
449*b1cdbd2cSJim Jagielski 	for( nSourceCounter=0; nSourceCounter<nSourceSize; ++nSourceCounter )
450*b1cdbd2cSJim Jagielski 	{
451*b1cdbd2cSJim Jagielski 		// If item a special localized one ... split it and insert his parts to output lists ...
452*b1cdbd2cSJim Jagielski 		if( lInValues[nSourceCounter].getValueType() == ::getCppuType( (const Sequence< PropertyValue >*)NULL ) )
453*b1cdbd2cSJim Jagielski 		{
454*b1cdbd2cSJim Jagielski 			lInValues[nSourceCounter]	>>=	lProperties				;
455*b1cdbd2cSJim Jagielski 			sNodeName				=	lInNames[nSourceCounter] 	;
456*b1cdbd2cSJim Jagielski 			sNodeName				+=	C2U("/")					;
457*b1cdbd2cSJim Jagielski 			nPropertiesSize			=	lProperties.getLength()		;
458*b1cdbd2cSJim Jagielski 
459*b1cdbd2cSJim Jagielski 			if( (nDestinationCounter+nPropertiesSize) > lOutNames.getLength() )
460*b1cdbd2cSJim Jagielski 			{
461*b1cdbd2cSJim Jagielski 				lOutNames.realloc	( nDestinationCounter+nPropertiesSize );
462*b1cdbd2cSJim Jagielski 				lOutValues.realloc	( nDestinationCounter+nPropertiesSize );
463*b1cdbd2cSJim Jagielski 			}
464*b1cdbd2cSJim Jagielski 
465*b1cdbd2cSJim Jagielski 			for( nPropertyCounter=0; nPropertyCounter<nPropertiesSize; ++nPropertyCounter )
466*b1cdbd2cSJim Jagielski 			{
467*b1cdbd2cSJim Jagielski  				lOutNames [nDestinationCounter] = sNodeName + lProperties[nPropertyCounter].Name	;
468*b1cdbd2cSJim Jagielski 				lOutValues[nDestinationCounter] = lProperties[nPropertyCounter].Value				;
469*b1cdbd2cSJim Jagielski 				++nDestinationCounter;
470*b1cdbd2cSJim Jagielski 			}
471*b1cdbd2cSJim Jagielski 		}
472*b1cdbd2cSJim Jagielski 		// ... or copy normal items to return lists directly.
473*b1cdbd2cSJim Jagielski 		else
474*b1cdbd2cSJim Jagielski 		{
475*b1cdbd2cSJim Jagielski 			if( (nDestinationCounter+1) > lOutNames.getLength() )
476*b1cdbd2cSJim Jagielski 			{
477*b1cdbd2cSJim Jagielski 				lOutNames.realloc	( nDestinationCounter+1 );
478*b1cdbd2cSJim Jagielski 				lOutValues.realloc	( nDestinationCounter+1 );
479*b1cdbd2cSJim Jagielski 			}
480*b1cdbd2cSJim Jagielski 
481*b1cdbd2cSJim Jagielski 			lOutNames [nDestinationCounter] = lInNames [nSourceCounter];
482*b1cdbd2cSJim Jagielski 			lOutValues[nDestinationCounter] = lInValues[nSourceCounter];
483*b1cdbd2cSJim Jagielski 			++nDestinationCounter;
484*b1cdbd2cSJim Jagielski 		}
485*b1cdbd2cSJim Jagielski 	}
486*b1cdbd2cSJim Jagielski }
487*b1cdbd2cSJim Jagielski /* -----------------------------03.02.2003 14:44------------------------------
488*b1cdbd2cSJim Jagielski 
489*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
GetReadOnlyStates(const com::sun::star::uno::Sequence<rtl::OUString> & rNames)490*b1cdbd2cSJim Jagielski Sequence< sal_Bool > ConfigItem::GetReadOnlyStates(const com::sun::star::uno::Sequence< rtl::OUString >& rNames)
491*b1cdbd2cSJim Jagielski {
492*b1cdbd2cSJim Jagielski     sal_Int32 i;
493*b1cdbd2cSJim Jagielski 
494*b1cdbd2cSJim Jagielski     // size of return list is fix!
495*b1cdbd2cSJim Jagielski     // Every item must match to length of incoming name list.
496*b1cdbd2cSJim Jagielski     sal_Int32 nCount = rNames.getLength();
497*b1cdbd2cSJim Jagielski     Sequence< sal_Bool > lStates(nCount);
498*b1cdbd2cSJim Jagielski 
499*b1cdbd2cSJim Jagielski     // We must be shure to return a valid information everytime!
500*b1cdbd2cSJim Jagielski     // Set default to non readonly ... similar to the configuration handling of this property.
501*b1cdbd2cSJim Jagielski     for ( i=0; i<nCount; ++i)
502*b1cdbd2cSJim Jagielski         lStates[i] = sal_False;
503*b1cdbd2cSJim Jagielski 
504*b1cdbd2cSJim Jagielski     // no access - no informations ...
505*b1cdbd2cSJim Jagielski     Reference< XHierarchicalNameAccess > xHierarchyAccess = GetTree();
506*b1cdbd2cSJim Jagielski     if (!xHierarchyAccess.is())
507*b1cdbd2cSJim Jagielski         return lStates;
508*b1cdbd2cSJim Jagielski 
509*b1cdbd2cSJim Jagielski     for (i=0; i<nCount; ++i)
510*b1cdbd2cSJim Jagielski     {
511*b1cdbd2cSJim Jagielski         try
512*b1cdbd2cSJim Jagielski         {
513*b1cdbd2cSJim Jagielski             if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, rNames[i]))
514*b1cdbd2cSJim Jagielski             {
515*b1cdbd2cSJim Jagielski                 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nlocal mode seams to be used!?\n");
516*b1cdbd2cSJim Jagielski                 continue;
517*b1cdbd2cSJim Jagielski             }
518*b1cdbd2cSJim Jagielski 
519*b1cdbd2cSJim Jagielski             OUString sName = rNames[i];
520*b1cdbd2cSJim Jagielski             OUString sPath;
521*b1cdbd2cSJim Jagielski             OUString sProperty;
522*b1cdbd2cSJim Jagielski 
523*b1cdbd2cSJim Jagielski             ::utl::splitLastFromConfigurationPath(sName,sPath,sProperty);
524*b1cdbd2cSJim Jagielski             if (!sPath.getLength() && !sProperty.getLength())
525*b1cdbd2cSJim Jagielski             {
526*b1cdbd2cSJim Jagielski                 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nsplitt failed\n");
527*b1cdbd2cSJim Jagielski                 continue;
528*b1cdbd2cSJim Jagielski             }
529*b1cdbd2cSJim Jagielski 
530*b1cdbd2cSJim Jagielski             Reference< XInterface >       xNode;
531*b1cdbd2cSJim Jagielski             Reference< XPropertySet >     xSet ;
532*b1cdbd2cSJim Jagielski             Reference< XPropertySetInfo > xInfo;
533*b1cdbd2cSJim Jagielski             if (sPath.getLength())
534*b1cdbd2cSJim Jagielski             {
535*b1cdbd2cSJim Jagielski                 Any aNode = xHierarchyAccess->getByHierarchicalName(sPath);
536*b1cdbd2cSJim Jagielski                 if (!(aNode >>= xNode) || !xNode.is())
537*b1cdbd2cSJim Jagielski                 {
538*b1cdbd2cSJim Jagielski                     OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno set available\n");
539*b1cdbd2cSJim Jagielski                     continue;
540*b1cdbd2cSJim Jagielski                 }
541*b1cdbd2cSJim Jagielski             }
542*b1cdbd2cSJim Jagielski             else
543*b1cdbd2cSJim Jagielski             {
544*b1cdbd2cSJim Jagielski                 xNode = Reference< XInterface >(xHierarchyAccess, UNO_QUERY);
545*b1cdbd2cSJim Jagielski             }
546*b1cdbd2cSJim Jagielski 
547*b1cdbd2cSJim Jagielski 	    xSet = Reference< XPropertySet >(xNode, UNO_QUERY);
548*b1cdbd2cSJim Jagielski             if (xSet.is())
549*b1cdbd2cSJim Jagielski 	    {
550*b1cdbd2cSJim Jagielski 	        xInfo = xSet->getPropertySetInfo();
551*b1cdbd2cSJim Jagielski                 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\ngetPropertySetInfo failed ...\n");
552*b1cdbd2cSJim Jagielski 	    }
553*b1cdbd2cSJim Jagielski             else
554*b1cdbd2cSJim Jagielski 	    {
555*b1cdbd2cSJim Jagielski 	       	xInfo = Reference< XPropertySetInfo >(xNode, UNO_QUERY);
556*b1cdbd2cSJim Jagielski                 OSL_ENSURE(xInfo.is(), "ConfigItem::IsReadonly()\nUNO_QUERY failed ...\n");
557*b1cdbd2cSJim Jagielski 	    }
558*b1cdbd2cSJim Jagielski 
559*b1cdbd2cSJim Jagielski             if (!xInfo.is())
560*b1cdbd2cSJim Jagielski             {
561*b1cdbd2cSJim Jagielski                 OSL_ENSURE(sal_False, "ConfigItem::IsReadonly()\nno prop info available\n");
562*b1cdbd2cSJim Jagielski                 continue;
563*b1cdbd2cSJim Jagielski             }
564*b1cdbd2cSJim Jagielski 
565*b1cdbd2cSJim Jagielski             Property aProp = xInfo->getPropertyByName(sProperty);
566*b1cdbd2cSJim Jagielski             lStates[i] = ((aProp.Attributes & PropertyAttribute::READONLY) == PropertyAttribute::READONLY);
567*b1cdbd2cSJim Jagielski         }
568*b1cdbd2cSJim Jagielski         catch(Exception&){}
569*b1cdbd2cSJim Jagielski     }
570*b1cdbd2cSJim Jagielski 
571*b1cdbd2cSJim Jagielski     return lStates;
572*b1cdbd2cSJim Jagielski }
573*b1cdbd2cSJim Jagielski 
574*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 15:10--------------------------------
575*b1cdbd2cSJim Jagielski 
576*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
GetProperties(const Sequence<OUString> & rNames)577*b1cdbd2cSJim Jagielski Sequence< Any > ConfigItem::GetProperties(const Sequence< OUString >& rNames)
578*b1cdbd2cSJim Jagielski {
579*b1cdbd2cSJim Jagielski 	Sequence< Any > aRet(rNames.getLength());
580*b1cdbd2cSJim Jagielski 	const OUString* pNames = rNames.getConstArray();
581*b1cdbd2cSJim Jagielski 	Any* pRet = aRet.getArray();
582*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
583*b1cdbd2cSJim Jagielski     if(xHierarchyAccess.is())
584*b1cdbd2cSJim Jagielski 	{
585*b1cdbd2cSJim Jagielski 		for(int i = 0; i < rNames.getLength(); i++)
586*b1cdbd2cSJim Jagielski 		{
587*b1cdbd2cSJim Jagielski 			try
588*b1cdbd2cSJim Jagielski 			{
589*b1cdbd2cSJim Jagielski 				if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i]))
590*b1cdbd2cSJim Jagielski 				{
591*b1cdbd2cSJim Jagielski 					OUString sProperty(sSubTree);
592*b1cdbd2cSJim Jagielski 					sProperty += C2U("/");
593*b1cdbd2cSJim Jagielski 					sProperty += pNames[i];
594*b1cdbd2cSJim Jagielski 					pRet[i] = pImpl->pManager->GetLocalProperty(sProperty);
595*b1cdbd2cSJim Jagielski 				}
596*b1cdbd2cSJim Jagielski 				else
597*b1cdbd2cSJim Jagielski 					pRet[i] = xHierarchyAccess->getByHierarchicalName(pNames[i]);
598*b1cdbd2cSJim Jagielski 			}
599*b1cdbd2cSJim Jagielski 			catch(Exception& rEx)
600*b1cdbd2cSJim Jagielski 			{
601*b1cdbd2cSJim Jagielski #if OSL_DEBUG_LEVEL > 0
602*b1cdbd2cSJim Jagielski 				OString sMsg("XHierarchicalNameAccess: ");
603*b1cdbd2cSJim Jagielski 				sMsg += OString(rEx.Message.getStr(),
604*b1cdbd2cSJim Jagielski 					rEx.Message.getLength(),
605*b1cdbd2cSJim Jagielski 				 	RTL_TEXTENCODING_ASCII_US);
606*b1cdbd2cSJim Jagielski 				sMsg += OString("\n");
607*b1cdbd2cSJim Jagielski 				sMsg += OString(ConfigManager::GetConfigBaseURL().getStr(),
608*b1cdbd2cSJim Jagielski 					ConfigManager::GetConfigBaseURL().getLength(),
609*b1cdbd2cSJim Jagielski 				 	RTL_TEXTENCODING_ASCII_US);
610*b1cdbd2cSJim Jagielski 				sMsg += OString(sSubTree.getStr(),
611*b1cdbd2cSJim Jagielski 					sSubTree.getLength(),
612*b1cdbd2cSJim Jagielski 				 	RTL_TEXTENCODING_ASCII_US);
613*b1cdbd2cSJim Jagielski 				sMsg += OString("/");
614*b1cdbd2cSJim Jagielski 				sMsg += OString(pNames[i].getStr(),
615*b1cdbd2cSJim Jagielski 					pNames[i].getLength(),
616*b1cdbd2cSJim Jagielski 				 	RTL_TEXTENCODING_ASCII_US);
617*b1cdbd2cSJim Jagielski 				OSL_ENSURE(sal_False, sMsg.getStr());
618*b1cdbd2cSJim Jagielski #else
619*b1cdbd2cSJim Jagielski                 (void) rEx; // avoid warning
620*b1cdbd2cSJim Jagielski #endif
621*b1cdbd2cSJim Jagielski 			}
622*b1cdbd2cSJim Jagielski 		}
623*b1cdbd2cSJim Jagielski 
624*b1cdbd2cSJim Jagielski 		// In special mode "ALL_LOCALES" we must convert localized values to Sequence< PropertyValue >.
625*b1cdbd2cSJim Jagielski         if((pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES)
626*b1cdbd2cSJim Jagielski 		{
627*b1cdbd2cSJim Jagielski 			Sequence< Any > lValues;
628*b1cdbd2cSJim Jagielski 			impl_packLocalizedProperties( rNames, aRet, lValues );
629*b1cdbd2cSJim Jagielski 			aRet = lValues;
630*b1cdbd2cSJim Jagielski 		}
631*b1cdbd2cSJim Jagielski 	}
632*b1cdbd2cSJim Jagielski 	return aRet;
633*b1cdbd2cSJim Jagielski }
634*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 17:28--------------------------------
635*b1cdbd2cSJim Jagielski 
636*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
PutProperties(const Sequence<OUString> & rNames,const Sequence<Any> & rValues)637*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::PutProperties( const Sequence< OUString >& rNames,
638*b1cdbd2cSJim Jagielski 												const Sequence< Any>& rValues)
639*b1cdbd2cSJim Jagielski {
640*b1cdbd2cSJim Jagielski 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
641*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
642*b1cdbd2cSJim Jagielski     Reference<XNameReplace> xTopNodeReplace(xHierarchyAccess, UNO_QUERY);
643*b1cdbd2cSJim Jagielski 	sal_Bool bRet = xHierarchyAccess.is() && xTopNodeReplace.is();
644*b1cdbd2cSJim Jagielski 	if(bRet)
645*b1cdbd2cSJim Jagielski 	{
646*b1cdbd2cSJim Jagielski 		Sequence< OUString >	lNames			;
647*b1cdbd2cSJim Jagielski 		Sequence< Any >			lValues			;
648*b1cdbd2cSJim Jagielski 		const OUString*			pNames	= NULL	;
649*b1cdbd2cSJim Jagielski 		const Any*				pValues	= NULL	;
650*b1cdbd2cSJim Jagielski 		sal_Int32				nNameCount		;
651*b1cdbd2cSJim Jagielski         if(( pImpl->nMode & CONFIG_MODE_ALL_LOCALES ) == CONFIG_MODE_ALL_LOCALES )
652*b1cdbd2cSJim Jagielski 		{
653*b1cdbd2cSJim Jagielski 			// If ConfigItem works in "ALL_LOCALES"-mode ... we must support a Sequence< PropertyValue >
654*b1cdbd2cSJim Jagielski 			// as value of an localized configuration entry!
655*b1cdbd2cSJim Jagielski 			// How we can do that?
656*b1cdbd2cSJim Jagielski 			// We must split all PropertyValues to "Sequence< OUString >" AND "Sequence< Any >"!
657*b1cdbd2cSJim Jagielski 			impl_unpackLocalizedProperties( rNames, rValues, lNames, lValues );
658*b1cdbd2cSJim Jagielski 			pNames		= lNames.getConstArray	();
659*b1cdbd2cSJim Jagielski 			pValues		= lValues.getConstArray	();
660*b1cdbd2cSJim Jagielski 			nNameCount	= lNames.getLength		();
661*b1cdbd2cSJim Jagielski 		}
662*b1cdbd2cSJim Jagielski 		else
663*b1cdbd2cSJim Jagielski 		{
664*b1cdbd2cSJim Jagielski 			// This is the normal mode ...
665*b1cdbd2cSJim Jagielski 			// Use given input lists directly.
666*b1cdbd2cSJim Jagielski 			pNames		= rNames.getConstArray	();
667*b1cdbd2cSJim Jagielski 			pValues		= rValues.getConstArray	();
668*b1cdbd2cSJim Jagielski 			nNameCount	= rNames.getLength		();
669*b1cdbd2cSJim Jagielski 		}
670*b1cdbd2cSJim Jagielski 		for(int i = 0; i < nNameCount; i++)
671*b1cdbd2cSJim Jagielski 		{
672*b1cdbd2cSJim Jagielski 			if(pImpl->pManager->IsLocalConfigProvider() && lcl_IsLocalProperty(sSubTree, pNames[i]))
673*b1cdbd2cSJim Jagielski 			{
674*b1cdbd2cSJim Jagielski 				OUString sProperty(sSubTree);
675*b1cdbd2cSJim Jagielski 				sProperty += C2U("/");
676*b1cdbd2cSJim Jagielski 				sProperty += pNames[i];
677*b1cdbd2cSJim Jagielski 				pImpl->pManager->PutLocalProperty(sProperty, pValues[i]);
678*b1cdbd2cSJim Jagielski 			}
679*b1cdbd2cSJim Jagielski 			else
680*b1cdbd2cSJim Jagielski 			{
681*b1cdbd2cSJim Jagielski 				try
682*b1cdbd2cSJim Jagielski 				{
683*b1cdbd2cSJim Jagielski                     OUString sNode, sProperty;
684*b1cdbd2cSJim Jagielski                     if (splitLastFromConfigurationPath(pNames[i],sNode, sProperty))
685*b1cdbd2cSJim Jagielski                     {
686*b1cdbd2cSJim Jagielski 						Any aNode = xHierarchyAccess->getByHierarchicalName(sNode);
687*b1cdbd2cSJim Jagielski 
688*b1cdbd2cSJim Jagielski                         Reference<XNameAccess> xNodeAcc;
689*b1cdbd2cSJim Jagielski 						aNode >>= xNodeAcc;
690*b1cdbd2cSJim Jagielski 						Reference<XNameReplace>   xNodeReplace(xNodeAcc, UNO_QUERY);
691*b1cdbd2cSJim Jagielski 						Reference<XNameContainer> xNodeCont   (xNodeAcc, UNO_QUERY);
692*b1cdbd2cSJim Jagielski 
693*b1cdbd2cSJim Jagielski                         sal_Bool bExist = (xNodeAcc.is() && xNodeAcc->hasByName(sProperty));
694*b1cdbd2cSJim Jagielski                         if (bExist && xNodeReplace.is())
695*b1cdbd2cSJim Jagielski 						    xNodeReplace->replaceByName(sProperty, pValues[i]);
696*b1cdbd2cSJim Jagielski                         else
697*b1cdbd2cSJim Jagielski 						if (!bExist && xNodeCont.is())
698*b1cdbd2cSJim Jagielski 						    xNodeCont->insertByName(sProperty, pValues[i]);
699*b1cdbd2cSJim Jagielski 						else
700*b1cdbd2cSJim Jagielski 							bRet = sal_False;
701*b1cdbd2cSJim Jagielski 					}
702*b1cdbd2cSJim Jagielski 					else //direct value
703*b1cdbd2cSJim Jagielski 					{
704*b1cdbd2cSJim Jagielski 						xTopNodeReplace->replaceByName(sProperty, pValues[i]);
705*b1cdbd2cSJim Jagielski 					}
706*b1cdbd2cSJim Jagielski 				}
707*b1cdbd2cSJim Jagielski                 CATCH_INFO("Exception from PutProperties: ");
708*b1cdbd2cSJim Jagielski 			}
709*b1cdbd2cSJim Jagielski 		}
710*b1cdbd2cSJim Jagielski 		try
711*b1cdbd2cSJim Jagielski 		{
712*b1cdbd2cSJim Jagielski 			Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
713*b1cdbd2cSJim Jagielski 			xBatch->commitChanges();
714*b1cdbd2cSJim Jagielski 		}
715*b1cdbd2cSJim Jagielski         CATCH_INFO("Exception from commitChanges(): ")
716*b1cdbd2cSJim Jagielski 	}
717*b1cdbd2cSJim Jagielski 
718*b1cdbd2cSJim Jagielski 	return bRet;
719*b1cdbd2cSJim Jagielski }
720*b1cdbd2cSJim Jagielski /* -----------------------------08.12.05 15:27--------------------------------
721*b1cdbd2cSJim Jagielski 
722*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
DisableNotification()723*b1cdbd2cSJim Jagielski void ConfigItem::DisableNotification()
724*b1cdbd2cSJim Jagielski {
725*b1cdbd2cSJim Jagielski     OSL_ENSURE( xChangeLstnr.is(), "ConfigItem::DisableNotification: notifications not enabled currently!" );
726*b1cdbd2cSJim Jagielski     RemoveChangesListener();
727*b1cdbd2cSJim Jagielski }
728*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 16:19--------------------------------
729*b1cdbd2cSJim Jagielski 
730*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
EnableNotification(const Sequence<OUString> & rNames,sal_Bool bEnableInternalNotification)731*b1cdbd2cSJim Jagielski sal_Bool    ConfigItem::EnableNotification(const Sequence< OUString >& rNames,
732*b1cdbd2cSJim Jagielski                 sal_Bool bEnableInternalNotification )
733*b1cdbd2cSJim Jagielski 
734*b1cdbd2cSJim Jagielski {
735*b1cdbd2cSJim Jagielski     OSL_ENSURE(0 == (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "notification in CONFIG_MODE_RELEASE_TREE mode not possible");
736*b1cdbd2cSJim Jagielski     pImpl->bEnableInternalNotification = bEnableInternalNotification;
737*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
738*b1cdbd2cSJim Jagielski     Reference<XChangesNotifier> xChgNot(xHierarchyAccess, UNO_QUERY);
739*b1cdbd2cSJim Jagielski 	if(!xChgNot.is())
740*b1cdbd2cSJim Jagielski 		return sal_False;
741*b1cdbd2cSJim Jagielski 
742*b1cdbd2cSJim Jagielski 	OSL_ENSURE(!xChangeLstnr.is(), "EnableNotification already called");
743*b1cdbd2cSJim Jagielski 	if(xChangeLstnr.is())
744*b1cdbd2cSJim Jagielski 		xChgNot->removeChangesListener( xChangeLstnr );
745*b1cdbd2cSJim Jagielski 	sal_Bool bRet = sal_True;
746*b1cdbd2cSJim Jagielski 
747*b1cdbd2cSJim Jagielski 	try
748*b1cdbd2cSJim Jagielski 	{
749*b1cdbd2cSJim Jagielski 		xChangeLstnr = new ConfigChangeListener_Impl(*this, rNames);
750*b1cdbd2cSJim Jagielski 		xChgNot->addChangesListener( xChangeLstnr );
751*b1cdbd2cSJim Jagielski 	}
752*b1cdbd2cSJim Jagielski 	catch(RuntimeException& )
753*b1cdbd2cSJim Jagielski 	{
754*b1cdbd2cSJim Jagielski 		bRet = sal_False;
755*b1cdbd2cSJim Jagielski 	}
756*b1cdbd2cSJim Jagielski 	return bRet;
757*b1cdbd2cSJim Jagielski }
758*b1cdbd2cSJim Jagielski /* -----------------------------29.08.00 16:47--------------------------------
759*b1cdbd2cSJim Jagielski 
760*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
RemoveChangesListener()761*b1cdbd2cSJim Jagielski void ConfigItem::RemoveChangesListener()
762*b1cdbd2cSJim Jagielski {
763*b1cdbd2cSJim Jagielski     Reference<XChangesNotifier> xChgNot(m_xHierarchyAccess, UNO_QUERY);
764*b1cdbd2cSJim Jagielski 	if(xChgNot.is() && xChangeLstnr.is())
765*b1cdbd2cSJim Jagielski 	{
766*b1cdbd2cSJim Jagielski 		try
767*b1cdbd2cSJim Jagielski 		{
768*b1cdbd2cSJim Jagielski 			xChgNot->removeChangesListener( xChangeLstnr );
769*b1cdbd2cSJim Jagielski             xChangeLstnr = 0;
770*b1cdbd2cSJim Jagielski 		}
771*b1cdbd2cSJim Jagielski 		catch(Exception & )
772*b1cdbd2cSJim Jagielski 		{
773*b1cdbd2cSJim Jagielski 		}
774*b1cdbd2cSJim Jagielski 	}
775*b1cdbd2cSJim Jagielski }
776*b1cdbd2cSJim Jagielski /* -----------------------------10.07.00      --------------------------------
777*b1cdbd2cSJim Jagielski 
778*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
lcl_normalizeLocalNames(Sequence<OUString> & _rNames,ConfigNameFormat _eFormat,Reference<XInterface> const & _xParentNode)779*b1cdbd2cSJim Jagielski void lcl_normalizeLocalNames(Sequence< OUString >& _rNames, ConfigNameFormat _eFormat, Reference<XInterface> const& _xParentNode)
780*b1cdbd2cSJim Jagielski {
781*b1cdbd2cSJim Jagielski     switch (_eFormat)
782*b1cdbd2cSJim Jagielski     {
783*b1cdbd2cSJim Jagielski     case CONFIG_NAME_LOCAL_NAME:
784*b1cdbd2cSJim Jagielski         // unaltered - this is our input format
785*b1cdbd2cSJim Jagielski         break;
786*b1cdbd2cSJim Jagielski 
787*b1cdbd2cSJim Jagielski     case CONFIG_NAME_FULL_PATH:
788*b1cdbd2cSJim Jagielski         {
789*b1cdbd2cSJim Jagielski             Reference<XHierarchicalName> xFormatter(_xParentNode, UNO_QUERY);
790*b1cdbd2cSJim Jagielski             if (xFormatter.is())
791*b1cdbd2cSJim Jagielski             {
792*b1cdbd2cSJim Jagielski                 OUString * pNames = _rNames.getArray();
793*b1cdbd2cSJim Jagielski                 for(int i = 0; i<_rNames.getLength(); ++i)
794*b1cdbd2cSJim Jagielski                 try
795*b1cdbd2cSJim Jagielski                 {
796*b1cdbd2cSJim Jagielski                     pNames[i] = xFormatter->composeHierarchicalName(pNames[i]);
797*b1cdbd2cSJim Jagielski                 }
798*b1cdbd2cSJim Jagielski                 CATCH_INFO("Exception from composeHierarchicalName(): ")
799*b1cdbd2cSJim Jagielski                 break;
800*b1cdbd2cSJim Jagielski             }
801*b1cdbd2cSJim Jagielski         }
802*b1cdbd2cSJim Jagielski         OSL_ENSURE(false, "Cannot create absolute pathes: missing interface");
803*b1cdbd2cSJim Jagielski         // make local pathes instaed
804*b1cdbd2cSJim Jagielski 
805*b1cdbd2cSJim Jagielski     case CONFIG_NAME_LOCAL_PATH:
806*b1cdbd2cSJim Jagielski         {
807*b1cdbd2cSJim Jagielski             Reference<XTemplateContainer> xTypeContainer(_xParentNode, UNO_QUERY);
808*b1cdbd2cSJim Jagielski             if (xTypeContainer.is())
809*b1cdbd2cSJim Jagielski             {
810*b1cdbd2cSJim Jagielski                 OUString sTypeName = xTypeContainer->getElementTemplateName();
811*b1cdbd2cSJim Jagielski                 sTypeName = sTypeName.copy(sTypeName.lastIndexOf('/')+1);
812*b1cdbd2cSJim Jagielski 
813*b1cdbd2cSJim Jagielski                 OUString * pNames = _rNames.getArray();
814*b1cdbd2cSJim Jagielski                 for(int i = 0; i<_rNames.getLength(); ++i)
815*b1cdbd2cSJim Jagielski                 {
816*b1cdbd2cSJim Jagielski                     pNames[i] = wrapConfigurationElementName(pNames[i],sTypeName);
817*b1cdbd2cSJim Jagielski                 }
818*b1cdbd2cSJim Jagielski             }
819*b1cdbd2cSJim Jagielski             else
820*b1cdbd2cSJim Jagielski             {
821*b1cdbd2cSJim Jagielski                 static const OUString sSetService(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.configuration.SetAccess"));
822*b1cdbd2cSJim Jagielski                 Reference<XServiceInfo> xSVI(_xParentNode, UNO_QUERY);
823*b1cdbd2cSJim Jagielski                 if (xSVI.is() && xSVI->supportsService(sSetService))
824*b1cdbd2cSJim Jagielski                 {
825*b1cdbd2cSJim Jagielski                     OUString * pNames = _rNames.getArray();
826*b1cdbd2cSJim Jagielski                     for(int i = 0; i<_rNames.getLength(); ++i)
827*b1cdbd2cSJim Jagielski                     {
828*b1cdbd2cSJim Jagielski                         pNames[i] = wrapConfigurationElementName(pNames[i]);
829*b1cdbd2cSJim Jagielski                     }
830*b1cdbd2cSJim Jagielski                 }
831*b1cdbd2cSJim Jagielski             }
832*b1cdbd2cSJim Jagielski         }
833*b1cdbd2cSJim Jagielski         break;
834*b1cdbd2cSJim Jagielski 
835*b1cdbd2cSJim Jagielski     case CONFIG_NAME_PLAINTEXT_NAME:
836*b1cdbd2cSJim Jagielski         {
837*b1cdbd2cSJim Jagielski             Reference<XStringEscape> xEscaper(_xParentNode, UNO_QUERY);
838*b1cdbd2cSJim Jagielski             if (xEscaper.is())
839*b1cdbd2cSJim Jagielski             {
840*b1cdbd2cSJim Jagielski                 OUString * pNames = _rNames.getArray();
841*b1cdbd2cSJim Jagielski                 for(int i = 0; i<_rNames.getLength(); ++i)
842*b1cdbd2cSJim Jagielski                 try
843*b1cdbd2cSJim Jagielski                 {
844*b1cdbd2cSJim Jagielski                     pNames[i] = xEscaper->unescapeString(pNames[i]);
845*b1cdbd2cSJim Jagielski                 }
846*b1cdbd2cSJim Jagielski                 CATCH_INFO("Exception from unescapeString(): ")
847*b1cdbd2cSJim Jagielski             }
848*b1cdbd2cSJim Jagielski         }
849*b1cdbd2cSJim Jagielski         break;
850*b1cdbd2cSJim Jagielski 
851*b1cdbd2cSJim Jagielski     }
852*b1cdbd2cSJim Jagielski }
853*b1cdbd2cSJim Jagielski /* -----------------------------10.07.00      --------------------------------
854*b1cdbd2cSJim Jagielski 
855*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
GetNodeNames(const OUString & rNode)856*b1cdbd2cSJim Jagielski Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode)
857*b1cdbd2cSJim Jagielski {
858*b1cdbd2cSJim Jagielski     ConfigNameFormat const eDefaultFormat = CONFIG_NAME_LOCAL_NAME; // CONFIG_NAME_DEFAULT;
859*b1cdbd2cSJim Jagielski 
860*b1cdbd2cSJim Jagielski     return GetNodeNames(rNode, eDefaultFormat);
861*b1cdbd2cSJim Jagielski }
862*b1cdbd2cSJim Jagielski /* -----------------------------15.09.00 12:06--------------------------------
863*b1cdbd2cSJim Jagielski 
864*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
GetNodeNames(const OUString & rNode,ConfigNameFormat eFormat)865*b1cdbd2cSJim Jagielski Sequence< OUString > ConfigItem::GetNodeNames(const OUString& rNode, ConfigNameFormat eFormat)
866*b1cdbd2cSJim Jagielski {
867*b1cdbd2cSJim Jagielski 	Sequence< OUString > aRet;
868*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
869*b1cdbd2cSJim Jagielski     if(xHierarchyAccess.is())
870*b1cdbd2cSJim Jagielski 	{
871*b1cdbd2cSJim Jagielski 		try
872*b1cdbd2cSJim Jagielski 		{
873*b1cdbd2cSJim Jagielski 			Reference<XNameAccess> xCont;
874*b1cdbd2cSJim Jagielski 			if(rNode.getLength())
875*b1cdbd2cSJim Jagielski 			{
876*b1cdbd2cSJim Jagielski 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
877*b1cdbd2cSJim Jagielski 				aNode >>= xCont;
878*b1cdbd2cSJim Jagielski 			}
879*b1cdbd2cSJim Jagielski 			else
880*b1cdbd2cSJim Jagielski 				xCont = Reference<XNameAccess> (xHierarchyAccess, UNO_QUERY);
881*b1cdbd2cSJim Jagielski 			if(xCont.is())
882*b1cdbd2cSJim Jagielski 			{
883*b1cdbd2cSJim Jagielski 				aRet = xCont->getElementNames();
884*b1cdbd2cSJim Jagielski                 lcl_normalizeLocalNames(aRet,eFormat,xCont);
885*b1cdbd2cSJim Jagielski             }
886*b1cdbd2cSJim Jagielski 
887*b1cdbd2cSJim Jagielski 		}
888*b1cdbd2cSJim Jagielski         CATCH_INFO("Exception from GetNodeNames: ");
889*b1cdbd2cSJim Jagielski 	}
890*b1cdbd2cSJim Jagielski 	return aRet;
891*b1cdbd2cSJim Jagielski }
892*b1cdbd2cSJim Jagielski /* -----------------------------15.09.00 15:52--------------------------------
893*b1cdbd2cSJim Jagielski 
894*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
ClearNodeSet(const OUString & rNode)895*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::ClearNodeSet(const OUString& rNode)
896*b1cdbd2cSJim Jagielski {
897*b1cdbd2cSJim Jagielski 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
898*b1cdbd2cSJim Jagielski     sal_Bool bRet = sal_False;
899*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
900*b1cdbd2cSJim Jagielski     if(xHierarchyAccess.is())
901*b1cdbd2cSJim Jagielski 	{
902*b1cdbd2cSJim Jagielski 		try
903*b1cdbd2cSJim Jagielski 		{
904*b1cdbd2cSJim Jagielski 			Reference<XNameContainer> xCont;
905*b1cdbd2cSJim Jagielski 			if(rNode.getLength())
906*b1cdbd2cSJim Jagielski 			{
907*b1cdbd2cSJim Jagielski 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
908*b1cdbd2cSJim Jagielski 				aNode >>= xCont;
909*b1cdbd2cSJim Jagielski 			}
910*b1cdbd2cSJim Jagielski 			else
911*b1cdbd2cSJim Jagielski 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
912*b1cdbd2cSJim Jagielski 			if(!xCont.is())
913*b1cdbd2cSJim Jagielski 				return sal_False;
914*b1cdbd2cSJim Jagielski 			Sequence< OUString > aNames = xCont->getElementNames();
915*b1cdbd2cSJim Jagielski 			const OUString* pNames = aNames.getConstArray();
916*b1cdbd2cSJim Jagielski 			Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
917*b1cdbd2cSJim Jagielski 			for(sal_Int32 i = 0; i < aNames.getLength(); i++)
918*b1cdbd2cSJim Jagielski 			{
919*b1cdbd2cSJim Jagielski 				try
920*b1cdbd2cSJim Jagielski 				{
921*b1cdbd2cSJim Jagielski 					xCont->removeByName(pNames[i]);
922*b1cdbd2cSJim Jagielski 				}
923*b1cdbd2cSJim Jagielski                 CATCH_INFO("Exception from removeByName(): ")
924*b1cdbd2cSJim Jagielski 			}
925*b1cdbd2cSJim Jagielski 			xBatch->commitChanges();
926*b1cdbd2cSJim Jagielski             bRet = sal_True;
927*b1cdbd2cSJim Jagielski 		}
928*b1cdbd2cSJim Jagielski         CATCH_INFO("Exception from ClearNodeSet")
929*b1cdbd2cSJim Jagielski 	}
930*b1cdbd2cSJim Jagielski 	return bRet;
931*b1cdbd2cSJim Jagielski }
932*b1cdbd2cSJim Jagielski /* -----------------------------24.11.00 10:58--------------------------------
933*b1cdbd2cSJim Jagielski 
934*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
ClearNodeElements(const OUString & rNode,Sequence<OUString> & rElements)935*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::ClearNodeElements(const OUString& rNode, Sequence< OUString >& rElements)
936*b1cdbd2cSJim Jagielski {
937*b1cdbd2cSJim Jagielski 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
938*b1cdbd2cSJim Jagielski     sal_Bool bRet = sal_False;
939*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
940*b1cdbd2cSJim Jagielski     if(xHierarchyAccess.is())
941*b1cdbd2cSJim Jagielski 	{
942*b1cdbd2cSJim Jagielski 		const OUString* pElements = rElements.getConstArray();
943*b1cdbd2cSJim Jagielski 		try
944*b1cdbd2cSJim Jagielski 		{
945*b1cdbd2cSJim Jagielski 			Reference<XNameContainer> xCont;
946*b1cdbd2cSJim Jagielski 			if(rNode.getLength())
947*b1cdbd2cSJim Jagielski 			{
948*b1cdbd2cSJim Jagielski 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
949*b1cdbd2cSJim Jagielski 				aNode >>= xCont;
950*b1cdbd2cSJim Jagielski 			}
951*b1cdbd2cSJim Jagielski 			else
952*b1cdbd2cSJim Jagielski 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
953*b1cdbd2cSJim Jagielski 			if(!xCont.is())
954*b1cdbd2cSJim Jagielski 				return sal_False;
955*b1cdbd2cSJim Jagielski 			try
956*b1cdbd2cSJim Jagielski 			{
957*b1cdbd2cSJim Jagielski 				for(sal_Int32 nElement = 0; nElement < rElements.getLength(); nElement++)
958*b1cdbd2cSJim Jagielski 				{
959*b1cdbd2cSJim Jagielski 					xCont->removeByName(pElements[nElement]);
960*b1cdbd2cSJim Jagielski 				}
961*b1cdbd2cSJim Jagielski 				Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
962*b1cdbd2cSJim Jagielski 				xBatch->commitChanges();
963*b1cdbd2cSJim Jagielski 			}
964*b1cdbd2cSJim Jagielski             CATCH_INFO("Exception from commitChanges(): ")
965*b1cdbd2cSJim Jagielski             bRet = sal_True;
966*b1cdbd2cSJim Jagielski         }
967*b1cdbd2cSJim Jagielski         CATCH_INFO("Exception from GetNodeNames: ")
968*b1cdbd2cSJim Jagielski 	}
969*b1cdbd2cSJim Jagielski 	return bRet;
970*b1cdbd2cSJim Jagielski }
971*b1cdbd2cSJim Jagielski //----------------------------------------------------------------------------
972*b1cdbd2cSJim Jagielski static inline
lcl_extractSetPropertyName(const OUString & rInPath,const OUString & rPrefix)973*b1cdbd2cSJim Jagielski OUString lcl_extractSetPropertyName( const OUString& rInPath, const OUString& rPrefix )
974*b1cdbd2cSJim Jagielski {
975*b1cdbd2cSJim Jagielski     OUString const sSubPath = dropPrefixFromConfigurationPath( rInPath, rPrefix);
976*b1cdbd2cSJim Jagielski     return extractFirstFromConfigurationPath( sSubPath );
977*b1cdbd2cSJim Jagielski }
978*b1cdbd2cSJim Jagielski //----------------------------------------------------------------------------
979*b1cdbd2cSJim Jagielski static
lcl_extractSetPropertyNames(const Sequence<PropertyValue> & rValues,const OUString & rPrefix)980*b1cdbd2cSJim Jagielski Sequence< OUString > lcl_extractSetPropertyNames( const Sequence< PropertyValue >& rValues, const OUString& rPrefix )
981*b1cdbd2cSJim Jagielski {
982*b1cdbd2cSJim Jagielski     const PropertyValue* pProperties = rValues.getConstArray();
983*b1cdbd2cSJim Jagielski 
984*b1cdbd2cSJim Jagielski     Sequence< OUString > aSubNodeNames(rValues.getLength());
985*b1cdbd2cSJim Jagielski     OUString* pSubNodeNames = aSubNodeNames.getArray();
986*b1cdbd2cSJim Jagielski 
987*b1cdbd2cSJim Jagielski     OUString sLastSubNode;
988*b1cdbd2cSJim Jagielski     sal_Int32 nSubIndex = 0;
989*b1cdbd2cSJim Jagielski 
990*b1cdbd2cSJim Jagielski     for(sal_Int32 i = 0; i < rValues.getLength(); i++)
991*b1cdbd2cSJim Jagielski     {
992*b1cdbd2cSJim Jagielski         OUString const sSubPath = dropPrefixFromConfigurationPath( pProperties[i].Name, rPrefix);
993*b1cdbd2cSJim Jagielski         OUString const sSubNode = extractFirstFromConfigurationPath( sSubPath );
994*b1cdbd2cSJim Jagielski 
995*b1cdbd2cSJim Jagielski         if(sLastSubNode != sSubNode)
996*b1cdbd2cSJim Jagielski 	    {
997*b1cdbd2cSJim Jagielski 		    pSubNodeNames[nSubIndex++] = sSubNode;
998*b1cdbd2cSJim Jagielski 	    }
999*b1cdbd2cSJim Jagielski 
1000*b1cdbd2cSJim Jagielski 	    sLastSubNode = sSubNode;
1001*b1cdbd2cSJim Jagielski     }
1002*b1cdbd2cSJim Jagielski     aSubNodeNames.realloc(nSubIndex);
1003*b1cdbd2cSJim Jagielski 
1004*b1cdbd2cSJim Jagielski     return aSubNodeNames;
1005*b1cdbd2cSJim Jagielski }
1006*b1cdbd2cSJim Jagielski /* -----------------------------15.09.00 15:52--------------------------------
1007*b1cdbd2cSJim Jagielski 	add or change properties
1008*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
SetSetProperties(const OUString & rNode,Sequence<PropertyValue> rValues)1009*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::SetSetProperties(
1010*b1cdbd2cSJim Jagielski 	const OUString& rNode, Sequence< PropertyValue > rValues)
1011*b1cdbd2cSJim Jagielski {
1012*b1cdbd2cSJim Jagielski 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
1013*b1cdbd2cSJim Jagielski     sal_Bool bRet = sal_True;
1014*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1015*b1cdbd2cSJim Jagielski     if(xHierarchyAccess.is())
1016*b1cdbd2cSJim Jagielski 	{
1017*b1cdbd2cSJim Jagielski 		Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
1018*b1cdbd2cSJim Jagielski 		try
1019*b1cdbd2cSJim Jagielski 		{
1020*b1cdbd2cSJim Jagielski 			Reference<XNameContainer> xCont;
1021*b1cdbd2cSJim Jagielski 			if(rNode.getLength())
1022*b1cdbd2cSJim Jagielski 			{
1023*b1cdbd2cSJim Jagielski 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
1024*b1cdbd2cSJim Jagielski 				aNode >>= xCont;
1025*b1cdbd2cSJim Jagielski 			}
1026*b1cdbd2cSJim Jagielski 			else
1027*b1cdbd2cSJim Jagielski 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
1028*b1cdbd2cSJim Jagielski 			if(!xCont.is())
1029*b1cdbd2cSJim Jagielski 				return sal_False;
1030*b1cdbd2cSJim Jagielski 
1031*b1cdbd2cSJim Jagielski 			Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
1032*b1cdbd2cSJim Jagielski 
1033*b1cdbd2cSJim Jagielski             if(xFac.is())
1034*b1cdbd2cSJim Jagielski 			{
1035*b1cdbd2cSJim Jagielski 				const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
1036*b1cdbd2cSJim Jagielski 
1037*b1cdbd2cSJim Jagielski                 const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
1038*b1cdbd2cSJim Jagielski 
1039*b1cdbd2cSJim Jagielski 				for(sal_Int32 j = 0; j <nSubNodeCount ; j++)
1040*b1cdbd2cSJim Jagielski 				{
1041*b1cdbd2cSJim Jagielski 					if(!xCont->hasByName(aSubNodeNames[j]))
1042*b1cdbd2cSJim Jagielski 					{
1043*b1cdbd2cSJim Jagielski 						Reference<XInterface> xInst = xFac->createInstance();
1044*b1cdbd2cSJim Jagielski 						Any aVal; aVal <<= xInst;
1045*b1cdbd2cSJim Jagielski 						xCont->insertByName(aSubNodeNames[j], aVal);
1046*b1cdbd2cSJim Jagielski 					}
1047*b1cdbd2cSJim Jagielski 					//set values
1048*b1cdbd2cSJim Jagielski 				}
1049*b1cdbd2cSJim Jagielski 				try
1050*b1cdbd2cSJim Jagielski 				{
1051*b1cdbd2cSJim Jagielski 					xBatch->commitChanges();
1052*b1cdbd2cSJim Jagielski 				}
1053*b1cdbd2cSJim Jagielski                 CATCH_INFO("Exception from commitChanges(): ")
1054*b1cdbd2cSJim Jagielski 
1055*b1cdbd2cSJim Jagielski 				const PropertyValue* pProperties = rValues.getConstArray();
1056*b1cdbd2cSJim Jagielski 
1057*b1cdbd2cSJim Jagielski 				Sequence< OUString > aSetNames(rValues.getLength());
1058*b1cdbd2cSJim Jagielski 				OUString* pSetNames = aSetNames.getArray();
1059*b1cdbd2cSJim Jagielski 
1060*b1cdbd2cSJim Jagielski 				Sequence< Any> aSetValues(rValues.getLength());
1061*b1cdbd2cSJim Jagielski 				Any* pSetValues = aSetValues.getArray();
1062*b1cdbd2cSJim Jagielski 
1063*b1cdbd2cSJim Jagielski 				sal_Bool bEmptyNode = rNode.getLength() == 0;
1064*b1cdbd2cSJim Jagielski 				for(sal_Int32 k = 0; k < rValues.getLength(); k++)
1065*b1cdbd2cSJim Jagielski 				{
1066*b1cdbd2cSJim Jagielski 					pSetNames[k] =  pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
1067*b1cdbd2cSJim Jagielski 					pSetValues[k] = pProperties[k].Value;
1068*b1cdbd2cSJim Jagielski 				}
1069*b1cdbd2cSJim Jagielski 				bRet = PutProperties(aSetNames, aSetValues);
1070*b1cdbd2cSJim Jagielski 			}
1071*b1cdbd2cSJim Jagielski 			else
1072*b1cdbd2cSJim Jagielski 			{
1073*b1cdbd2cSJim Jagielski 				//if no factory is available then the node contains basic data elements
1074*b1cdbd2cSJim Jagielski 				const PropertyValue* pValues = rValues.getConstArray();
1075*b1cdbd2cSJim Jagielski 				for(int nValue = 0; nValue < rValues.getLength();nValue++)
1076*b1cdbd2cSJim Jagielski 				{
1077*b1cdbd2cSJim Jagielski 					try
1078*b1cdbd2cSJim Jagielski 					{
1079*b1cdbd2cSJim Jagielski 						OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
1080*b1cdbd2cSJim Jagielski 
1081*b1cdbd2cSJim Jagielski                         if(xCont->hasByName(sSubNode))
1082*b1cdbd2cSJim Jagielski 							xCont->replaceByName(sSubNode, pValues[nValue].Value);
1083*b1cdbd2cSJim Jagielski 						else
1084*b1cdbd2cSJim Jagielski 							xCont->insertByName(sSubNode, pValues[nValue].Value);
1085*b1cdbd2cSJim Jagielski 
1086*b1cdbd2cSJim Jagielski 						OSL_ENSURE( xHierarchyAccess->hasByHierarchicalName(pValues[nValue].Name),
1087*b1cdbd2cSJim Jagielski 							"Invalid config path" );
1088*b1cdbd2cSJim Jagielski 					}
1089*b1cdbd2cSJim Jagielski                     CATCH_INFO("Exception form insert/replaceByName(): ")
1090*b1cdbd2cSJim Jagielski 				}
1091*b1cdbd2cSJim Jagielski 				xBatch->commitChanges();
1092*b1cdbd2cSJim Jagielski 			}
1093*b1cdbd2cSJim Jagielski 		}
1094*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL
1095*b1cdbd2cSJim Jagielski         catch(Exception& rEx)
1096*b1cdbd2cSJim Jagielski 		{
1097*b1cdbd2cSJim Jagielski             lcl_CFG_DBG_EXCEPTION("Exception from SetSetProperties: ", rEx);
1098*b1cdbd2cSJim Jagielski #else
1099*b1cdbd2cSJim Jagielski         catch(Exception&)
1100*b1cdbd2cSJim Jagielski 		{
1101*b1cdbd2cSJim Jagielski #endif
1102*b1cdbd2cSJim Jagielski 			bRet = sal_False;
1103*b1cdbd2cSJim Jagielski 		}
1104*b1cdbd2cSJim Jagielski     }
1105*b1cdbd2cSJim Jagielski 	return bRet;
1106*b1cdbd2cSJim Jagielski }
1107*b1cdbd2cSJim Jagielski /* -----------------------------15.09.00 15:52--------------------------------
1108*b1cdbd2cSJim Jagielski 
1109*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1110*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::ReplaceSetProperties(
1111*b1cdbd2cSJim Jagielski 	const OUString& rNode, Sequence< PropertyValue > rValues)
1112*b1cdbd2cSJim Jagielski {
1113*b1cdbd2cSJim Jagielski 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
1114*b1cdbd2cSJim Jagielski     sal_Bool bRet = sal_True;
1115*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1116*b1cdbd2cSJim Jagielski     if(xHierarchyAccess.is())
1117*b1cdbd2cSJim Jagielski 	{
1118*b1cdbd2cSJim Jagielski 		Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
1119*b1cdbd2cSJim Jagielski 		try
1120*b1cdbd2cSJim Jagielski 		{
1121*b1cdbd2cSJim Jagielski 			Reference<XNameContainer> xCont;
1122*b1cdbd2cSJim Jagielski 			if(rNode.getLength())
1123*b1cdbd2cSJim Jagielski 			{
1124*b1cdbd2cSJim Jagielski 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
1125*b1cdbd2cSJim Jagielski 				aNode >>= xCont;
1126*b1cdbd2cSJim Jagielski 			}
1127*b1cdbd2cSJim Jagielski 			else
1128*b1cdbd2cSJim Jagielski 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
1129*b1cdbd2cSJim Jagielski 			if(!xCont.is())
1130*b1cdbd2cSJim Jagielski 				return sal_False;
1131*b1cdbd2cSJim Jagielski 
1132*b1cdbd2cSJim Jagielski             // JB: Change: now the same name handling for sets of simple values
1133*b1cdbd2cSJim Jagielski 			const Sequence< OUString > aSubNodeNames = lcl_extractSetPropertyNames(rValues, rNode);
1134*b1cdbd2cSJim Jagielski 			const OUString* pSubNodeNames = aSubNodeNames.getConstArray();
1135*b1cdbd2cSJim Jagielski             const sal_Int32 nSubNodeCount = aSubNodeNames.getLength();
1136*b1cdbd2cSJim Jagielski 
1137*b1cdbd2cSJim Jagielski 			Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
1138*b1cdbd2cSJim Jagielski             const bool isSimpleValueSet = !xFac.is();
1139*b1cdbd2cSJim Jagielski 
1140*b1cdbd2cSJim Jagielski 		    //remove unknown members first
1141*b1cdbd2cSJim Jagielski             {
1142*b1cdbd2cSJim Jagielski 				const Sequence<OUString> aContainerSubNodes = xCont->getElementNames();
1143*b1cdbd2cSJim Jagielski 				const OUString* pContainerSubNodes = aContainerSubNodes.getConstArray();
1144*b1cdbd2cSJim Jagielski 
1145*b1cdbd2cSJim Jagielski 				for(sal_Int32 nContSub = 0; nContSub < aContainerSubNodes.getLength(); nContSub++)
1146*b1cdbd2cSJim Jagielski 				{
1147*b1cdbd2cSJim Jagielski 					sal_Bool bFound = sal_False;
1148*b1cdbd2cSJim Jagielski 					for(sal_Int32 j = 0; j < nSubNodeCount; j++)
1149*b1cdbd2cSJim Jagielski                     {
1150*b1cdbd2cSJim Jagielski 						if(pSubNodeNames[j] == pContainerSubNodes[nContSub])
1151*b1cdbd2cSJim Jagielski 						{
1152*b1cdbd2cSJim Jagielski 							bFound = sal_True;
1153*b1cdbd2cSJim Jagielski 							break;
1154*b1cdbd2cSJim Jagielski 						}
1155*b1cdbd2cSJim Jagielski                     }
1156*b1cdbd2cSJim Jagielski 					if(!bFound)
1157*b1cdbd2cSJim Jagielski                     try
1158*b1cdbd2cSJim Jagielski 					{
1159*b1cdbd2cSJim Jagielski 						xCont->removeByName(pContainerSubNodes[nContSub]);
1160*b1cdbd2cSJim Jagielski 					}
1161*b1cdbd2cSJim Jagielski                     catch (Exception & )
1162*b1cdbd2cSJim Jagielski                     {
1163*b1cdbd2cSJim Jagielski                         if (isSimpleValueSet)
1164*b1cdbd2cSJim Jagielski                         try
1165*b1cdbd2cSJim Jagielski                         {
1166*b1cdbd2cSJim Jagielski                             // #i37322#: fallback action: replace with <void/>
1167*b1cdbd2cSJim Jagielski                             xCont->replaceByName(pContainerSubNodes[nContSub], Any());
1168*b1cdbd2cSJim Jagielski                             // fallback successfull: continue looping
1169*b1cdbd2cSJim Jagielski                             continue;
1170*b1cdbd2cSJim Jagielski                         }
1171*b1cdbd2cSJim Jagielski                         catch (Exception &)
1172*b1cdbd2cSJim Jagielski                         {} // propagate original exception, if fallback fails
1173*b1cdbd2cSJim Jagielski 
1174*b1cdbd2cSJim Jagielski                         throw;
1175*b1cdbd2cSJim Jagielski                     }
1176*b1cdbd2cSJim Jagielski 				}
1177*b1cdbd2cSJim Jagielski 				try { xBatch->commitChanges(); }
1178*b1cdbd2cSJim Jagielski                 CATCH_INFO("Exception from commitChanges(): ")
1179*b1cdbd2cSJim Jagielski             }
1180*b1cdbd2cSJim Jagielski 
1181*b1cdbd2cSJim Jagielski 			if(xFac.is()) // !isSimpleValueSet
1182*b1cdbd2cSJim Jagielski 			{
1183*b1cdbd2cSJim Jagielski 				for(sal_Int32 j = 0; j < nSubNodeCount; j++)
1184*b1cdbd2cSJim Jagielski 				{
1185*b1cdbd2cSJim Jagielski 					if(!xCont->hasByName(pSubNodeNames[j]))
1186*b1cdbd2cSJim Jagielski 					{
1187*b1cdbd2cSJim Jagielski 						//create if not available
1188*b1cdbd2cSJim Jagielski 						Reference<XInterface> xInst = xFac->createInstance();
1189*b1cdbd2cSJim Jagielski 						Any aVal; aVal <<= xInst;
1190*b1cdbd2cSJim Jagielski 						xCont->insertByName(pSubNodeNames[j], aVal);
1191*b1cdbd2cSJim Jagielski 					}
1192*b1cdbd2cSJim Jagielski 				}
1193*b1cdbd2cSJim Jagielski 				try	{ xBatch->commitChanges(); }
1194*b1cdbd2cSJim Jagielski                 CATCH_INFO("Exception from commitChanges(): ")
1195*b1cdbd2cSJim Jagielski 
1196*b1cdbd2cSJim Jagielski 				const PropertyValue* pProperties = rValues.getConstArray();
1197*b1cdbd2cSJim Jagielski 
1198*b1cdbd2cSJim Jagielski 				Sequence< OUString > aSetNames(rValues.getLength());
1199*b1cdbd2cSJim Jagielski 				OUString* pSetNames = aSetNames.getArray();
1200*b1cdbd2cSJim Jagielski 
1201*b1cdbd2cSJim Jagielski 				Sequence< Any> aSetValues(rValues.getLength());
1202*b1cdbd2cSJim Jagielski 				Any* pSetValues = aSetValues.getArray();
1203*b1cdbd2cSJim Jagielski 
1204*b1cdbd2cSJim Jagielski                 sal_Bool bEmptyNode = rNode.getLength() == 0;
1205*b1cdbd2cSJim Jagielski                 for(sal_Int32 k = 0; k < rValues.getLength(); k++)
1206*b1cdbd2cSJim Jagielski 				{
1207*b1cdbd2cSJim Jagielski                     pSetNames[k] =  pProperties[k].Name.copy( bEmptyNode ? 1 : 0);
1208*b1cdbd2cSJim Jagielski 					pSetValues[k] = pProperties[k].Value;
1209*b1cdbd2cSJim Jagielski 				}
1210*b1cdbd2cSJim Jagielski 				bRet = PutProperties(aSetNames, aSetValues);
1211*b1cdbd2cSJim Jagielski 			}
1212*b1cdbd2cSJim Jagielski 			else
1213*b1cdbd2cSJim Jagielski 			{
1214*b1cdbd2cSJim Jagielski 				const PropertyValue* pValues = rValues.getConstArray();
1215*b1cdbd2cSJim Jagielski 
1216*b1cdbd2cSJim Jagielski 				//if no factory is available then the node contains basic data elements
1217*b1cdbd2cSJim Jagielski 				for(int nValue = 0; nValue < rValues.getLength();nValue++)
1218*b1cdbd2cSJim Jagielski 				{
1219*b1cdbd2cSJim Jagielski 					try
1220*b1cdbd2cSJim Jagielski 					{
1221*b1cdbd2cSJim Jagielski 						OUString sSubNode = lcl_extractSetPropertyName( pValues[nValue].Name, rNode );
1222*b1cdbd2cSJim Jagielski 
1223*b1cdbd2cSJim Jagielski                         if(xCont->hasByName(sSubNode))
1224*b1cdbd2cSJim Jagielski 							xCont->replaceByName(sSubNode, pValues[nValue].Value);
1225*b1cdbd2cSJim Jagielski 						else
1226*b1cdbd2cSJim Jagielski 							xCont->insertByName(sSubNode, pValues[nValue].Value);
1227*b1cdbd2cSJim Jagielski 					}
1228*b1cdbd2cSJim Jagielski                     CATCH_INFO("Exception from insert/replaceByName(): ");
1229*b1cdbd2cSJim Jagielski                 }
1230*b1cdbd2cSJim Jagielski 				xBatch->commitChanges();
1231*b1cdbd2cSJim Jagielski 			}
1232*b1cdbd2cSJim Jagielski 		}
1233*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL
1234*b1cdbd2cSJim Jagielski         catch(Exception& rEx)
1235*b1cdbd2cSJim Jagielski 		{
1236*b1cdbd2cSJim Jagielski             lcl_CFG_DBG_EXCEPTION("Exception from ReplaceSetProperties: ", rEx);
1237*b1cdbd2cSJim Jagielski #else
1238*b1cdbd2cSJim Jagielski         catch(Exception&)
1239*b1cdbd2cSJim Jagielski 		{
1240*b1cdbd2cSJim Jagielski #endif
1241*b1cdbd2cSJim Jagielski 			bRet = sal_False;
1242*b1cdbd2cSJim Jagielski 		}
1243*b1cdbd2cSJim Jagielski     }
1244*b1cdbd2cSJim Jagielski 	return bRet;
1245*b1cdbd2cSJim Jagielski }
1246*b1cdbd2cSJim Jagielski /* -----------------------------07.05.01 12:15--------------------------------
1247*b1cdbd2cSJim Jagielski 
1248*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1249*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::getUniqueSetElementName( const ::rtl::OUString& _rSetNode, ::rtl::OUString& _rName)
1250*b1cdbd2cSJim Jagielski {
1251*b1cdbd2cSJim Jagielski 	::rtl::OUString sNewElementName;
1252*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1253*b1cdbd2cSJim Jagielski     sal_Bool bRet = sal_False;
1254*b1cdbd2cSJim Jagielski     if(xHierarchyAccess.is())
1255*b1cdbd2cSJim Jagielski     {
1256*b1cdbd2cSJim Jagielski         try
1257*b1cdbd2cSJim Jagielski         {
1258*b1cdbd2cSJim Jagielski             Reference< XNameAccess > xSetNode;
1259*b1cdbd2cSJim Jagielski             xHierarchyAccess->getByHierarchicalName(_rSetNode) >>= xSetNode;
1260*b1cdbd2cSJim Jagielski             if (xSetNode.is())
1261*b1cdbd2cSJim Jagielski             {
1262*b1cdbd2cSJim Jagielski                 const sal_uInt32 nPrime = 65521;                            // a prime number
1263*b1cdbd2cSJim Jagielski                 const sal_uInt32 nPrimeLess2 = nPrime - 2;
1264*b1cdbd2cSJim Jagielski                 sal_uInt32 nEngendering     = (rand() % nPrimeLess2) + 2;   // the engendering of the field
1265*b1cdbd2cSJim Jagielski 
1266*b1cdbd2cSJim Jagielski                 // the element which will loop through the field
1267*b1cdbd2cSJim Jagielski                 sal_uInt32 nFieldElement = nEngendering;
1268*b1cdbd2cSJim Jagielski 
1269*b1cdbd2cSJim Jagielski                 for (; 1 != nFieldElement; nFieldElement = (nFieldElement * nEngendering) % nPrime)
1270*b1cdbd2cSJim Jagielski                 {
1271*b1cdbd2cSJim Jagielski                     ::rtl::OUString sThisRoundTrial = _rName;
1272*b1cdbd2cSJim Jagielski                     sThisRoundTrial += ::rtl::OUString::valueOf((sal_Int32)nFieldElement);
1273*b1cdbd2cSJim Jagielski 
1274*b1cdbd2cSJim Jagielski                     if (!xSetNode->hasByName(sThisRoundTrial))
1275*b1cdbd2cSJim Jagielski                     {
1276*b1cdbd2cSJim Jagielski                         _rName = sThisRoundTrial;
1277*b1cdbd2cSJim Jagielski                         bRet =  sal_True;
1278*b1cdbd2cSJim Jagielski 						break;
1279*b1cdbd2cSJim Jagielski                     }
1280*b1cdbd2cSJim Jagielski                 }
1281*b1cdbd2cSJim Jagielski             }
1282*b1cdbd2cSJim Jagielski         }
1283*b1cdbd2cSJim Jagielski         CATCH_INFO("Exception from getUniqueSetElementName(): ")
1284*b1cdbd2cSJim Jagielski     }
1285*b1cdbd2cSJim Jagielski     return bRet;
1286*b1cdbd2cSJim Jagielski }
1287*b1cdbd2cSJim Jagielski /* -----------------------------23.01.01 12:49--------------------------------
1288*b1cdbd2cSJim Jagielski 
1289*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1290*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::AddNode(const rtl::OUString& rNode, const rtl::OUString& rNewNode)
1291*b1cdbd2cSJim Jagielski {
1292*b1cdbd2cSJim Jagielski 	ValueCounter_Impl aCounter(pImpl->nInValueChange);
1293*b1cdbd2cSJim Jagielski     sal_Bool bRet = sal_True;
1294*b1cdbd2cSJim Jagielski     Reference<XHierarchicalNameAccess> xHierarchyAccess = GetTree();
1295*b1cdbd2cSJim Jagielski     if(xHierarchyAccess.is())
1296*b1cdbd2cSJim Jagielski 	{
1297*b1cdbd2cSJim Jagielski 		Reference<XChangesBatch> xBatch(xHierarchyAccess, UNO_QUERY);
1298*b1cdbd2cSJim Jagielski 		try
1299*b1cdbd2cSJim Jagielski 		{
1300*b1cdbd2cSJim Jagielski 			Reference<XNameContainer> xCont;
1301*b1cdbd2cSJim Jagielski 			if(rNode.getLength())
1302*b1cdbd2cSJim Jagielski 			{
1303*b1cdbd2cSJim Jagielski 				Any aNode = xHierarchyAccess->getByHierarchicalName(rNode);
1304*b1cdbd2cSJim Jagielski 				aNode >>= xCont;
1305*b1cdbd2cSJim Jagielski 			}
1306*b1cdbd2cSJim Jagielski 			else
1307*b1cdbd2cSJim Jagielski 				xCont = Reference<XNameContainer> (xHierarchyAccess, UNO_QUERY);
1308*b1cdbd2cSJim Jagielski 			if(!xCont.is())
1309*b1cdbd2cSJim Jagielski 				return sal_False;
1310*b1cdbd2cSJim Jagielski 
1311*b1cdbd2cSJim Jagielski 			Reference<XSingleServiceFactory> xFac(xCont, UNO_QUERY);
1312*b1cdbd2cSJim Jagielski 
1313*b1cdbd2cSJim Jagielski             if(xFac.is())
1314*b1cdbd2cSJim Jagielski 			{
1315*b1cdbd2cSJim Jagielski 				if(!xCont->hasByName(rNewNode))
1316*b1cdbd2cSJim Jagielski 				{
1317*b1cdbd2cSJim Jagielski 					Reference<XInterface> xInst = xFac->createInstance();
1318*b1cdbd2cSJim Jagielski 					Any aVal; aVal <<= xInst;
1319*b1cdbd2cSJim Jagielski 					xCont->insertByName(rNewNode, aVal);
1320*b1cdbd2cSJim Jagielski 				}
1321*b1cdbd2cSJim Jagielski 				try
1322*b1cdbd2cSJim Jagielski 				{
1323*b1cdbd2cSJim Jagielski 					xBatch->commitChanges();
1324*b1cdbd2cSJim Jagielski 				}
1325*b1cdbd2cSJim Jagielski                 CATCH_INFO("Exception from commitChanges(): ")
1326*b1cdbd2cSJim Jagielski 			}
1327*b1cdbd2cSJim Jagielski 			else
1328*b1cdbd2cSJim Jagielski 			{
1329*b1cdbd2cSJim Jagielski 				//if no factory is available then the node contains basic data elements
1330*b1cdbd2cSJim Jagielski 				try
1331*b1cdbd2cSJim Jagielski 				{
1332*b1cdbd2cSJim Jagielski 					if(!xCont->hasByName(rNewNode))
1333*b1cdbd2cSJim Jagielski 						xCont->insertByName(rNewNode, Any());
1334*b1cdbd2cSJim Jagielski 				}
1335*b1cdbd2cSJim Jagielski                 CATCH_INFO("Exception from AddNode(): ")
1336*b1cdbd2cSJim Jagielski 			}
1337*b1cdbd2cSJim Jagielski 			xBatch->commitChanges();
1338*b1cdbd2cSJim Jagielski 		}
1339*b1cdbd2cSJim Jagielski #ifdef DBG_UTIL
1340*b1cdbd2cSJim Jagielski         catch(Exception& rEx)
1341*b1cdbd2cSJim Jagielski 		{
1342*b1cdbd2cSJim Jagielski             lcl_CFG_DBG_EXCEPTION("Exception from AddNode(): ", rEx);
1343*b1cdbd2cSJim Jagielski #else
1344*b1cdbd2cSJim Jagielski         catch(Exception&)
1345*b1cdbd2cSJim Jagielski 		{
1346*b1cdbd2cSJim Jagielski #endif
1347*b1cdbd2cSJim Jagielski 			bRet = sal_False;
1348*b1cdbd2cSJim Jagielski 		}
1349*b1cdbd2cSJim Jagielski 	}
1350*b1cdbd2cSJim Jagielski 	return bRet;
1351*b1cdbd2cSJim Jagielski }
1352*b1cdbd2cSJim Jagielski /* -----------------------------12.02.01 11:38--------------------------------
1353*b1cdbd2cSJim Jagielski 
1354*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1355*b1cdbd2cSJim Jagielski sal_Int16 	ConfigItem::GetMode() const
1356*b1cdbd2cSJim Jagielski {
1357*b1cdbd2cSJim Jagielski 	return pImpl->nMode;
1358*b1cdbd2cSJim Jagielski }
1359*b1cdbd2cSJim Jagielski /* -----------------------------12.02.01 13:31--------------------------------
1360*b1cdbd2cSJim Jagielski 
1361*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1362*b1cdbd2cSJim Jagielski void 	ConfigItem::SetModified()
1363*b1cdbd2cSJim Jagielski {
1364*b1cdbd2cSJim Jagielski 	pImpl->bIsModified = sal_True;
1365*b1cdbd2cSJim Jagielski }
1366*b1cdbd2cSJim Jagielski /* -----------------------------05.05.01 14:07--------------------------------
1367*b1cdbd2cSJim Jagielski 
1368*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1369*b1cdbd2cSJim Jagielski void    ConfigItem::ClearModified()
1370*b1cdbd2cSJim Jagielski {
1371*b1cdbd2cSJim Jagielski     pImpl->bIsModified = sal_False;
1372*b1cdbd2cSJim Jagielski }
1373*b1cdbd2cSJim Jagielski /* -----------------------------12.02.01 13:31--------------------------------
1374*b1cdbd2cSJim Jagielski 
1375*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1376*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::IsModified() const
1377*b1cdbd2cSJim Jagielski {
1378*b1cdbd2cSJim Jagielski 	return pImpl->bIsModified;
1379*b1cdbd2cSJim Jagielski }
1380*b1cdbd2cSJim Jagielski /* -----------------------------12.02.01 13:33--------------------------------
1381*b1cdbd2cSJim Jagielski 
1382*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1383*b1cdbd2cSJim Jagielski sal_Bool ConfigItem::IsInValueChange() const
1384*b1cdbd2cSJim Jagielski {
1385*b1cdbd2cSJim Jagielski 	return pImpl->nInValueChange > 0;
1386*b1cdbd2cSJim Jagielski }
1387*b1cdbd2cSJim Jagielski /* -----------------------------21.06.01 12:26--------------------------------
1388*b1cdbd2cSJim Jagielski 
1389*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1390*b1cdbd2cSJim Jagielski Reference< XHierarchicalNameAccess> ConfigItem::GetTree()
1391*b1cdbd2cSJim Jagielski {
1392*b1cdbd2cSJim Jagielski     Reference< XHierarchicalNameAccess> xRet;
1393*b1cdbd2cSJim Jagielski     if(!m_xHierarchyAccess.is())
1394*b1cdbd2cSJim Jagielski         xRet = pImpl->pManager->AcquireTree(*this);
1395*b1cdbd2cSJim Jagielski     else
1396*b1cdbd2cSJim Jagielski         xRet = m_xHierarchyAccess;
1397*b1cdbd2cSJim Jagielski     OSL_ENSURE(xRet.is(), "AcquireTree failed");
1398*b1cdbd2cSJim Jagielski     return xRet;
1399*b1cdbd2cSJim Jagielski }
1400*b1cdbd2cSJim Jagielski /* -----------------------------22.06.01 08:42--------------------------------
1401*b1cdbd2cSJim Jagielski 
1402*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1403*b1cdbd2cSJim Jagielski void ConfigItem::LockTree()
1404*b1cdbd2cSJim Jagielski {
1405*b1cdbd2cSJim Jagielski     OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call LockTree in CONFIG_MODE_RELEASE_TREE mode, only");
1406*b1cdbd2cSJim Jagielski     m_xHierarchyAccess = GetTree();
1407*b1cdbd2cSJim Jagielski }
1408*b1cdbd2cSJim Jagielski /* -----------------------------22.06.01 08:42--------------------------------
1409*b1cdbd2cSJim Jagielski 
1410*b1cdbd2cSJim Jagielski  ---------------------------------------------------------------------------*/
1411*b1cdbd2cSJim Jagielski void ConfigItem::UnlockTree()
1412*b1cdbd2cSJim Jagielski {
1413*b1cdbd2cSJim Jagielski     OSL_ENSURE(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE), "call UnlockTree in CONFIG_MODE_RELEASE_TREE mode, only");
1414*b1cdbd2cSJim Jagielski     if(0 != (pImpl->nMode&CONFIG_MODE_RELEASE_TREE))
1415*b1cdbd2cSJim Jagielski         m_xHierarchyAccess = 0;
1416*b1cdbd2cSJim Jagielski }
1417*b1cdbd2cSJim Jagielski 
1418*b1cdbd2cSJim Jagielski 
1419