1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_framework.hxx"
30*cdf0e10cSrcweir // ______________________________________________
31*cdf0e10cSrcweir // my own includes
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir /** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
34*cdf0e10cSrcweir                with solaris headers ...
35*cdf0e10cSrcweir */
36*cdf0e10cSrcweir #include <vector>
37*cdf0e10cSrcweir #include <services/pathsettings.hxx>
38*cdf0e10cSrcweir #include <threadhelp/readguard.hxx>
39*cdf0e10cSrcweir #include <threadhelp/writeguard.hxx>
40*cdf0e10cSrcweir #include <services.h>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir // ______________________________________________
43*cdf0e10cSrcweir // interface includes
44*cdf0e10cSrcweir #include <com/sun/star/beans/Property.hpp>
45*cdf0e10cSrcweir #include <com/sun/star/beans/XProperty.hpp>
46*cdf0e10cSrcweir #include <com/sun/star/beans/PropertyAttribute.hpp>
47*cdf0e10cSrcweir #include <com/sun/star/container/XContainer.hpp>
48*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
49*cdf0e10cSrcweir #include <com/sun/star/util/XChangesNotifier.hpp>
50*cdf0e10cSrcweir 
51*cdf0e10cSrcweir // ______________________________________________
52*cdf0e10cSrcweir // includes of other projects
53*cdf0e10cSrcweir #include <tools/urlobj.hxx>
54*cdf0e10cSrcweir #include <rtl/ustrbuf.hxx>
55*cdf0e10cSrcweir #include <rtl/logfile.hxx>
56*cdf0e10cSrcweir 
57*cdf0e10cSrcweir #include <comphelper/configurationhelper.hxx>
58*cdf0e10cSrcweir #include <unotools/configpathes.hxx>
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir #include <fwkdllapi.h>
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir // ______________________________________________
63*cdf0e10cSrcweir //	non exported const
64*cdf0e10cSrcweir 
65*cdf0e10cSrcweir #define CFG_READONLY_DEFAULT    sal_False
66*cdf0e10cSrcweir 
67*cdf0e10cSrcweir const ::rtl::OUString CFGPROP_INTERNALPATHES = ::rtl::OUString::createFromAscii("InternalPaths");
68*cdf0e10cSrcweir const ::rtl::OUString CFGPROP_USERPATHES     = ::rtl::OUString::createFromAscii("UserPaths"    );
69*cdf0e10cSrcweir const ::rtl::OUString CFGPROP_WRITEPATH      = ::rtl::OUString::createFromAscii("WritePath"    );
70*cdf0e10cSrcweir const ::rtl::OUString CFGPROP_ISSINGLEPATH   = ::rtl::OUString::createFromAscii("IsSinglePath" );
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir /*
73*cdf0e10cSrcweir     0 : old style              "Template"              string using ";" as seperator
74*cdf0e10cSrcweir     1 : internal paths         "Template_internal"     string list
75*cdf0e10cSrcweir     2 : user paths             "Template_user"         string list
76*cdf0e10cSrcweir     3 : write path             "Template_write"        string
77*cdf0e10cSrcweir  */
78*cdf0e10cSrcweir 
79*cdf0e10cSrcweir const ::rtl::OUString POSTFIX_INTERNAL_PATHES = ::rtl::OUString::createFromAscii("_internal");
80*cdf0e10cSrcweir const ::rtl::OUString POSTFIX_USER_PATHES     = ::rtl::OUString::createFromAscii("_user"    );
81*cdf0e10cSrcweir const ::rtl::OUString POSTFIX_WRITE_PATH      = ::rtl::OUString::createFromAscii("_writable");
82*cdf0e10cSrcweir 
83*cdf0e10cSrcweir const sal_Int32 IDGROUP_OLDSTYLE        = 0;
84*cdf0e10cSrcweir const sal_Int32 IDGROUP_INTERNAL_PATHES = 1;
85*cdf0e10cSrcweir const sal_Int32 IDGROUP_USER_PATHES     = 2;
86*cdf0e10cSrcweir const sal_Int32 IDGROUP_WRITE_PATH      = 3;
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir const sal_Int32 IDGROUP_COUNT           = 4;
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir sal_Int32 impl_getPropGroup(sal_Int32 nID)
91*cdf0e10cSrcweir {
92*cdf0e10cSrcweir     return (nID % IDGROUP_COUNT);
93*cdf0e10cSrcweir }
94*cdf0e10cSrcweir 
95*cdf0e10cSrcweir // ______________________________________________
96*cdf0e10cSrcweir //	namespace
97*cdf0e10cSrcweir 
98*cdf0e10cSrcweir namespace framework
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir 
101*cdf0e10cSrcweir //-----------------------------------------------------------------------------
102*cdf0e10cSrcweir // XInterface, XTypeProvider, XServiceInfo
103*cdf0e10cSrcweir 
104*cdf0e10cSrcweir DEFINE_XINTERFACE_7						(   PathSettings                                             ,
105*cdf0e10cSrcweir                                             OWeakObject                                              ,
106*cdf0e10cSrcweir                                             DIRECT_INTERFACE ( css::lang::XTypeProvider              ),
107*cdf0e10cSrcweir                                             DIRECT_INTERFACE ( css::lang::XServiceInfo               ),
108*cdf0e10cSrcweir                                             DERIVED_INTERFACE( css::lang::XEventListener, css::util::XChangesListener),
109*cdf0e10cSrcweir                                             DIRECT_INTERFACE ( css::util::XChangesListener           ),
110*cdf0e10cSrcweir                                             DIRECT_INTERFACE ( css::beans::XPropertySet				 ),
111*cdf0e10cSrcweir                                             DIRECT_INTERFACE ( css::beans::XFastPropertySet			 ),
112*cdf0e10cSrcweir                                             DIRECT_INTERFACE ( css::beans::XMultiPropertySet		)
113*cdf0e10cSrcweir 										)
114*cdf0e10cSrcweir 
115*cdf0e10cSrcweir DEFINE_XTYPEPROVIDER_7					(   PathSettings                                            ,
116*cdf0e10cSrcweir                                             css::lang::XTypeProvider                                ,
117*cdf0e10cSrcweir                                             css::lang::XServiceInfo                                 ,
118*cdf0e10cSrcweir                                             css::lang::XEventListener                               ,
119*cdf0e10cSrcweir                                             css::util::XChangesListener                             ,
120*cdf0e10cSrcweir                                             css::beans::XPropertySet								,
121*cdf0e10cSrcweir                                             css::beans::XFastPropertySet							,
122*cdf0e10cSrcweir                                             css::beans::XMultiPropertySet
123*cdf0e10cSrcweir 										)
124*cdf0e10cSrcweir 
125*cdf0e10cSrcweir DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   PathSettings                                            ,
126*cdf0e10cSrcweir                                             ::cppu::OWeakObject                                     ,
127*cdf0e10cSrcweir                                             SERVICENAME_PATHSETTINGS                                ,
128*cdf0e10cSrcweir 											IMPLEMENTATIONNAME_PATHSETTINGS
129*cdf0e10cSrcweir 										)
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir DEFINE_INIT_SERVICE                     (   PathSettings,
132*cdf0e10cSrcweir                                             {
133*cdf0e10cSrcweir                                                 /*Attention
134*cdf0e10cSrcweir                                                     I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
135*cdf0e10cSrcweir                                                     to create a new instance of this class by our own supported service factory.
136*cdf0e10cSrcweir                                                     see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
137*cdf0e10cSrcweir                                                 */
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir                                                 // fill cache
140*cdf0e10cSrcweir                                                 impl_readAll();
141*cdf0e10cSrcweir                                             }
142*cdf0e10cSrcweir                                         )
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir //-----------------------------------------------------------------------------
145*cdf0e10cSrcweir PathSettings::PathSettings( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
146*cdf0e10cSrcweir     //	Init baseclasses first
147*cdf0e10cSrcweir     //  Attention: Don't change order of initialization!
148*cdf0e10cSrcweir     //      ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
149*cdf0e10cSrcweir     //      We must garant right initialization and a valid value of this to initialize other baseclasses!
150*cdf0e10cSrcweir     :   ThreadHelpBase()
151*cdf0e10cSrcweir     ,   ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >(m_aLock.getShareableOslMutex())
152*cdf0e10cSrcweir     ,   ::cppu::OPropertySetHelper(*(static_cast< ::cppu::OBroadcastHelper* >(this)))
153*cdf0e10cSrcweir     ,   ::cppu::OWeakObject()
154*cdf0e10cSrcweir     // Init member
155*cdf0e10cSrcweir     ,   m_xSMGR    (xSMGR)
156*cdf0e10cSrcweir     ,   m_pPropHelp(0    )
157*cdf0e10cSrcweir 	,  m_bIgnoreEvents(sal_False)
158*cdf0e10cSrcweir {
159*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::PathSettings" );
160*cdf0e10cSrcweir }
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir //-----------------------------------------------------------------------------
163*cdf0e10cSrcweir PathSettings::~PathSettings()
164*cdf0e10cSrcweir {
165*cdf0e10cSrcweir     if (m_pPropHelp)
166*cdf0e10cSrcweir        delete m_pPropHelp;
167*cdf0e10cSrcweir }
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir //-----------------------------------------------------------------------------
170*cdf0e10cSrcweir void SAL_CALL PathSettings::changesOccurred(const css::util::ChangesEvent& aEvent)
171*cdf0e10cSrcweir     throw (css::uno::RuntimeException)
172*cdf0e10cSrcweir {
173*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::changesOccurred" );
174*cdf0e10cSrcweir 	/*
175*cdf0e10cSrcweir 	if (m_bIgnoreEvents)
176*cdf0e10cSrcweir 		return;
177*cdf0e10cSrcweir 	*/
178*cdf0e10cSrcweir 
179*cdf0e10cSrcweir     sal_Int32 c                 = aEvent.Changes.getLength();
180*cdf0e10cSrcweir     sal_Int32 i                 = 0;
181*cdf0e10cSrcweir     sal_Bool  bUpdateDescriptor = sal_False;
182*cdf0e10cSrcweir 
183*cdf0e10cSrcweir     for (i=0; i<c; ++i)
184*cdf0e10cSrcweir     {
185*cdf0e10cSrcweir         const css::util::ElementChange& aChange = aEvent.Changes[i];
186*cdf0e10cSrcweir 
187*cdf0e10cSrcweir         ::rtl::OUString sChanged;
188*cdf0e10cSrcweir         aChange.Accessor >>= sChanged;
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir         ::rtl::OUString sPath = ::utl::extractFirstFromConfigurationPath(sChanged);
191*cdf0e10cSrcweir         if (sPath.getLength())
192*cdf0e10cSrcweir         {
193*cdf0e10cSrcweir             PathSettings::EChangeOp eOp = impl_updatePath(sPath, sal_True);
194*cdf0e10cSrcweir             if (
195*cdf0e10cSrcweir                 (eOp == PathSettings::E_ADDED  ) ||
196*cdf0e10cSrcweir                 (eOp == PathSettings::E_REMOVED)
197*cdf0e10cSrcweir                )
198*cdf0e10cSrcweir                 bUpdateDescriptor = sal_True;
199*cdf0e10cSrcweir         }
200*cdf0e10cSrcweir     }
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir     if (bUpdateDescriptor)
203*cdf0e10cSrcweir         impl_rebuildPropertyDescriptor();
204*cdf0e10cSrcweir }
205*cdf0e10cSrcweir 
206*cdf0e10cSrcweir //-----------------------------------------------------------------------------
207*cdf0e10cSrcweir void SAL_CALL PathSettings::disposing(const css::lang::EventObject& aSource)
208*cdf0e10cSrcweir     throw(css::uno::RuntimeException)
209*cdf0e10cSrcweir {
210*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::disposing" );
211*cdf0e10cSrcweir     // SAFE ->
212*cdf0e10cSrcweir     WriteGuard aWriteLock(m_aLock);
213*cdf0e10cSrcweir 
214*cdf0e10cSrcweir     if (aSource.Source == m_xCfgNew)
215*cdf0e10cSrcweir         m_xCfgNew.clear();
216*cdf0e10cSrcweir 
217*cdf0e10cSrcweir     aWriteLock.unlock();
218*cdf0e10cSrcweir     // <- SAFE
219*cdf0e10cSrcweir }
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir //-----------------------------------------------------------------------------
222*cdf0e10cSrcweir void PathSettings::impl_readAll()
223*cdf0e10cSrcweir {
224*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readAll" );
225*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT(aLog, "framework (as96863) ::PathSettings::load config (all)");
226*cdf0e10cSrcweir 
227*cdf0e10cSrcweir     // TODO think about me
228*cdf0e10cSrcweir     css::uno::Reference< css::container::XNameAccess > xCfg    = fa_getCfgNew();
229*cdf0e10cSrcweir     css::uno::Sequence< ::rtl::OUString >              lPaths = xCfg->getElementNames();
230*cdf0e10cSrcweir 
231*cdf0e10cSrcweir     sal_Int32 c = lPaths.getLength();
232*cdf0e10cSrcweir     sal_Int32 i = 0;
233*cdf0e10cSrcweir 
234*cdf0e10cSrcweir     for (i=0; i<c; ++i)
235*cdf0e10cSrcweir     {
236*cdf0e10cSrcweir         const ::rtl::OUString& sPath = lPaths[i];
237*cdf0e10cSrcweir         impl_updatePath(sPath, sal_False);
238*cdf0e10cSrcweir     }
239*cdf0e10cSrcweir 
240*cdf0e10cSrcweir 	impl_rebuildPropertyDescriptor();
241*cdf0e10cSrcweir }
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir //-----------------------------------------------------------------------------
244*cdf0e10cSrcweir // NO substitution here ! It's done outside ...
245*cdf0e10cSrcweir OUStringList PathSettings::impl_readOldFormat(const ::rtl::OUString& sPath)
246*cdf0e10cSrcweir {
247*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readOldFormat" );
248*cdf0e10cSrcweir     css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
249*cdf0e10cSrcweir     OUStringList aPathVal;
250*cdf0e10cSrcweir 
251*cdf0e10cSrcweir 	if( xCfg->hasByName(sPath) )
252*cdf0e10cSrcweir 	{
253*cdf0e10cSrcweir 		css::uno::Any aVal( xCfg->getByName(sPath) );
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir 		::rtl::OUString                       sStringVal;
256*cdf0e10cSrcweir 		css::uno::Sequence< ::rtl::OUString > lStringListVal;
257*cdf0e10cSrcweir 
258*cdf0e10cSrcweir 		if (aVal >>= sStringVal)
259*cdf0e10cSrcweir 		{
260*cdf0e10cSrcweir 			aPathVal.push_back(sStringVal);
261*cdf0e10cSrcweir 		}
262*cdf0e10cSrcweir 		else if (aVal >>= lStringListVal)
263*cdf0e10cSrcweir 		{
264*cdf0e10cSrcweir 			aPathVal << lStringListVal;
265*cdf0e10cSrcweir 		}
266*cdf0e10cSrcweir 	}
267*cdf0e10cSrcweir 
268*cdf0e10cSrcweir     return aPathVal;
269*cdf0e10cSrcweir }
270*cdf0e10cSrcweir 
271*cdf0e10cSrcweir //-----------------------------------------------------------------------------
272*cdf0e10cSrcweir // NO substitution here ! It's done outside ...
273*cdf0e10cSrcweir PathSettings::PathInfo PathSettings::impl_readNewFormat(const ::rtl::OUString& sPath)
274*cdf0e10cSrcweir {
275*cdf0e10cSrcweir     css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
276*cdf0e10cSrcweir 
277*cdf0e10cSrcweir     // get access to the "queried" path
278*cdf0e10cSrcweir     css::uno::Reference< css::container::XNameAccess > xPath;
279*cdf0e10cSrcweir     xCfg->getByName(sPath) >>= xPath;
280*cdf0e10cSrcweir 
281*cdf0e10cSrcweir     PathSettings::PathInfo aPathVal;
282*cdf0e10cSrcweir 
283*cdf0e10cSrcweir     // read internal path list
284*cdf0e10cSrcweir     css::uno::Reference< css::container::XNameAccess > xIPath;
285*cdf0e10cSrcweir     xPath->getByName(CFGPROP_INTERNALPATHES) >>= xIPath;
286*cdf0e10cSrcweir     aPathVal.lInternalPaths << xIPath->getElementNames();
287*cdf0e10cSrcweir 
288*cdf0e10cSrcweir     // read user defined path list
289*cdf0e10cSrcweir     aPathVal.lUserPaths << xPath->getByName(CFGPROP_USERPATHES);
290*cdf0e10cSrcweir 
291*cdf0e10cSrcweir     // read the writeable path
292*cdf0e10cSrcweir     xPath->getByName(CFGPROP_WRITEPATH) >>= aPathVal.sWritePath;
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir     // read state props
295*cdf0e10cSrcweir     xPath->getByName(CFGPROP_ISSINGLEPATH) >>= aPathVal.bIsSinglePath;
296*cdf0e10cSrcweir 
297*cdf0e10cSrcweir     // analyze finalized/mandatory states
298*cdf0e10cSrcweir     aPathVal.bIsReadonly = sal_False;
299*cdf0e10cSrcweir     css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
300*cdf0e10cSrcweir     if (xInfo.is())
301*cdf0e10cSrcweir     {
302*cdf0e10cSrcweir         css::beans::Property aInfo = xInfo->getAsProperty();
303*cdf0e10cSrcweir         sal_Bool bFinalized = ((aInfo.Attributes & css::beans::PropertyAttribute::READONLY  ) == css::beans::PropertyAttribute::READONLY  );
304*cdf0e10cSrcweir 		//sal_Bool bMandatory = ((aInfo.Attributes & css::beans::PropertyAttribute::REMOVEABLE) != css::beans::PropertyAttribute::REMOVEABLE);
305*cdf0e10cSrcweir 
306*cdf0e10cSrcweir         // Note: Till we support finalized / mandatory on our API more in detail we handle
307*cdf0e10cSrcweir         // all states simple as READONLY ! But because all realy needed pathes are "mandatory" by default
308*cdf0e10cSrcweir         // we have to handle "finalized" as the real "readonly" indicator .
309*cdf0e10cSrcweir         aPathVal.bIsReadonly = bFinalized;
310*cdf0e10cSrcweir     }
311*cdf0e10cSrcweir 
312*cdf0e10cSrcweir     return aPathVal;
313*cdf0e10cSrcweir }
314*cdf0e10cSrcweir 
315*cdf0e10cSrcweir //-----------------------------------------------------------------------------
316*cdf0e10cSrcweir void PathSettings::impl_storePath(const PathSettings::PathInfo& aPath)
317*cdf0e10cSrcweir {
318*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_storePath" );
319*cdf0e10cSrcweir 	m_bIgnoreEvents = sal_True;
320*cdf0e10cSrcweir 
321*cdf0e10cSrcweir     css::uno::Reference< css::container::XNameAccess > xCfgNew = fa_getCfgNew();
322*cdf0e10cSrcweir     css::uno::Reference< css::container::XNameAccess > xCfgOld = fa_getCfgOld();
323*cdf0e10cSrcweir 
324*cdf0e10cSrcweir     // try to replace path-parts with well known and uspported variables.
325*cdf0e10cSrcweir     // So an office can be moved easialy to another location without loosing
326*cdf0e10cSrcweir     // it's related pathes.
327*cdf0e10cSrcweir     PathInfo aResubstPath(aPath);
328*cdf0e10cSrcweir     impl_subst(aResubstPath, sal_True);
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir     // update new configuration
331*cdf0e10cSrcweir     if (! aResubstPath.bIsSinglePath)
332*cdf0e10cSrcweir     {
333*cdf0e10cSrcweir         ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
334*cdf0e10cSrcweir                                                             aResubstPath.sPathName,
335*cdf0e10cSrcweir                                                             CFGPROP_USERPATHES,
336*cdf0e10cSrcweir                                                             css::uno::makeAny(aResubstPath.lUserPaths.getAsConstList()));
337*cdf0e10cSrcweir     }
338*cdf0e10cSrcweir 
339*cdf0e10cSrcweir     ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
340*cdf0e10cSrcweir                                                         aResubstPath.sPathName,
341*cdf0e10cSrcweir                                                         CFGPROP_WRITEPATH,
342*cdf0e10cSrcweir                                                         css::uno::makeAny(aResubstPath.sWritePath));
343*cdf0e10cSrcweir 
344*cdf0e10cSrcweir     ::comphelper::ConfigurationHelper::flush(xCfgNew);
345*cdf0e10cSrcweir 
346*cdf0e10cSrcweir     // remove the whole path from the old configuration !
347*cdf0e10cSrcweir     // Otherwise we cant make sure that the diff between new and old configuration
348*cdf0e10cSrcweir     // on loading time realy represent an user setting !!!
349*cdf0e10cSrcweir 
350*cdf0e10cSrcweir     // Check if the given path exists inside the old configuration.
351*cdf0e10cSrcweir     // Because our new configuration knows more then the list of old pathes ... !
352*cdf0e10cSrcweir     if (xCfgOld->hasByName(aResubstPath.sPathName))
353*cdf0e10cSrcweir     {
354*cdf0e10cSrcweir         css::uno::Reference< css::beans::XPropertySet > xProps(xCfgOld, css::uno::UNO_QUERY_THROW);
355*cdf0e10cSrcweir         xProps->setPropertyValue(aResubstPath.sPathName, css::uno::Any());
356*cdf0e10cSrcweir         ::comphelper::ConfigurationHelper::flush(xCfgOld);
357*cdf0e10cSrcweir     }
358*cdf0e10cSrcweir 
359*cdf0e10cSrcweir 	m_bIgnoreEvents = sal_False;
360*cdf0e10cSrcweir }
361*cdf0e10cSrcweir 
362*cdf0e10cSrcweir //-----------------------------------------------------------------------------
363*cdf0e10cSrcweir #ifdef MIGRATE_OLD_USER_PATHES
364*cdf0e10cSrcweir void PathSettings::impl_mergeOldUserPaths(      PathSettings::PathInfo& rPath,
365*cdf0e10cSrcweir                                           const OUStringList&           lOld )
366*cdf0e10cSrcweir {
367*cdf0e10cSrcweir     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_mergeOldUserPaths" );
368*cdf0e10cSrcweir     OUStringList::const_iterator pIt;
369*cdf0e10cSrcweir     for (  pIt  = lOld.begin();
370*cdf0e10cSrcweir            pIt != lOld.end()  ;
371*cdf0e10cSrcweir          ++pIt                )
372*cdf0e10cSrcweir     {
373*cdf0e10cSrcweir         const ::rtl::OUString& sOld = *pIt;
374*cdf0e10cSrcweir 
375*cdf0e10cSrcweir         if (rPath.bIsSinglePath)
376*cdf0e10cSrcweir         {
377*cdf0e10cSrcweir             LOG_ASSERT2(lOld.size()>1, "PathSettings::impl_mergeOldUserPaths()", "Single path has more then one path value inside old configuration (Common.xcu)!")
378*cdf0e10cSrcweir             if (! rPath.sWritePath.equals(sOld))
379*cdf0e10cSrcweir                rPath.sWritePath = sOld;
380*cdf0e10cSrcweir         }
381*cdf0e10cSrcweir         else
382*cdf0e10cSrcweir         {
383*cdf0e10cSrcweir             if (
384*cdf0e10cSrcweir                 (  rPath.lInternalPaths.findConst(sOld) == rPath.lInternalPaths.end()) &&
385*cdf0e10cSrcweir                 (  rPath.lUserPaths.findConst(sOld)     == rPath.lUserPaths.end()    ) &&
386*cdf0e10cSrcweir                 (! rPath.sWritePath.equals(sOld)                                     )
387*cdf0e10cSrcweir                )
388*cdf0e10cSrcweir                rPath.lUserPaths.push_back(sOld);
389*cdf0e10cSrcweir         }
390*cdf0e10cSrcweir     }
391*cdf0e10cSrcweir }
392*cdf0e10cSrcweir #endif // MIGRATE_OLD_USER_PATHES
393*cdf0e10cSrcweir 
394*cdf0e10cSrcweir //-----------------------------------------------------------------------------
395*cdf0e10cSrcweir PathSettings::EChangeOp PathSettings::impl_updatePath(const ::rtl::OUString& sPath          ,
396*cdf0e10cSrcweir                                                             sal_Bool         bNotifyListener)
397*cdf0e10cSrcweir {
398*cdf0e10cSrcweir     // SAFE ->
399*cdf0e10cSrcweir     WriteGuard aWriteLock(m_aLock);
400*cdf0e10cSrcweir 
401*cdf0e10cSrcweir     PathSettings::PathInfo* pPathOld = 0;
402*cdf0e10cSrcweir     PathSettings::PathInfo* pPathNew = 0;
403*cdf0e10cSrcweir     PathSettings::EChangeOp eOp      = PathSettings::E_UNDEFINED;
404*cdf0e10cSrcweir     PathSettings::PathInfo  aPath;
405*cdf0e10cSrcweir 
406*cdf0e10cSrcweir     try
407*cdf0e10cSrcweir     {
408*cdf0e10cSrcweir         aPath = impl_readNewFormat(sPath);
409*cdf0e10cSrcweir         aPath.sPathName = sPath;
410*cdf0e10cSrcweir         // replace all might existing variables with real values
411*cdf0e10cSrcweir         // Do it before these old pathes will be compared against the
412*cdf0e10cSrcweir         // new path configuration. Otherwise some striungs uses different variables ... but substitution
413*cdf0e10cSrcweir         // will produce strings with same content (because some variables are redundant!)
414*cdf0e10cSrcweir         impl_subst(aPath, sal_False);
415*cdf0e10cSrcweir     }
416*cdf0e10cSrcweir     catch(const css::uno::RuntimeException& exRun)
417*cdf0e10cSrcweir         { throw exRun; }
418*cdf0e10cSrcweir     catch(const css::container::NoSuchElementException&)
419*cdf0e10cSrcweir         { eOp = PathSettings::E_REMOVED; }
420*cdf0e10cSrcweir     catch(const css::uno::Exception& exAny)
421*cdf0e10cSrcweir         { throw exAny; }
422*cdf0e10cSrcweir 
423*cdf0e10cSrcweir     #ifdef MIGRATE_OLD_USER_PATHES
424*cdf0e10cSrcweir     try
425*cdf0e10cSrcweir     {
426*cdf0e10cSrcweir         // migration of old user defined values on demand
427*cdf0e10cSrcweir         // can be disabled for a new major
428*cdf0e10cSrcweir         OUStringList lOldVals = impl_readOldFormat(sPath);
429*cdf0e10cSrcweir         // replace all might existing variables with real values
430*cdf0e10cSrcweir         // Do it before these old pathes will be compared against the
431*cdf0e10cSrcweir         // new path configuration. Otherwise some striungs uses different variables ... but substitution
432*cdf0e10cSrcweir         // will produce strings with same content (because some variables are redundant!)
433*cdf0e10cSrcweir         impl_subst(lOldVals, fa_getSubstitution(), sal_False);
434*cdf0e10cSrcweir         impl_mergeOldUserPaths(aPath, lOldVals);
435*cdf0e10cSrcweir     }
436*cdf0e10cSrcweir     catch(const css::uno::RuntimeException& exRun)
437*cdf0e10cSrcweir         { throw exRun; }
438*cdf0e10cSrcweir     // Normal(!) exceptions can be ignored!
439*cdf0e10cSrcweir     // E.g. in case an addon installs a new path, which was not well known for an OOo 1.x installation
440*cdf0e10cSrcweir     // we cant find a value for it inside the "old" configuration. So a NoSuchElementException
441*cdf0e10cSrcweir     // will be normal .-)
442*cdf0e10cSrcweir     catch(const css::uno::Exception&)
443*cdf0e10cSrcweir         {}
444*cdf0e10cSrcweir     #endif // MIGRATE_OLD_USER_PATHES
445*cdf0e10cSrcweir 
446*cdf0e10cSrcweir     PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
447*cdf0e10cSrcweir     if (eOp == PathSettings::E_UNDEFINED)
448*cdf0e10cSrcweir     {
449*cdf0e10cSrcweir         if (pPath != m_lPaths.end())
450*cdf0e10cSrcweir             eOp = PathSettings::E_CHANGED;
451*cdf0e10cSrcweir         else
452*cdf0e10cSrcweir             eOp = PathSettings::E_ADDED;
453*cdf0e10cSrcweir     }
454*cdf0e10cSrcweir 
455*cdf0e10cSrcweir     switch(eOp)
456*cdf0e10cSrcweir     {
457*cdf0e10cSrcweir         case PathSettings::E_ADDED :
458*cdf0e10cSrcweir              {
459*cdf0e10cSrcweir                 if (bNotifyListener)
460*cdf0e10cSrcweir                 {
461*cdf0e10cSrcweir                     pPathOld = 0;
462*cdf0e10cSrcweir                     pPathNew = &aPath;
463*cdf0e10cSrcweir                     impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
464*cdf0e10cSrcweir                 }
465*cdf0e10cSrcweir                 m_lPaths[sPath] = aPath;
466*cdf0e10cSrcweir              }
467*cdf0e10cSrcweir              break;
468*cdf0e10cSrcweir 
469*cdf0e10cSrcweir         case PathSettings::E_CHANGED :
470*cdf0e10cSrcweir              {
471*cdf0e10cSrcweir                 if (bNotifyListener)
472*cdf0e10cSrcweir                 {
473*cdf0e10cSrcweir                     pPathOld = &(pPath->second);
474*cdf0e10cSrcweir                     pPathNew = &aPath;
475*cdf0e10cSrcweir                     impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
476*cdf0e10cSrcweir                 }
477*cdf0e10cSrcweir                 m_lPaths[sPath] = aPath;
478*cdf0e10cSrcweir              }
479*cdf0e10cSrcweir              break;
480*cdf0e10cSrcweir 
481*cdf0e10cSrcweir         case PathSettings::E_REMOVED :
482*cdf0e10cSrcweir              {
483*cdf0e10cSrcweir                 if (pPath != m_lPaths.end())
484*cdf0e10cSrcweir                 {
485*cdf0e10cSrcweir                     if (bNotifyListener)
486*cdf0e10cSrcweir                     {
487*cdf0e10cSrcweir                         pPathOld = &(pPath->second);
488*cdf0e10cSrcweir                         pPathNew = 0;
489*cdf0e10cSrcweir                         impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
490*cdf0e10cSrcweir                     }
491*cdf0e10cSrcweir                     m_lPaths.erase(pPath);
492*cdf0e10cSrcweir                 }
493*cdf0e10cSrcweir              }
494*cdf0e10cSrcweir              break;
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir 		default: // to let compiler be happy
497*cdf0e10cSrcweir 			 break;
498*cdf0e10cSrcweir     }
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir     return eOp;
501*cdf0e10cSrcweir }
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir //-----------------------------------------------------------------------------
504*cdf0e10cSrcweir css::uno::Sequence< sal_Int32 > PathSettings::impl_mapPathName2IDList(const ::rtl::OUString& sPath)
505*cdf0e10cSrcweir {
506*cdf0e10cSrcweir     ::rtl::OUString sOldStyleProp = sPath;
507*cdf0e10cSrcweir     ::rtl::OUString sInternalProp = sPath+POSTFIX_INTERNAL_PATHES;
508*cdf0e10cSrcweir     ::rtl::OUString sUserProp     = sPath+POSTFIX_USER_PATHES;
509*cdf0e10cSrcweir     ::rtl::OUString sWriteProp    = sPath+POSTFIX_WRITE_PATH;
510*cdf0e10cSrcweir 
511*cdf0e10cSrcweir     // Attention: The default set of IDs is fix and must follow these schema.
512*cdf0e10cSrcweir     // Otherwhise the outside code ant work for new added properties.
513*cdf0e10cSrcweir     // Why ?
514*cdf0e10cSrcweir     // The outside code must fire N events for every changed property.
515*cdf0e10cSrcweir     // And the knowing about packaging of variables of the structure PathInfo
516*cdf0e10cSrcweir     // follow these group IDs ! But if such ID isnt in the range of [0..IDGROUP_COUNT]
517*cdf0e10cSrcweir     // the outside cant determine the right group ... and cant fire the right events .-)
518*cdf0e10cSrcweir 
519*cdf0e10cSrcweir     css::uno::Sequence< sal_Int32 > lIDs(IDGROUP_COUNT);
520*cdf0e10cSrcweir     lIDs[0] = IDGROUP_OLDSTYLE       ;
521*cdf0e10cSrcweir     lIDs[1] = IDGROUP_INTERNAL_PATHES;
522*cdf0e10cSrcweir     lIDs[2] = IDGROUP_USER_PATHES    ;
523*cdf0e10cSrcweir     lIDs[3] = IDGROUP_WRITE_PATH     ;
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir     sal_Int32 c = m_lPropDesc.getLength();
526*cdf0e10cSrcweir     sal_Int32 i = 0;
527*cdf0e10cSrcweir     for (i=0; i<c; ++i)
528*cdf0e10cSrcweir     {
529*cdf0e10cSrcweir         const css::beans::Property& rProp = m_lPropDesc[i];
530*cdf0e10cSrcweir 
531*cdf0e10cSrcweir         if (rProp.Name.equals(sOldStyleProp))
532*cdf0e10cSrcweir             lIDs[IDGROUP_OLDSTYLE] = rProp.Handle;
533*cdf0e10cSrcweir         else
534*cdf0e10cSrcweir         if (rProp.Name.equals(sInternalProp))
535*cdf0e10cSrcweir             lIDs[IDGROUP_INTERNAL_PATHES] = rProp.Handle;
536*cdf0e10cSrcweir         else
537*cdf0e10cSrcweir         if (rProp.Name.equals(sUserProp))
538*cdf0e10cSrcweir             lIDs[IDGROUP_USER_PATHES] = rProp.Handle;
539*cdf0e10cSrcweir         else
540*cdf0e10cSrcweir         if (rProp.Name.equals(sWriteProp))
541*cdf0e10cSrcweir             lIDs[IDGROUP_WRITE_PATH] = rProp.Handle;
542*cdf0e10cSrcweir     }
543*cdf0e10cSrcweir 
544*cdf0e10cSrcweir     return lIDs;
545*cdf0e10cSrcweir }
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir //-----------------------------------------------------------------------------
548*cdf0e10cSrcweir void PathSettings::impl_notifyPropListener(      PathSettings::EChangeOp /*eOp*/     ,
549*cdf0e10cSrcweir                                            const ::rtl::OUString&        sPath   ,
550*cdf0e10cSrcweir                                            const PathSettings::PathInfo* pPathOld,
551*cdf0e10cSrcweir                                            const PathSettings::PathInfo* pPathNew)
552*cdf0e10cSrcweir {
553*cdf0e10cSrcweir     css::uno::Sequence< sal_Int32 >     lHandles(1);
554*cdf0e10cSrcweir     css::uno::Sequence< css::uno::Any > lOldVals(1);
555*cdf0e10cSrcweir     css::uno::Sequence< css::uno::Any > lNewVals(1);
556*cdf0e10cSrcweir 
557*cdf0e10cSrcweir     css::uno::Sequence< sal_Int32 > lIDs   = impl_mapPathName2IDList(sPath);
558*cdf0e10cSrcweir     sal_Int32                       c      = lIDs.getLength();
559*cdf0e10cSrcweir     sal_Int32                       i      = 0;
560*cdf0e10cSrcweir     sal_Int32                       nMaxID = m_lPropDesc.getLength()-1;
561*cdf0e10cSrcweir     for (i=0; i<c; ++i)
562*cdf0e10cSrcweir     {
563*cdf0e10cSrcweir         sal_Int32 nID = lIDs[i];
564*cdf0e10cSrcweir 
565*cdf0e10cSrcweir         if (
566*cdf0e10cSrcweir             (nID < 0     ) ||
567*cdf0e10cSrcweir             (nID > nMaxID)
568*cdf0e10cSrcweir            )
569*cdf0e10cSrcweir            continue;
570*cdf0e10cSrcweir 
571*cdf0e10cSrcweir         lHandles[0] = nID;
572*cdf0e10cSrcweir         switch(impl_getPropGroup(nID))
573*cdf0e10cSrcweir         {
574*cdf0e10cSrcweir             case IDGROUP_OLDSTYLE :
575*cdf0e10cSrcweir                  {
576*cdf0e10cSrcweir                     if (pPathOld)
577*cdf0e10cSrcweir                     {
578*cdf0e10cSrcweir                         ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathOld);
579*cdf0e10cSrcweir                         lOldVals[0] <<= sVal;
580*cdf0e10cSrcweir                     }
581*cdf0e10cSrcweir                     if (pPathNew)
582*cdf0e10cSrcweir                     {
583*cdf0e10cSrcweir                         ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathNew);
584*cdf0e10cSrcweir                         lNewVals[0] <<= sVal;
585*cdf0e10cSrcweir                     }
586*cdf0e10cSrcweir                  }
587*cdf0e10cSrcweir                  break;
588*cdf0e10cSrcweir 
589*cdf0e10cSrcweir             case IDGROUP_INTERNAL_PATHES :
590*cdf0e10cSrcweir                  {
591*cdf0e10cSrcweir                     if (pPathOld)
592*cdf0e10cSrcweir                         lOldVals[0] <<= pPathOld->lInternalPaths.getAsConstList();
593*cdf0e10cSrcweir                     if (pPathNew)
594*cdf0e10cSrcweir                         lNewVals[0] <<= pPathNew->lInternalPaths.getAsConstList();
595*cdf0e10cSrcweir                  }
596*cdf0e10cSrcweir                  break;
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir             case IDGROUP_USER_PATHES :
599*cdf0e10cSrcweir                  {
600*cdf0e10cSrcweir                     if (pPathOld)
601*cdf0e10cSrcweir                         lOldVals[0] <<= pPathOld->lUserPaths.getAsConstList();
602*cdf0e10cSrcweir                     if (pPathNew)
603*cdf0e10cSrcweir                         lNewVals[0] <<= pPathNew->lUserPaths.getAsConstList();
604*cdf0e10cSrcweir                  }
605*cdf0e10cSrcweir                  break;
606*cdf0e10cSrcweir 
607*cdf0e10cSrcweir             case IDGROUP_WRITE_PATH :
608*cdf0e10cSrcweir                  {
609*cdf0e10cSrcweir                     if (pPathOld)
610*cdf0e10cSrcweir                         lOldVals[0] <<= pPathOld->sWritePath;
611*cdf0e10cSrcweir                     if (pPathNew)
612*cdf0e10cSrcweir                         lNewVals[0] <<= pPathNew->sWritePath;
613*cdf0e10cSrcweir                  }
614*cdf0e10cSrcweir                  break;
615*cdf0e10cSrcweir         }
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir         fire(lHandles.getArray(),
618*cdf0e10cSrcweir              lNewVals.getArray(),
619*cdf0e10cSrcweir              lOldVals.getArray(),
620*cdf0e10cSrcweir              1,
621*cdf0e10cSrcweir              sal_False);
622*cdf0e10cSrcweir     }
623*cdf0e10cSrcweir }
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir //-----------------------------------------------------------------------------
626*cdf0e10cSrcweir void PathSettings::impl_subst(      OUStringList&                                          lVals   ,
627*cdf0e10cSrcweir                               const css::uno::Reference< css::util::XStringSubstitution >& xSubst  ,
628*cdf0e10cSrcweir                                     sal_Bool                                               bReSubst)
629*cdf0e10cSrcweir {
630*cdf0e10cSrcweir     OUStringList::iterator pIt;
631*cdf0e10cSrcweir 
632*cdf0e10cSrcweir     for (  pIt  = lVals.begin();
633*cdf0e10cSrcweir            pIt != lVals.end()  ;
634*cdf0e10cSrcweir          ++pIt                 )
635*cdf0e10cSrcweir     {
636*cdf0e10cSrcweir         const ::rtl::OUString& sOld = *pIt;
637*cdf0e10cSrcweir               ::rtl::OUString  sNew ;
638*cdf0e10cSrcweir         if (bReSubst)
639*cdf0e10cSrcweir             sNew = xSubst->reSubstituteVariables(sOld);
640*cdf0e10cSrcweir         else
641*cdf0e10cSrcweir             sNew = xSubst->substituteVariables(sOld, sal_False);
642*cdf0e10cSrcweir 
643*cdf0e10cSrcweir         *pIt = sNew;
644*cdf0e10cSrcweir     }
645*cdf0e10cSrcweir }
646*cdf0e10cSrcweir 
647*cdf0e10cSrcweir //-----------------------------------------------------------------------------
648*cdf0e10cSrcweir void PathSettings::impl_subst(PathSettings::PathInfo& aPath   ,
649*cdf0e10cSrcweir                               sal_Bool                bReSubst)
650*cdf0e10cSrcweir {
651*cdf0e10cSrcweir     css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();
652*cdf0e10cSrcweir 
653*cdf0e10cSrcweir     impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
654*cdf0e10cSrcweir     impl_subst(aPath.lUserPaths    , xSubst, bReSubst);
655*cdf0e10cSrcweir     if (bReSubst)
656*cdf0e10cSrcweir         aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
657*cdf0e10cSrcweir     else
658*cdf0e10cSrcweir         aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, sal_False);
659*cdf0e10cSrcweir }
660*cdf0e10cSrcweir 
661*cdf0e10cSrcweir //-----------------------------------------------------------------------------
662*cdf0e10cSrcweir ::rtl::OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
663*cdf0e10cSrcweir {
664*cdf0e10cSrcweir     OUStringList::const_iterator pIt;
665*cdf0e10cSrcweir 	OUStringList				 lTemp;
666*cdf0e10cSrcweir     lTemp.reserve(rPath.lInternalPaths.size() + rPath.lUserPaths.size() + 1);
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir     for (  pIt  = rPath.lInternalPaths.begin();
669*cdf0e10cSrcweir            pIt != rPath.lInternalPaths.end()  ;
670*cdf0e10cSrcweir          ++pIt                                 )
671*cdf0e10cSrcweir     {
672*cdf0e10cSrcweir         lTemp.push_back(*pIt);
673*cdf0e10cSrcweir     }
674*cdf0e10cSrcweir     for (  pIt  = rPath.lUserPaths.begin();
675*cdf0e10cSrcweir            pIt != rPath.lUserPaths.end()  ;
676*cdf0e10cSrcweir          ++pIt                             )
677*cdf0e10cSrcweir     {
678*cdf0e10cSrcweir         lTemp.push_back(*pIt);
679*cdf0e10cSrcweir     }
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir 	if (rPath.sWritePath.getLength() > 0)
682*cdf0e10cSrcweir         lTemp.push_back(rPath.sWritePath);
683*cdf0e10cSrcweir 
684*cdf0e10cSrcweir     ::rtl::OUStringBuffer sPathVal(256);
685*cdf0e10cSrcweir     for (  pIt  = lTemp.begin();
686*cdf0e10cSrcweir            pIt != lTemp.end()  ;
687*cdf0e10cSrcweir                                )
688*cdf0e10cSrcweir     {
689*cdf0e10cSrcweir         sPathVal.append(*pIt);
690*cdf0e10cSrcweir         ++pIt;
691*cdf0e10cSrcweir         if (pIt != lTemp.end())
692*cdf0e10cSrcweir             sPathVal.appendAscii(";");
693*cdf0e10cSrcweir     }
694*cdf0e10cSrcweir 
695*cdf0e10cSrcweir     return sPathVal.makeStringAndClear();
696*cdf0e10cSrcweir }
697*cdf0e10cSrcweir 
698*cdf0e10cSrcweir //-----------------------------------------------------------------------------
699*cdf0e10cSrcweir OUStringList PathSettings::impl_convertOldStyle2Path(const ::rtl::OUString& sOldStylePath) const
700*cdf0e10cSrcweir {
701*cdf0e10cSrcweir     OUStringList lList;
702*cdf0e10cSrcweir     sal_Int32    nToken = 0;
703*cdf0e10cSrcweir     do
704*cdf0e10cSrcweir     {
705*cdf0e10cSrcweir         ::rtl::OUString sToken = sOldStylePath.getToken(0, ';', nToken);
706*cdf0e10cSrcweir         if (sToken.getLength())
707*cdf0e10cSrcweir             lList.push_back(sToken);
708*cdf0e10cSrcweir     }
709*cdf0e10cSrcweir     while(nToken >= 0);
710*cdf0e10cSrcweir 
711*cdf0e10cSrcweir     return lList;
712*cdf0e10cSrcweir }
713*cdf0e10cSrcweir 
714*cdf0e10cSrcweir //-----------------------------------------------------------------------------
715*cdf0e10cSrcweir void PathSettings::impl_purgeKnownPaths(const PathSettings::PathInfo& rPath,
716*cdf0e10cSrcweir                                                OUStringList&           lList)
717*cdf0e10cSrcweir {
718*cdf0e10cSrcweir     OUStringList::const_iterator pIt;
719*cdf0e10cSrcweir     for (  pIt  = rPath.lInternalPaths.begin();
720*cdf0e10cSrcweir            pIt != rPath.lInternalPaths.end()  ;
721*cdf0e10cSrcweir          ++pIt                                 )
722*cdf0e10cSrcweir     {
723*cdf0e10cSrcweir         const ::rtl::OUString& rItem = *pIt;
724*cdf0e10cSrcweir         OUStringList::iterator pItem = lList.find(rItem);
725*cdf0e10cSrcweir         if (pItem != lList.end())
726*cdf0e10cSrcweir             lList.erase(pItem);
727*cdf0e10cSrcweir     }
728*cdf0e10cSrcweir     for (  pIt  = rPath.lUserPaths.begin();
729*cdf0e10cSrcweir            pIt != rPath.lUserPaths.end()  ;
730*cdf0e10cSrcweir          ++pIt                             )
731*cdf0e10cSrcweir     {
732*cdf0e10cSrcweir         const ::rtl::OUString& rItem = *pIt;
733*cdf0e10cSrcweir         OUStringList::iterator pItem = lList.find(rItem);
734*cdf0e10cSrcweir         if (pItem != lList.end())
735*cdf0e10cSrcweir             lList.erase(pItem);
736*cdf0e10cSrcweir     }
737*cdf0e10cSrcweir 
738*cdf0e10cSrcweir     OUStringList::iterator pItem = lList.find(rPath.sWritePath);
739*cdf0e10cSrcweir     if (pItem != lList.end())
740*cdf0e10cSrcweir         lList.erase(pItem);
741*cdf0e10cSrcweir }
742*cdf0e10cSrcweir 
743*cdf0e10cSrcweir //-----------------------------------------------------------------------------
744*cdf0e10cSrcweir void PathSettings::impl_rebuildPropertyDescriptor()
745*cdf0e10cSrcweir {
746*cdf0e10cSrcweir     // SAFE ->
747*cdf0e10cSrcweir     WriteGuard aWriteLock(m_aLock);
748*cdf0e10cSrcweir 
749*cdf0e10cSrcweir     sal_Int32 c = (sal_Int32)m_lPaths.size();
750*cdf0e10cSrcweir     sal_Int32 i = 0;
751*cdf0e10cSrcweir     m_lPropDesc.realloc(c*IDGROUP_COUNT);
752*cdf0e10cSrcweir 
753*cdf0e10cSrcweir     PathHash::const_iterator pIt;
754*cdf0e10cSrcweir     for (  pIt  = m_lPaths.begin();
755*cdf0e10cSrcweir            pIt != m_lPaths.end()  ;
756*cdf0e10cSrcweir          ++pIt                     )
757*cdf0e10cSrcweir     {
758*cdf0e10cSrcweir         const PathSettings::PathInfo& rPath = pIt->second;
759*cdf0e10cSrcweir               css::beans::Property*   pProp = 0;
760*cdf0e10cSrcweir 
761*cdf0e10cSrcweir         pProp             = &(m_lPropDesc[i]);
762*cdf0e10cSrcweir         pProp->Name       = rPath.sPathName;
763*cdf0e10cSrcweir         pProp->Handle     = i;
764*cdf0e10cSrcweir         pProp->Type       = ::getCppuType((::rtl::OUString*)0);
765*cdf0e10cSrcweir         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
766*cdf0e10cSrcweir         if (rPath.bIsReadonly)
767*cdf0e10cSrcweir             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
768*cdf0e10cSrcweir         ++i;
769*cdf0e10cSrcweir 
770*cdf0e10cSrcweir         pProp             = &(m_lPropDesc[i]);
771*cdf0e10cSrcweir         pProp->Name       = rPath.sPathName+POSTFIX_INTERNAL_PATHES;
772*cdf0e10cSrcweir         pProp->Handle     = i;
773*cdf0e10cSrcweir         pProp->Type       = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
774*cdf0e10cSrcweir         pProp->Attributes = css::beans::PropertyAttribute::BOUND   |
775*cdf0e10cSrcweir                             css::beans::PropertyAttribute::READONLY;
776*cdf0e10cSrcweir         ++i;
777*cdf0e10cSrcweir 
778*cdf0e10cSrcweir         pProp             = &(m_lPropDesc[i]);
779*cdf0e10cSrcweir         pProp->Name       = rPath.sPathName+POSTFIX_USER_PATHES;
780*cdf0e10cSrcweir         pProp->Handle     = i;
781*cdf0e10cSrcweir         pProp->Type       = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
782*cdf0e10cSrcweir         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
783*cdf0e10cSrcweir         if (rPath.bIsReadonly)
784*cdf0e10cSrcweir             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
785*cdf0e10cSrcweir         ++i;
786*cdf0e10cSrcweir 
787*cdf0e10cSrcweir         pProp             = &(m_lPropDesc[i]);
788*cdf0e10cSrcweir         pProp->Name       = rPath.sPathName+POSTFIX_WRITE_PATH;
789*cdf0e10cSrcweir         pProp->Handle     = i;
790*cdf0e10cSrcweir         pProp->Type       = ::getCppuType((::rtl::OUString*)0);
791*cdf0e10cSrcweir         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
792*cdf0e10cSrcweir         if (rPath.bIsReadonly)
793*cdf0e10cSrcweir             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
794*cdf0e10cSrcweir         ++i;
795*cdf0e10cSrcweir     }
796*cdf0e10cSrcweir 
797*cdf0e10cSrcweir     if (m_pPropHelp)
798*cdf0e10cSrcweir        delete m_pPropHelp;
799*cdf0e10cSrcweir     m_pPropHelp = new ::cppu::OPropertyArrayHelper(m_lPropDesc, sal_False); // false => not sorted ... must be done inside helper
800*cdf0e10cSrcweir 
801*cdf0e10cSrcweir     aWriteLock.unlock();
802*cdf0e10cSrcweir     // <- SAFE
803*cdf0e10cSrcweir }
804*cdf0e10cSrcweir 
805*cdf0e10cSrcweir //-----------------------------------------------------------------------------
806*cdf0e10cSrcweir css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
807*cdf0e10cSrcweir {
808*cdf0e10cSrcweir     const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
809*cdf0e10cSrcweir     if (! pPath)
810*cdf0e10cSrcweir         throw css::container::NoSuchElementException();
811*cdf0e10cSrcweir 
812*cdf0e10cSrcweir     css::uno::Any aVal;
813*cdf0e10cSrcweir     switch(impl_getPropGroup(nID))
814*cdf0e10cSrcweir     {
815*cdf0e10cSrcweir         case IDGROUP_OLDSTYLE :
816*cdf0e10cSrcweir              {
817*cdf0e10cSrcweir                 ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPath);
818*cdf0e10cSrcweir                 aVal <<= sVal;
819*cdf0e10cSrcweir              }
820*cdf0e10cSrcweir              break;
821*cdf0e10cSrcweir 
822*cdf0e10cSrcweir         case IDGROUP_INTERNAL_PATHES :
823*cdf0e10cSrcweir              {
824*cdf0e10cSrcweir                 aVal <<= pPath->lInternalPaths.getAsConstList();
825*cdf0e10cSrcweir              }
826*cdf0e10cSrcweir              break;
827*cdf0e10cSrcweir 
828*cdf0e10cSrcweir         case IDGROUP_USER_PATHES :
829*cdf0e10cSrcweir              {
830*cdf0e10cSrcweir                 aVal <<= pPath->lUserPaths.getAsConstList();
831*cdf0e10cSrcweir              }
832*cdf0e10cSrcweir              break;
833*cdf0e10cSrcweir 
834*cdf0e10cSrcweir         case IDGROUP_WRITE_PATH :
835*cdf0e10cSrcweir              {
836*cdf0e10cSrcweir                 aVal <<= pPath->sWritePath;
837*cdf0e10cSrcweir              }
838*cdf0e10cSrcweir              break;
839*cdf0e10cSrcweir     }
840*cdf0e10cSrcweir 
841*cdf0e10cSrcweir     return aVal;
842*cdf0e10cSrcweir }
843*cdf0e10cSrcweir 
844*cdf0e10cSrcweir //-----------------------------------------------------------------------------
845*cdf0e10cSrcweir void PathSettings::impl_setPathValue(      sal_Int32      nID ,
846*cdf0e10cSrcweir                                      const css::uno::Any& aVal)
847*cdf0e10cSrcweir {
848*cdf0e10cSrcweir     PathSettings::PathInfo* pOrgPath = impl_getPathAccess(nID);
849*cdf0e10cSrcweir     if (! pOrgPath)
850*cdf0e10cSrcweir         throw css::container::NoSuchElementException();
851*cdf0e10cSrcweir 
852*cdf0e10cSrcweir     // We work on a copied path ... so we can be sure that errors during this operation
853*cdf0e10cSrcweir     // does not make our internal cache invalid  .-)
854*cdf0e10cSrcweir     PathSettings::PathInfo aChangePath(*pOrgPath);
855*cdf0e10cSrcweir 
856*cdf0e10cSrcweir     switch(impl_getPropGroup(nID))
857*cdf0e10cSrcweir     {
858*cdf0e10cSrcweir         case IDGROUP_OLDSTYLE :
859*cdf0e10cSrcweir              {
860*cdf0e10cSrcweir                 ::rtl::OUString sVal;
861*cdf0e10cSrcweir                 aVal >>= sVal;
862*cdf0e10cSrcweir                 OUStringList lList = impl_convertOldStyle2Path(sVal);
863*cdf0e10cSrcweir                 impl_subst(lList, fa_getSubstitution(), sal_False);
864*cdf0e10cSrcweir                 impl_purgeKnownPaths(aChangePath, lList);
865*cdf0e10cSrcweir                 if (! impl_isValidPath(lList))
866*cdf0e10cSrcweir                     throw css::lang::IllegalArgumentException();
867*cdf0e10cSrcweir 
868*cdf0e10cSrcweir                 if (aChangePath.bIsSinglePath)
869*cdf0e10cSrcweir                 {
870*cdf0e10cSrcweir                     LOG_ASSERT2(lList.size()>1, "PathSettings::impl_setPathValue()", "You try to set more then path value for a defined SINGLE_PATH!")
871*cdf0e10cSrcweir                     if ( !lList.empty() )
872*cdf0e10cSrcweir                         aChangePath.sWritePath = *(lList.begin());
873*cdf0e10cSrcweir                     else
874*cdf0e10cSrcweir                         aChangePath.sWritePath = ::rtl::OUString();
875*cdf0e10cSrcweir                 }
876*cdf0e10cSrcweir                 else
877*cdf0e10cSrcweir                 {
878*cdf0e10cSrcweir 					OUStringList::const_iterator pIt;
879*cdf0e10cSrcweir 					for (  pIt  = lList.begin();
880*cdf0e10cSrcweir 						   pIt != lList.end()  ;
881*cdf0e10cSrcweir 						 ++pIt                 )
882*cdf0e10cSrcweir 					{
883*cdf0e10cSrcweir 	                    aChangePath.lUserPaths.push_back(*pIt);
884*cdf0e10cSrcweir 					}
885*cdf0e10cSrcweir                 }
886*cdf0e10cSrcweir              }
887*cdf0e10cSrcweir              break;
888*cdf0e10cSrcweir 
889*cdf0e10cSrcweir         case IDGROUP_INTERNAL_PATHES :
890*cdf0e10cSrcweir              {
891*cdf0e10cSrcweir                 if (aChangePath.bIsSinglePath)
892*cdf0e10cSrcweir                 {
893*cdf0e10cSrcweir                     ::rtl::OUStringBuffer sMsg(256);
894*cdf0e10cSrcweir                     sMsg.appendAscii("The path '"    );
895*cdf0e10cSrcweir                     sMsg.append     (aChangePath.sPathName);
896*cdf0e10cSrcweir                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal pathes cant be set.");
897*cdf0e10cSrcweir                     throw css::uno::Exception(sMsg.makeStringAndClear(),
898*cdf0e10cSrcweir                                               static_cast< ::cppu::OWeakObject* >(this));
899*cdf0e10cSrcweir                 }
900*cdf0e10cSrcweir 
901*cdf0e10cSrcweir                 OUStringList lList;
902*cdf0e10cSrcweir                 lList << aVal;
903*cdf0e10cSrcweir                 if (! impl_isValidPath(lList))
904*cdf0e10cSrcweir                     throw css::lang::IllegalArgumentException();
905*cdf0e10cSrcweir                 aChangePath.lInternalPaths = lList;
906*cdf0e10cSrcweir              }
907*cdf0e10cSrcweir              break;
908*cdf0e10cSrcweir 
909*cdf0e10cSrcweir         case IDGROUP_USER_PATHES :
910*cdf0e10cSrcweir              {
911*cdf0e10cSrcweir                 if (aChangePath.bIsSinglePath)
912*cdf0e10cSrcweir                 {
913*cdf0e10cSrcweir                     ::rtl::OUStringBuffer sMsg(256);
914*cdf0e10cSrcweir                     sMsg.appendAscii("The path '"    );
915*cdf0e10cSrcweir                     sMsg.append     (aChangePath.sPathName);
916*cdf0e10cSrcweir                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal pathes cant be set.");
917*cdf0e10cSrcweir                     throw css::uno::Exception(sMsg.makeStringAndClear(),
918*cdf0e10cSrcweir                                               static_cast< ::cppu::OWeakObject* >(this));
919*cdf0e10cSrcweir                 }
920*cdf0e10cSrcweir 
921*cdf0e10cSrcweir                 OUStringList lList;
922*cdf0e10cSrcweir                 lList << aVal;
923*cdf0e10cSrcweir                 if (! impl_isValidPath(lList))
924*cdf0e10cSrcweir                     throw css::lang::IllegalArgumentException();
925*cdf0e10cSrcweir                 aChangePath.lUserPaths = lList;
926*cdf0e10cSrcweir              }
927*cdf0e10cSrcweir              break;
928*cdf0e10cSrcweir 
929*cdf0e10cSrcweir         case IDGROUP_WRITE_PATH :
930*cdf0e10cSrcweir              {
931*cdf0e10cSrcweir                 ::rtl::OUString sVal;
932*cdf0e10cSrcweir                 aVal >>= sVal;
933*cdf0e10cSrcweir                 if (! impl_isValidPath(sVal))
934*cdf0e10cSrcweir                     throw css::lang::IllegalArgumentException();
935*cdf0e10cSrcweir                 aChangePath.sWritePath = sVal;
936*cdf0e10cSrcweir              }
937*cdf0e10cSrcweir              break;
938*cdf0e10cSrcweir     }
939*cdf0e10cSrcweir 
940*cdf0e10cSrcweir     // TODO check if path has at least one path value set
941*cdf0e10cSrcweir     // At least it depends from the feature using this path, if an empty path list is allowed.
942*cdf0e10cSrcweir     /*
943*cdf0e10cSrcweir     if (impl_isPathEmpty(aChangePath))
944*cdf0e10cSrcweir     {
945*cdf0e10cSrcweir         ::rtl::OUStringBuffer sMsg(256);
946*cdf0e10cSrcweir         sMsg.appendAscii("The path '"    );
947*cdf0e10cSrcweir         sMsg.append     (aChangePath.sPathName);
948*cdf0e10cSrcweir         sMsg.appendAscii("' is empty now ... Not a real good idea.");
949*cdf0e10cSrcweir         throw css::uno::Exception(sMsg.makeStringAndClear(),
950*cdf0e10cSrcweir                                   static_cast< ::cppu::OWeakObject* >(this));
951*cdf0e10cSrcweir     }
952*cdf0e10cSrcweir     */
953*cdf0e10cSrcweir 
954*cdf0e10cSrcweir     // first we should try to store the changed (copied!) path ...
955*cdf0e10cSrcweir     // In case an error occure on saving time an exception is thrown ...
956*cdf0e10cSrcweir     // If no exception occures we can update our internal cache (means
957*cdf0e10cSrcweir     // we can overwrite pOrgPath !
958*cdf0e10cSrcweir     impl_storePath(aChangePath);
959*cdf0e10cSrcweir     pOrgPath->takeOver(aChangePath);
960*cdf0e10cSrcweir }
961*cdf0e10cSrcweir 
962*cdf0e10cSrcweir //-----------------------------------------------------------------------------
963*cdf0e10cSrcweir sal_Bool PathSettings::impl_isValidPath(const OUStringList& lPath) const
964*cdf0e10cSrcweir {
965*cdf0e10cSrcweir     OUStringList::const_iterator pIt;
966*cdf0e10cSrcweir     for (  pIt  = lPath.begin();
967*cdf0e10cSrcweir            pIt != lPath.end()  ;
968*cdf0e10cSrcweir          ++pIt                 )
969*cdf0e10cSrcweir     {
970*cdf0e10cSrcweir         const ::rtl::OUString& rVal = *pIt;
971*cdf0e10cSrcweir         if (! impl_isValidPath(rVal))
972*cdf0e10cSrcweir             return sal_False;
973*cdf0e10cSrcweir     }
974*cdf0e10cSrcweir 
975*cdf0e10cSrcweir     return sal_True;
976*cdf0e10cSrcweir }
977*cdf0e10cSrcweir 
978*cdf0e10cSrcweir //-----------------------------------------------------------------------------
979*cdf0e10cSrcweir sal_Bool PathSettings::impl_isValidPath(const ::rtl::OUString& sPath) const
980*cdf0e10cSrcweir {
981*cdf0e10cSrcweir     // allow empty path to reset a path.
982*cdf0e10cSrcweir // idea by LLA to support empty pathes
983*cdf0e10cSrcweir //    if (sPath.getLength() == 0)
984*cdf0e10cSrcweir //    {
985*cdf0e10cSrcweir //        return sal_True;
986*cdf0e10cSrcweir //    }
987*cdf0e10cSrcweir 
988*cdf0e10cSrcweir     return (! INetURLObject(sPath).HasError());
989*cdf0e10cSrcweir }
990*cdf0e10cSrcweir 
991*cdf0e10cSrcweir //-----------------------------------------------------------------------------
992*cdf0e10cSrcweir ::rtl::OUString impl_extractBaseFromPropName(const ::rtl::OUString& sPropName)
993*cdf0e10cSrcweir {
994*cdf0e10cSrcweir     sal_Int32 i = -1;
995*cdf0e10cSrcweir 
996*cdf0e10cSrcweir     i = sPropName.indexOf(POSTFIX_INTERNAL_PATHES);
997*cdf0e10cSrcweir     if (i > -1)
998*cdf0e10cSrcweir         return sPropName.copy(0, i);
999*cdf0e10cSrcweir     i = sPropName.indexOf(POSTFIX_USER_PATHES);
1000*cdf0e10cSrcweir     if (i > -1)
1001*cdf0e10cSrcweir         return sPropName.copy(0, i);
1002*cdf0e10cSrcweir     i = sPropName.indexOf(POSTFIX_WRITE_PATH);
1003*cdf0e10cSrcweir     if (i > -1)
1004*cdf0e10cSrcweir         return sPropName.copy(0, i);
1005*cdf0e10cSrcweir 
1006*cdf0e10cSrcweir     return sPropName;
1007*cdf0e10cSrcweir }
1008*cdf0e10cSrcweir 
1009*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1010*cdf0e10cSrcweir PathSettings::PathInfo* PathSettings::impl_getPathAccess(sal_Int32 nHandle)
1011*cdf0e10cSrcweir {
1012*cdf0e10cSrcweir     // SAFE ->
1013*cdf0e10cSrcweir     ReadGuard aReadLock(m_aLock);
1014*cdf0e10cSrcweir 
1015*cdf0e10cSrcweir     if (nHandle > (m_lPropDesc.getLength()-1))
1016*cdf0e10cSrcweir         return 0;
1017*cdf0e10cSrcweir 
1018*cdf0e10cSrcweir     const css::beans::Property&            rProp = m_lPropDesc[nHandle];
1019*cdf0e10cSrcweir           ::rtl::OUString                  sProp = impl_extractBaseFromPropName(rProp.Name);
1020*cdf0e10cSrcweir           PathSettings::PathHash::iterator rPath = m_lPaths.find(sProp);
1021*cdf0e10cSrcweir 
1022*cdf0e10cSrcweir     if (rPath != m_lPaths.end())
1023*cdf0e10cSrcweir        return &(rPath->second);
1024*cdf0e10cSrcweir 
1025*cdf0e10cSrcweir     return 0;
1026*cdf0e10cSrcweir     // <- SAFE
1027*cdf0e10cSrcweir }
1028*cdf0e10cSrcweir 
1029*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1030*cdf0e10cSrcweir const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
1031*cdf0e10cSrcweir {
1032*cdf0e10cSrcweir     // SAFE ->
1033*cdf0e10cSrcweir     ReadGuard aReadLock(m_aLock);
1034*cdf0e10cSrcweir 
1035*cdf0e10cSrcweir     if (nHandle > (m_lPropDesc.getLength()-1))
1036*cdf0e10cSrcweir         return 0;
1037*cdf0e10cSrcweir 
1038*cdf0e10cSrcweir     const css::beans::Property&                  rProp = m_lPropDesc[nHandle];
1039*cdf0e10cSrcweir           ::rtl::OUString                        sProp = impl_extractBaseFromPropName(rProp.Name);
1040*cdf0e10cSrcweir           PathSettings::PathHash::const_iterator rPath = m_lPaths.find(sProp);
1041*cdf0e10cSrcweir 
1042*cdf0e10cSrcweir     if (rPath != m_lPaths.end())
1043*cdf0e10cSrcweir        return &(rPath->second);
1044*cdf0e10cSrcweir 
1045*cdf0e10cSrcweir     return 0;
1046*cdf0e10cSrcweir     // <- SAFE
1047*cdf0e10cSrcweir }
1048*cdf0e10cSrcweir 
1049*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1050*cdf0e10cSrcweir sal_Bool SAL_CALL PathSettings::convertFastPropertyValue(      css::uno::Any& aConvertedValue,
1051*cdf0e10cSrcweir                                                                css::uno::Any& aOldValue      ,
1052*cdf0e10cSrcweir                                                                sal_Int32      nHandle        ,
1053*cdf0e10cSrcweir                                                          const css::uno::Any& aValue         )
1054*cdf0e10cSrcweir     throw(css::lang::IllegalArgumentException)
1055*cdf0e10cSrcweir {
1056*cdf0e10cSrcweir     // throws NoSuchElementException !
1057*cdf0e10cSrcweir     css::uno::Any aCurrentVal = impl_getPathValue(nHandle);
1058*cdf0e10cSrcweir 
1059*cdf0e10cSrcweir     return PropHelper::willPropertyBeChanged(
1060*cdf0e10cSrcweir                 aCurrentVal,
1061*cdf0e10cSrcweir                 aValue,
1062*cdf0e10cSrcweir                 aOldValue,
1063*cdf0e10cSrcweir                 aConvertedValue);
1064*cdf0e10cSrcweir }
1065*cdf0e10cSrcweir 
1066*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1067*cdf0e10cSrcweir void SAL_CALL PathSettings::setFastPropertyValue_NoBroadcast(      sal_Int32      nHandle,
1068*cdf0e10cSrcweir                                                              const css::uno::Any& aValue )
1069*cdf0e10cSrcweir     throw(css::uno::Exception)
1070*cdf0e10cSrcweir {
1071*cdf0e10cSrcweir     // throws NoSuchElement- and IllegalArgumentException !
1072*cdf0e10cSrcweir     impl_setPathValue(nHandle, aValue);
1073*cdf0e10cSrcweir }
1074*cdf0e10cSrcweir 
1075*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1076*cdf0e10cSrcweir void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
1077*cdf0e10cSrcweir                                                  sal_Int32      nHandle) const
1078*cdf0e10cSrcweir {
1079*cdf0e10cSrcweir     aValue = impl_getPathValue(nHandle);
1080*cdf0e10cSrcweir }
1081*cdf0e10cSrcweir 
1082*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1083*cdf0e10cSrcweir ::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
1084*cdf0e10cSrcweir {
1085*cdf0e10cSrcweir     return *m_pPropHelp;
1086*cdf0e10cSrcweir }
1087*cdf0e10cSrcweir 
1088*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1089*cdf0e10cSrcweir css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
1090*cdf0e10cSrcweir     throw(css::uno::RuntimeException)
1091*cdf0e10cSrcweir {
1092*cdf0e10cSrcweir     return css::uno::Reference< css::beans::XPropertySetInfo >(createPropertySetInfo(getInfoHelper()));
1093*cdf0e10cSrcweir }
1094*cdf0e10cSrcweir 
1095*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1096*cdf0e10cSrcweir css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
1097*cdf0e10cSrcweir {
1098*cdf0e10cSrcweir     // SAFE ->
1099*cdf0e10cSrcweir     ReadGuard aReadLock(m_aLock);
1100*cdf0e10cSrcweir     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR  = m_xSMGR;
1101*cdf0e10cSrcweir     css::uno::Reference< css::util::XStringSubstitution >  xSubst = m_xSubstitution;
1102*cdf0e10cSrcweir     aReadLock.unlock();
1103*cdf0e10cSrcweir     // <- SAFE
1104*cdf0e10cSrcweir 
1105*cdf0e10cSrcweir     if (! xSubst.is())
1106*cdf0e10cSrcweir     {
1107*cdf0e10cSrcweir         // create the needed substitution service.
1108*cdf0e10cSrcweir         // We must replace all used variables inside readed path values.
1109*cdf0e10cSrcweir         // In case we can't do so ... the whole office can't work realy.
1110*cdf0e10cSrcweir         // That's why it seams to be OK to throw a RuntimeException then.
1111*cdf0e10cSrcweir         xSubst = css::uno::Reference< css::util::XStringSubstitution >(
1112*cdf0e10cSrcweir                                 xSMGR->createInstance(SERVICENAME_SUBSTITUTEPATHVARIABLES),
1113*cdf0e10cSrcweir                                 css::uno::UNO_QUERY_THROW);
1114*cdf0e10cSrcweir 
1115*cdf0e10cSrcweir         // SAFE ->
1116*cdf0e10cSrcweir         WriteGuard aWriteLock(m_aLock);
1117*cdf0e10cSrcweir         m_xSubstitution = xSubst;
1118*cdf0e10cSrcweir         aWriteLock.unlock();
1119*cdf0e10cSrcweir     }
1120*cdf0e10cSrcweir 
1121*cdf0e10cSrcweir     return xSubst;
1122*cdf0e10cSrcweir }
1123*cdf0e10cSrcweir 
1124*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1125*cdf0e10cSrcweir css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
1126*cdf0e10cSrcweir {
1127*cdf0e10cSrcweir     const static ::rtl::OUString CFG_NODE_OLD = ::rtl::OUString::createFromAscii("org.openoffice.Office.Common/Path/Current");
1128*cdf0e10cSrcweir 
1129*cdf0e10cSrcweir     // SAFE ->
1130*cdf0e10cSrcweir     ReadGuard aReadLock(m_aLock);
1131*cdf0e10cSrcweir     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1132*cdf0e10cSrcweir     css::uno::Reference< css::container::XNameAccess >     xCfg  = m_xCfgOld;
1133*cdf0e10cSrcweir     aReadLock.unlock();
1134*cdf0e10cSrcweir     // <- SAFE
1135*cdf0e10cSrcweir 
1136*cdf0e10cSrcweir     if (! xCfg.is())
1137*cdf0e10cSrcweir     {
1138*cdf0e10cSrcweir         xCfg = css::uno::Reference< css::container::XNameAccess >(
1139*cdf0e10cSrcweir                    ::comphelper::ConfigurationHelper::openConfig(
1140*cdf0e10cSrcweir                         xSMGR,
1141*cdf0e10cSrcweir                         CFG_NODE_OLD,
1142*cdf0e10cSrcweir                         ::comphelper::ConfigurationHelper::E_STANDARD), // not readonly! Somtimes we need write access there !!!
1143*cdf0e10cSrcweir                    css::uno::UNO_QUERY_THROW);
1144*cdf0e10cSrcweir 
1145*cdf0e10cSrcweir         // SAFE ->
1146*cdf0e10cSrcweir         WriteGuard aWriteLock(m_aLock);
1147*cdf0e10cSrcweir         m_xCfgOld = xCfg;
1148*cdf0e10cSrcweir         aWriteLock.unlock();
1149*cdf0e10cSrcweir     }
1150*cdf0e10cSrcweir 
1151*cdf0e10cSrcweir     return xCfg;
1152*cdf0e10cSrcweir }
1153*cdf0e10cSrcweir 
1154*cdf0e10cSrcweir //-----------------------------------------------------------------------------
1155*cdf0e10cSrcweir css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
1156*cdf0e10cSrcweir {
1157*cdf0e10cSrcweir     const static ::rtl::OUString CFG_NODE_NEW = ::rtl::OUString::createFromAscii("org.openoffice.Office.Paths/Paths");
1158*cdf0e10cSrcweir 
1159*cdf0e10cSrcweir     // SAFE ->
1160*cdf0e10cSrcweir     ReadGuard aReadLock(m_aLock);
1161*cdf0e10cSrcweir     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
1162*cdf0e10cSrcweir     css::uno::Reference< css::container::XNameAccess >     xCfg  = m_xCfgNew;
1163*cdf0e10cSrcweir     aReadLock.unlock();
1164*cdf0e10cSrcweir     // <- SAFE
1165*cdf0e10cSrcweir 
1166*cdf0e10cSrcweir     if (! xCfg.is())
1167*cdf0e10cSrcweir     {
1168*cdf0e10cSrcweir         xCfg = css::uno::Reference< css::container::XNameAccess >(
1169*cdf0e10cSrcweir                    ::comphelper::ConfigurationHelper::openConfig(
1170*cdf0e10cSrcweir                         xSMGR,
1171*cdf0e10cSrcweir                         CFG_NODE_NEW,
1172*cdf0e10cSrcweir                         ::comphelper::ConfigurationHelper::E_STANDARD),
1173*cdf0e10cSrcweir                    css::uno::UNO_QUERY_THROW);
1174*cdf0e10cSrcweir 
1175*cdf0e10cSrcweir         // SAFE ->
1176*cdf0e10cSrcweir         WriteGuard aWriteLock(m_aLock);
1177*cdf0e10cSrcweir         m_xCfgNew = xCfg;
1178*cdf0e10cSrcweir         aWriteLock.unlock();
1179*cdf0e10cSrcweir 
1180*cdf0e10cSrcweir         css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
1181*cdf0e10cSrcweir         xBroadcaster->addChangesListener(static_cast< css::util::XChangesListener* >(this));
1182*cdf0e10cSrcweir     }
1183*cdf0e10cSrcweir 
1184*cdf0e10cSrcweir     return xCfg;
1185*cdf0e10cSrcweir }
1186*cdf0e10cSrcweir 
1187*cdf0e10cSrcweir } // namespace framework
1188