1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <sal/config.h>
22 #include <string_view>
24 #include <unordered_map>
26 #include <properties.h>
27 #include <helper/mischelper.hxx>
29 #include <com/sun/star/beans/Property.hpp>
30 #include <com/sun/star/beans/XProperty.hpp>
31 #include <com/sun/star/beans/PropertyAttribute.hpp>
32 #include <com/sun/star/beans/XPropertySet.hpp>
33 #include <com/sun/star/util/XChangesNotifier.hpp>
34 #include <com/sun/star/util/PathSubstitution.hpp>
35 #include <com/sun/star/container/XNameAccess.hpp>
36 #include <com/sun/star/lang/XServiceInfo.hpp>
37 #include <com/sun/star/util/XStringSubstitution.hpp>
38 #include <com/sun/star/util/XChangesListener.hpp>
39 #include <com/sun/star/util/XPathSettings.hpp>
41 #include <tools/urlobj.hxx>
42 #include <rtl/ustrbuf.hxx>
43 #include <rtl/ref.hxx>
44 #include <sal/log.hxx>
46 #include <cppuhelper/basemutex.hxx>
47 #include <cppuhelper/propshlp.hxx>
48 #include <cppuhelper/compbase.hxx>
49 #include <cppuhelper/supportsservice.hxx>
50 #include <comphelper/sequence.hxx>
51 #include <comphelper/configurationhelper.hxx>
52 #include <unotools/configpaths.hxx>
53 #include <o3tl/string_view.hxx>
55 using namespace framework
;
57 constexpr OUStringLiteral CFGPROP_USERPATHS
= u
"UserPaths";
58 constexpr OUStringLiteral CFGPROP_WRITEPATH
= u
"WritePath";
61 0 : old style "Template" string using ";" as separator
62 1 : internal paths "Template_internal" string list
63 2 : user paths "Template_user" string list
64 3 : write path "Template_write" string
67 constexpr OUStringLiteral POSTFIX_INTERNAL_PATHS
= u
"_internal";
68 constexpr OUStringLiteral POSTFIX_USER_PATHS
= u
"_user";
69 constexpr OUStringLiteral POSTFIX_WRITE_PATH
= u
"_writable";
73 const sal_Int32 IDGROUP_OLDSTYLE
= 0;
74 const sal_Int32 IDGROUP_INTERNAL_PATHS
= 1;
75 const sal_Int32 IDGROUP_USER_PATHS
= 2;
76 const sal_Int32 IDGROUP_WRITE_PATH
= 3;
78 const sal_Int32 IDGROUP_COUNT
= 4;
80 sal_Int32
impl_getPropGroup(sal_Int32 nID
)
82 return (nID
% IDGROUP_COUNT
);
85 /* enable it if you wish to migrate old user settings (using the old cfg schema) on demand...
86 disable it in case only the new schema must be used.
89 typedef ::cppu::WeakComponentImplHelper
<
90 css::lang::XServiceInfo
,
91 css::util::XChangesListener
, // => XEventListener
92 css::util::XPathSettings
> // => XPropertySet
95 class PathSettings
: private cppu::BaseMutex
96 , public PathSettings_BASE
97 , public ::cppu::OPropertySetHelper
104 : bIsSinglePath (false)
105 , bIsReadonly (false)
108 /// an internal name describing this path
111 /// contains all paths, which are used internally - but are not visible for the user.
112 std::vector
<OUString
> lInternalPaths
;
114 /// contains all paths configured by the user
115 std::vector
<OUString
> lUserPaths
;
117 /// this special path is used to generate feature depending content there
120 /// indicates real single paths, which uses WritePath property only
123 /// simple handling of finalized/mandatory states ... => we know one state READONLY only .-)
127 typedef std::unordered_map
<OUString
, PathSettings::PathInfo
> PathHash
;
139 /** reference to factory, which has create this instance. */
140 css::uno::Reference
< css::uno::XComponentContext
> m_xContext
;
142 /** list of all path variables and her corresponding values. */
143 PathSettings::PathHash m_lPaths
;
145 /** describes all properties available on our interface.
146 Will be generated on demand based on our path list m_lPaths. */
147 css::uno::Sequence
< css::beans::Property
> m_lPropDesc
;
149 /** helper needed to (re-)substitute all internal save path values. */
150 css::uno::Reference
< css::util::XStringSubstitution
> m_xSubstitution
;
152 /** provides access to the old configuration schema (which will be migrated on demand). */
153 css::uno::Reference
< css::container::XNameAccess
> m_xCfgOld
;
155 /** provides access to the new configuration schema. */
156 css::uno::Reference
< css::container::XNameAccess
> m_xCfgNew
;
158 /** helper to listen for configuration changes without ownership cycle problems */
159 css::uno::Reference
< css::util::XChangesListener
> m_xCfgNewListener
;
161 std::unique_ptr
<::cppu::OPropertyArrayHelper
> m_pPropHelp
;
165 /** initialize a new instance of this class.
166 Attention: It's necessary for right function of this class, that the order of base
167 classes is the right one. Because we transfer information from one base to another
168 during this ctor runs! */
169 explicit PathSettings(css::uno::Reference
< css::uno::XComponentContext
> xContext
);
171 /** free all used resources ... if it was not already done. */
172 virtual ~PathSettings() override
;
174 virtual OUString SAL_CALL
getImplementationName() override
176 return "com.sun.star.comp.framework.PathSettings";
179 virtual sal_Bool SAL_CALL
supportsService(OUString
const & ServiceName
) override
181 return cppu::supportsService(this, ServiceName
);
184 virtual css::uno::Sequence
<OUString
> SAL_CALL
getSupportedServiceNames() override
186 return {"com.sun.star.util.PathSettings"};
190 virtual css::uno::Any SAL_CALL
queryInterface( const css::uno::Type
& type
) override
;
191 virtual void SAL_CALL
acquire() noexcept override
192 { OWeakObject::acquire(); }
193 virtual void SAL_CALL
release() noexcept override
194 { OWeakObject::release(); }
197 virtual css::uno::Sequence
< css::uno::Type
> SAL_CALL
getTypes( ) override
;
199 // css::util::XChangesListener
200 virtual void SAL_CALL
changesOccurred(const css::util::ChangesEvent
& aEvent
) override
;
202 // css::lang::XEventListener
203 virtual void SAL_CALL
disposing(const css::lang::EventObject
& aSource
) override
;
206 * XPathSettings attribute methods
208 virtual OUString SAL_CALL
getAddin() override
209 { return getStringProperty("Addin"); }
210 virtual void SAL_CALL
setAddin(const OUString
& p1
) override
211 { setStringProperty("Addin", p1
); }
212 virtual OUString SAL_CALL
getAutoCorrect() override
213 { return getStringProperty("AutoCorrect"); }
214 virtual void SAL_CALL
setAutoCorrect(const OUString
& p1
) override
215 { setStringProperty("AutoCorrect", p1
); }
216 virtual OUString SAL_CALL
getAutoText() override
217 { return getStringProperty("AutoText"); }
218 virtual void SAL_CALL
setAutoText(const OUString
& p1
) override
219 { setStringProperty("AutoText", p1
); }
220 virtual OUString SAL_CALL
getBackup() override
221 { return getStringProperty("Backup"); }
222 virtual void SAL_CALL
setBackup(const OUString
& p1
) override
223 { setStringProperty("Backup", p1
); }
224 virtual OUString SAL_CALL
getBasic() override
225 { return getStringProperty("Basic"); }
226 virtual void SAL_CALL
setBasic(const OUString
& p1
) override
227 { setStringProperty("Basic", p1
); }
228 virtual OUString SAL_CALL
getBitmap() override
229 { return getStringProperty("Bitmap"); }
230 virtual void SAL_CALL
setBitmap(const OUString
& p1
) override
231 { setStringProperty("Bitmap", p1
); }
232 virtual OUString SAL_CALL
getConfig() override
233 { return getStringProperty("Config"); }
234 virtual void SAL_CALL
setConfig(const OUString
& p1
) override
235 { setStringProperty("Config", p1
); }
236 virtual OUString SAL_CALL
getDictionary() override
237 { return getStringProperty("Dictionary"); }
238 virtual void SAL_CALL
setDictionary(const OUString
& p1
) override
239 { setStringProperty("Dictionary", p1
); }
240 virtual OUString SAL_CALL
getFavorite() override
241 { return getStringProperty("Favorite"); }
242 virtual void SAL_CALL
setFavorite(const OUString
& p1
) override
243 { setStringProperty("Favorite", p1
); }
244 virtual OUString SAL_CALL
getFilter() override
245 { return getStringProperty("Filter"); }
246 virtual void SAL_CALL
setFilter(const OUString
& p1
) override
247 { setStringProperty("Filter", p1
); }
248 virtual OUString SAL_CALL
getGallery() override
249 { return getStringProperty("Gallery"); }
250 virtual void SAL_CALL
setGallery(const OUString
& p1
) override
251 { setStringProperty("Gallery", p1
); }
252 virtual OUString SAL_CALL
getGraphic() override
253 { return getStringProperty("Graphic"); }
254 virtual void SAL_CALL
setGraphic(const OUString
& p1
) override
255 { setStringProperty("Graphic", p1
); }
256 virtual OUString SAL_CALL
getHelp() override
257 { return getStringProperty("Help"); }
258 virtual void SAL_CALL
setHelp(const OUString
& p1
) override
259 { setStringProperty("Help", p1
); }
260 virtual OUString SAL_CALL
getLinguistic() override
261 { return getStringProperty("Linguistic"); }
262 virtual void SAL_CALL
setLinguistic(const OUString
& p1
) override
263 { setStringProperty("Linguistic", p1
); }
264 virtual OUString SAL_CALL
getModule() override
265 { return getStringProperty("Module"); }
266 virtual void SAL_CALL
setModule(const OUString
& p1
) override
267 { setStringProperty("Module", p1
); }
268 virtual OUString SAL_CALL
getPalette() override
269 { return getStringProperty("Palette"); }
270 virtual void SAL_CALL
setPalette(const OUString
& p1
) override
271 { setStringProperty("Palette", p1
); }
272 virtual OUString SAL_CALL
getPlugin() override
273 { return getStringProperty("Plugin"); }
274 virtual void SAL_CALL
setPlugin(const OUString
& p1
) override
275 { setStringProperty("Plugin", p1
); }
276 virtual OUString SAL_CALL
getStorage() override
277 { return getStringProperty("Storage"); }
278 virtual void SAL_CALL
setStorage(const OUString
& p1
) override
279 { setStringProperty("Storage", p1
); }
280 virtual OUString SAL_CALL
getTemp() override
281 { return getStringProperty("Temp"); }
282 virtual void SAL_CALL
setTemp(const OUString
& p1
) override
283 { setStringProperty("Temp", p1
); }
284 virtual OUString SAL_CALL
getTemplate() override
285 { return getStringProperty("Template"); }
286 virtual void SAL_CALL
setTemplate(const OUString
& p1
) override
287 { setStringProperty("Template", p1
); }
288 virtual OUString SAL_CALL
getUIConfig() override
289 { return getStringProperty("UIConfig"); }
290 virtual void SAL_CALL
setUIConfig(const OUString
& p1
) override
291 { setStringProperty("UIConfig", p1
); }
292 virtual OUString SAL_CALL
getUserConfig() override
293 { return getStringProperty("UserConfig"); }
294 virtual void SAL_CALL
setUserConfig(const OUString
& p1
) override
295 { setStringProperty("UserConfig", p1
); }
296 virtual OUString SAL_CALL
getUserDictionary() override
297 { return getStringProperty("UserDictionary"); }
298 virtual void SAL_CALL
setUserDictionary(const OUString
& p1
) override
299 { setStringProperty("UserDictionary", p1
); }
300 virtual OUString SAL_CALL
getWork() override
301 { return getStringProperty("Work"); }
302 virtual void SAL_CALL
setWork(const OUString
& p1
) override
303 { setStringProperty("Work", p1
); }
304 virtual OUString SAL_CALL
getBasePathShareLayer() override
305 { return getStringProperty("UIConfig"); }
306 virtual void SAL_CALL
setBasePathShareLayer(const OUString
& p1
) override
307 { setStringProperty("UIConfig", p1
); }
308 virtual OUString SAL_CALL
getBasePathUserLayer() override
309 { return getStringProperty("UserConfig"); }
310 virtual void SAL_CALL
setBasePathUserLayer(const OUString
& p1
) override
311 { setStringProperty("UserConfig", p1
); }
314 * overrides to resolve inheritance ambiguity
316 virtual void SAL_CALL
setPropertyValue(const OUString
& p1
, const css::uno::Any
& p2
) override
317 { ::cppu::OPropertySetHelper::setPropertyValue(p1
, p2
); }
318 virtual css::uno::Any SAL_CALL
getPropertyValue(const OUString
& p1
) override
319 { return ::cppu::OPropertySetHelper::getPropertyValue(p1
); }
320 virtual void SAL_CALL
addPropertyChangeListener(const OUString
& p1
, const css::uno::Reference
<css::beans::XPropertyChangeListener
>& p2
) override
321 { ::cppu::OPropertySetHelper::addPropertyChangeListener(p1
, p2
); }
322 virtual void SAL_CALL
removePropertyChangeListener(const OUString
& p1
, const css::uno::Reference
<css::beans::XPropertyChangeListener
>& p2
) override
323 { ::cppu::OPropertySetHelper::removePropertyChangeListener(p1
, p2
); }
324 virtual void SAL_CALL
addVetoableChangeListener(const OUString
& p1
, const css::uno::Reference
<css::beans::XVetoableChangeListener
>& p2
) override
325 { ::cppu::OPropertySetHelper::addVetoableChangeListener(p1
, p2
); }
326 virtual void SAL_CALL
removeVetoableChangeListener(const OUString
& p1
, const css::uno::Reference
<css::beans::XVetoableChangeListener
>& p2
) override
327 { ::cppu::OPropertySetHelper::removeVetoableChangeListener(p1
, p2
); }
328 /** read all configured paths and create all needed internal structures. */
332 virtual void SAL_CALL
disposing() final override
;
334 /// @throws css::uno::RuntimeException
335 OUString
getStringProperty(const OUString
& p1
);
337 /// @throws css::uno::RuntimeException
338 void setStringProperty(const OUString
& p1
, const OUString
& p2
);
340 /** read a path info using the old cfg schema.
341 This is needed for "migration on demand" reasons only.
342 Can be removed for next major release .-) */
343 std::vector
<OUString
> impl_readOldFormat(const OUString
& sPath
);
345 /** read a path info using the new cfg schema. */
346 PathSettings::PathInfo
impl_readNewFormat(const OUString
& sPath
);
348 /** filter "real user defined paths" from the old configuration schema
349 and set it as UserPaths on the new schema.
350 Can be removed with new major release ... */
352 void impl_mergeOldUserPaths( PathSettings::PathInfo
& rPath
,
353 const std::vector
<OUString
>& lOld
);
355 /** reload one path directly from the new configuration schema (because
356 it was updated by any external code) */
357 PathSettings::EChangeOp
impl_updatePath(const OUString
& sPath
,
358 bool bNotifyListener
);
360 /** replace all might existing placeholder variables inside the given path ...
361 or check if the given path value uses paths, which can be replaced with predefined
362 placeholder variables ...
364 void impl_subst(std::vector
<OUString
>& lVals
,
365 const css::uno::Reference
< css::util::XStringSubstitution
>& xSubst
,
368 void impl_subst(PathSettings::PathInfo
& aPath
,
371 /** converts our new string list schema to the old ";" separated schema ... */
372 OUString
impl_convertPath2OldStyle(const PathSettings::PathInfo
& rPath
) const;
373 std::vector
<OUString
> impl_convertOldStyle2Path(std::u16string_view sOldStylePath
) const;
375 /** remove still known paths from the given lList argument.
376 So real user defined paths can be extracted from the list of
379 void impl_purgeKnownPaths(PathSettings::PathInfo
& rPath
,
380 std::vector
<OUString
>& lList
);
382 /** rebuild the member m_lPropDesc using the path list m_lPaths. */
383 void impl_rebuildPropertyDescriptor();
385 /** provides direct access to the list of path values
386 using its internal property id.
388 css::uno::Any
impl_getPathValue( sal_Int32 nID
) const;
389 void impl_setPathValue( sal_Int32 nID
,
390 const css::uno::Any
& aVal
);
392 /** check the given handle and return the corresponding PathInfo reference.
393 These reference can be used then directly to manipulate these path. */
394 PathSettings::PathInfo
* impl_getPathAccess (sal_Int32 nHandle
);
395 const PathSettings::PathInfo
* impl_getPathAccessConst(sal_Int32 nHandle
) const;
397 /** it checks, if the given path value seems to be a valid URL or system path. */
398 bool impl_isValidPath(std::u16string_view sPath
) const;
399 bool impl_isValidPath(const std::vector
<OUString
>& lPath
) const;
401 void impl_storePath(const PathSettings::PathInfo
& aPath
);
403 css::uno::Sequence
< sal_Int32
> impl_mapPathName2IDList(std::u16string_view sPath
);
405 void impl_notifyPropListener( std::u16string_view sPath
,
406 const PathSettings::PathInfo
* pPathOld
,
407 const PathSettings::PathInfo
* pPathNew
);
409 // OPropertySetHelper
410 virtual sal_Bool SAL_CALL
convertFastPropertyValue( css::uno::Any
& aConvertedValue
,
411 css::uno::Any
& aOldValue
,
413 const css::uno::Any
& aValue
) override
;
414 virtual void SAL_CALL
setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
,
415 const css::uno::Any
& aValue
) override
;
416 virtual void SAL_CALL
getFastPropertyValue( css::uno::Any
& aValue
,
417 sal_Int32 nHandle
) const override
;
419 // warning: 'virtual css::uno::Any cppu::OPropertySetHelper::getFastPropertyValue(sal_Int32)' was hidden [-Woverloaded-virtual]
420 // warning: by ‘virtual void {anonymous}::PathSettings::getFastPropertyValue(css::uno::Any&, sal_Int32) const’ [-Woverloaded-virtual]
421 using cppu::OPropertySetHelper::getFastPropertyValue
;
422 virtual ::cppu::IPropertyArrayHelper
& SAL_CALL
getInfoHelper() override
;
423 virtual css::uno::Reference
< css::beans::XPropertySetInfo
> SAL_CALL
getPropertySetInfo() override
;
425 /** factory methods to guarantee right (but on demand) initialized members ... */
426 css::uno::Reference
< css::util::XStringSubstitution
> fa_getSubstitution();
427 css::uno::Reference
< css::container::XNameAccess
> fa_getCfgOld();
428 css::uno::Reference
< css::container::XNameAccess
> fa_getCfgNew();
431 PathSettings::PathSettings( css::uno::Reference
< css::uno::XComponentContext
> xContext
)
432 : PathSettings_BASE(m_aMutex
)
433 , ::cppu::OPropertySetHelper(cppu::WeakComponentImplHelperBase::rBHelper
)
434 , m_xContext (std::move(xContext
))
438 PathSettings::~PathSettings()
443 void SAL_CALL
PathSettings::disposing()
445 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
447 css::uno::Reference
< css::util::XChangesNotifier
>
448 xBroadcaster(m_xCfgNew
, css::uno::UNO_QUERY
);
449 if (xBroadcaster
.is())
450 xBroadcaster
->removeChangesListener(m_xCfgNewListener
);
452 m_xSubstitution
.clear();
455 m_xCfgNewListener
.clear();
460 css::uno::Any SAL_CALL
PathSettings::queryInterface( const css::uno::Type
& _rType
)
462 css::uno::Any aRet
= PathSettings_BASE::queryInterface( _rType
);
463 if ( !aRet
.hasValue() )
464 aRet
= ::cppu::OPropertySetHelper::queryInterface( _rType
);
468 css::uno::Sequence
< css::uno::Type
> SAL_CALL
PathSettings::getTypes( )
470 return comphelper::concatSequences(
471 PathSettings_BASE::getTypes(),
472 ::cppu::OPropertySetHelper::getTypes()
476 void SAL_CALL
PathSettings::changesOccurred(const css::util::ChangesEvent
& aEvent
)
478 sal_Int32 c
= aEvent
.Changes
.getLength();
480 bool bUpdateDescriptor
= false;
484 const css::util::ElementChange
& aChange
= aEvent
.Changes
[i
];
487 aChange
.Accessor
>>= sChanged
;
489 OUString sPath
= ::utl::extractFirstFromConfigurationPath(sChanged
);
490 if (!sPath
.isEmpty())
492 PathSettings::EChangeOp eOp
= impl_updatePath(sPath
, true);
494 (eOp
== PathSettings::E_ADDED
) ||
495 (eOp
== PathSettings::E_REMOVED
)
497 bUpdateDescriptor
= true;
501 if (bUpdateDescriptor
)
502 impl_rebuildPropertyDescriptor();
505 void SAL_CALL
PathSettings::disposing(const css::lang::EventObject
& aSource
)
507 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
509 if (aSource
.Source
== m_xCfgNew
)
513 OUString
PathSettings::getStringProperty(const OUString
& p1
)
515 css::uno::Any a
= ::cppu::OPropertySetHelper::getPropertyValue(p1
);
521 void PathSettings::setStringProperty(const OUString
& p1
, const OUString
& p2
)
523 ::cppu::OPropertySetHelper::setPropertyValue(p1
, css::uno::Any(p2
));
526 void PathSettings::impl_readAll()
530 // TODO think about me
531 css::uno::Reference
< css::container::XNameAccess
> xCfg
= fa_getCfgNew();
532 css::uno::Sequence
< OUString
> lPaths
= xCfg
->getElementNames();
534 sal_Int32 c
= lPaths
.getLength();
535 for (sal_Int32 i
= 0; i
< c
; ++i
)
537 const OUString
& sPath
= lPaths
[i
];
538 impl_updatePath(sPath
, false);
541 catch(const css::uno::RuntimeException
& )
545 impl_rebuildPropertyDescriptor();
548 // NO substitution here ! It's done outside ...
549 std::vector
<OUString
> PathSettings::impl_readOldFormat(const OUString
& sPath
)
551 css::uno::Reference
< css::container::XNameAccess
> xCfg( fa_getCfgOld() );
552 std::vector
<OUString
> aPathVal
;
554 if( xCfg
->hasByName(sPath
) )
556 css::uno::Any
aVal( xCfg
->getByName(sPath
) );
559 css::uno::Sequence
< OUString
> lStringListVal
;
561 if (aVal
>>= sStringVal
)
563 aPathVal
.push_back(sStringVal
);
565 else if (aVal
>>= lStringListVal
)
567 aPathVal
= comphelper::sequenceToContainer
<std::vector
<OUString
>>(lStringListVal
);
574 // NO substitution here ! It's done outside ...
575 PathSettings::PathInfo
PathSettings::impl_readNewFormat(const OUString
& sPath
)
577 css::uno::Reference
< css::container::XNameAccess
> xCfg
= fa_getCfgNew();
579 // get access to the "queried" path
580 css::uno::Reference
< css::container::XNameAccess
> xPath
;
581 xCfg
->getByName(sPath
) >>= xPath
;
583 PathSettings::PathInfo aPathVal
;
585 // read internal path list
586 css::uno::Reference
< css::container::XNameAccess
> xIPath
;
587 xPath
->getByName("InternalPaths") >>= xIPath
;
588 aPathVal
.lInternalPaths
= comphelper::sequenceToContainer
<std::vector
<OUString
>>(xIPath
->getElementNames());
590 // read user defined path list
591 css::uno::Sequence
<OUString
> vTmpUserPathsSeq
;
592 xPath
->getByName(CFGPROP_USERPATHS
) >>= vTmpUserPathsSeq
;
593 aPathVal
.lUserPaths
= comphelper::sequenceToContainer
<std::vector
<OUString
>>(vTmpUserPathsSeq
);
595 // read the writeable path
596 xPath
->getByName(CFGPROP_WRITEPATH
) >>= aPathVal
.sWritePath
;
598 // avoid duplicates, by removing the writeable path from
599 // the user defined path list if it happens to be there too
600 std::vector
<OUString
>::iterator aI
= std::find(aPathVal
.lUserPaths
.begin(), aPathVal
.lUserPaths
.end(), aPathVal
.sWritePath
);
601 if (aI
!= aPathVal
.lUserPaths
.end())
602 aPathVal
.lUserPaths
.erase(aI
);
605 xPath
->getByName("IsSinglePath") >>= aPathVal
.bIsSinglePath
;
607 // analyze finalized/mandatory states
608 aPathVal
.bIsReadonly
= false;
609 css::uno::Reference
< css::beans::XProperty
> xInfo(xPath
, css::uno::UNO_QUERY
);
612 css::beans::Property aInfo
= xInfo
->getAsProperty();
613 bool bFinalized
= ((aInfo
.Attributes
& css::beans::PropertyAttribute::READONLY
) == css::beans::PropertyAttribute::READONLY
);
615 // Note: 'till we support finalized/mandatory on our API more in detail we handle
616 // all states simple as READONLY! But because all really needed paths are "mandatory" by default
617 // we have to handle "finalized" as the real "readonly" indicator.
618 aPathVal
.bIsReadonly
= bFinalized
;
624 void PathSettings::impl_storePath(const PathSettings::PathInfo
& aPath
)
626 css::uno::Reference
< css::container::XNameAccess
> xCfgNew
= fa_getCfgNew();
627 css::uno::Reference
< css::container::XNameAccess
> xCfgOld
= fa_getCfgOld();
629 // try to replace path-parts with well known and supported variables.
630 // So an office can be moved easily to another location without losing
631 // its related paths.
632 PathInfo
aResubstPath(aPath
);
633 impl_subst(aResubstPath
, true);
635 // update new configuration
636 if (! aResubstPath
.bIsSinglePath
)
638 ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew
,
639 aResubstPath
.sPathName
,
641 css::uno::Any(comphelper::containerToSequence(aResubstPath
.lUserPaths
)));
644 ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew
,
645 aResubstPath
.sPathName
,
647 css::uno::Any(aResubstPath
.sWritePath
));
649 ::comphelper::ConfigurationHelper::flush(xCfgNew
);
651 // remove the whole path from the old configuration!
652 // Otherwise we can't make sure that the diff between new and old configuration
653 // on loading time really represents a user setting!!!
655 // Check if the given path exists inside the old configuration.
656 // Because our new configuration knows more than the list of old paths ... !
657 if (xCfgOld
->hasByName(aResubstPath
.sPathName
))
659 css::uno::Reference
< css::beans::XPropertySet
> xProps(xCfgOld
, css::uno::UNO_QUERY_THROW
);
660 xProps
->setPropertyValue(aResubstPath
.sPathName
, css::uno::Any());
661 ::comphelper::ConfigurationHelper::flush(xCfgOld
);
665 void PathSettings::impl_mergeOldUserPaths( PathSettings::PathInfo
& rPath
,
666 const std::vector
<OUString
>& lOld
)
668 for (auto const& old
: lOld
)
670 if (rPath
.bIsSinglePath
)
672 SAL_WARN_IF(lOld
.size()>1, "fwk", "PathSettings::impl_mergeOldUserPaths(): Single path has more than one path value inside old configuration (Common.xcu)!");
673 if ( rPath
.sWritePath
!= old
)
674 rPath
.sWritePath
= old
;
679 ( std::find(rPath
.lInternalPaths
.begin(), rPath
.lInternalPaths
.end(), old
) == rPath
.lInternalPaths
.end()) &&
680 ( std::find(rPath
.lUserPaths
.begin(), rPath
.lUserPaths
.end(), old
) == rPath
.lUserPaths
.end() ) &&
681 ( rPath
.sWritePath
!= old
)
683 rPath
.lUserPaths
.push_back(old
);
688 PathSettings::EChangeOp
PathSettings::impl_updatePath(const OUString
& sPath
,
689 bool bNotifyListener
)
692 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
694 PathSettings::PathInfo
* pPathOld
= nullptr;
695 PathSettings::PathInfo
* pPathNew
= nullptr;
696 PathSettings::EChangeOp eOp
= PathSettings::E_UNDEFINED
;
697 PathSettings::PathInfo aPath
;
701 aPath
= impl_readNewFormat(sPath
);
702 aPath
.sPathName
= sPath
;
703 // replace all might existing variables with real values
704 // Do it before these old paths will be compared against the
705 // new path configuration. Otherwise some strings uses different variables ... but substitution
706 // will produce strings with same content (because some variables are redundant!)
707 impl_subst(aPath
, false);
709 catch(const css::uno::RuntimeException
&)
711 catch(const css::container::NoSuchElementException
&)
712 { eOp
= PathSettings::E_REMOVED
; }
713 catch(const css::uno::Exception
&)
718 // migration of old user defined values on demand
719 // can be disabled for a new major
720 std::vector
<OUString
> lOldVals
= impl_readOldFormat(sPath
);
721 // replace all might existing variables with real values
722 // Do it before these old paths will be compared against the
723 // new path configuration. Otherwise some strings uses different variables ... but substitution
724 // will produce strings with same content (because some variables are redundant!)
725 impl_subst(lOldVals
, fa_getSubstitution(), false);
726 impl_mergeOldUserPaths(aPath
, lOldVals
);
728 catch(const css::uno::RuntimeException
&)
730 // Normal(!) exceptions can be ignored!
731 // E.g. in case an addon installs a new path, which was not well known for an OOo 1.x installation
732 // we can't find a value for it inside the "old" configuration. So a NoSuchElementException
733 // will be normal .-)
734 catch(const css::uno::Exception
&)
737 PathSettings::PathHash::iterator pPath
= m_lPaths
.find(sPath
);
738 if (eOp
== PathSettings::E_UNDEFINED
)
740 if (pPath
!= m_lPaths
.end())
741 eOp
= PathSettings::E_CHANGED
;
743 eOp
= PathSettings::E_ADDED
;
748 case PathSettings::E_ADDED
:
754 impl_notifyPropListener(sPath
, pPathOld
, pPathNew
);
756 m_lPaths
[sPath
] = aPath
;
760 case PathSettings::E_CHANGED
:
764 pPathOld
= &(pPath
->second
);
766 impl_notifyPropListener(sPath
, pPathOld
, pPathNew
);
768 m_lPaths
[sPath
] = aPath
;
772 case PathSettings::E_REMOVED
:
774 if (pPath
!= m_lPaths
.end())
778 pPathOld
= &(pPath
->second
);
780 impl_notifyPropListener(sPath
, pPathOld
, pPathNew
);
782 m_lPaths
.erase(pPath
);
787 default: // to let compiler be happy
794 css::uno::Sequence
< sal_Int32
> PathSettings::impl_mapPathName2IDList(std::u16string_view sPath
)
796 OUString sInternalProp
= OUString::Concat(sPath
)+POSTFIX_INTERNAL_PATHS
;
797 OUString sUserProp
= OUString::Concat(sPath
)+POSTFIX_USER_PATHS
;
798 OUString sWriteProp
= OUString::Concat(sPath
)+POSTFIX_WRITE_PATH
;
800 // Attention: The default set of IDs is fix and must follow these schema.
801 // Otherwise the outside code ant work for new added properties.
803 // The outside code must fire N events for every changed property.
804 // And the knowing about packaging of variables of the structure PathInfo
805 // follow these group IDs! But if such ID is not in the range of [0..IDGROUP_COUNT]
806 // the outside can't determine the right group ... and can not fire the right events .-)
808 css::uno::Sequence
<sal_Int32
> lIDs
{ IDGROUP_OLDSTYLE
, IDGROUP_INTERNAL_PATHS
,
809 IDGROUP_USER_PATHS
, IDGROUP_WRITE_PATH
};
810 assert(lIDs
.getLength() == IDGROUP_COUNT
);
811 auto plIDs
= lIDs
.getArray();
813 sal_Int32 c
= m_lPropDesc
.getLength();
817 const css::beans::Property
& rProp
= m_lPropDesc
[i
];
819 if (rProp
.Name
== sPath
)
820 plIDs
[IDGROUP_OLDSTYLE
] = rProp
.Handle
;
822 if (rProp
.Name
== sInternalProp
)
823 plIDs
[IDGROUP_INTERNAL_PATHS
] = rProp
.Handle
;
825 if (rProp
.Name
== sUserProp
)
826 plIDs
[IDGROUP_USER_PATHS
] = rProp
.Handle
;
828 if (rProp
.Name
== sWriteProp
)
829 plIDs
[IDGROUP_WRITE_PATH
] = rProp
.Handle
;
835 void PathSettings::impl_notifyPropListener( std::u16string_view sPath
,
836 const PathSettings::PathInfo
* pPathOld
,
837 const PathSettings::PathInfo
* pPathNew
)
839 css::uno::Sequence
< sal_Int32
> lHandles(1);
840 auto plHandles
= lHandles
.getArray();
841 css::uno::Sequence
< css::uno::Any
> lOldVals(1);
842 auto plOldVals
= lOldVals
.getArray();
843 css::uno::Sequence
< css::uno::Any
> lNewVals(1);
844 auto plNewVals
= lNewVals
.getArray();
846 css::uno::Sequence
< sal_Int32
> lIDs
= impl_mapPathName2IDList(sPath
);
847 sal_Int32 c
= lIDs
.getLength();
849 sal_Int32 nMaxID
= m_lPropDesc
.getLength()-1;
852 sal_Int32 nID
= lIDs
[i
];
861 switch(impl_getPropGroup(nID
))
863 case IDGROUP_OLDSTYLE
:
867 OUString sVal
= impl_convertPath2OldStyle(*pPathOld
);
868 plOldVals
[0] <<= sVal
;
872 OUString sVal
= impl_convertPath2OldStyle(*pPathNew
);
873 plNewVals
[0] <<= sVal
;
878 case IDGROUP_INTERNAL_PATHS
:
881 plOldVals
[0] <<= comphelper::containerToSequence(pPathOld
->lInternalPaths
);
883 plNewVals
[0] <<= comphelper::containerToSequence(pPathNew
->lInternalPaths
);
887 case IDGROUP_USER_PATHS
:
890 plOldVals
[0] <<= comphelper::containerToSequence(pPathOld
->lUserPaths
);
892 plNewVals
[0] <<= comphelper::containerToSequence(pPathNew
->lUserPaths
);
896 case IDGROUP_WRITE_PATH
:
899 plOldVals
[0] <<= pPathOld
->sWritePath
;
901 plNewVals
[0] <<= pPathNew
->sWritePath
;
914 void PathSettings::impl_subst(std::vector
<OUString
>& lVals
,
915 const css::uno::Reference
< css::util::XStringSubstitution
>& xSubst
,
918 for (auto & old
: lVals
)
922 sNew
= xSubst
->reSubstituteVariables(old
);
924 sNew
= xSubst
->substituteVariables(old
, false);
930 void PathSettings::impl_subst(PathSettings::PathInfo
& aPath
,
933 css::uno::Reference
< css::util::XStringSubstitution
> xSubst
= fa_getSubstitution();
935 impl_subst(aPath
.lInternalPaths
, xSubst
, bReSubst
);
936 impl_subst(aPath
.lUserPaths
, xSubst
, bReSubst
);
938 aPath
.sWritePath
= xSubst
->reSubstituteVariables(aPath
.sWritePath
);
940 aPath
.sWritePath
= xSubst
->substituteVariables(aPath
.sWritePath
, false);
943 OUString
PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo
& rPath
) const
945 OUStringBuffer
sPathVal(256);
947 for (auto const& internalPath
: rPath
.lInternalPaths
)
949 if (sPathVal
.getLength())
950 sPathVal
.append(";");
951 sPathVal
.append(internalPath
);
953 for (auto const& userPath
: rPath
.lUserPaths
)
955 if (sPathVal
.getLength())
956 sPathVal
.append(";");
957 sPathVal
.append(userPath
);
959 if (!rPath
.sWritePath
.isEmpty())
961 if (sPathVal
.getLength())
962 sPathVal
.append(";");
963 sPathVal
.append(rPath
.sWritePath
);
966 return sPathVal
.makeStringAndClear();
969 std::vector
<OUString
> PathSettings::impl_convertOldStyle2Path(std::u16string_view sOldStylePath
) const
971 std::vector
<OUString
> lList
;
972 sal_Int32 nToken
= 0;
975 OUString
sToken( o3tl::getToken(sOldStylePath
, 0, ';', nToken
) );
976 if (!sToken
.isEmpty())
977 lList
.push_back(sToken
);
984 void PathSettings::impl_purgeKnownPaths(PathSettings::PathInfo
& rPath
,
985 std::vector
<OUString
>& lList
)
987 // Erase items in the internal path list from lList.
988 // Also erase items in the internal path list from the user path list.
989 for (auto const& internalPath
: rPath
.lInternalPaths
)
991 std::vector
<OUString
>::iterator pItem
= std::find(lList
.begin(), lList
.end(), internalPath
);
992 if (pItem
!= lList
.end())
994 pItem
= std::find(rPath
.lUserPaths
.begin(), rPath
.lUserPaths
.end(), internalPath
);
995 if (pItem
!= rPath
.lUserPaths
.end())
996 rPath
.lUserPaths
.erase(pItem
);
999 // Erase items not in lList from the user path list.
1000 rPath
.lUserPaths
.erase(std::remove_if(rPath
.lUserPaths
.begin(), rPath
.lUserPaths
.end(),
1001 [&lList
](const OUString
& rItem
) {
1002 return std::find(lList
.begin(), lList
.end(), rItem
) == lList
.end();
1004 rPath
.lUserPaths
.end());
1006 // Erase items in the user path list from lList.
1007 for (auto const& userPath
: rPath
.lUserPaths
)
1009 std::vector
<OUString
>::iterator pItem
= std::find(lList
.begin(), lList
.end(), userPath
);
1010 if (pItem
!= lList
.end())
1014 // Erase the write path from lList
1015 std::vector
<OUString
>::iterator pItem
= std::find(lList
.begin(), lList
.end(), rPath
.sWritePath
);
1016 if (pItem
!= lList
.end())
1020 void PathSettings::impl_rebuildPropertyDescriptor()
1023 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1025 sal_Int32 c
= static_cast<sal_Int32
>(m_lPaths
.size());
1027 m_lPropDesc
.realloc(c
*IDGROUP_COUNT
);
1028 auto plPropDesc
= m_lPropDesc
.getArray();
1030 for (auto const& path
: m_lPaths
)
1032 const PathSettings::PathInfo
& rPath
= path
.second
;
1033 css::beans::Property
* pProp
= nullptr;
1035 pProp
= &(plPropDesc
[i
]);
1036 pProp
->Name
= rPath
.sPathName
;
1038 pProp
->Type
= cppu::UnoType
<OUString
>::get();
1039 pProp
->Attributes
= css::beans::PropertyAttribute::BOUND
;
1040 if (rPath
.bIsReadonly
)
1041 pProp
->Attributes
|= css::beans::PropertyAttribute::READONLY
;
1044 pProp
= &(plPropDesc
[i
]);
1045 pProp
->Name
= rPath
.sPathName
+POSTFIX_INTERNAL_PATHS
;
1047 pProp
->Type
= cppu::UnoType
<css::uno::Sequence
< OUString
>>::get();
1048 pProp
->Attributes
= css::beans::PropertyAttribute::BOUND
|
1049 css::beans::PropertyAttribute::READONLY
;
1052 pProp
= &(plPropDesc
[i
]);
1053 pProp
->Name
= rPath
.sPathName
+POSTFIX_USER_PATHS
;
1055 pProp
->Type
= cppu::UnoType
<css::uno::Sequence
< OUString
>>::get();
1056 pProp
->Attributes
= css::beans::PropertyAttribute::BOUND
;
1057 if (rPath
.bIsReadonly
)
1058 pProp
->Attributes
|= css::beans::PropertyAttribute::READONLY
;
1061 pProp
= &(plPropDesc
[i
]);
1062 pProp
->Name
= rPath
.sPathName
+POSTFIX_WRITE_PATH
;
1064 pProp
->Type
= cppu::UnoType
<OUString
>::get();
1065 pProp
->Attributes
= css::beans::PropertyAttribute::BOUND
;
1066 if (rPath
.bIsReadonly
)
1067 pProp
->Attributes
|= css::beans::PropertyAttribute::READONLY
;
1071 m_pPropHelp
.reset(new ::cppu::OPropertyArrayHelper(m_lPropDesc
, false)); // false => not sorted ... must be done inside helper
1076 css::uno::Any
PathSettings::impl_getPathValue(sal_Int32 nID
) const
1078 const PathSettings::PathInfo
* pPath
= impl_getPathAccessConst(nID
);
1080 throw css::lang::IllegalArgumentException();
1083 switch(impl_getPropGroup(nID
))
1085 case IDGROUP_OLDSTYLE
:
1087 OUString sVal
= impl_convertPath2OldStyle(*pPath
);
1092 case IDGROUP_INTERNAL_PATHS
:
1094 aVal
<<= comphelper::containerToSequence(pPath
->lInternalPaths
);
1098 case IDGROUP_USER_PATHS
:
1100 aVal
<<= comphelper::containerToSequence(pPath
->lUserPaths
);
1104 case IDGROUP_WRITE_PATH
:
1106 aVal
<<= pPath
->sWritePath
;
1114 void PathSettings::impl_setPathValue( sal_Int32 nID
,
1115 const css::uno::Any
& aVal
)
1117 PathSettings::PathInfo
* pOrgPath
= impl_getPathAccess(nID
);
1119 throw css::container::NoSuchElementException();
1121 // We work on a copied path ... so we can be sure that errors during this operation
1122 // does not make our internal cache invalid .-)
1123 PathSettings::PathInfo
aChangePath(*pOrgPath
);
1125 switch(impl_getPropGroup(nID
))
1127 case IDGROUP_OLDSTYLE
:
1131 std::vector
<OUString
> lList
= impl_convertOldStyle2Path(sVal
);
1132 impl_subst(lList
, fa_getSubstitution(), false);
1133 impl_purgeKnownPaths(aChangePath
, lList
);
1134 if (! impl_isValidPath(lList
))
1135 throw css::lang::IllegalArgumentException();
1137 if (aChangePath
.bIsSinglePath
)
1139 SAL_WARN_IF(lList
.size()>1, "fwk", "PathSettings::impl_setPathValue(): You try to set more than path value for a defined SINGLE_PATH!");
1140 if ( !lList
.empty() )
1141 aChangePath
.sWritePath
= *(lList
.begin());
1143 aChangePath
.sWritePath
.clear();
1147 for (auto const& elem
: lList
)
1149 aChangePath
.lUserPaths
.push_back(elem
);
1155 case IDGROUP_INTERNAL_PATHS
:
1157 if (aChangePath
.bIsSinglePath
)
1159 throw css::uno::Exception(
1160 "The path '" + aChangePath
.sPathName
1161 + "' is defined as SINGLE_PATH. It's sub set of internal paths can't be set.",
1162 static_cast< ::cppu::OWeakObject
* >(this));
1165 css::uno::Sequence
<OUString
> lTmpList
;
1167 std::vector
<OUString
> lList
= comphelper::sequenceToContainer
<std::vector
<OUString
>>(lTmpList
);
1168 if (! impl_isValidPath(lList
))
1169 throw css::lang::IllegalArgumentException();
1170 aChangePath
.lInternalPaths
= lList
;
1174 case IDGROUP_USER_PATHS
:
1176 if (aChangePath
.bIsSinglePath
)
1178 throw css::uno::Exception(
1179 "The path '" + aChangePath
.sPathName
1180 + "' is defined as SINGLE_PATH. It's sub set of internal paths can't be set.",
1181 static_cast< ::cppu::OWeakObject
* >(this));
1184 css::uno::Sequence
<OUString
> lTmpList
;
1186 std::vector
<OUString
> lList
= comphelper::sequenceToContainer
<std::vector
<OUString
>>(lTmpList
);
1187 if (! impl_isValidPath(lList
))
1188 throw css::lang::IllegalArgumentException();
1189 aChangePath
.lUserPaths
= lList
;
1193 case IDGROUP_WRITE_PATH
:
1197 if (! impl_isValidPath(sVal
))
1198 throw css::lang::IllegalArgumentException();
1199 aChangePath
.sWritePath
= sVal
;
1204 // TODO check if path has at least one path value set
1205 // At least it depends from the feature using this path, if an empty path list is allowed.
1207 // first we should try to store the changed (copied!) path ...
1208 // In case an error occurs on saving time an exception is thrown ...
1209 // If no exception occurs we can update our internal cache (means
1210 // we can overwrite pOrgPath !
1211 impl_storePath(aChangePath
);
1212 *pOrgPath
= std::move(aChangePath
);
1215 bool PathSettings::impl_isValidPath(const std::vector
<OUString
>& lPath
) const
1217 for (auto const& path
: lPath
)
1219 if (! impl_isValidPath(path
))
1226 bool PathSettings::impl_isValidPath(std::u16string_view sPath
) const
1228 // allow empty path to reset a path.
1229 // idea by LLA to support empty paths
1230 // if (sPath.getLength() == 0)
1235 return (! INetURLObject(sPath
).HasError());
1238 OUString
impl_extractBaseFromPropName(const OUString
& sPropName
)
1240 sal_Int32 i
= sPropName
.indexOf(POSTFIX_INTERNAL_PATHS
);
1242 return sPropName
.copy(0, i
);
1243 i
= sPropName
.indexOf(POSTFIX_USER_PATHS
);
1245 return sPropName
.copy(0, i
);
1246 i
= sPropName
.indexOf(POSTFIX_WRITE_PATH
);
1248 return sPropName
.copy(0, i
);
1253 PathSettings::PathInfo
* PathSettings::impl_getPathAccess(sal_Int32 nHandle
)
1256 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1258 if (nHandle
> (m_lPropDesc
.getLength()-1))
1261 const css::beans::Property
& rProp
= m_lPropDesc
[nHandle
];
1262 OUString sProp
= impl_extractBaseFromPropName(rProp
.Name
);
1263 PathSettings::PathHash::iterator rPath
= m_lPaths
.find(sProp
);
1265 if (rPath
!= m_lPaths
.end())
1266 return &(rPath
->second
);
1272 const PathSettings::PathInfo
* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle
) const
1275 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1277 if (nHandle
> (m_lPropDesc
.getLength()-1))
1280 const css::beans::Property
& rProp
= m_lPropDesc
[nHandle
];
1281 OUString sProp
= impl_extractBaseFromPropName(rProp
.Name
);
1282 PathSettings::PathHash::const_iterator rPath
= m_lPaths
.find(sProp
);
1284 if (rPath
!= m_lPaths
.end())
1285 return &(rPath
->second
);
1291 sal_Bool SAL_CALL
PathSettings::convertFastPropertyValue( css::uno::Any
& aConvertedValue
,
1292 css::uno::Any
& aOldValue
,
1294 const css::uno::Any
& aValue
)
1296 // throws NoSuchElementException !
1297 css::uno::Any aCurrentVal
= impl_getPathValue(nHandle
);
1299 return PropHelper::willPropertyBeChanged(
1306 void SAL_CALL
PathSettings::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle
,
1307 const css::uno::Any
& aValue
)
1309 // throws NoSuchElement- and IllegalArgumentException !
1310 impl_setPathValue(nHandle
, aValue
);
1313 void SAL_CALL
PathSettings::getFastPropertyValue(css::uno::Any
& aValue
,
1314 sal_Int32 nHandle
) const
1316 aValue
= impl_getPathValue(nHandle
);
1319 ::cppu::IPropertyArrayHelper
& SAL_CALL
PathSettings::getInfoHelper()
1321 return *m_pPropHelp
;
1324 css::uno::Reference
< css::beans::XPropertySetInfo
> SAL_CALL
PathSettings::getPropertySetInfo()
1326 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1329 css::uno::Reference
< css::util::XStringSubstitution
> PathSettings::fa_getSubstitution()
1331 css::uno::Reference
< css::util::XStringSubstitution
> xSubst
;
1333 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1334 xSubst
= m_xSubstitution
;
1339 // create the needed substitution service.
1340 // We must replace all used variables inside read path values.
1341 // In case we can't do so... the whole office can't work really.
1342 // That's why it seems to be OK to throw a RuntimeException then.
1343 xSubst
= css::util::PathSubstitution::create(m_xContext
);
1346 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1347 m_xSubstitution
= xSubst
;
1354 css::uno::Reference
< css::container::XNameAccess
> PathSettings::fa_getCfgOld()
1356 css::uno::Reference
< css::container::XNameAccess
> xCfg
;
1358 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1364 xCfg
.set( ::comphelper::ConfigurationHelper::openConfig(
1366 "org.openoffice.Office.Common/Path/Current",
1367 ::comphelper::EConfigurationModes::Standard
), // not readonly! Sometimes we need write access there !!!
1368 css::uno::UNO_QUERY_THROW
);
1371 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1379 css::uno::Reference
< css::container::XNameAccess
> PathSettings::fa_getCfgNew()
1381 css::uno::Reference
< css::container::XNameAccess
> xCfg
;
1383 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1389 xCfg
.set( ::comphelper::ConfigurationHelper::openConfig(
1391 "org.openoffice.Office.Paths/Paths",
1392 ::comphelper::EConfigurationModes::Standard
),
1393 css::uno::UNO_QUERY_THROW
);
1396 osl::MutexGuard
g(cppu::WeakComponentImplHelperBase::rBHelper
.rMutex
);
1398 m_xCfgNewListener
= new WeakChangesListener(this);
1401 css::uno::Reference
< css::util::XChangesNotifier
> xBroadcaster(xCfg
, css::uno::UNO_QUERY_THROW
);
1402 xBroadcaster
->addChangesListener(m_xCfgNewListener
);
1410 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
1411 com_sun_star_comp_framework_PathSettings_get_implementation(
1412 css::uno::XComponentContext
*context
,
1413 css::uno::Sequence
<css::uno::Any
> const &)
1415 rtl::Reference
<PathSettings
> xPathSettings
= new PathSettings(context
);
1417 xPathSettings
->impl_readAll();
1419 return cppu::acquire(xPathSettings
.get());
1422 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */