LCOV - code coverage report
Current view: top level - framework/source/services - pathsettings.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 293 684 42.8 %
Date: 2015-06-13 12:38:46 Functions: 38 111 34.2 %
Legend: Lines: hit not hit

          Line data    Source code
       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 <properties.h>
      21             : #include <stdtypes.h>
      22             : #include <helper/mischelper.hxx>
      23             : 
      24             : #include <com/sun/star/beans/Property.hpp>
      25             : #include <com/sun/star/beans/XProperty.hpp>
      26             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      27             : #include <com/sun/star/beans/XPropertySet.hpp>
      28             : #include <com/sun/star/util/XChangesNotifier.hpp>
      29             : #include <com/sun/star/util/PathSubstitution.hpp>
      30             : #include <com/sun/star/container/XNameAccess.hpp>
      31             : #include <com/sun/star/lang/XServiceInfo.hpp>
      32             : #include <com/sun/star/util/XStringSubstitution.hpp>
      33             : #include <com/sun/star/util/XChangesListener.hpp>
      34             : #include <com/sun/star/util/XPathSettings.hpp>
      35             : 
      36             : #include <tools/urlobj.hxx>
      37             : #include <rtl/ustrbuf.hxx>
      38             : 
      39             : #include <cppuhelper/basemutex.hxx>
      40             : #include <cppuhelper/propshlp.hxx>
      41             : #include <cppuhelper/compbase3.hxx>
      42             : #include <cppuhelper/supportsservice.hxx>
      43             : #include <comphelper/sequence.hxx>
      44             : #include <comphelper/configurationhelper.hxx>
      45             : #include <unotools/configitem.hxx>
      46             : #include <unotools/configpaths.hxx>
      47             : 
      48             : using namespace framework;
      49             : 
      50             : #define CFGPROP_USERPATHS "UserPaths"
      51             : #define CFGPROP_WRITEPATH "WritePath"
      52             : 
      53             : /*
      54             :     0 : old style              "Template"              string using ";" as separator
      55             :     1 : internal paths         "Template_internal"     string list
      56             :     2 : user paths             "Template_user"         string list
      57             :     3 : write path             "Template_write"        string
      58             :  */
      59             : 
      60             : #define POSTFIX_INTERNAL_PATHS "_internal"
      61             : #define POSTFIX_USER_PATHS "_user"
      62             : #define POSTFIX_WRITE_PATH "_writable"
      63             : 
      64             : namespace {
      65             : 
      66             : const sal_Int32 IDGROUP_OLDSTYLE        = 0;
      67             : const sal_Int32 IDGROUP_INTERNAL_PATHS = 1;
      68             : const sal_Int32 IDGROUP_USER_PATHS     = 2;
      69             : const sal_Int32 IDGROUP_WRITE_PATH      = 3;
      70             : 
      71             : const sal_Int32 IDGROUP_COUNT           = 4;
      72             : 
      73       19932 : sal_Int32 impl_getPropGroup(sal_Int32 nID)
      74             : {
      75       19932 :     return (nID % IDGROUP_COUNT);
      76             : }
      77             : 
      78             : /* enable it if you wish to migrate old user settings (using the old cfg schema) on demand ....
      79             :    disable it in case only the new schema must be used.
      80             :  */
      81             : 
      82             : typedef ::cppu::WeakComponentImplHelper3<
      83             :             css::lang::XServiceInfo,
      84             :             css::util::XChangesListener,    // => XEventListener
      85             :             css::util::XPathSettings>       // => XPropertySet
      86             :                 PathSettings_BASE;
      87             : 
      88             : class PathSettings : private cppu::BaseMutex
      89             :                    , public  PathSettings_BASE
      90             :                    , public  ::cppu::OPropertySetHelper
      91             : {
      92       25152 :     struct PathInfo
      93             :     {
      94             :         public:
      95             : 
      96       15120 :             PathInfo()
      97             :                 : sPathName     ()
      98             :                 , lInternalPaths()
      99             :                 , lUserPaths    ()
     100             :                 , sWritePath    ()
     101             :                 , bIsSinglePath (false)
     102       15120 :                 , bIsReadonly   (false)
     103       15120 :             {}
     104             : 
     105           0 :             PathInfo(const PathInfo& rCopy)
     106           0 :             {
     107           0 :                 takeOver(rCopy);
     108           0 :             }
     109             : 
     110           0 :             void takeOver(const PathInfo& rCopy)
     111             :             {
     112           0 :                 sPathName      = rCopy.sPathName;
     113           0 :                 lInternalPaths = rCopy.lInternalPaths;
     114           0 :                 lUserPaths     = rCopy.lUserPaths;
     115           0 :                 sWritePath     = rCopy.sWritePath;
     116           0 :                 bIsSinglePath  = rCopy.bIsSinglePath;
     117           0 :                 bIsReadonly    = rCopy.bIsReadonly;
     118           0 :             }
     119             : 
     120             :             /// an internal name describing this path
     121             :             OUString sPathName;
     122             : 
     123             :             /// contains all paths, which are used internally - but are not visible for the user.
     124             :             OUStringList lInternalPaths;
     125             : 
     126             :             /// contains all paths configured by the user
     127             :             OUStringList lUserPaths;
     128             : 
     129             :             /// this special path is used to generate feature depending content there
     130             :             OUString sWritePath;
     131             : 
     132             :             /// indicates real single paths, which uses WritePath property only
     133             :             bool bIsSinglePath;
     134             : 
     135             :             /// simple handling of finalized/mandatory states ... => we know one state READONLY only .-)
     136             :             bool bIsReadonly;
     137             :     };
     138             : 
     139             :     typedef BaseHash< PathSettings::PathInfo > PathHash;
     140             : 
     141             :     enum EChangeOp
     142             :     {
     143             :         E_UNDEFINED,
     144             :         E_ADDED,
     145             :         E_CHANGED,
     146             :         E_REMOVED
     147             :     };
     148             : 
     149             : private:
     150             : 
     151             :     /** reference to factory, which has create this instance. */
     152             :     css::uno::Reference< css::uno::XComponentContext > m_xContext;
     153             : 
     154             :     /** list of all path variables and her corresponding values. */
     155             :     PathSettings::PathHash m_lPaths;
     156             : 
     157             :     /** describes all properties available on our interface.
     158             :         Will be generated on demand based on our path list m_lPaths. */
     159             :     css::uno::Sequence< css::beans::Property > m_lPropDesc;
     160             : 
     161             :     /** helper needed to (re-)substitute all internal save path values. */
     162             :     css::uno::Reference< css::util::XStringSubstitution > m_xSubstitution;
     163             : 
     164             :     /** provides access to the old configuration schema (which will be migrated on demand). */
     165             :     css::uno::Reference< css::container::XNameAccess > m_xCfgOld;
     166             : 
     167             :     /** provides access to the new configuration schema. */
     168             :     css::uno::Reference< css::container::XNameAccess > m_xCfgNew;
     169             : 
     170             :     /** helper to listen for configuration changes without ownership cycle problems */
     171             :     css::uno::Reference< css::util::XChangesListener > m_xCfgNewListener;
     172             : 
     173             :     ::cppu::OPropertyArrayHelper* m_pPropHelp;
     174             : 
     175             :     bool m_bIgnoreEvents;
     176             : 
     177             : public:
     178             : 
     179             :     /** initialize a new instance of this class.
     180             :         Attention: It's necessary for right function of this class, that the order of base
     181             :         classes is the right one. Because we transfer information from one base to another
     182             :         during this ctor runs! */
     183             :     PathSettings(const css::uno::Reference< css::uno::XComponentContext >& xContext);
     184             : 
     185             :     /** free all used resources ... if it was not already done. */
     186             :     virtual ~PathSettings();
     187             : 
     188           1 :     virtual OUString SAL_CALL getImplementationName()
     189             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     190             :     {
     191           1 :         return OUString("com.sun.star.comp.framework.PathSettings");
     192             :     }
     193             : 
     194           0 :     virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
     195             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     196             :     {
     197           0 :         return cppu::supportsService(this, ServiceName);
     198             :     }
     199             : 
     200           1 :     virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
     201             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     202             :     {
     203           1 :         css::uno::Sequence< OUString > aSeq(1);
     204           1 :         aSeq[0] = "com.sun.star.util.PathSettings";
     205           1 :         return aSeq;
     206             :     }
     207             : 
     208             :     // XInterface
     209             :     virtual css::uno::Any SAL_CALL queryInterface( const css::uno::Type& type) throw ( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
     210       10108 :     virtual void SAL_CALL acquire() throw () SAL_OVERRIDE
     211       10108 :         { OWeakObject::acquire(); }
     212       10104 :     virtual void SAL_CALL release() throw () SAL_OVERRIDE
     213       10104 :         { OWeakObject::release(); }
     214             : 
     215             :     // XTypeProvider
     216             :     virtual css::uno::Sequence< css::uno::Type > SAL_CALL getTypes(  ) throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     217             : 
     218             :     // css::util::XChangesListener
     219             :     virtual void SAL_CALL changesOccurred(const css::util::ChangesEvent& aEvent) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     220             : 
     221             :     // css::lang::XEventListener
     222             :     virtual void SAL_CALL disposing(const css::lang::EventObject& aSource)
     223             :         throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     224             : 
     225             :     /**
     226             :      * XPathSettings attribute methods
     227             :      */
     228           0 :     virtual OUString SAL_CALL getAddin() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     229           0 :         { return getStringProperty("Addin"); }
     230           0 :     virtual void SAL_CALL setAddin(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     231           0 :         { setStringProperty("Addin", p1); }
     232           0 :     virtual OUString SAL_CALL getAutoCorrect() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     233           0 :         { return getStringProperty("AutoCorrect"); }
     234           0 :     virtual void SAL_CALL setAutoCorrect(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     235           0 :         { setStringProperty("AutoCorrect", p1); }
     236           0 :     virtual OUString SAL_CALL getAutoText() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     237           0 :         { return getStringProperty("AutoText"); }
     238           0 :     virtual void SAL_CALL setAutoText(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     239           0 :         { setStringProperty("AutoText", p1); }
     240           0 :     virtual OUString SAL_CALL getBackup() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     241           0 :         { return getStringProperty("Backup"); }
     242           0 :     virtual void SAL_CALL setBackup(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     243           0 :         { setStringProperty("Backup", p1); }
     244           0 :     virtual OUString SAL_CALL getBasic() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     245           0 :         { return getStringProperty("Basic"); }
     246           0 :     virtual void SAL_CALL setBasic(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     247           0 :         { setStringProperty("Basic", p1); }
     248           0 :     virtual OUString SAL_CALL getBitmap() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     249           0 :         { return getStringProperty("Bitmap"); }
     250           0 :     virtual void SAL_CALL setBitmap(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     251           0 :         { setStringProperty("Bitmap", p1); }
     252           0 :     virtual OUString SAL_CALL getConfig() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     253           0 :         { return getStringProperty("Config"); }
     254           0 :     virtual void SAL_CALL setConfig(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     255           0 :         { setStringProperty("Config", p1); }
     256           0 :     virtual OUString SAL_CALL getDictionary() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     257           0 :         { return getStringProperty("Dictionary"); }
     258           0 :     virtual void SAL_CALL setDictionary(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     259           0 :         { setStringProperty("Dictionary", p1); }
     260           0 :     virtual OUString SAL_CALL getFavorite() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     261           0 :         { return getStringProperty("Favorite"); }
     262           0 :     virtual void SAL_CALL setFavorite(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     263           0 :         { setStringProperty("Favorite", p1); }
     264           0 :     virtual OUString SAL_CALL getFilter() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     265           0 :         { return getStringProperty("Filter"); }
     266           0 :     virtual void SAL_CALL setFilter(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     267           0 :         { setStringProperty("Filter", p1); }
     268           0 :     virtual OUString SAL_CALL getGallery() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     269           0 :         { return getStringProperty("Gallery"); }
     270           0 :     virtual void SAL_CALL setGallery(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     271           0 :         { setStringProperty("Gallery", p1); }
     272           0 :     virtual OUString SAL_CALL getGraphic() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     273           0 :         { return getStringProperty("Graphic"); }
     274           0 :     virtual void SAL_CALL setGraphic(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     275           0 :         { setStringProperty("Graphic", p1); }
     276           0 :     virtual OUString SAL_CALL getHelp() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     277           0 :         { return getStringProperty("Help"); }
     278           0 :     virtual void SAL_CALL setHelp(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     279           0 :         { setStringProperty("Help", p1); }
     280           0 :     virtual OUString SAL_CALL getLinguistic() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     281           0 :         { return getStringProperty("Linguistic"); }
     282           0 :     virtual void SAL_CALL setLinguistic(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     283           0 :         { setStringProperty("Linguistic", p1); }
     284           0 :     virtual OUString SAL_CALL getModule() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     285           0 :         { return getStringProperty("Module"); }
     286           0 :     virtual void SAL_CALL setModule(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     287           0 :         { setStringProperty("Module", p1); }
     288           0 :     virtual OUString SAL_CALL getPalette() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     289           0 :         { return getStringProperty("Palette"); }
     290           0 :     virtual void SAL_CALL setPalette(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     291           0 :         { setStringProperty("Palette", p1); }
     292           0 :     virtual OUString SAL_CALL getPlugin() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     293           0 :         { return getStringProperty("Plugin"); }
     294           0 :     virtual void SAL_CALL setPlugin(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     295           0 :         { setStringProperty("Plugin", p1); }
     296           0 :     virtual OUString SAL_CALL getStorage() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     297           0 :         { return getStringProperty("Storage"); }
     298           0 :     virtual void SAL_CALL setStorage(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     299           0 :         { setStringProperty("Storage", p1); }
     300           0 :     virtual OUString SAL_CALL getTemp() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     301           0 :         { return getStringProperty("Temp"); }
     302           0 :     virtual void SAL_CALL setTemp(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     303           0 :         { setStringProperty("Temp", p1); }
     304           0 :     virtual OUString SAL_CALL getTemplate() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     305           0 :         { return getStringProperty("Template"); }
     306           0 :     virtual void SAL_CALL setTemplate(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     307           0 :         { setStringProperty("Template", p1); }
     308           0 :     virtual OUString SAL_CALL getUIConfig() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     309           0 :         { return getStringProperty("UIConfig"); }
     310           0 :     virtual void SAL_CALL setUIConfig(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     311           0 :         { setStringProperty("UIConfig", p1); }
     312           0 :     virtual OUString SAL_CALL getUserConfig() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     313           0 :         { return getStringProperty("UserConfig"); }
     314           0 :     virtual void SAL_CALL setUserConfig(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     315           0 :         { setStringProperty("UserConfig", p1); }
     316           0 :     virtual OUString SAL_CALL getUserDictionary() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     317           0 :         { return getStringProperty("UserDictionary"); }
     318           0 :     virtual void SAL_CALL setUserDictionary(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     319           0 :         { setStringProperty("UserDictionary", p1); }
     320           0 :     virtual OUString SAL_CALL getWork() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     321           0 :         { return getStringProperty("Work"); }
     322           0 :     virtual void SAL_CALL setWork(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     323           0 :         { setStringProperty("Work", p1); }
     324        1877 :     virtual OUString SAL_CALL getBasePathShareLayer() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     325        1877 :         { return getStringProperty("UIConfig"); }
     326           0 :     virtual void SAL_CALL setBasePathShareLayer(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     327           0 :         { setStringProperty("UIConfig", p1); }
     328         107 :     virtual OUString SAL_CALL getBasePathUserLayer() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     329         107 :         { return getStringProperty("UserConfig"); }
     330           0 :     virtual void SAL_CALL setBasePathUserLayer(const OUString& p1) throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     331           0 :         { setStringProperty("UserConfig", p1); }
     332             : 
     333             :     /**
     334             :      * overrides to resolve inheritance ambiguity
     335             :      */
     336           0 :     virtual void SAL_CALL setPropertyValue(const OUString& p1, const css::uno::Any& p2)
     337             :         throw (css::beans::UnknownPropertyException, css::beans::PropertyVetoException, css::lang::IllegalArgumentException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     338           0 :         { ::cppu::OPropertySetHelper::setPropertyValue(p1, p2); }
     339         691 :     virtual css::uno::Any SAL_CALL getPropertyValue(const OUString& p1)
     340             :         throw (css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     341         691 :         { return ::cppu::OPropertySetHelper::getPropertyValue(p1); }
     342           0 :     virtual void SAL_CALL addPropertyChangeListener(const OUString& p1, const css::uno::Reference<css::beans::XPropertyChangeListener>& p2)
     343             :         throw (css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     344           0 :         { ::cppu::OPropertySetHelper::addPropertyChangeListener(p1, p2); }
     345           0 :     virtual void SAL_CALL removePropertyChangeListener(const OUString& p1, const css::uno::Reference<css::beans::XPropertyChangeListener>& p2)
     346             :         throw (css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     347           0 :         { ::cppu::OPropertySetHelper::removePropertyChangeListener(p1, p2); }
     348           0 :     virtual void SAL_CALL addVetoableChangeListener(const OUString& p1, const css::uno::Reference<css::beans::XVetoableChangeListener>& p2)
     349             :         throw (css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     350           0 :         { ::cppu::OPropertySetHelper::addVetoableChangeListener(p1, p2); }
     351           0 :     virtual void SAL_CALL removeVetoableChangeListener(const OUString& p1, const css::uno::Reference<css::beans::XVetoableChangeListener>& p2)
     352             :         throw (css::beans::UnknownPropertyException, css::lang::WrappedTargetException, css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     353           0 :         { ::cppu::OPropertySetHelper::removeVetoableChangeListener(p1, p2); }
     354             :     /** read all configured paths and create all needed internal structures. */
     355             :     void impl_readAll();
     356             : 
     357             : private:
     358             :     virtual void SAL_CALL disposing() SAL_OVERRIDE;
     359             : 
     360             :     OUString getStringProperty(const OUString& p1)
     361             :         throw(css::uno::RuntimeException);
     362             : 
     363             :     void setStringProperty(const OUString& p1, const OUString& p2)
     364             :         throw(css::uno::RuntimeException);
     365             : 
     366             :     /** read a path info using the old cfg schema.
     367             :         This is needed for "migration on demand" reasons only.
     368             :         Can be removed for next major release .-) */
     369             :     OUStringList impl_readOldFormat(const OUString& sPath);
     370             : 
     371             :     /** read a path info using the new cfg schema. */
     372             :     PathSettings::PathInfo impl_readNewFormat(const OUString& sPath);
     373             : 
     374             :     /** filter "real user defined paths" from the old configuration schema
     375             :         and set it as UserPaths on the new schema.
     376             :         Can be removed with new major release ... */
     377             : 
     378             :     void impl_mergeOldUserPaths(      PathSettings::PathInfo& rPath,
     379             :                                  const OUStringList&           lOld );
     380             : 
     381             :     /** reload one path directly from the new configuration schema (because
     382             :         it was updated by any external code) */
     383             :     PathSettings::EChangeOp impl_updatePath(const OUString& sPath          ,
     384             :                                                   bool         bNotifyListener);
     385             : 
     386             :     /** replace all might existing placeholder variables inside the given path ...
     387             :         or check if the given path value uses paths, which can be replaced with predefined
     388             :         placeholder variables ...
     389             :      */
     390             :     void impl_subst(      OUStringList&                                          lVals   ,
     391             :                     const css::uno::Reference< css::util::XStringSubstitution >& xSubst  ,
     392             :                           bool                                               bReSubst);
     393             : 
     394             :     void impl_subst(PathSettings::PathInfo& aPath   ,
     395             :                     bool                bReSubst);
     396             : 
     397             :     /** converts our new string list schema to the old ";" separated schema ... */
     398             :     OUString impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath        ) const;
     399             :     OUStringList    impl_convertOldStyle2Path(const OUString&        sOldStylePath) const;
     400             : 
     401             :     /** remove still known paths from the given lList argument.
     402             :         So real user defined paths can be extracted from the list of
     403             :         fix internal paths !
     404             :      */
     405             :     void impl_purgeKnownPaths(PathSettings::PathInfo& rPath,
     406             :                               OUStringList&           lList);
     407             : 
     408             :     /** rebuild the member m_lPropDesc using the path list m_lPaths. */
     409             :     void impl_rebuildPropertyDescriptor();
     410             : 
     411             :     /** provides direct access to the list of path values
     412             :         using it's internal property id.
     413             :      */
     414             :     css::uno::Any impl_getPathValue(      sal_Int32      nID ) const;
     415             :     void          impl_setPathValue(      sal_Int32      nID ,
     416             :                                     const css::uno::Any& aVal);
     417             : 
     418             :     /** check the given handle and return the corresponding PathInfo reference.
     419             :         These reference can be used then directly to manipulate these path. */
     420             :           PathSettings::PathInfo* impl_getPathAccess     (sal_Int32 nHandle);
     421             :     const PathSettings::PathInfo* impl_getPathAccessConst(sal_Int32 nHandle) const;
     422             : 
     423             :     /** it checks, if the given path value seems to be a valid URL or system path. */
     424             :     bool impl_isValidPath(const OUString& sPath) const;
     425             :     bool impl_isValidPath(const OUStringList&    lPath) const;
     426             : 
     427             :     void impl_storePath(const PathSettings::PathInfo& aPath);
     428             : 
     429             :     css::uno::Sequence< sal_Int32 > impl_mapPathName2IDList(const OUString& sPath);
     430             : 
     431             :     void impl_notifyPropListener(      PathSettings::EChangeOp eOp     ,
     432             :                                        const OUString&        sPath   ,
     433             :                                        const PathSettings::PathInfo* pPathOld,
     434             :                                        const PathSettings::PathInfo* pPathNew);
     435             : 
     436             :     //  OPropertySetHelper
     437             :     virtual sal_Bool SAL_CALL convertFastPropertyValue( css::uno::Any&  aConvertedValue,
     438             :             css::uno::Any& aOldValue,
     439             :             sal_Int32 nHandle,
     440             :             const css::uno::Any& aValue ) throw(css::lang::IllegalArgumentException) SAL_OVERRIDE;
     441             :     virtual void SAL_CALL setFastPropertyValue_NoBroadcast( sal_Int32 nHandle,
     442             :             const css::uno::Any&  aValue ) throw(css::uno::Exception, std::exception) SAL_OVERRIDE;
     443             :     virtual void SAL_CALL getFastPropertyValue( css::uno::Any&  aValue,
     444             :             sal_Int32 nHandle ) const SAL_OVERRIDE;
     445             :     // Avoid:
     446             :     // warning: ‘virtual com::sun::star::uno::Any cppu::OPropertySetHelper::getFastPropertyValue(sal_Int32)’ was hidden [-Woverloaded-virtual]
     447             :     // warning:   by ‘virtual void {anonymous}::PathSettings::getFastPropertyValue(com::sun::star::uno::Any&, sal_Int32) const’ [-Woverloaded-virtual]
     448             :     using cppu::OPropertySetHelper::getFastPropertyValue;
     449             :     virtual ::cppu::IPropertyArrayHelper& SAL_CALL getInfoHelper() SAL_OVERRIDE;
     450             :     virtual css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo() throw(css::uno::RuntimeException, std::exception) SAL_OVERRIDE;
     451             : 
     452             :     /** factory methods to guarantee right (but on demand) initialized members ... */
     453             :     css::uno::Reference< css::util::XStringSubstitution > fa_getSubstitution();
     454             :     css::uno::Reference< css::container::XNameAccess >    fa_getCfgOld();
     455             :     css::uno::Reference< css::container::XNameAccess >    fa_getCfgNew();
     456             : };
     457             : 
     458         210 : PathSettings::PathSettings( const css::uno::Reference< css::uno::XComponentContext >& xContext )
     459             :     : PathSettings_BASE(m_aMutex)
     460             :     , ::cppu::OPropertySetHelper(cppu::WeakComponentImplHelperBase::rBHelper)
     461             :     ,   m_xContext (xContext)
     462             :     ,   m_pPropHelp(0    )
     463         210 :     ,  m_bIgnoreEvents(false)
     464             : {
     465         210 : }
     466             : 
     467         624 : PathSettings::~PathSettings()
     468             : {
     469         208 :     disposing();
     470         416 : }
     471             : 
     472         416 : void SAL_CALL PathSettings::disposing()
     473             : {
     474         416 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
     475             : 
     476             :     css::uno::Reference< css::util::XChangesNotifier >
     477         832 :         xBroadcaster(m_xCfgNew, css::uno::UNO_QUERY);
     478         416 :     if (xBroadcaster.is())
     479         208 :         xBroadcaster->removeChangesListener(m_xCfgNewListener);
     480             : 
     481         416 :     m_xSubstitution.clear();
     482         416 :     m_xCfgOld.clear();
     483         416 :     m_xCfgNew.clear();
     484         416 :     m_xCfgNewListener.clear();
     485             : 
     486         416 :     delete m_pPropHelp;
     487         832 :     m_pPropHelp = 0;
     488         416 : }
     489             : 
     490        3359 : css::uno::Any SAL_CALL PathSettings::queryInterface( const css::uno::Type& _rType )
     491             :     throw(css::uno::RuntimeException, std::exception)
     492             : {
     493        3359 :     css::uno::Any aRet = PathSettings_BASE::queryInterface( _rType );
     494        3359 :     if ( !aRet.hasValue() )
     495         210 :         aRet = ::cppu::OPropertySetHelper::queryInterface( _rType );
     496        3359 :     return aRet;
     497             : }
     498             : 
     499           0 : css::uno::Sequence< css::uno::Type > SAL_CALL PathSettings::getTypes(  )
     500             :     throw(css::uno::RuntimeException, std::exception)
     501             : {
     502             :     return comphelper::concatSequences(
     503             :         PathSettings_BASE::getTypes(),
     504             :         ::cppu::OPropertySetHelper::getTypes()
     505           0 :     );
     506             : }
     507             : 
     508           0 : void SAL_CALL PathSettings::changesOccurred(const css::util::ChangesEvent& aEvent)
     509             :     throw (css::uno::RuntimeException, std::exception)
     510             : {
     511           0 :     sal_Int32 c                 = aEvent.Changes.getLength();
     512           0 :     sal_Int32 i                 = 0;
     513           0 :     bool  bUpdateDescriptor = false;
     514             : 
     515           0 :     for (i=0; i<c; ++i)
     516             :     {
     517           0 :         const css::util::ElementChange& aChange = aEvent.Changes[i];
     518             : 
     519           0 :         OUString sChanged;
     520           0 :         aChange.Accessor >>= sChanged;
     521             : 
     522           0 :         OUString sPath = ::utl::extractFirstFromConfigurationPath(sChanged);
     523           0 :         if (!sPath.isEmpty())
     524             :         {
     525           0 :             PathSettings::EChangeOp eOp = impl_updatePath(sPath, true);
     526           0 :             if (
     527           0 :                 (eOp == PathSettings::E_ADDED  ) ||
     528             :                 (eOp == PathSettings::E_REMOVED)
     529             :                )
     530           0 :                 bUpdateDescriptor = true;
     531             :         }
     532           0 :     }
     533             : 
     534           0 :     if (bUpdateDescriptor)
     535           0 :         impl_rebuildPropertyDescriptor();
     536           0 : }
     537             : 
     538           0 : void SAL_CALL PathSettings::disposing(const css::lang::EventObject& aSource)
     539             :     throw(css::uno::RuntimeException, std::exception)
     540             : {
     541           0 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
     542             : 
     543           0 :     if (aSource.Source == m_xCfgNew)
     544           0 :         m_xCfgNew.clear();
     545           0 : }
     546             : 
     547        1984 : OUString PathSettings::getStringProperty(const OUString& p1)
     548             :     throw(css::uno::RuntimeException)
     549             : {
     550        1984 :     css::uno::Any a = ::cppu::OPropertySetHelper::getPropertyValue(p1);
     551        1984 :     OUString s;
     552        1984 :     a >>= s;
     553        1984 :     return s;
     554             : }
     555             : 
     556           0 : void PathSettings::setStringProperty(const OUString& p1, const OUString& p2)
     557             :     throw(css::uno::RuntimeException)
     558             : {
     559           0 :     ::cppu::OPropertySetHelper::setPropertyValue(p1, css::uno::Any(p2));
     560           0 : }
     561             : 
     562         210 : void PathSettings::impl_readAll()
     563             : {
     564             :     try
     565             :     {
     566             :         // TODO think about me
     567         210 :         css::uno::Reference< css::container::XNameAccess > xCfg    = fa_getCfgNew();
     568         420 :         css::uno::Sequence< OUString >              lPaths = xCfg->getElementNames();
     569             : 
     570         210 :         sal_Int32 c = lPaths.getLength();
     571        5250 :         for (sal_Int32 i = 0; i < c; ++i)
     572             :         {
     573        5040 :             const OUString& sPath = lPaths[i];
     574        5040 :             impl_updatePath(sPath, false);
     575         210 :         }
     576             :     }
     577           0 :     catch(const css::uno::RuntimeException& )
     578             :     {
     579             :     }
     580             : 
     581         210 :     impl_rebuildPropertyDescriptor();
     582         210 : }
     583             : 
     584             : // NO substitution here ! It's done outside ...
     585        5040 : OUStringList PathSettings::impl_readOldFormat(const OUString& sPath)
     586             : {
     587        5040 :     css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
     588        5040 :     OUStringList aPathVal;
     589             : 
     590        5040 :     if( xCfg->hasByName(sPath) )
     591             :     {
     592        4830 :         css::uno::Any aVal( xCfg->getByName(sPath) );
     593             : 
     594        9660 :         OUString                       sStringVal;
     595        9660 :         css::uno::Sequence< OUString > lStringListVal;
     596             : 
     597        4830 :         if (aVal >>= sStringVal)
     598             :         {
     599        3150 :             aPathVal.push_back(sStringVal);
     600             :         }
     601        1680 :         else if (aVal >>= lStringListVal)
     602             :         {
     603        1680 :             aPathVal = comphelper::sequenceToContainer<OUStringList>(lStringListVal);
     604        4830 :         }
     605             :     }
     606             : 
     607        5040 :     return aPathVal;
     608             : }
     609             : 
     610             : // NO substitution here ! It's done outside ...
     611        5040 : PathSettings::PathInfo PathSettings::impl_readNewFormat(const OUString& sPath)
     612             : {
     613        5040 :     const OUString CFGPROP_INTERNALPATHS("InternalPaths");
     614       10080 :     const OUString CFGPROP_ISSINGLEPATH("IsSinglePath");
     615             : 
     616       10080 :     css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
     617             : 
     618             :     // get access to the "queried" path
     619       10080 :     css::uno::Reference< css::container::XNameAccess > xPath;
     620        5040 :     xCfg->getByName(sPath) >>= xPath;
     621             : 
     622        5040 :     PathSettings::PathInfo aPathVal;
     623             : 
     624             :     // read internal path list
     625       10080 :     css::uno::Reference< css::container::XNameAccess > xIPath;
     626        5040 :     xPath->getByName(CFGPROP_INTERNALPATHS) >>= xIPath;
     627        5040 :     aPathVal.lInternalPaths = comphelper::sequenceToContainer<OUStringList>(xIPath->getElementNames());
     628             : 
     629             :     // read user defined path list
     630       10080 :     css::uno::Sequence<OUString> vTmpUserPathsSeq;
     631        5040 :     xPath->getByName(CFGPROP_USERPATHS) >>= vTmpUserPathsSeq;
     632        5040 :     aPathVal.lUserPaths = comphelper::sequenceToContainer<OUStringList>(vTmpUserPathsSeq);
     633             : 
     634             :     // read the writeable path
     635        5040 :     xPath->getByName(CFGPROP_WRITEPATH) >>= aPathVal.sWritePath;
     636             : 
     637             :     // avoid duplicates, by removing the writeable path from
     638             :     // the user defined path list if it happens to be there too
     639        5040 :     OUStringList::iterator aI = find(aPathVal.lUserPaths, aPathVal.sWritePath);
     640        5040 :     if (aI != aPathVal.lUserPaths.end())
     641         210 :         aPathVal.lUserPaths.erase(aI);
     642             : 
     643             :     // read state props
     644        5040 :     xPath->getByName(CFGPROP_ISSINGLEPATH) >>= aPathVal.bIsSinglePath;
     645             : 
     646             :     // analyze finalized/mandatory states
     647        5040 :     aPathVal.bIsReadonly = false;
     648       10080 :     css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
     649        5040 :     if (xInfo.is())
     650             :     {
     651        5040 :         css::beans::Property aInfo = xInfo->getAsProperty();
     652        5040 :         bool bFinalized = ((aInfo.Attributes & css::beans::PropertyAttribute::READONLY  ) == css::beans::PropertyAttribute::READONLY  );
     653             : 
     654             :         // Note: 'till we support finalized/mandatory on our API more in detail we handle
     655             :         // all states simple as READONLY! But because all really needed paths are "mandatory" by default
     656             :         // we have to handle "finalized" as the real "readonly" indicator.
     657        5040 :         aPathVal.bIsReadonly = bFinalized;
     658             :     }
     659             : 
     660       10080 :     return aPathVal;
     661             : }
     662             : 
     663           0 : void PathSettings::impl_storePath(const PathSettings::PathInfo& aPath)
     664             : {
     665           0 :     m_bIgnoreEvents = true;
     666             : 
     667           0 :     css::uno::Reference< css::container::XNameAccess > xCfgNew = fa_getCfgNew();
     668           0 :     css::uno::Reference< css::container::XNameAccess > xCfgOld = fa_getCfgOld();
     669             : 
     670             :     // try to replace path-parts with well known and supported variables.
     671             :     // So an office can be moved easialy to another location without losing
     672             :     // it's related paths.
     673           0 :     PathInfo aResubstPath(aPath);
     674           0 :     impl_subst(aResubstPath, true);
     675             : 
     676             :     // update new configuration
     677           0 :     if (! aResubstPath.bIsSinglePath)
     678             :     {
     679             :         ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
     680             :                                                             aResubstPath.sPathName,
     681             :                                                             CFGPROP_USERPATHS,
     682           0 :                             css::uno::makeAny(comphelper::containerToSequence(aResubstPath.lUserPaths)));
     683             :     }
     684             : 
     685             :     ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
     686             :                                                         aResubstPath.sPathName,
     687             :                                                         CFGPROP_WRITEPATH,
     688           0 :                                                         css::uno::makeAny(aResubstPath.sWritePath));
     689             : 
     690           0 :     ::comphelper::ConfigurationHelper::flush(xCfgNew);
     691             : 
     692             :     // remove the whole path from the old configuration!
     693             :     // Otherwise we can't make sure that the diff between new and old configuration
     694             :     // on loading time really represents a user setting!!!
     695             : 
     696             :     // Check if the given path exists inside the old configuration.
     697             :     // Because our new configuration knows more than the list of old paths ... !
     698           0 :     if (xCfgOld->hasByName(aResubstPath.sPathName))
     699             :     {
     700           0 :         css::uno::Reference< css::beans::XPropertySet > xProps(xCfgOld, css::uno::UNO_QUERY_THROW);
     701           0 :         xProps->setPropertyValue(aResubstPath.sPathName, css::uno::Any());
     702           0 :         ::comphelper::ConfigurationHelper::flush(xCfgOld);
     703             :     }
     704             : 
     705           0 :     m_bIgnoreEvents = false;
     706           0 : }
     707             : 
     708        5040 : void PathSettings::impl_mergeOldUserPaths(      PathSettings::PathInfo& rPath,
     709             :                                           const OUStringList&           lOld )
     710             : {
     711        5040 :     OUStringList::const_iterator pIt;
     712       34020 :     for (  pIt  = lOld.begin();
     713       22680 :            pIt != lOld.end();
     714             :          ++pIt                )
     715             :     {
     716        6300 :         const OUString& sOld = *pIt;
     717             : 
     718        6300 :         if (rPath.bIsSinglePath)
     719             :         {
     720             :             SAL_WARN_IF(lOld.size()>1, "fwk", "PathSettings::impl_mergeOldUserPaths(): Single path has more than one path value inside old configuration (Common.xcu)!");
     721        1050 :             if (! rPath.sWritePath.equals(sOld))
     722           0 :                rPath.sWritePath = sOld;
     723             :         }
     724             :         else
     725             :         {
     726       10500 :             if (
     727       31533 :                 (  find(rPath.lInternalPaths, sOld) == rPath.lInternalPaths.end()) &&
     728       31533 :                 (  find(rPath.lUserPaths, sOld)     == rPath.lUserPaths.end()    ) &&
     729        1761 :                 (! rPath.sWritePath.equals(sOld)                                     )
     730             :                )
     731          81 :                rPath.lUserPaths.push_back(sOld);
     732             :         }
     733             :     }
     734        5040 : }
     735             : 
     736        5040 : PathSettings::EChangeOp PathSettings::impl_updatePath(const OUString& sPath          ,
     737             :                                                             bool         bNotifyListener)
     738             : {
     739             :     // SAFE ->
     740        5040 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
     741             : 
     742        5040 :     PathSettings::PathInfo* pPathOld = 0;
     743        5040 :     PathSettings::PathInfo* pPathNew = 0;
     744        5040 :     PathSettings::EChangeOp eOp      = PathSettings::E_UNDEFINED;
     745       10080 :     PathSettings::PathInfo  aPath;
     746             : 
     747             :     try
     748             :     {
     749        5040 :         aPath = impl_readNewFormat(sPath);
     750        5040 :         aPath.sPathName = sPath;
     751             :         // replace all might existing variables with real values
     752             :         // Do it before these old paths will be compared against the
     753             :         // new path configuration. Otherwise some striungs uses different variables ... but substitution
     754             :         // will produce strings with same content (because some variables are redundant!)
     755        5040 :         impl_subst(aPath, false);
     756             :     }
     757           0 :     catch(const css::uno::RuntimeException&)
     758           0 :         { throw; }
     759           0 :     catch(const css::container::NoSuchElementException&)
     760           0 :         { eOp = PathSettings::E_REMOVED; }
     761           0 :     catch(const css::uno::Exception&)
     762           0 :         { throw; }
     763             : 
     764             :     try
     765             :     {
     766             :         // migration of old user defined values on demand
     767             :         // can be disabled for a new major
     768        5040 :         OUStringList lOldVals = impl_readOldFormat(sPath);
     769             :         // replace all might existing variables with real values
     770             :         // Do it before these old paths will be compared against the
     771             :         // new path configuration. Otherwise some striungs uses different variables ... but substitution
     772             :         // will produce strings with same content (because some variables are redundant!)
     773        5040 :         impl_subst(lOldVals, fa_getSubstitution(), false);
     774        5040 :         impl_mergeOldUserPaths(aPath, lOldVals);
     775             :     }
     776           0 :     catch(const css::uno::RuntimeException&)
     777           0 :         { throw; }
     778             :     // Normal(!) exceptions can be ignored!
     779             :     // E.g. in case an addon installs a new path, which was not well known for an OOo 1.x installation
     780             :     // we can't find a value for it inside the "old" configuration. So a NoSuchElementException
     781             :     // will be normal .-)
     782           0 :     catch(const css::uno::Exception&)
     783             :         {}
     784             : 
     785        5040 :     PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
     786        5040 :     if (eOp == PathSettings::E_UNDEFINED)
     787             :     {
     788        5040 :         if (pPath != m_lPaths.end())
     789           0 :             eOp = PathSettings::E_CHANGED;
     790             :         else
     791        5040 :             eOp = PathSettings::E_ADDED;
     792             :     }
     793             : 
     794        5040 :     switch(eOp)
     795             :     {
     796             :         case PathSettings::E_ADDED :
     797             :              {
     798        5040 :                 if (bNotifyListener)
     799             :                 {
     800           0 :                     pPathOld = 0;
     801           0 :                     pPathNew = &aPath;
     802           0 :                     impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     803             :                 }
     804        5040 :                 m_lPaths[sPath] = aPath;
     805             :              }
     806        5040 :              break;
     807             : 
     808             :         case PathSettings::E_CHANGED :
     809             :              {
     810           0 :                 if (bNotifyListener)
     811             :                 {
     812           0 :                     pPathOld = &(pPath->second);
     813           0 :                     pPathNew = &aPath;
     814           0 :                     impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     815             :                 }
     816           0 :                 m_lPaths[sPath] = aPath;
     817             :              }
     818           0 :              break;
     819             : 
     820             :         case PathSettings::E_REMOVED :
     821             :              {
     822           0 :                 if (pPath != m_lPaths.end())
     823             :                 {
     824           0 :                     if (bNotifyListener)
     825             :                     {
     826           0 :                         pPathOld = &(pPath->second);
     827           0 :                         pPathNew = 0;
     828           0 :                         impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     829             :                     }
     830           0 :                     m_lPaths.erase(pPath);
     831             :                 }
     832             :              }
     833           0 :              break;
     834             : 
     835             :         default: // to let compiler be happy
     836           0 :              break;
     837             :     }
     838             : 
     839       10080 :     return eOp;
     840             : }
     841             : 
     842           0 : css::uno::Sequence< sal_Int32 > PathSettings::impl_mapPathName2IDList(const OUString& sPath)
     843             : {
     844           0 :     OUString sOldStyleProp = sPath;
     845           0 :     OUString sInternalProp = sPath+POSTFIX_INTERNAL_PATHS;
     846           0 :     OUString sUserProp     = sPath+POSTFIX_USER_PATHS;
     847           0 :     OUString sWriteProp    = sPath+POSTFIX_WRITE_PATH;
     848             : 
     849             :     // Attention: The default set of IDs is fix and must follow these schema.
     850             :     // Otherwhise the outside code ant work for new added properties.
     851             :     // Why?
     852             :     // The outside code must fire N events for every changed property.
     853             :     // And the knowing about packaging of variables of the structure PathInfo
     854             :     // follow these group IDs! But if such ID is not in the range of [0..IDGROUP_COUNT]
     855             :     // the outside can't determine the right group ... and can not fire the right events .-)
     856             : 
     857           0 :     css::uno::Sequence< sal_Int32 > lIDs(IDGROUP_COUNT);
     858           0 :     lIDs[0] = IDGROUP_OLDSTYLE;
     859           0 :     lIDs[1] = IDGROUP_INTERNAL_PATHS;
     860           0 :     lIDs[2] = IDGROUP_USER_PATHS;
     861           0 :     lIDs[3] = IDGROUP_WRITE_PATH;
     862             : 
     863           0 :     sal_Int32 c = m_lPropDesc.getLength();
     864           0 :     sal_Int32 i = 0;
     865           0 :     for (i=0; i<c; ++i)
     866             :     {
     867           0 :         const css::beans::Property& rProp = m_lPropDesc[i];
     868             : 
     869           0 :         if (rProp.Name.equals(sOldStyleProp))
     870           0 :             lIDs[IDGROUP_OLDSTYLE] = rProp.Handle;
     871             :         else
     872           0 :         if (rProp.Name.equals(sInternalProp))
     873           0 :             lIDs[IDGROUP_INTERNAL_PATHS] = rProp.Handle;
     874             :         else
     875           0 :         if (rProp.Name.equals(sUserProp))
     876           0 :             lIDs[IDGROUP_USER_PATHS] = rProp.Handle;
     877             :         else
     878           0 :         if (rProp.Name.equals(sWriteProp))
     879           0 :             lIDs[IDGROUP_WRITE_PATH] = rProp.Handle;
     880             :     }
     881             : 
     882           0 :     return lIDs;
     883             : }
     884             : 
     885           0 : void PathSettings::impl_notifyPropListener(      PathSettings::EChangeOp /*eOp*/     ,
     886             :                                            const OUString&        sPath   ,
     887             :                                            const PathSettings::PathInfo* pPathOld,
     888             :                                            const PathSettings::PathInfo* pPathNew)
     889             : {
     890           0 :     css::uno::Sequence< sal_Int32 >     lHandles(1);
     891           0 :     css::uno::Sequence< css::uno::Any > lOldVals(1);
     892           0 :     css::uno::Sequence< css::uno::Any > lNewVals(1);
     893             : 
     894           0 :     css::uno::Sequence< sal_Int32 > lIDs   = impl_mapPathName2IDList(sPath);
     895           0 :     sal_Int32                       c      = lIDs.getLength();
     896           0 :     sal_Int32                       i      = 0;
     897           0 :     sal_Int32                       nMaxID = m_lPropDesc.getLength()-1;
     898           0 :     for (i=0; i<c; ++i)
     899             :     {
     900           0 :         sal_Int32 nID = lIDs[i];
     901             : 
     902           0 :         if (
     903           0 :             (nID < 0     ) ||
     904             :             (nID > nMaxID)
     905             :            )
     906           0 :            continue;
     907             : 
     908           0 :         lHandles[0] = nID;
     909           0 :         switch(impl_getPropGroup(nID))
     910             :         {
     911             :             case IDGROUP_OLDSTYLE :
     912             :                  {
     913           0 :                     if (pPathOld)
     914             :                     {
     915           0 :                         OUString sVal = impl_convertPath2OldStyle(*pPathOld);
     916           0 :                         lOldVals[0] <<= sVal;
     917             :                     }
     918           0 :                     if (pPathNew)
     919             :                     {
     920           0 :                         OUString sVal = impl_convertPath2OldStyle(*pPathNew);
     921           0 :                         lNewVals[0] <<= sVal;
     922             :                     }
     923             :                  }
     924           0 :                  break;
     925             : 
     926             :             case IDGROUP_INTERNAL_PATHS :
     927             :                  {
     928           0 :                     if (pPathOld)
     929           0 :                         lOldVals[0] <<= comphelper::containerToSequence(pPathOld->lInternalPaths);
     930           0 :                     if (pPathNew)
     931           0 :                         lNewVals[0] <<= comphelper::containerToSequence(pPathNew->lInternalPaths);
     932             :                  }
     933           0 :                  break;
     934             : 
     935             :             case IDGROUP_USER_PATHS :
     936             :                  {
     937           0 :                     if (pPathOld)
     938           0 :                         lOldVals[0] <<= comphelper::containerToSequence(pPathOld->lUserPaths);
     939           0 :                     if (pPathNew)
     940           0 :                         lNewVals[0] <<= comphelper::containerToSequence(pPathNew->lUserPaths);
     941             :                  }
     942           0 :                  break;
     943             : 
     944             :             case IDGROUP_WRITE_PATH :
     945             :                  {
     946           0 :                     if (pPathOld)
     947           0 :                         lOldVals[0] <<= pPathOld->sWritePath;
     948           0 :                     if (pPathNew)
     949           0 :                         lNewVals[0] <<= pPathNew->sWritePath;
     950             :                  }
     951           0 :                  break;
     952             :         }
     953             : 
     954             :         fire(lHandles.getArray(),
     955           0 :              lNewVals.getArray(),
     956           0 :              lOldVals.getArray(),
     957             :              1,
     958           0 :              sal_False);
     959           0 :     }
     960           0 : }
     961             : 
     962       15120 : void PathSettings::impl_subst(      OUStringList&                                          lVals   ,
     963             :                               const css::uno::Reference< css::util::XStringSubstitution >& xSubst  ,
     964             :                                     bool                                               bReSubst)
     965             : {
     966       15120 :     OUStringList::iterator pIt;
     967             : 
     968       76860 :     for (  pIt  = lVals.begin();
     969       51240 :            pIt != lVals.end();
     970             :          ++pIt                 )
     971             :     {
     972       10500 :         const OUString& sOld = *pIt;
     973       10500 :               OUString  sNew;
     974       10500 :         if (bReSubst)
     975           0 :             sNew = xSubst->reSubstituteVariables(sOld);
     976             :         else
     977       10500 :             sNew = xSubst->substituteVariables(sOld, sal_False);
     978             : 
     979       10500 :         *pIt = sNew;
     980       10500 :     }
     981       15120 : }
     982             : 
     983        5040 : void PathSettings::impl_subst(PathSettings::PathInfo& aPath   ,
     984             :                               bool                bReSubst)
     985             : {
     986        5040 :     css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();
     987             : 
     988        5040 :     impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
     989        5040 :     impl_subst(aPath.lUserPaths    , xSubst, bReSubst);
     990        5040 :     if (bReSubst)
     991           0 :         aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
     992             :     else
     993        5040 :         aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, sal_False);
     994        5040 : }
     995             : 
     996       19590 : OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
     997             : {
     998       19590 :     OUStringList::const_iterator pIt;
     999       19590 :     OUStringList                 lTemp;
    1000       19590 :     lTemp.reserve(rPath.lInternalPaths.size() + rPath.lUserPaths.size() + 1);
    1001             : 
    1002      112923 :     for (  pIt  = rPath.lInternalPaths.begin();
    1003       75282 :            pIt != rPath.lInternalPaths.end();
    1004             :          ++pIt                                 )
    1005             :     {
    1006       18051 :         lTemp.push_back(*pIt);
    1007             :     }
    1008       59352 :     for (  pIt  = rPath.lUserPaths.begin();
    1009       39568 :            pIt != rPath.lUserPaths.end();
    1010             :          ++pIt                             )
    1011             :     {
    1012         194 :         lTemp.push_back(*pIt);
    1013             :     }
    1014             : 
    1015       19590 :     if (!rPath.sWritePath.isEmpty())
    1016       17525 :         lTemp.push_back(rPath.sWritePath);
    1017             : 
    1018       39180 :     OUStringBuffer sPathVal(256);
    1019      130310 :     for (  pIt  = lTemp.begin();
    1020      110720 :            pIt != lTemp.end();
    1021             :                                )
    1022             :     {
    1023       35770 :         sPathVal.append(*pIt);
    1024       35770 :         ++pIt;
    1025       35770 :         if (pIt != lTemp.end())
    1026       16180 :             sPathVal.appendAscii(";");
    1027             :     }
    1028             : 
    1029       39180 :     return sPathVal.makeStringAndClear();
    1030             : }
    1031             : 
    1032           0 : OUStringList PathSettings::impl_convertOldStyle2Path(const OUString& sOldStylePath) const
    1033             : {
    1034           0 :     OUStringList lList;
    1035           0 :     sal_Int32    nToken = 0;
    1036           0 :     do
    1037             :     {
    1038           0 :         OUString sToken = sOldStylePath.getToken(0, ';', nToken);
    1039           0 :         if (!sToken.isEmpty())
    1040           0 :             lList.push_back(sToken);
    1041             :     }
    1042           0 :     while(nToken >= 0);
    1043             : 
    1044           0 :     return lList;
    1045             : }
    1046             : 
    1047           0 : void PathSettings::impl_purgeKnownPaths(PathSettings::PathInfo& rPath,
    1048             :                                         OUStringList&           lList)
    1049             : {
    1050           0 :     OUStringList::iterator pIt;
    1051             : 
    1052             :     // Erase items in the internal path list from lList.
    1053             :     // Also erase items in the internal path list from the user path list.
    1054           0 :     for (  pIt  = rPath.lInternalPaths.begin();
    1055           0 :            pIt != rPath.lInternalPaths.end();
    1056             :          ++pIt                                 )
    1057             :     {
    1058           0 :         const OUString& rItem = *pIt;
    1059           0 :         OUStringList::iterator pItem = find(lList, rItem);
    1060           0 :         if (pItem != lList.end())
    1061           0 :             lList.erase(pItem);
    1062           0 :         pItem = find(rPath.lUserPaths, rItem);
    1063           0 :         if (pItem != rPath.lUserPaths.end())
    1064           0 :             rPath.lUserPaths.erase(pItem);
    1065             :     }
    1066             : 
    1067             :     // Erase itsems not in lList from the user path list.
    1068           0 :     pIt = rPath.lUserPaths.begin();
    1069           0 :     while ( pIt != rPath.lUserPaths.end() )
    1070             :     {
    1071           0 :         const OUString& rItem = *pIt;
    1072           0 :         OUStringList::iterator pItem = find(lList, rItem);
    1073           0 :         if ( pItem == lList.end() )
    1074             :         {
    1075           0 :             rPath.lUserPaths.erase(pIt);
    1076           0 :             pIt = rPath.lUserPaths.begin();
    1077             :         }
    1078             :         else
    1079             :         {
    1080           0 :             ++pIt;
    1081             :         }
    1082             :     }
    1083             : 
    1084             :     // Erase items in the user path list from lList.
    1085           0 :     for (  pIt  = rPath.lUserPaths.begin();
    1086           0 :            pIt != rPath.lUserPaths.end();
    1087             :          ++pIt                             )
    1088             :     {
    1089           0 :         const OUString& rItem = *pIt;
    1090           0 :         OUStringList::iterator pItem = find(lList, rItem);
    1091           0 :         if (pItem != lList.end())
    1092           0 :             lList.erase(pItem);
    1093             :     }
    1094             : 
    1095             :     // Erase the write path from lList
    1096           0 :     OUStringList::iterator pItem = find(lList, rPath.sWritePath);
    1097           0 :     if (pItem != lList.end())
    1098           0 :         lList.erase(pItem);
    1099           0 : }
    1100             : 
    1101         210 : void PathSettings::impl_rebuildPropertyDescriptor()
    1102             : {
    1103             :     // SAFE ->
    1104         210 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1105             : 
    1106         210 :     sal_Int32 c = (sal_Int32)m_lPaths.size();
    1107         210 :     sal_Int32 i = 0;
    1108         210 :     m_lPropDesc.realloc(c*IDGROUP_COUNT);
    1109             : 
    1110         210 :     PathHash::const_iterator pIt;
    1111       15750 :     for (  pIt  = m_lPaths.begin();
    1112       10500 :            pIt != m_lPaths.end();
    1113             :          ++pIt                     )
    1114             :     {
    1115        5040 :         const PathSettings::PathInfo& rPath = pIt->second;
    1116        5040 :               css::beans::Property*   pProp = 0;
    1117             : 
    1118        5040 :         pProp             = &(m_lPropDesc[i]);
    1119        5040 :         pProp->Name       = rPath.sPathName;
    1120        5040 :         pProp->Handle     = i;
    1121        5040 :         pProp->Type       = cppu::UnoType<OUString>::get();
    1122        5040 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
    1123        5040 :         if (rPath.bIsReadonly)
    1124           0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
    1125        5040 :         ++i;
    1126             : 
    1127        5040 :         pProp             = &(m_lPropDesc[i]);
    1128        5040 :         pProp->Name       = rPath.sPathName+POSTFIX_INTERNAL_PATHS;
    1129        5040 :         pProp->Handle     = i;
    1130        5040 :         pProp->Type       = cppu::UnoType<css::uno::Sequence< OUString >>::get();
    1131             :         pProp->Attributes = css::beans::PropertyAttribute::BOUND   |
    1132        5040 :                             css::beans::PropertyAttribute::READONLY;
    1133        5040 :         ++i;
    1134             : 
    1135        5040 :         pProp             = &(m_lPropDesc[i]);
    1136        5040 :         pProp->Name       = rPath.sPathName+POSTFIX_USER_PATHS;
    1137        5040 :         pProp->Handle     = i;
    1138        5040 :         pProp->Type       = cppu::UnoType<css::uno::Sequence< OUString >>::get();
    1139        5040 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
    1140        5040 :         if (rPath.bIsReadonly)
    1141           0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
    1142        5040 :         ++i;
    1143             : 
    1144        5040 :         pProp             = &(m_lPropDesc[i]);
    1145        5040 :         pProp->Name       = rPath.sPathName+POSTFIX_WRITE_PATH;
    1146        5040 :         pProp->Handle     = i;
    1147        5040 :         pProp->Type       = cppu::UnoType<OUString>::get();
    1148        5040 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
    1149        5040 :         if (rPath.bIsReadonly)
    1150           0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
    1151        5040 :         ++i;
    1152             :     }
    1153             : 
    1154         210 :     delete m_pPropHelp;
    1155         210 :     m_pPropHelp = new ::cppu::OPropertyArrayHelper(m_lPropDesc, sal_False); // false => not sorted ... must be done inside helper
    1156             : 
    1157             :     // <- SAFE
    1158         210 : }
    1159             : 
    1160       19932 : css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
    1161             : {
    1162       19932 :     const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
    1163       19932 :     if (! pPath)
    1164           0 :         throw css::lang::IllegalArgumentException();
    1165             : 
    1166       19932 :     css::uno::Any aVal;
    1167       19932 :     switch(impl_getPropGroup(nID))
    1168             :     {
    1169             :         case IDGROUP_OLDSTYLE :
    1170             :              {
    1171       19590 :                 OUString sVal = impl_convertPath2OldStyle(*pPath);
    1172       19590 :                 aVal <<= sVal;
    1173             :              }
    1174       19590 :              break;
    1175             : 
    1176             :         case IDGROUP_INTERNAL_PATHS :
    1177             :              {
    1178         114 :                 aVal <<= comphelper::containerToSequence(pPath->lInternalPaths);
    1179             :              }
    1180         114 :              break;
    1181             : 
    1182             :         case IDGROUP_USER_PATHS :
    1183             :              {
    1184         114 :                 aVal <<= comphelper::containerToSequence(pPath->lUserPaths);
    1185             :              }
    1186         114 :              break;
    1187             : 
    1188             :         case IDGROUP_WRITE_PATH :
    1189             :              {
    1190         114 :                 aVal <<= pPath->sWritePath;
    1191             :              }
    1192         114 :              break;
    1193             :     }
    1194             : 
    1195       19932 :     return aVal;
    1196             : }
    1197             : 
    1198           0 : void PathSettings::impl_setPathValue(      sal_Int32      nID ,
    1199             :                                      const css::uno::Any& aVal)
    1200             : {
    1201           0 :     PathSettings::PathInfo* pOrgPath = impl_getPathAccess(nID);
    1202           0 :     if (! pOrgPath)
    1203           0 :         throw css::container::NoSuchElementException();
    1204             : 
    1205             :     // We work on a copied path ... so we can be sure that errors during this operation
    1206             :     // does not make our internal cache invalid  .-)
    1207           0 :     PathSettings::PathInfo aChangePath(*pOrgPath);
    1208             : 
    1209           0 :     switch(impl_getPropGroup(nID))
    1210             :     {
    1211             :         case IDGROUP_OLDSTYLE :
    1212             :              {
    1213           0 :                 OUString sVal;
    1214           0 :                 aVal >>= sVal;
    1215           0 :                 OUStringList lList = impl_convertOldStyle2Path(sVal);
    1216           0 :                 impl_subst(lList, fa_getSubstitution(), false);
    1217           0 :                 impl_purgeKnownPaths(aChangePath, lList);
    1218           0 :                 if (! impl_isValidPath(lList))
    1219           0 :                     throw css::lang::IllegalArgumentException();
    1220             : 
    1221           0 :                 if (aChangePath.bIsSinglePath)
    1222             :                 {
    1223             :                     SAL_WARN_IF(lList.size()>1, "fwk", "PathSettings::impl_setPathValue(): You try to set more than path value for a defined SINGLE_PATH!");
    1224           0 :                     if ( !lList.empty() )
    1225           0 :                         aChangePath.sWritePath = *(lList.begin());
    1226             :                     else
    1227           0 :                         aChangePath.sWritePath.clear();
    1228             :                 }
    1229             :                 else
    1230             :                 {
    1231           0 :                     OUStringList::const_iterator pIt;
    1232           0 :                     for (  pIt  = lList.begin();
    1233           0 :                            pIt != lList.end();
    1234             :                          ++pIt                 )
    1235             :                     {
    1236           0 :                         aChangePath.lUserPaths.push_back(*pIt);
    1237             :                     }
    1238           0 :                 }
    1239             :              }
    1240           0 :              break;
    1241             : 
    1242             :         case IDGROUP_INTERNAL_PATHS :
    1243             :              {
    1244           0 :                 if (aChangePath.bIsSinglePath)
    1245             :                 {
    1246           0 :                     OUStringBuffer sMsg(256);
    1247           0 :                     sMsg.appendAscii("The path '"    );
    1248           0 :                     sMsg.append     (aChangePath.sPathName);
    1249           0 :                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths can't be set.");
    1250             :                     throw css::uno::Exception(sMsg.makeStringAndClear(),
    1251           0 :                                               static_cast< ::cppu::OWeakObject* >(this));
    1252             :                 }
    1253             : 
    1254           0 :                 css::uno::Sequence<OUString> lTmpList;
    1255           0 :                 aVal >>= lTmpList;
    1256           0 :                 OUStringList lList = comphelper::sequenceToContainer<OUStringList>(lTmpList);
    1257           0 :                 if (! impl_isValidPath(lList))
    1258           0 :                     throw css::lang::IllegalArgumentException();
    1259           0 :                 aChangePath.lInternalPaths = lList;
    1260             :              }
    1261           0 :              break;
    1262             : 
    1263             :         case IDGROUP_USER_PATHS :
    1264             :              {
    1265           0 :                 if (aChangePath.bIsSinglePath)
    1266             :                 {
    1267           0 :                     OUStringBuffer sMsg(256);
    1268           0 :                     sMsg.appendAscii("The path '"    );
    1269           0 :                     sMsg.append     (aChangePath.sPathName);
    1270           0 :                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths can't be set.");
    1271             :                     throw css::uno::Exception(sMsg.makeStringAndClear(),
    1272           0 :                                               static_cast< ::cppu::OWeakObject* >(this));
    1273             :                 }
    1274             : 
    1275           0 :                 css::uno::Sequence<OUString> lTmpList;
    1276           0 :                 aVal >>= lTmpList;
    1277           0 :                 OUStringList lList = comphelper::sequenceToContainer<OUStringList>(lTmpList);
    1278           0 :                 if (! impl_isValidPath(lList))
    1279           0 :                     throw css::lang::IllegalArgumentException();
    1280           0 :                 aChangePath.lUserPaths = lList;
    1281             :              }
    1282           0 :              break;
    1283             : 
    1284             :         case IDGROUP_WRITE_PATH :
    1285             :              {
    1286           0 :                 OUString sVal;
    1287           0 :                 aVal >>= sVal;
    1288           0 :                 if (! impl_isValidPath(sVal))
    1289           0 :                     throw css::lang::IllegalArgumentException();
    1290           0 :                 aChangePath.sWritePath = sVal;
    1291             :              }
    1292           0 :              break;
    1293             :     }
    1294             : 
    1295             :     // TODO check if path has at least one path value set
    1296             :     // At least it depends from the feature using this path, if an empty path list is allowed.
    1297             : 
    1298             :     // first we should try to store the changed (copied!) path ...
    1299             :     // In case an error occurs on saving time an exception is thrown ...
    1300             :     // If no exception occurs we can update our internal cache (means
    1301             :     // we can overwrite pOrgPath !
    1302           0 :     impl_storePath(aChangePath);
    1303           0 :     pOrgPath->takeOver(aChangePath);
    1304           0 : }
    1305             : 
    1306           0 : bool PathSettings::impl_isValidPath(const OUStringList& lPath) const
    1307             : {
    1308           0 :     OUStringList::const_iterator pIt;
    1309           0 :     for (  pIt  = lPath.begin();
    1310           0 :            pIt != lPath.end();
    1311             :          ++pIt                 )
    1312             :     {
    1313           0 :         const OUString& rVal = *pIt;
    1314           0 :         if (! impl_isValidPath(rVal))
    1315           0 :             return false;
    1316             :     }
    1317             : 
    1318           0 :     return true;
    1319             : }
    1320             : 
    1321           0 : bool PathSettings::impl_isValidPath(const OUString& sPath) const
    1322             : {
    1323             :     // allow empty path to reset a path.
    1324             : // idea by LLA to support empty paths
    1325             : //    if (sPath.getLength() == 0)
    1326             : //    {
    1327             : //        return sal_True;
    1328             : //    }
    1329             : 
    1330           0 :     return (! INetURLObject(sPath).HasError());
    1331             : }
    1332             : 
    1333       19932 : OUString impl_extractBaseFromPropName(const OUString& sPropName)
    1334             : {
    1335       19932 :     sal_Int32 i = sPropName.indexOf(POSTFIX_INTERNAL_PATHS);
    1336       19932 :     if (i > -1)
    1337         114 :         return sPropName.copy(0, i);
    1338       19818 :     i = sPropName.indexOf(POSTFIX_USER_PATHS);
    1339       19818 :     if (i > -1)
    1340         114 :         return sPropName.copy(0, i);
    1341       19704 :     i = sPropName.indexOf(POSTFIX_WRITE_PATH);
    1342       19704 :     if (i > -1)
    1343         114 :         return sPropName.copy(0, i);
    1344             : 
    1345       19590 :     return sPropName;
    1346             : }
    1347             : 
    1348           0 : PathSettings::PathInfo* PathSettings::impl_getPathAccess(sal_Int32 nHandle)
    1349             : {
    1350             :     // SAFE ->
    1351           0 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1352             : 
    1353           0 :     if (nHandle > (m_lPropDesc.getLength()-1))
    1354           0 :         return 0;
    1355             : 
    1356           0 :     const css::beans::Property&            rProp = m_lPropDesc[nHandle];
    1357           0 :           OUString                  sProp = impl_extractBaseFromPropName(rProp.Name);
    1358           0 :           PathSettings::PathHash::iterator rPath = m_lPaths.find(sProp);
    1359             : 
    1360           0 :     if (rPath != m_lPaths.end())
    1361           0 :        return &(rPath->second);
    1362             : 
    1363           0 :     return 0;
    1364             :     // <- SAFE
    1365             : }
    1366             : 
    1367       19932 : const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
    1368             : {
    1369             :     // SAFE ->
    1370       19932 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1371             : 
    1372       19932 :     if (nHandle > (m_lPropDesc.getLength()-1))
    1373           0 :         return 0;
    1374             : 
    1375       19932 :     const css::beans::Property&                  rProp = m_lPropDesc[nHandle];
    1376       39864 :           OUString                        sProp = impl_extractBaseFromPropName(rProp.Name);
    1377       19932 :           PathSettings::PathHash::const_iterator rPath = m_lPaths.find(sProp);
    1378             : 
    1379       19932 :     if (rPath != m_lPaths.end())
    1380       19932 :        return &(rPath->second);
    1381             : 
    1382       19932 :     return 0;
    1383             :     // <- SAFE
    1384             : }
    1385             : 
    1386           0 : sal_Bool SAL_CALL PathSettings::convertFastPropertyValue(      css::uno::Any& aConvertedValue,
    1387             :                                                                css::uno::Any& aOldValue      ,
    1388             :                                                                sal_Int32      nHandle        ,
    1389             :                                                          const css::uno::Any& aValue         )
    1390             :     throw(css::lang::IllegalArgumentException)
    1391             : {
    1392             :     // throws NoSuchElementException !
    1393           0 :     css::uno::Any aCurrentVal = impl_getPathValue(nHandle);
    1394             : 
    1395             :     return PropHelper::willPropertyBeChanged(
    1396             :                 aCurrentVal,
    1397             :                 aValue,
    1398             :                 aOldValue,
    1399           0 :                 aConvertedValue);
    1400             : }
    1401             : 
    1402           0 : void SAL_CALL PathSettings::setFastPropertyValue_NoBroadcast(      sal_Int32      nHandle,
    1403             :                                                              const css::uno::Any& aValue )
    1404             :     throw(css::uno::Exception, std::exception)
    1405             : {
    1406             :     // throws NoSuchElement- and IllegalArgumentException !
    1407           0 :     impl_setPathValue(nHandle, aValue);
    1408           0 : }
    1409             : 
    1410       19932 : void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
    1411             :                                                  sal_Int32      nHandle) const
    1412             : {
    1413       19932 :     aValue = impl_getPathValue(nHandle);
    1414       19932 : }
    1415             : 
    1416       22817 : ::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
    1417             : {
    1418       22817 :     return *m_pPropHelp;
    1419             : }
    1420             : 
    1421         210 : css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
    1422             :     throw(css::uno::RuntimeException, std::exception)
    1423             : {
    1424             :     return css::uno::Reference< css::beans::XPropertySetInfo >(
    1425         210 :             ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()));
    1426             : }
    1427             : 
    1428       10080 : css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
    1429             : {
    1430       10080 :     css::uno::Reference< css::util::XStringSubstitution > xSubst;
    1431             :     { // SAFE ->
    1432       10080 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1433       10080 :     xSubst = m_xSubstitution;
    1434             :     }
    1435             : 
    1436       10080 :     if (! xSubst.is())
    1437             :     {
    1438             :         // create the needed substitution service.
    1439             :         // We must replace all used variables inside readed path values.
    1440             :         // In case we can't do so ... the whole office can't work really.
    1441             :         // That's why it seems to be OK to throw a RuntimeException then.
    1442         210 :         xSubst = css::util::PathSubstitution::create(m_xContext);
    1443             : 
    1444             :         { // SAFE ->
    1445         210 :         osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1446         210 :         m_xSubstitution = xSubst;
    1447             :         }
    1448             :     }
    1449             : 
    1450       10080 :     return xSubst;
    1451             : }
    1452             : 
    1453        5040 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
    1454             : {
    1455        5040 :     const OUString CFG_NODE_OLD("org.openoffice.Office.Common/Path/Current");
    1456             : 
    1457        5040 :     css::uno::Reference< css::container::XNameAccess > xCfg;
    1458             :     { // SAFE ->
    1459        5040 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1460        5040 :     xCfg = m_xCfgOld;
    1461             :     } // <- SAFE
    1462             : 
    1463        5040 :     if (! xCfg.is())
    1464             :     {
    1465         420 :         xCfg = css::uno::Reference< css::container::XNameAccess >(
    1466             :                    ::comphelper::ConfigurationHelper::openConfig(
    1467             :                         m_xContext,
    1468             :                         CFG_NODE_OLD,
    1469             :                         ::comphelper::ConfigurationHelper::E_STANDARD), // not readonly! Sometimes we need write access there !!!
    1470         210 :                    css::uno::UNO_QUERY_THROW);
    1471             : 
    1472             :         { // SAFE ->
    1473         210 :         osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1474         210 :         m_xCfgOld = xCfg;
    1475             :         }
    1476             :     }
    1477             : 
    1478        5040 :     return xCfg;
    1479             : }
    1480             : 
    1481        5250 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
    1482             : {
    1483        5250 :     const OUString CFG_NODE_NEW("org.openoffice.Office.Paths/Paths");
    1484             : 
    1485        5250 :     css::uno::Reference< css::container::XNameAccess > xCfg;
    1486             :     { // SAFE ->
    1487        5250 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1488        5250 :     xCfg = m_xCfgNew;
    1489             :     } // <- SAFE
    1490             : 
    1491        5250 :     if (! xCfg.is())
    1492             :     {
    1493         420 :         xCfg = css::uno::Reference< css::container::XNameAccess >(
    1494             :                    ::comphelper::ConfigurationHelper::openConfig(
    1495             :                         m_xContext,
    1496             :                         CFG_NODE_NEW,
    1497             :                         ::comphelper::ConfigurationHelper::E_STANDARD),
    1498         210 :                    css::uno::UNO_QUERY_THROW);
    1499             : 
    1500             :         { // SAFE ->
    1501         210 :         osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1502         210 :         m_xCfgNew = xCfg;
    1503         210 :         m_xCfgNewListener = new WeakChangesListener(this);
    1504             :         }
    1505             : 
    1506         210 :         css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
    1507         210 :         xBroadcaster->addChangesListener(m_xCfgNewListener);
    1508             :     }
    1509             : 
    1510        5250 :     return xCfg;
    1511             : }
    1512             : 
    1513         210 : struct Instance {
    1514         210 :     explicit Instance(
    1515             :         css::uno::Reference<css::uno::XComponentContext> const & context):
    1516             :         instance(
    1517         210 :             static_cast<cppu::OWeakObject *>(new PathSettings(context)))
    1518             :     {
    1519             :         // fill cache
    1520             :         static_cast<PathSettings *>(static_cast<cppu::OWeakObject *>
    1521         210 :                 (instance.get()))->impl_readAll();
    1522         210 :     }
    1523             : 
    1524             :     css::uno::Reference<css::uno::XInterface> instance;
    1525             : };
    1526             : 
    1527             : struct Singleton:
    1528             :     public rtl::StaticWithArg<
    1529             :         Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
    1530             : {};
    1531             : 
    1532             : }
    1533             : 
    1534             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    1535         555 : com_sun_star_comp_framework_PathSettings_get_implementation(
    1536             :     css::uno::XComponentContext *context,
    1537             :     css::uno::Sequence<css::uno::Any> const &)
    1538             : {
    1539             :     return cppu::acquire(static_cast<cppu::OWeakObject *>(
    1540         555 :                 Singleton::get(context).instance.get()));
    1541             : }
    1542             : 
    1543             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11