LibreOffice Module framework (master) 1
pathsettings.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20#include <sal/config.h>
21
22#include <string_view>
23#include <utility>
24#include <unordered_map>
25
26#include <properties.h>
27#include <helper/mischelper.hxx>
28
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>
40
41#include <tools/urlobj.hxx>
42#include <rtl/ustrbuf.hxx>
43#include <rtl/ref.hxx>
44#include <sal/log.hxx>
45
53#include <o3tl/string_view.hxx>
54
55using namespace framework;
56
57constexpr OUStringLiteral CFGPROP_USERPATHS = u"UserPaths";
58constexpr OUStringLiteral CFGPROP_WRITEPATH = u"WritePath";
59
60/*
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
65 */
66
67constexpr OUStringLiteral POSTFIX_INTERNAL_PATHS = u"_internal";
68constexpr OUStringLiteral POSTFIX_USER_PATHS = u"_user";
69constexpr OUStringLiteral POSTFIX_WRITE_PATH = u"_writable";
70
71namespace {
72
73const sal_Int32 IDGROUP_OLDSTYLE = 0;
74const sal_Int32 IDGROUP_INTERNAL_PATHS = 1;
75const sal_Int32 IDGROUP_USER_PATHS = 2;
76const sal_Int32 IDGROUP_WRITE_PATH = 3;
77
78const sal_Int32 IDGROUP_COUNT = 4;
79
80sal_Int32 impl_getPropGroup(sal_Int32 nID)
81{
82 return (nID % IDGROUP_COUNT);
83}
84
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.
87 */
88
89typedef ::cppu::WeakComponentImplHelper<
90 css::lang::XServiceInfo,
91 css::util::XChangesListener, // => XEventListener
92 css::util::XPathSettings> // => XPropertySet
93 PathSettings_BASE;
94
95class PathSettings : private cppu::BaseMutex
96 , public PathSettings_BASE
98{
99 struct PathInfo
100 {
101 public:
102
103 PathInfo()
104 : bIsSinglePath (false)
105 , bIsReadonly (false)
106 {}
107
109 OUString sPathName;
110
112 std::vector<OUString> lInternalPaths;
113
115 std::vector<OUString> lUserPaths;
116
118 OUString sWritePath;
119
121 bool bIsSinglePath;
122
124 bool bIsReadonly;
125 };
126
127 typedef std::unordered_map<OUString, PathSettings::PathInfo> PathHash;
128
129 enum EChangeOp
130 {
131 E_UNDEFINED,
132 E_ADDED,
133 E_CHANGED,
134 E_REMOVED
135 };
136
137private:
138
140 css::uno::Reference< css::uno::XComponentContext > m_xContext;
141
143 PathSettings::PathHash m_lPaths;
144
147 css::uno::Sequence< css::beans::Property > m_lPropDesc;
148
150 css::uno::Reference< css::util::XStringSubstitution > m_xSubstitution;
151
153 css::uno::Reference< css::container::XNameAccess > m_xCfgOld;
154
156 css::uno::Reference< css::container::XNameAccess > m_xCfgNew;
157
159 css::uno::Reference< css::util::XChangesListener > m_xCfgNewListener;
160
161 std::unique_ptr<::cppu::OPropertyArrayHelper> m_pPropHelp;
162
163public:
164
169 explicit PathSettings(css::uno::Reference< css::uno::XComponentContext > xContext);
170
172 virtual ~PathSettings() override;
173
174 virtual OUString SAL_CALL getImplementationName() override
175 {
176 return "com.sun.star.comp.framework.PathSettings";
177 }
178
179 virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName) override
180 {
182 }
183
184 virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames() override
185 {
186 return {"com.sun.star.util.PathSettings"};
187 }
188
189 // XInterface
190 virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& type) override;
191 virtual void SAL_CALL acquire() noexcept override
193 virtual void SAL_CALL release() noexcept override
195
196 // XTypeProvider
197 virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes( ) override;
198
199 // css::util::XChangesListener
200 virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent) override;
201
202 // css::lang::XEventListener
203 virtual void SAL_CALL disposing(const css::lang::EventObject& aSource) override;
204
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); }
312
316 virtual void SAL_CALL setPropertyValue(const OUString& p1, const css::uno::Any& p2) override
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
322 virtual void SAL_CALL removePropertyChangeListener(const OUString& p1, const css::uno::Reference<css::beans::XPropertyChangeListener>& p2) override
324 virtual void SAL_CALL addVetoableChangeListener(const OUString& p1, const css::uno::Reference<css::beans::XVetoableChangeListener>& p2) override
326 virtual void SAL_CALL removeVetoableChangeListener(const OUString& p1, const css::uno::Reference<css::beans::XVetoableChangeListener>& p2) override
329 void impl_readAll();
330
331private:
332 virtual void SAL_CALL disposing() final override;
333
335 OUString getStringProperty(const OUString& p1);
336
338 void setStringProperty(const OUString& p1, const OUString& p2);
339
343 std::vector<OUString> impl_readOldFormat(const OUString& sPath);
344
346 PathSettings::PathInfo impl_readNewFormat(const OUString& sPath);
347
352 void impl_mergeOldUserPaths( PathSettings::PathInfo& rPath,
353 const std::vector<OUString>& lOld );
354
357 PathSettings::EChangeOp impl_updatePath(const OUString& sPath ,
358 bool bNotifyListener);
359
364 void impl_subst(std::vector<OUString>& lVals ,
365 const css::uno::Reference< css::util::XStringSubstitution >& xSubst ,
366 bool bReSubst);
367
368 void impl_subst(PathSettings::PathInfo& aPath ,
369 bool bReSubst);
370
372 OUString impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath ) const;
373 std::vector<OUString> impl_convertOldStyle2Path(std::u16string_view sOldStylePath) const;
374
379 void impl_purgeKnownPaths(PathSettings::PathInfo& rPath,
380 std::vector<OUString>& lList);
381
383 void impl_rebuildPropertyDescriptor();
384
388 css::uno::Any impl_getPathValue( sal_Int32 nID ) const;
389 void impl_setPathValue( sal_Int32 nID ,
390 const css::uno::Any& aVal);
391
394 PathSettings::PathInfo* impl_getPathAccess (sal_Int32 nHandle);
395 const PathSettings::PathInfo* impl_getPathAccessConst(sal_Int32 nHandle) const;
396
398 bool impl_isValidPath(std::u16string_view sPath) const;
399 bool impl_isValidPath(const std::vector<OUString>& lPath) const;
400
401 void impl_storePath(const PathSettings::PathInfo& aPath);
402
403 css::uno::Sequence< sal_Int32 > impl_mapPathName2IDList(std::u16string_view sPath);
404
405 void impl_notifyPropListener( std::u16string_view sPath ,
406 const PathSettings::PathInfo* pPathOld,
407 const PathSettings::PathInfo* pPathNew);
408
409 // OPropertySetHelper
410 virtual sal_Bool SAL_CALL convertFastPropertyValue( css::uno::Any& aConvertedValue,
411 css::uno::Any& aOldValue,
412 sal_Int32 nHandle,
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;
418 // Avoid:
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]
422 virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() override;
423 virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() override;
424
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();
429};
430
431PathSettings::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))
435{
436}
437
438PathSettings::~PathSettings()
439{
440 disposing();
441}
442
443void SAL_CALL PathSettings::disposing()
444{
445 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
446
447 css::uno::Reference< css::util::XChangesNotifier >
448 xBroadcaster(m_xCfgNew, css::uno::UNO_QUERY);
449 if (xBroadcaster.is())
450 xBroadcaster->removeChangesListener(m_xCfgNewListener);
451
452 m_xSubstitution.clear();
453 m_xCfgOld.clear();
454 m_xCfgNew.clear();
455 m_xCfgNewListener.clear();
456
457 m_pPropHelp.reset();
458}
459
460css::uno::Any SAL_CALL PathSettings::queryInterface( const css::uno::Type& _rType )
461{
462 css::uno::Any aRet = PathSettings_BASE::queryInterface( _rType );
463 if ( !aRet.hasValue() )
465 return aRet;
466}
467
468css::uno::Sequence< css::uno::Type > SAL_CALL PathSettings::getTypes( )
469{
471 PathSettings_BASE::getTypes(),
473 );
474}
475
476void SAL_CALL PathSettings::changesOccurred(const css::util::ChangesEvent& aEvent)
477{
478 sal_Int32 c = aEvent.Changes.getLength();
479 sal_Int32 i = 0;
480 bool bUpdateDescriptor = false;
481
482 for (i=0; i<c; ++i)
483 {
484 const css::util::ElementChange& aChange = aEvent.Changes[i];
485
486 OUString sChanged;
487 aChange.Accessor >>= sChanged;
488
489 OUString sPath = ::utl::extractFirstFromConfigurationPath(sChanged);
490 if (!sPath.isEmpty())
491 {
492 PathSettings::EChangeOp eOp = impl_updatePath(sPath, true);
493 if (
494 (eOp == PathSettings::E_ADDED ) ||
495 (eOp == PathSettings::E_REMOVED)
496 )
497 bUpdateDescriptor = true;
498 }
499 }
500
501 if (bUpdateDescriptor)
502 impl_rebuildPropertyDescriptor();
503}
504
505void SAL_CALL PathSettings::disposing(const css::lang::EventObject& aSource)
506{
507 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
508
509 if (aSource.Source == m_xCfgNew)
510 m_xCfgNew.clear();
511}
512
513OUString PathSettings::getStringProperty(const OUString& p1)
514{
516 OUString s;
517 a >>= s;
518 return s;
519}
520
521void PathSettings::setStringProperty(const OUString& p1, const OUString& p2)
522{
524}
525
526void PathSettings::impl_readAll()
527{
528 try
529 {
530 // TODO think about me
531 css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
532 css::uno::Sequence< OUString > lPaths = xCfg->getElementNames();
533
534 sal_Int32 c = lPaths.getLength();
535 for (sal_Int32 i = 0; i < c; ++i)
536 {
537 const OUString& sPath = lPaths[i];
538 impl_updatePath(sPath, false);
539 }
540 }
541 catch(const css::uno::RuntimeException& )
542 {
543 }
544
545 impl_rebuildPropertyDescriptor();
546}
547
548// NO substitution here ! It's done outside ...
549std::vector<OUString> PathSettings::impl_readOldFormat(const OUString& sPath)
550{
551 css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
552 std::vector<OUString> aPathVal;
553
554 if( xCfg->hasByName(sPath) )
555 {
556 css::uno::Any aVal( xCfg->getByName(sPath) );
557
558 OUString sStringVal;
559 css::uno::Sequence< OUString > lStringListVal;
560
561 if (aVal >>= sStringVal)
562 {
563 aPathVal.push_back(sStringVal);
564 }
565 else if (aVal >>= lStringListVal)
566 {
567 aPathVal = comphelper::sequenceToContainer<std::vector<OUString>>(lStringListVal);
568 }
569 }
570
571 return aPathVal;
572}
573
574// NO substitution here ! It's done outside ...
575PathSettings::PathInfo PathSettings::impl_readNewFormat(const OUString& sPath)
576{
577 css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
578
579 // get access to the "queried" path
580 css::uno::Reference< css::container::XNameAccess > xPath;
581 xCfg->getByName(sPath) >>= xPath;
582
583 PathSettings::PathInfo aPathVal;
584
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());
589
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);
594
595 // read the writeable path
596 xPath->getByName(CFGPROP_WRITEPATH) >>= aPathVal.sWritePath;
597
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);
603
604 // read state props
605 xPath->getByName("IsSinglePath") >>= aPathVal.bIsSinglePath;
606
607 // analyze finalized/mandatory states
608 aPathVal.bIsReadonly = false;
609 css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
610 if (xInfo.is())
611 {
612 css::beans::Property aInfo = xInfo->getAsProperty();
613 bool bFinalized = ((aInfo.Attributes & css::beans::PropertyAttribute::READONLY ) == css::beans::PropertyAttribute::READONLY );
614
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;
619 }
620
621 return aPathVal;
622}
623
624void PathSettings::impl_storePath(const PathSettings::PathInfo& aPath)
625{
626 css::uno::Reference< css::container::XNameAccess > xCfgNew = fa_getCfgNew();
627 css::uno::Reference< css::container::XNameAccess > xCfgOld = fa_getCfgOld();
628
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);
634
635 // update new configuration
636 if (! aResubstPath.bIsSinglePath)
637 {
639 aResubstPath.sPathName,
641 css::uno::Any(comphelper::containerToSequence(aResubstPath.lUserPaths)));
642 }
643
645 aResubstPath.sPathName,
647 css::uno::Any(aResubstPath.sWritePath));
648
650
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!!!
654
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))
658 {
659 css::uno::Reference< css::beans::XPropertySet > xProps(xCfgOld, css::uno::UNO_QUERY_THROW);
660 xProps->setPropertyValue(aResubstPath.sPathName, css::uno::Any());
662 }
663}
664
665void PathSettings::impl_mergeOldUserPaths( PathSettings::PathInfo& rPath,
666 const std::vector<OUString>& lOld )
667{
668 for (auto const& old : lOld)
669 {
670 if (rPath.bIsSinglePath)
671 {
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;
675 }
676 else
677 {
678 if (
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 )
682 )
683 rPath.lUserPaths.push_back(old);
684 }
685 }
686}
687
688PathSettings::EChangeOp PathSettings::impl_updatePath(const OUString& sPath ,
689 bool bNotifyListener)
690{
691 // SAFE ->
692 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
693
694 PathSettings::PathInfo* pPathOld = nullptr;
695 PathSettings::PathInfo* pPathNew = nullptr;
696 PathSettings::EChangeOp eOp = PathSettings::E_UNDEFINED;
697 PathSettings::PathInfo aPath;
698
699 try
700 {
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);
708 }
709 catch(const css::uno::RuntimeException&)
710 { throw; }
711 catch(const css::container::NoSuchElementException&)
712 { eOp = PathSettings::E_REMOVED; }
713 catch(const css::uno::Exception&)
714 { throw; }
715
716 try
717 {
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);
727 }
728 catch(const css::uno::RuntimeException&)
729 { throw; }
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&)
735 {}
736
737 PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
738 if (eOp == PathSettings::E_UNDEFINED)
739 {
740 if (pPath != m_lPaths.end())
741 eOp = PathSettings::E_CHANGED;
742 else
743 eOp = PathSettings::E_ADDED;
744 }
745
746 switch(eOp)
747 {
748 case PathSettings::E_ADDED :
749 {
750 if (bNotifyListener)
751 {
752 pPathOld = nullptr;
753 pPathNew = &aPath;
754 impl_notifyPropListener(sPath, pPathOld, pPathNew);
755 }
756 m_lPaths[sPath] = aPath;
757 }
758 break;
759
760 case PathSettings::E_CHANGED :
761 {
762 if (bNotifyListener)
763 {
764 pPathOld = &(pPath->second);
765 pPathNew = &aPath;
766 impl_notifyPropListener(sPath, pPathOld, pPathNew);
767 }
768 m_lPaths[sPath] = aPath;
769 }
770 break;
771
772 case PathSettings::E_REMOVED :
773 {
774 if (pPath != m_lPaths.end())
775 {
776 if (bNotifyListener)
777 {
778 pPathOld = &(pPath->second);
779 pPathNew = nullptr;
780 impl_notifyPropListener(sPath, pPathOld, pPathNew);
781 }
782 m_lPaths.erase(pPath);
783 }
784 }
785 break;
786
787 default: // to let compiler be happy
788 break;
789 }
790
791 return eOp;
792}
793
794css::uno::Sequence< sal_Int32 > PathSettings::impl_mapPathName2IDList(std::u16string_view sPath)
795{
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;
799
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.
802 // Why?
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 .-)
807
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();
812
813 sal_Int32 c = m_lPropDesc.getLength();
814 sal_Int32 i = 0;
815 for (i=0; i<c; ++i)
816 {
817 const css::beans::Property& rProp = m_lPropDesc[i];
818
819 if (rProp.Name == sPath)
820 plIDs[IDGROUP_OLDSTYLE] = rProp.Handle;
821 else
822 if (rProp.Name == sInternalProp)
823 plIDs[IDGROUP_INTERNAL_PATHS] = rProp.Handle;
824 else
825 if (rProp.Name == sUserProp)
826 plIDs[IDGROUP_USER_PATHS] = rProp.Handle;
827 else
828 if (rProp.Name == sWriteProp)
829 plIDs[IDGROUP_WRITE_PATH] = rProp.Handle;
830 }
831
832 return lIDs;
833}
834
835void PathSettings::impl_notifyPropListener( std::u16string_view sPath,
836 const PathSettings::PathInfo* pPathOld,
837 const PathSettings::PathInfo* pPathNew)
838{
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();
845
846 css::uno::Sequence< sal_Int32 > lIDs = impl_mapPathName2IDList(sPath);
847 sal_Int32 c = lIDs.getLength();
848 sal_Int32 i = 0;
849 sal_Int32 nMaxID = m_lPropDesc.getLength()-1;
850 for (i=0; i<c; ++i)
851 {
852 sal_Int32 nID = lIDs[i];
853
854 if (
855 (nID < 0 ) ||
856 (nID > nMaxID)
857 )
858 continue;
859
860 plHandles[0] = nID;
861 switch(impl_getPropGroup(nID))
862 {
863 case IDGROUP_OLDSTYLE :
864 {
865 if (pPathOld)
866 {
867 OUString sVal = impl_convertPath2OldStyle(*pPathOld);
868 plOldVals[0] <<= sVal;
869 }
870 if (pPathNew)
871 {
872 OUString sVal = impl_convertPath2OldStyle(*pPathNew);
873 plNewVals[0] <<= sVal;
874 }
875 }
876 break;
877
878 case IDGROUP_INTERNAL_PATHS :
879 {
880 if (pPathOld)
881 plOldVals[0] <<= comphelper::containerToSequence(pPathOld->lInternalPaths);
882 if (pPathNew)
883 plNewVals[0] <<= comphelper::containerToSequence(pPathNew->lInternalPaths);
884 }
885 break;
886
887 case IDGROUP_USER_PATHS :
888 {
889 if (pPathOld)
890 plOldVals[0] <<= comphelper::containerToSequence(pPathOld->lUserPaths);
891 if (pPathNew)
892 plNewVals[0] <<= comphelper::containerToSequence(pPathNew->lUserPaths);
893 }
894 break;
895
896 case IDGROUP_WRITE_PATH :
897 {
898 if (pPathOld)
899 plOldVals[0] <<= pPathOld->sWritePath;
900 if (pPathNew)
901 plNewVals[0] <<= pPathNew->sWritePath;
902 }
903 break;
904 }
905
906 fire(plHandles,
907 plNewVals,
908 plOldVals,
909 1,
910 false);
911 }
912}
913
914void PathSettings::impl_subst(std::vector<OUString>& lVals ,
915 const css::uno::Reference< css::util::XStringSubstitution >& xSubst ,
916 bool bReSubst)
917{
918 for (auto & old : lVals)
919 {
920 OUString sNew;
921 if (bReSubst)
922 sNew = xSubst->reSubstituteVariables(old);
923 else
924 sNew = xSubst->substituteVariables(old, false);
925
926 old = sNew;
927 }
928}
929
930void PathSettings::impl_subst(PathSettings::PathInfo& aPath ,
931 bool bReSubst)
932{
933 css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();
934
935 impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
936 impl_subst(aPath.lUserPaths , xSubst, bReSubst);
937 if (bReSubst)
938 aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
939 else
940 aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, false);
941}
942
943OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
944{
945 OUStringBuffer sPathVal(256);
946
947 for (auto const& internalPath : rPath.lInternalPaths)
948 {
949 if (sPathVal.getLength())
950 sPathVal.append(";");
951 sPathVal.append(internalPath);
952 }
953 for (auto const& userPath : rPath.lUserPaths)
954 {
955 if (sPathVal.getLength())
956 sPathVal.append(";");
957 sPathVal.append(userPath);
958 }
959 if (!rPath.sWritePath.isEmpty())
960 {
961 if (sPathVal.getLength())
962 sPathVal.append(";");
963 sPathVal.append(rPath.sWritePath);
964 }
965
966 return sPathVal.makeStringAndClear();
967}
968
969std::vector<OUString> PathSettings::impl_convertOldStyle2Path(std::u16string_view sOldStylePath) const
970{
971 std::vector<OUString> lList;
972 sal_Int32 nToken = 0;
973 do
974 {
975 OUString sToken( o3tl::getToken(sOldStylePath, 0, ';', nToken) );
976 if (!sToken.isEmpty())
977 lList.push_back(sToken);
978 }
979 while(nToken >= 0);
980
981 return lList;
982}
983
984void PathSettings::impl_purgeKnownPaths(PathSettings::PathInfo& rPath,
985 std::vector<OUString>& lList)
986{
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)
990 {
991 std::vector<OUString>::iterator pItem = std::find(lList.begin(), lList.end(), internalPath);
992 if (pItem != lList.end())
993 lList.erase(pItem);
994 pItem = std::find(rPath.lUserPaths.begin(), rPath.lUserPaths.end(), internalPath);
995 if (pItem != rPath.lUserPaths.end())
996 rPath.lUserPaths.erase(pItem);
997 }
998
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();
1003 }),
1004 rPath.lUserPaths.end());
1005
1006 // Erase items in the user path list from lList.
1007 for (auto const& userPath : rPath.lUserPaths)
1008 {
1009 std::vector<OUString>::iterator pItem = std::find(lList.begin(), lList.end(), userPath);
1010 if (pItem != lList.end())
1011 lList.erase(pItem);
1012 }
1013
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())
1017 lList.erase(pItem);
1018}
1019
1020void PathSettings::impl_rebuildPropertyDescriptor()
1021{
1022 // SAFE ->
1023 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1024
1025 sal_Int32 c = static_cast<sal_Int32>(m_lPaths.size());
1026 sal_Int32 i = 0;
1027 m_lPropDesc.realloc(c*IDGROUP_COUNT);
1028 auto plPropDesc = m_lPropDesc.getArray();
1029
1030 for (auto const& path : m_lPaths)
1031 {
1032 const PathSettings::PathInfo& rPath = path.second;
1033 css::beans::Property* pProp = nullptr;
1034
1035 pProp = &(plPropDesc[i]);
1036 pProp->Name = rPath.sPathName;
1037 pProp->Handle = i;
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;
1042 ++i;
1043
1044 pProp = &(plPropDesc[i]);
1045 pProp->Name = rPath.sPathName+POSTFIX_INTERNAL_PATHS;
1046 pProp->Handle = i;
1048 pProp->Attributes = css::beans::PropertyAttribute::BOUND |
1049 css::beans::PropertyAttribute::READONLY;
1050 ++i;
1051
1052 pProp = &(plPropDesc[i]);
1053 pProp->Name = rPath.sPathName+POSTFIX_USER_PATHS;
1054 pProp->Handle = i;
1056 pProp->Attributes = css::beans::PropertyAttribute::BOUND;
1057 if (rPath.bIsReadonly)
1058 pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
1059 ++i;
1060
1061 pProp = &(plPropDesc[i]);
1062 pProp->Name = rPath.sPathName+POSTFIX_WRITE_PATH;
1063 pProp->Handle = i;
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;
1068 ++i;
1069 }
1070
1071 m_pPropHelp.reset(new ::cppu::OPropertyArrayHelper(m_lPropDesc, false)); // false => not sorted ... must be done inside helper
1072
1073 // <- SAFE
1074}
1075
1076css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
1077{
1078 const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
1079 if (! pPath)
1080 throw css::lang::IllegalArgumentException();
1081
1082 css::uno::Any aVal;
1083 switch(impl_getPropGroup(nID))
1084 {
1085 case IDGROUP_OLDSTYLE :
1086 {
1087 OUString sVal = impl_convertPath2OldStyle(*pPath);
1088 aVal <<= sVal;
1089 }
1090 break;
1091
1092 case IDGROUP_INTERNAL_PATHS :
1093 {
1094 aVal <<= comphelper::containerToSequence(pPath->lInternalPaths);
1095 }
1096 break;
1097
1098 case IDGROUP_USER_PATHS :
1099 {
1100 aVal <<= comphelper::containerToSequence(pPath->lUserPaths);
1101 }
1102 break;
1103
1104 case IDGROUP_WRITE_PATH :
1105 {
1106 aVal <<= pPath->sWritePath;
1107 }
1108 break;
1109 }
1110
1111 return aVal;
1112}
1113
1114void PathSettings::impl_setPathValue( sal_Int32 nID ,
1115 const css::uno::Any& aVal)
1116{
1117 PathSettings::PathInfo* pOrgPath = impl_getPathAccess(nID);
1118 if (! pOrgPath)
1119 throw css::container::NoSuchElementException();
1120
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);
1124
1125 switch(impl_getPropGroup(nID))
1126 {
1127 case IDGROUP_OLDSTYLE :
1128 {
1129 OUString sVal;
1130 aVal >>= sVal;
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();
1136
1137 if (aChangePath.bIsSinglePath)
1138 {
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());
1142 else
1143 aChangePath.sWritePath.clear();
1144 }
1145 else
1146 {
1147 for (auto const& elem : lList)
1148 {
1149 aChangePath.lUserPaths.push_back(elem);
1150 }
1151 }
1152 }
1153 break;
1154
1155 case IDGROUP_INTERNAL_PATHS :
1156 {
1157 if (aChangePath.bIsSinglePath)
1158 {
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));
1163 }
1164
1165 css::uno::Sequence<OUString> lTmpList;
1166 aVal >>= 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;
1171 }
1172 break;
1173
1174 case IDGROUP_USER_PATHS :
1175 {
1176 if (aChangePath.bIsSinglePath)
1177 {
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));
1182 }
1183
1184 css::uno::Sequence<OUString> lTmpList;
1185 aVal >>= 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;
1190 }
1191 break;
1192
1193 case IDGROUP_WRITE_PATH :
1194 {
1195 OUString sVal;
1196 aVal >>= sVal;
1197 if (! impl_isValidPath(sVal))
1198 throw css::lang::IllegalArgumentException();
1199 aChangePath.sWritePath = sVal;
1200 }
1201 break;
1202 }
1203
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.
1206
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);
1213}
1214
1215bool PathSettings::impl_isValidPath(const std::vector<OUString>& lPath) const
1216{
1217 for (auto const& path : lPath)
1218 {
1219 if (! impl_isValidPath(path))
1220 return false;
1221 }
1222
1223 return true;
1224}
1225
1226bool PathSettings::impl_isValidPath(std::u16string_view sPath) const
1227{
1228 // allow empty path to reset a path.
1229// idea by LLA to support empty paths
1230// if (sPath.getLength() == 0)
1231// {
1232// return sal_True;
1233// }
1234
1235 return (! INetURLObject(sPath).HasError());
1236}
1237
1238OUString impl_extractBaseFromPropName(const OUString& sPropName)
1239{
1240 sal_Int32 i = sPropName.indexOf(POSTFIX_INTERNAL_PATHS);
1241 if (i > -1)
1242 return sPropName.copy(0, i);
1243 i = sPropName.indexOf(POSTFIX_USER_PATHS);
1244 if (i > -1)
1245 return sPropName.copy(0, i);
1246 i = sPropName.indexOf(POSTFIX_WRITE_PATH);
1247 if (i > -1)
1248 return sPropName.copy(0, i);
1249
1250 return sPropName;
1251}
1252
1253PathSettings::PathInfo* PathSettings::impl_getPathAccess(sal_Int32 nHandle)
1254{
1255 // SAFE ->
1256 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1257
1258 if (nHandle > (m_lPropDesc.getLength()-1))
1259 return nullptr;
1260
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);
1264
1265 if (rPath != m_lPaths.end())
1266 return &(rPath->second);
1267
1268 return nullptr;
1269 // <- SAFE
1270}
1271
1272const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
1273{
1274 // SAFE ->
1275 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1276
1277 if (nHandle > (m_lPropDesc.getLength()-1))
1278 return nullptr;
1279
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);
1283
1284 if (rPath != m_lPaths.end())
1285 return &(rPath->second);
1286
1287 return nullptr;
1288 // <- SAFE
1289}
1290
1291sal_Bool SAL_CALL PathSettings::convertFastPropertyValue( css::uno::Any& aConvertedValue,
1292 css::uno::Any& aOldValue ,
1293 sal_Int32 nHandle ,
1294 const css::uno::Any& aValue )
1295{
1296 // throws NoSuchElementException !
1297 css::uno::Any aCurrentVal = impl_getPathValue(nHandle);
1298
1299 return PropHelper::willPropertyBeChanged(
1300 aCurrentVal,
1301 aValue,
1302 aOldValue,
1303 aConvertedValue);
1304}
1305
1306void SAL_CALL PathSettings::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
1307 const css::uno::Any& aValue )
1308{
1309 // throws NoSuchElement- and IllegalArgumentException !
1310 impl_setPathValue(nHandle, aValue);
1311}
1312
1313void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
1314 sal_Int32 nHandle) const
1315{
1316 aValue = impl_getPathValue(nHandle);
1317}
1318
1319::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
1320{
1321 return *m_pPropHelp;
1322}
1323
1324css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
1325{
1326 return ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper());
1327}
1328
1329css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
1330{
1331 css::uno::Reference< css::util::XStringSubstitution > xSubst;
1332 { // SAFE ->
1333 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1334 xSubst = m_xSubstitution;
1335 }
1336
1337 if (! xSubst.is())
1338 {
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);
1344
1345 { // SAFE ->
1346 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1347 m_xSubstitution = xSubst;
1348 }
1349 }
1350
1351 return xSubst;
1352}
1353
1354css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
1355{
1356 css::uno::Reference< css::container::XNameAccess > xCfg;
1357 { // SAFE ->
1358 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1359 xCfg = m_xCfgOld;
1360 } // <- SAFE
1361
1362 if (! xCfg.is())
1363 {
1365 m_xContext,
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);
1369
1370 { // SAFE ->
1371 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1372 m_xCfgOld = xCfg;
1373 }
1374 }
1375
1376 return xCfg;
1377}
1378
1379css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
1380{
1381 css::uno::Reference< css::container::XNameAccess > xCfg;
1382 { // SAFE ->
1383 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1384 xCfg = m_xCfgNew;
1385 } // <- SAFE
1386
1387 if (! xCfg.is())
1388 {
1390 m_xContext,
1391 "org.openoffice.Office.Paths/Paths",
1393 css::uno::UNO_QUERY_THROW);
1394
1395 { // SAFE ->
1396 osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
1397 m_xCfgNew = xCfg;
1398 m_xCfgNewListener = new WeakChangesListener(this);
1399 }
1400
1401 css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
1402 xBroadcaster->addChangesListener(m_xCfgNewListener);
1403 }
1404
1405 return xCfg;
1406}
1407
1408}
1409
1410extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface *
1412 css::uno::XComponentContext *context,
1413 css::uno::Sequence<css::uno::Any> const &)
1414{
1415 rtl::Reference<PathSettings> xPathSettings = new PathSettings(context);
1416 // fill cache
1417 xPathSettings->impl_readAll();
1418
1419 return cppu::acquire(xPathSettings.get());
1420}
1421
1422/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
AnyEventRef aEvent
static css::uno::Reference< css::uno::XInterface > openConfig(const css::uno::Reference< css::uno::XComponentContext > &rxContext, const OUString &sPackage, EConfigurationModes eMode)
static void flush(const css::uno::Reference< css::uno::XInterface > &xCFG)
static void writeRelativeKey(const css::uno::Reference< css::uno::XInterface > &xCFG, const OUString &sRelPath, const OUString &sKey, const css::uno::Any &aValue)
virtual css::uno::Any SAL_CALL getFastPropertyValue(sal_Int32 nHandle) SAL_OVERRIDE
virtual void SAL_CALL addVetoableChangeListener(const ::rtl::OUString &aPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) SAL_OVERRIDE
virtual IPropertyArrayHelper &SAL_CALL getInfoHelper()=0
virtual void SAL_CALL setFastPropertyValue_NoBroadcast(sal_Int32 nHandle, const css::uno::Any &rValue)=0
void SAL_CALL disposing()
virtual void SAL_CALL removePropertyChangeListener(const ::rtl::OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) SAL_OVERRIDE
virtual css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType) SAL_OVERRIDE
virtual sal_Bool SAL_CALL convertFastPropertyValue(css::uno::Any &rConvertedValue, css::uno::Any &rOldValue, sal_Int32 nHandle, const css::uno::Any &rValue)=0
virtual void SAL_CALL removeVetoableChangeListener(const ::rtl::OUString &aPropertyName, const css::uno::Reference< css::beans::XVetoableChangeListener > &aListener) SAL_OVERRIDE
virtual css::uno::Any SAL_CALL getPropertyValue(const ::rtl::OUString &aPropertyName) SAL_OVERRIDE
virtual void SAL_CALL setPropertyValue(const ::rtl::OUString &rPropertyName, const css::uno::Any &aValue) SAL_OVERRIDE
virtual void SAL_CALL addPropertyChangeListener(const ::rtl::OUString &aPropertyName, const css::uno::Reference< css::beans::XPropertyChangeListener > &aListener) SAL_OVERRIDE
css::uno::Sequence< css::uno::Type > getTypes()
virtual void SAL_CALL acquire() SAL_NOEXCEPT SAL_OVERRIDE
virtual void SAL_CALL release() SAL_NOEXCEPT SAL_OVERRIDE
css::uno::Type const & get()
float u
css::uno::Reference< css::uno::XComponentContext > m_xContext
uno_Any a
#define SAL_WARN_IF(condition, area, stream)
css::uno::Sequence< T > concatSequences(const css::uno::Sequence< T > &rS1, const Ss &... rSn)
css::uno::Sequence< DstElementType > containerToSequence(const SrcType &i_Container)
css::uno::Sequence< OUString > getSupportedServiceNames()
OUString getImplementationName()
css::uno::Any SAL_CALL queryInterface(const css::uno::Type &rType, Interface1 *p1)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
int i
std::basic_string_view< charT, traits > getToken(std::basic_string_view< charT, traits > sv, charT delimiter, std::size_t &position)
constexpr OUStringLiteral CFGPROP_USERPATHS
SAL_DLLPUBLIC_EXPORT css::uno::XInterface * com_sun_star_comp_framework_PathSettings_get_implementation(css::uno::XComponentContext *context, css::uno::Sequence< css::uno::Any > const &)
constexpr OUStringLiteral POSTFIX_WRITE_PATH
constexpr OUStringLiteral POSTFIX_INTERNAL_PATHS
constexpr OUStringLiteral POSTFIX_USER_PATHS
constexpr OUStringLiteral CFGPROP_WRITEPATH
DefTokenId nToken
sal_Int32 nHandle
unsigned char sal_Bool
ResultType type
std::mutex m_aMutex