LCOV - code coverage report
Current view: top level - framework/source/services - pathsettings.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 285 680 41.9 %
Date: 2014-11-03 Functions: 36 111 32.4 %
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       33879 : sal_Int32 impl_getPropGroup(sal_Int32 nID)
      74             : {
      75       33879 :     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       36744 :     struct PathInfo
      93             :     {
      94             :         public:
      95             : 
      96       22104 :             PathInfo()
      97             :                 : sPathName     ()
      98             :                 , lInternalPaths()
      99             :                 , lUserPaths    ()
     100             :                 , sWritePath    ()
     101             :                 , bIsSinglePath (false)
     102       22104 :                 , bIsReadonly   (false)
     103       22104 :             {}
     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           0 :     virtual OUString SAL_CALL getImplementationName()
     189             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     190             :     {
     191           0 :         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           0 :     virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
     201             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     202             :     {
     203           0 :         css::uno::Sequence< OUString > aSeq(1);
     204           0 :         aSeq[0] = OUString("com.sun.star.util.PathSettings");
     205           0 :         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       14206 :     virtual void SAL_CALL acquire() throw () SAL_OVERRIDE
     211       14206 :         { OWeakObject::acquire(); }
     212       14198 :     virtual void SAL_CALL release() throw () SAL_OVERRIDE
     213       14198 :         { 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        2430 :     virtual OUString SAL_CALL getBasePathShareLayer() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     325        2430 :         { 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         158 :     virtual OUString SAL_CALL getBasePathUserLayer() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     329         158 :         { 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        1198 :     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        1198 :         { 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         307 : 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         307 :     ,  m_bIgnoreEvents(false)
     464             : {
     465         307 : }
     466             : 
     467         909 : PathSettings::~PathSettings()
     468             : {
     469         303 :     disposing();
     470         606 : }
     471             : 
     472         606 : void SAL_CALL PathSettings::disposing()
     473             : {
     474         606 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
     475             : 
     476             :     css::uno::Reference< css::util::XChangesNotifier >
     477        1212 :         xBroadcaster(m_xCfgNew, css::uno::UNO_QUERY);
     478         606 :     if (xBroadcaster.is())
     479         303 :         xBroadcaster->removeChangesListener(m_xCfgNewListener);
     480             : 
     481         606 :     m_xSubstitution.clear();
     482         606 :     m_xCfgOld.clear();
     483         606 :     m_xCfgNew.clear();
     484         606 :     m_xCfgNewListener.clear();
     485             : 
     486         606 :     delete m_pPropHelp;
     487        1212 :     m_pPropHelp = 0;
     488         606 : }
     489             : 
     490        4786 : css::uno::Any SAL_CALL PathSettings::queryInterface( const css::uno::Type& _rType )
     491             :     throw(css::uno::RuntimeException, std::exception)
     492             : {
     493        4786 :     css::uno::Any aRet = PathSettings_BASE::queryInterface( _rType );
     494        4786 :     if ( !aRet.hasValue() )
     495         307 :         aRet = ::cppu::OPropertySetHelper::queryInterface( _rType );
     496        4786 :     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        2588 : OUString PathSettings::getStringProperty(const OUString& p1)
     548             :     throw(css::uno::RuntimeException)
     549             : {
     550        2588 :     css::uno::Any a = ::cppu::OPropertySetHelper::getPropertyValue(p1);
     551        2588 :     OUString s;
     552        2588 :     a >>= s;
     553        2588 :     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         307 : void PathSettings::impl_readAll()
     563             : {
     564             :     try
     565             :     {
     566             :         // TODO think about me
     567         307 :         css::uno::Reference< css::container::XNameAccess > xCfg    = fa_getCfgNew();
     568         614 :         css::uno::Sequence< OUString >              lPaths = xCfg->getElementNames();
     569             : 
     570         307 :         sal_Int32 c = lPaths.getLength();
     571        7675 :         for (sal_Int32 i = 0; i < c; ++i)
     572             :         {
     573        7368 :             const OUString& sPath = lPaths[i];
     574        7368 :             impl_updatePath(sPath, false);
     575         307 :         }
     576             :     }
     577           0 :     catch(const css::uno::RuntimeException& )
     578             :     {
     579             :     }
     580             : 
     581         307 :     impl_rebuildPropertyDescriptor();
     582         307 : }
     583             : 
     584             : // NO substitution here ! It's done outside ...
     585        7368 : OUStringList PathSettings::impl_readOldFormat(const OUString& sPath)
     586             : {
     587        7368 :     css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
     588        7368 :     OUStringList aPathVal;
     589             : 
     590        7368 :     if( xCfg->hasByName(sPath) )
     591             :     {
     592        7061 :         css::uno::Any aVal( xCfg->getByName(sPath) );
     593             : 
     594       14122 :         OUString                       sStringVal;
     595       14122 :         css::uno::Sequence< OUString > lStringListVal;
     596             : 
     597        7061 :         if (aVal >>= sStringVal)
     598             :         {
     599        4912 :             aPathVal.push_back(sStringVal);
     600             :         }
     601        2149 :         else if (aVal >>= lStringListVal)
     602             :         {
     603        2149 :             aPathVal << lStringListVal;
     604        7061 :         }
     605             :     }
     606             : 
     607        7368 :     return aPathVal;
     608             : }
     609             : 
     610             : // NO substitution here ! It's done outside ...
     611        7368 : PathSettings::PathInfo PathSettings::impl_readNewFormat(const OUString& sPath)
     612             : {
     613        7368 :     const OUString CFGPROP_INTERNALPATHS("InternalPaths");
     614       14736 :     const OUString CFGPROP_ISSINGLEPATH("IsSinglePath");
     615             : 
     616       14736 :     css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
     617             : 
     618             :     // get access to the "queried" path
     619       14736 :     css::uno::Reference< css::container::XNameAccess > xPath;
     620        7368 :     xCfg->getByName(sPath) >>= xPath;
     621             : 
     622        7368 :     PathSettings::PathInfo aPathVal;
     623             : 
     624             :     // read internal path list
     625       14736 :     css::uno::Reference< css::container::XNameAccess > xIPath;
     626        7368 :     xPath->getByName(CFGPROP_INTERNALPATHS) >>= xIPath;
     627        7368 :     aPathVal.lInternalPaths << xIPath->getElementNames();
     628             : 
     629             :     // read user defined path list
     630        7368 :     aPathVal.lUserPaths << xPath->getByName(CFGPROP_USERPATHS);
     631             : 
     632             :     // read the writeable path
     633        7368 :     xPath->getByName(CFGPROP_WRITEPATH) >>= aPathVal.sWritePath;
     634             : 
     635             :     // avoid duplicates, by removing the writeable path from
     636             :     // the user defined path list if it happens to be there too
     637        7368 :     OUStringList::iterator aI = aPathVal.lUserPaths.find(aPathVal.sWritePath);
     638        7368 :     if (aI != aPathVal.lUserPaths.end())
     639         307 :         aPathVal.lUserPaths.erase(aI);
     640             : 
     641             :     // read state props
     642        7368 :     xPath->getByName(CFGPROP_ISSINGLEPATH) >>= aPathVal.bIsSinglePath;
     643             : 
     644             :     // analyze finalized/mandatory states
     645        7368 :     aPathVal.bIsReadonly = false;
     646       14736 :     css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
     647        7368 :     if (xInfo.is())
     648             :     {
     649        7368 :         css::beans::Property aInfo = xInfo->getAsProperty();
     650        7368 :         bool bFinalized = ((aInfo.Attributes & css::beans::PropertyAttribute::READONLY  ) == css::beans::PropertyAttribute::READONLY  );
     651             : 
     652             :         // Note: Till we support finalized / mandatory on our API more in detail we handle
     653             :         // all states simple as READONLY ! But because all really needed paths are "mandatory" by default
     654             :         // we have to handle "finalized" as the real "readonly" indicator .
     655        7368 :         aPathVal.bIsReadonly = bFinalized;
     656             :     }
     657             : 
     658       14736 :     return aPathVal;
     659             : }
     660             : 
     661           0 : void PathSettings::impl_storePath(const PathSettings::PathInfo& aPath)
     662             : {
     663           0 :     m_bIgnoreEvents = true;
     664             : 
     665           0 :     css::uno::Reference< css::container::XNameAccess > xCfgNew = fa_getCfgNew();
     666           0 :     css::uno::Reference< css::container::XNameAccess > xCfgOld = fa_getCfgOld();
     667             : 
     668             :     // try to replace path-parts with well known and uspported variables.
     669             :     // So an office can be moved easialy to another location without loosing
     670             :     // it's related paths.
     671           0 :     PathInfo aResubstPath(aPath);
     672           0 :     impl_subst(aResubstPath, true);
     673             : 
     674             :     // update new configuration
     675           0 :     if (! aResubstPath.bIsSinglePath)
     676             :     {
     677             :         ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
     678             :                                                             aResubstPath.sPathName,
     679             :                                                             CFGPROP_USERPATHS,
     680           0 :                                                             css::uno::makeAny(aResubstPath.lUserPaths.getAsConstList()));
     681             :     }
     682             : 
     683             :     ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
     684             :                                                         aResubstPath.sPathName,
     685             :                                                         CFGPROP_WRITEPATH,
     686           0 :                                                         css::uno::makeAny(aResubstPath.sWritePath));
     687             : 
     688           0 :     ::comphelper::ConfigurationHelper::flush(xCfgNew);
     689             : 
     690             :     // remove the whole path from the old configuration !
     691             :     // Otherwise we can't make sure that the diff between new and old configuration
     692             :     // on loading time really represent an user setting !!!
     693             : 
     694             :     // Check if the given path exists inside the old configuration.
     695             :     // Because our new configuration knows more than the list of old paths ... !
     696           0 :     if (xCfgOld->hasByName(aResubstPath.sPathName))
     697             :     {
     698           0 :         css::uno::Reference< css::beans::XPropertySet > xProps(xCfgOld, css::uno::UNO_QUERY_THROW);
     699           0 :         xProps->setPropertyValue(aResubstPath.sPathName, css::uno::Any());
     700           0 :         ::comphelper::ConfigurationHelper::flush(xCfgOld);
     701             :     }
     702             : 
     703           0 :     m_bIgnoreEvents = false;
     704           0 : }
     705             : 
     706        7368 : void PathSettings::impl_mergeOldUserPaths(      PathSettings::PathInfo& rPath,
     707             :                                           const OUStringList&           lOld )
     708             : {
     709        7368 :     OUStringList::const_iterator pIt;
     710       48813 :     for (  pIt  = lOld.begin();
     711       32542 :            pIt != lOld.end();
     712             :          ++pIt                )
     713             :     {
     714        8903 :         const OUString& sOld = *pIt;
     715             : 
     716        8903 :         if (rPath.bIsSinglePath)
     717             :         {
     718             :             SAL_WARN_IF(lOld.size()>1, "fwk", "PathSettings::impl_mergeOldUserPaths(): Single path has more than one path value inside old configuration (Common.xcu)!");
     719        1535 :             if (! rPath.sWritePath.equals(sOld))
     720           0 :                rPath.sWritePath = sOld;
     721             :         }
     722             :         else
     723             :         {
     724       14736 :             if (
     725       44502 :                 (  rPath.lInternalPaths.findConst(sOld) == rPath.lInternalPaths.end()) &&
     726       44502 :                 (  rPath.lUserPaths.findConst(sOld)     == rPath.lUserPaths.end()    ) &&
     727        2554 :                 (! rPath.sWritePath.equals(sOld)                                     )
     728             :                )
     729          98 :                rPath.lUserPaths.push_back(sOld);
     730             :         }
     731             :     }
     732        7368 : }
     733             : 
     734        7368 : PathSettings::EChangeOp PathSettings::impl_updatePath(const OUString& sPath          ,
     735             :                                                             bool         bNotifyListener)
     736             : {
     737             :     // SAFE ->
     738        7368 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
     739             : 
     740        7368 :     PathSettings::PathInfo* pPathOld = 0;
     741        7368 :     PathSettings::PathInfo* pPathNew = 0;
     742        7368 :     PathSettings::EChangeOp eOp      = PathSettings::E_UNDEFINED;
     743       14736 :     PathSettings::PathInfo  aPath;
     744             : 
     745             :     try
     746             :     {
     747        7368 :         aPath = impl_readNewFormat(sPath);
     748        7368 :         aPath.sPathName = sPath;
     749             :         // replace all might existing variables with real values
     750             :         // Do it before these old paths will be compared against the
     751             :         // new path configuration. Otherwise some striungs uses different variables ... but substitution
     752             :         // will produce strings with same content (because some variables are redundant!)
     753        7368 :         impl_subst(aPath, false);
     754             :     }
     755           0 :     catch(const css::uno::RuntimeException&)
     756           0 :         { throw; }
     757           0 :     catch(const css::container::NoSuchElementException&)
     758           0 :         { eOp = PathSettings::E_REMOVED; }
     759           0 :     catch(const css::uno::Exception&)
     760           0 :         { throw; }
     761             : 
     762             :     try
     763             :     {
     764             :         // migration of old user defined values on demand
     765             :         // can be disabled for a new major
     766        7368 :         OUStringList lOldVals = impl_readOldFormat(sPath);
     767             :         // replace all might existing variables with real values
     768             :         // Do it before these old paths will be compared against the
     769             :         // new path configuration. Otherwise some striungs uses different variables ... but substitution
     770             :         // will produce strings with same content (because some variables are redundant!)
     771        7368 :         impl_subst(lOldVals, fa_getSubstitution(), false);
     772        7368 :         impl_mergeOldUserPaths(aPath, lOldVals);
     773             :     }
     774           0 :     catch(const css::uno::RuntimeException&)
     775           0 :         { throw; }
     776             :     // Normal(!) exceptions can be ignored!
     777             :     // E.g. in case an addon installs a new path, which was not well known for an OOo 1.x installation
     778             :     // we can't find a value for it inside the "old" configuration. So a NoSuchElementException
     779             :     // will be normal .-)
     780           0 :     catch(const css::uno::Exception&)
     781             :         {}
     782             : 
     783        7368 :     PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
     784        7368 :     if (eOp == PathSettings::E_UNDEFINED)
     785             :     {
     786        7368 :         if (pPath != m_lPaths.end())
     787           0 :             eOp = PathSettings::E_CHANGED;
     788             :         else
     789        7368 :             eOp = PathSettings::E_ADDED;
     790             :     }
     791             : 
     792        7368 :     switch(eOp)
     793             :     {
     794             :         case PathSettings::E_ADDED :
     795             :              {
     796        7368 :                 if (bNotifyListener)
     797             :                 {
     798           0 :                     pPathOld = 0;
     799           0 :                     pPathNew = &aPath;
     800           0 :                     impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     801             :                 }
     802        7368 :                 m_lPaths[sPath] = aPath;
     803             :              }
     804        7368 :              break;
     805             : 
     806             :         case PathSettings::E_CHANGED :
     807             :              {
     808           0 :                 if (bNotifyListener)
     809             :                 {
     810           0 :                     pPathOld = &(pPath->second);
     811           0 :                     pPathNew = &aPath;
     812           0 :                     impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     813             :                 }
     814           0 :                 m_lPaths[sPath] = aPath;
     815             :              }
     816           0 :              break;
     817             : 
     818             :         case PathSettings::E_REMOVED :
     819             :              {
     820           0 :                 if (pPath != m_lPaths.end())
     821             :                 {
     822           0 :                     if (bNotifyListener)
     823             :                     {
     824           0 :                         pPathOld = &(pPath->second);
     825           0 :                         pPathNew = 0;
     826           0 :                         impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     827             :                     }
     828           0 :                     m_lPaths.erase(pPath);
     829             :                 }
     830             :              }
     831           0 :              break;
     832             : 
     833             :         default: // to let compiler be happy
     834           0 :              break;
     835             :     }
     836             : 
     837       14736 :     return eOp;
     838             : }
     839             : 
     840           0 : css::uno::Sequence< sal_Int32 > PathSettings::impl_mapPathName2IDList(const OUString& sPath)
     841             : {
     842           0 :     OUString sOldStyleProp = sPath;
     843           0 :     OUString sInternalProp = sPath+POSTFIX_INTERNAL_PATHS;
     844           0 :     OUString sUserProp     = sPath+POSTFIX_USER_PATHS;
     845           0 :     OUString sWriteProp    = sPath+POSTFIX_WRITE_PATH;
     846             : 
     847             :     // Attention: The default set of IDs is fix and must follow these schema.
     848             :     // Otherwhise the outside code ant work for new added properties.
     849             :     // Why ?
     850             :     // The outside code must fire N events for every changed property.
     851             :     // And the knowing about packaging of variables of the structure PathInfo
     852             :     // follow these group IDs ! But if such ID isnt in the range of [0..IDGROUP_COUNT]
     853             :     // the outside can't determine the right group ... and cant fire the right events .-)
     854             : 
     855           0 :     css::uno::Sequence< sal_Int32 > lIDs(IDGROUP_COUNT);
     856           0 :     lIDs[0] = IDGROUP_OLDSTYLE;
     857           0 :     lIDs[1] = IDGROUP_INTERNAL_PATHS;
     858           0 :     lIDs[2] = IDGROUP_USER_PATHS;
     859           0 :     lIDs[3] = IDGROUP_WRITE_PATH;
     860             : 
     861           0 :     sal_Int32 c = m_lPropDesc.getLength();
     862           0 :     sal_Int32 i = 0;
     863           0 :     for (i=0; i<c; ++i)
     864             :     {
     865           0 :         const css::beans::Property& rProp = m_lPropDesc[i];
     866             : 
     867           0 :         if (rProp.Name.equals(sOldStyleProp))
     868           0 :             lIDs[IDGROUP_OLDSTYLE] = rProp.Handle;
     869             :         else
     870           0 :         if (rProp.Name.equals(sInternalProp))
     871           0 :             lIDs[IDGROUP_INTERNAL_PATHS] = rProp.Handle;
     872             :         else
     873           0 :         if (rProp.Name.equals(sUserProp))
     874           0 :             lIDs[IDGROUP_USER_PATHS] = rProp.Handle;
     875             :         else
     876           0 :         if (rProp.Name.equals(sWriteProp))
     877           0 :             lIDs[IDGROUP_WRITE_PATH] = rProp.Handle;
     878             :     }
     879             : 
     880           0 :     return lIDs;
     881             : }
     882             : 
     883           0 : void PathSettings::impl_notifyPropListener(      PathSettings::EChangeOp /*eOp*/     ,
     884             :                                            const OUString&        sPath   ,
     885             :                                            const PathSettings::PathInfo* pPathOld,
     886             :                                            const PathSettings::PathInfo* pPathNew)
     887             : {
     888           0 :     css::uno::Sequence< sal_Int32 >     lHandles(1);
     889           0 :     css::uno::Sequence< css::uno::Any > lOldVals(1);
     890           0 :     css::uno::Sequence< css::uno::Any > lNewVals(1);
     891             : 
     892           0 :     css::uno::Sequence< sal_Int32 > lIDs   = impl_mapPathName2IDList(sPath);
     893           0 :     sal_Int32                       c      = lIDs.getLength();
     894           0 :     sal_Int32                       i      = 0;
     895           0 :     sal_Int32                       nMaxID = m_lPropDesc.getLength()-1;
     896           0 :     for (i=0; i<c; ++i)
     897             :     {
     898           0 :         sal_Int32 nID = lIDs[i];
     899             : 
     900           0 :         if (
     901           0 :             (nID < 0     ) ||
     902             :             (nID > nMaxID)
     903             :            )
     904           0 :            continue;
     905             : 
     906           0 :         lHandles[0] = nID;
     907           0 :         switch(impl_getPropGroup(nID))
     908             :         {
     909             :             case IDGROUP_OLDSTYLE :
     910             :                  {
     911           0 :                     if (pPathOld)
     912             :                     {
     913           0 :                         OUString sVal = impl_convertPath2OldStyle(*pPathOld);
     914           0 :                         lOldVals[0] <<= sVal;
     915             :                     }
     916           0 :                     if (pPathNew)
     917             :                     {
     918           0 :                         OUString sVal = impl_convertPath2OldStyle(*pPathNew);
     919           0 :                         lNewVals[0] <<= sVal;
     920             :                     }
     921             :                  }
     922           0 :                  break;
     923             : 
     924             :             case IDGROUP_INTERNAL_PATHS :
     925             :                  {
     926           0 :                     if (pPathOld)
     927           0 :                         lOldVals[0] <<= pPathOld->lInternalPaths.getAsConstList();
     928           0 :                     if (pPathNew)
     929           0 :                         lNewVals[0] <<= pPathNew->lInternalPaths.getAsConstList();
     930             :                  }
     931           0 :                  break;
     932             : 
     933             :             case IDGROUP_USER_PATHS :
     934             :                  {
     935           0 :                     if (pPathOld)
     936           0 :                         lOldVals[0] <<= pPathOld->lUserPaths.getAsConstList();
     937           0 :                     if (pPathNew)
     938           0 :                         lNewVals[0] <<= pPathNew->lUserPaths.getAsConstList();
     939             :                  }
     940           0 :                  break;
     941             : 
     942             :             case IDGROUP_WRITE_PATH :
     943             :                  {
     944           0 :                     if (pPathOld)
     945           0 :                         lOldVals[0] <<= pPathOld->sWritePath;
     946           0 :                     if (pPathNew)
     947           0 :                         lNewVals[0] <<= pPathNew->sWritePath;
     948             :                  }
     949           0 :                  break;
     950             :         }
     951             : 
     952             :         fire(lHandles.getArray(),
     953           0 :              lNewVals.getArray(),
     954           0 :              lOldVals.getArray(),
     955             :              1,
     956           0 :              sal_False);
     957           0 :     }
     958           0 : }
     959             : 
     960       22104 : void PathSettings::impl_subst(      OUStringList&                                          lVals   ,
     961             :                               const css::uno::Reference< css::util::XStringSubstitution >& xSubst  ,
     962             :                                     bool                                               bReSubst)
     963             : {
     964       22104 :     OUStringList::iterator pIt;
     965             : 
     966      110520 :     for (  pIt  = lVals.begin();
     967       73680 :            pIt != lVals.end();
     968             :          ++pIt                 )
     969             :     {
     970       14736 :         const OUString& sOld = *pIt;
     971       14736 :               OUString  sNew;
     972       14736 :         if (bReSubst)
     973           0 :             sNew = xSubst->reSubstituteVariables(sOld);
     974             :         else
     975       14736 :             sNew = xSubst->substituteVariables(sOld, sal_False);
     976             : 
     977       14736 :         *pIt = sNew;
     978       14736 :     }
     979       22104 : }
     980             : 
     981        7368 : void PathSettings::impl_subst(PathSettings::PathInfo& aPath   ,
     982             :                               bool                bReSubst)
     983             : {
     984        7368 :     css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();
     985             : 
     986        7368 :     impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
     987        7368 :     impl_subst(aPath.lUserPaths    , xSubst, bReSubst);
     988        7368 :     if (bReSubst)
     989           0 :         aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
     990             :     else
     991        7368 :         aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, sal_False);
     992        7368 : }
     993             : 
     994       33403 : OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
     995             : {
     996       33403 :     OUStringList::const_iterator pIt;
     997       33403 :     OUStringList                 lTemp;
     998       33403 :     lTemp.reserve(rPath.lInternalPaths.size() + rPath.lUserPaths.size() + 1);
     999             : 
    1000      151740 :     for (  pIt  = rPath.lInternalPaths.begin();
    1001      101160 :            pIt != rPath.lInternalPaths.end();
    1002             :          ++pIt                                 )
    1003             :     {
    1004       17177 :         lTemp.push_back(*pIt);
    1005             :     }
    1006      100473 :     for (  pIt  = rPath.lUserPaths.begin();
    1007       66982 :            pIt != rPath.lUserPaths.end();
    1008             :          ++pIt                             )
    1009             :     {
    1010          88 :         lTemp.push_back(*pIt);
    1011             :     }
    1012             : 
    1013       33403 :     if (!rPath.sWritePath.isEmpty())
    1014       30702 :         lTemp.push_back(rPath.sWritePath);
    1015             : 
    1016       66806 :     OUStringBuffer sPathVal(256);
    1017      196143 :     for (  pIt  = lTemp.begin();
    1018      162740 :            pIt != lTemp.end();
    1019             :                                )
    1020             :     {
    1021       47967 :         sPathVal.append(*pIt);
    1022       47967 :         ++pIt;
    1023       47967 :         if (pIt != lTemp.end())
    1024       14564 :             sPathVal.appendAscii(";");
    1025             :     }
    1026             : 
    1027       66806 :     return sPathVal.makeStringAndClear();
    1028             : }
    1029             : 
    1030           0 : OUStringList PathSettings::impl_convertOldStyle2Path(const OUString& sOldStylePath) const
    1031             : {
    1032           0 :     OUStringList lList;
    1033           0 :     sal_Int32    nToken = 0;
    1034           0 :     do
    1035             :     {
    1036           0 :         OUString sToken = sOldStylePath.getToken(0, ';', nToken);
    1037           0 :         if (!sToken.isEmpty())
    1038           0 :             lList.push_back(sToken);
    1039             :     }
    1040           0 :     while(nToken >= 0);
    1041             : 
    1042           0 :     return lList;
    1043             : }
    1044             : 
    1045           0 : void PathSettings::impl_purgeKnownPaths(PathSettings::PathInfo& rPath,
    1046             :                                         OUStringList&           lList)
    1047             : {
    1048           0 :     OUStringList::iterator pIt;
    1049             : 
    1050             :     // Erase items in the internal path list from lList.
    1051             :     // Also erase items in the internal path list from the user path list.
    1052           0 :     for (  pIt  = rPath.lInternalPaths.begin();
    1053           0 :            pIt != rPath.lInternalPaths.end();
    1054             :          ++pIt                                 )
    1055             :     {
    1056           0 :         const OUString& rItem = *pIt;
    1057           0 :         OUStringList::iterator pItem = lList.find(rItem);
    1058           0 :         if (pItem != lList.end())
    1059           0 :             lList.erase(pItem);
    1060           0 :         pItem = rPath.lUserPaths.find(rItem);
    1061           0 :         if (pItem != rPath.lUserPaths.end())
    1062           0 :             rPath.lUserPaths.erase(pItem);
    1063             :     }
    1064             : 
    1065             :     // Erase itsems not in lList from the user path list.
    1066           0 :     pIt = rPath.lUserPaths.begin();
    1067           0 :     while ( pIt != rPath.lUserPaths.end() )
    1068             :     {
    1069           0 :         const OUString& rItem = *pIt;
    1070           0 :         OUStringList::iterator pItem = lList.find(rItem);
    1071           0 :         if ( pItem == lList.end() )
    1072             :         {
    1073           0 :             rPath.lUserPaths.erase(pIt);
    1074           0 :             pIt = rPath.lUserPaths.begin();
    1075             :         }
    1076             :         else
    1077             :         {
    1078           0 :             ++pIt;
    1079             :         }
    1080             :     }
    1081             : 
    1082             :     // Erase items in the user path list from lList.
    1083           0 :     for (  pIt  = rPath.lUserPaths.begin();
    1084           0 :            pIt != rPath.lUserPaths.end();
    1085             :          ++pIt                             )
    1086             :     {
    1087           0 :         const OUString& rItem = *pIt;
    1088           0 :         OUStringList::iterator pItem = lList.find(rItem);
    1089           0 :         if (pItem != lList.end())
    1090           0 :             lList.erase(pItem);
    1091             :     }
    1092             : 
    1093             :     // Erase the write path from lList
    1094           0 :     OUStringList::iterator pItem = lList.find(rPath.sWritePath);
    1095           0 :     if (pItem != lList.end())
    1096           0 :         lList.erase(pItem);
    1097           0 : }
    1098             : 
    1099         307 : void PathSettings::impl_rebuildPropertyDescriptor()
    1100             : {
    1101             :     // SAFE ->
    1102         307 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1103             : 
    1104         307 :     sal_Int32 c = (sal_Int32)m_lPaths.size();
    1105         307 :     sal_Int32 i = 0;
    1106         307 :     m_lPropDesc.realloc(c*IDGROUP_COUNT);
    1107             : 
    1108         307 :     PathHash::const_iterator pIt;
    1109       23025 :     for (  pIt  = m_lPaths.begin();
    1110       15350 :            pIt != m_lPaths.end();
    1111             :          ++pIt                     )
    1112             :     {
    1113        7368 :         const PathSettings::PathInfo& rPath = pIt->second;
    1114        7368 :               css::beans::Property*   pProp = 0;
    1115             : 
    1116        7368 :         pProp             = &(m_lPropDesc[i]);
    1117        7368 :         pProp->Name       = rPath.sPathName;
    1118        7368 :         pProp->Handle     = i;
    1119        7368 :         pProp->Type       = cppu::UnoType<OUString>::get();
    1120        7368 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
    1121        7368 :         if (rPath.bIsReadonly)
    1122           0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
    1123        7368 :         ++i;
    1124             : 
    1125        7368 :         pProp             = &(m_lPropDesc[i]);
    1126        7368 :         pProp->Name       = rPath.sPathName+POSTFIX_INTERNAL_PATHS;
    1127        7368 :         pProp->Handle     = i;
    1128        7368 :         pProp->Type       = ::getCppuType((css::uno::Sequence< OUString >*)0);
    1129             :         pProp->Attributes = css::beans::PropertyAttribute::BOUND   |
    1130        7368 :                             css::beans::PropertyAttribute::READONLY;
    1131        7368 :         ++i;
    1132             : 
    1133        7368 :         pProp             = &(m_lPropDesc[i]);
    1134        7368 :         pProp->Name       = rPath.sPathName+POSTFIX_USER_PATHS;
    1135        7368 :         pProp->Handle     = i;
    1136        7368 :         pProp->Type       = ::getCppuType((css::uno::Sequence< OUString >*)0);
    1137        7368 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
    1138        7368 :         if (rPath.bIsReadonly)
    1139           0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
    1140        7368 :         ++i;
    1141             : 
    1142        7368 :         pProp             = &(m_lPropDesc[i]);
    1143        7368 :         pProp->Name       = rPath.sPathName+POSTFIX_WRITE_PATH;
    1144        7368 :         pProp->Handle     = i;
    1145        7368 :         pProp->Type       = cppu::UnoType<OUString>::get();
    1146        7368 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
    1147        7368 :         if (rPath.bIsReadonly)
    1148           0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
    1149        7368 :         ++i;
    1150             :     }
    1151             : 
    1152         307 :     delete m_pPropHelp;
    1153         307 :     m_pPropHelp = new ::cppu::OPropertyArrayHelper(m_lPropDesc, sal_False); // false => not sorted ... must be done inside helper
    1154             : 
    1155             :     // <- SAFE
    1156         307 : }
    1157             : 
    1158       33879 : css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
    1159             : {
    1160       33879 :     const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
    1161       33879 :     if (! pPath)
    1162           0 :         throw css::lang::IllegalArgumentException();
    1163             : 
    1164       33879 :     css::uno::Any aVal;
    1165       33879 :     switch(impl_getPropGroup(nID))
    1166             :     {
    1167             :         case IDGROUP_OLDSTYLE :
    1168             :              {
    1169       33403 :                 OUString sVal = impl_convertPath2OldStyle(*pPath);
    1170       33403 :                 aVal <<= sVal;
    1171             :              }
    1172       33403 :              break;
    1173             : 
    1174             :         case IDGROUP_INTERNAL_PATHS :
    1175             :              {
    1176         160 :                 aVal <<= pPath->lInternalPaths.getAsConstList();
    1177             :              }
    1178         160 :              break;
    1179             : 
    1180             :         case IDGROUP_USER_PATHS :
    1181             :              {
    1182         158 :                 aVal <<= pPath->lUserPaths.getAsConstList();
    1183             :              }
    1184         158 :              break;
    1185             : 
    1186             :         case IDGROUP_WRITE_PATH :
    1187             :              {
    1188         158 :                 aVal <<= pPath->sWritePath;
    1189             :              }
    1190         158 :              break;
    1191             :     }
    1192             : 
    1193       33879 :     return aVal;
    1194             : }
    1195             : 
    1196           0 : void PathSettings::impl_setPathValue(      sal_Int32      nID ,
    1197             :                                      const css::uno::Any& aVal)
    1198             : {
    1199           0 :     PathSettings::PathInfo* pOrgPath = impl_getPathAccess(nID);
    1200           0 :     if (! pOrgPath)
    1201           0 :         throw css::container::NoSuchElementException();
    1202             : 
    1203             :     // We work on a copied path ... so we can be sure that errors during this operation
    1204             :     // does not make our internal cache invalid  .-)
    1205           0 :     PathSettings::PathInfo aChangePath(*pOrgPath);
    1206             : 
    1207           0 :     switch(impl_getPropGroup(nID))
    1208             :     {
    1209             :         case IDGROUP_OLDSTYLE :
    1210             :              {
    1211           0 :                 OUString sVal;
    1212           0 :                 aVal >>= sVal;
    1213           0 :                 OUStringList lList = impl_convertOldStyle2Path(sVal);
    1214           0 :                 impl_subst(lList, fa_getSubstitution(), false);
    1215           0 :                 impl_purgeKnownPaths(aChangePath, lList);
    1216           0 :                 if (! impl_isValidPath(lList))
    1217           0 :                     throw css::lang::IllegalArgumentException();
    1218             : 
    1219           0 :                 if (aChangePath.bIsSinglePath)
    1220             :                 {
    1221             :                     SAL_WARN_IF(lList.size()>1, "fwk", "PathSettings::impl_setPathValue(): You try to set more than path value for a defined SINGLE_PATH!");
    1222           0 :                     if ( !lList.empty() )
    1223           0 :                         aChangePath.sWritePath = *(lList.begin());
    1224             :                     else
    1225           0 :                         aChangePath.sWritePath = OUString();
    1226             :                 }
    1227             :                 else
    1228             :                 {
    1229           0 :                     OUStringList::const_iterator pIt;
    1230           0 :                     for (  pIt  = lList.begin();
    1231           0 :                            pIt != lList.end();
    1232             :                          ++pIt                 )
    1233             :                     {
    1234           0 :                         aChangePath.lUserPaths.push_back(*pIt);
    1235             :                     }
    1236           0 :                 }
    1237             :              }
    1238           0 :              break;
    1239             : 
    1240             :         case IDGROUP_INTERNAL_PATHS :
    1241             :              {
    1242           0 :                 if (aChangePath.bIsSinglePath)
    1243             :                 {
    1244           0 :                     OUStringBuffer sMsg(256);
    1245           0 :                     sMsg.appendAscii("The path '"    );
    1246           0 :                     sMsg.append     (aChangePath.sPathName);
    1247           0 :                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths can't be set.");
    1248             :                     throw css::uno::Exception(sMsg.makeStringAndClear(),
    1249           0 :                                               static_cast< ::cppu::OWeakObject* >(this));
    1250             :                 }
    1251             : 
    1252           0 :                 OUStringList lList;
    1253           0 :                 lList << aVal;
    1254           0 :                 if (! impl_isValidPath(lList))
    1255           0 :                     throw css::lang::IllegalArgumentException();
    1256           0 :                 aChangePath.lInternalPaths = lList;
    1257             :              }
    1258           0 :              break;
    1259             : 
    1260             :         case IDGROUP_USER_PATHS :
    1261             :              {
    1262           0 :                 if (aChangePath.bIsSinglePath)
    1263             :                 {
    1264           0 :                     OUStringBuffer sMsg(256);
    1265           0 :                     sMsg.appendAscii("The path '"    );
    1266           0 :                     sMsg.append     (aChangePath.sPathName);
    1267           0 :                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths can't be set.");
    1268             :                     throw css::uno::Exception(sMsg.makeStringAndClear(),
    1269           0 :                                               static_cast< ::cppu::OWeakObject* >(this));
    1270             :                 }
    1271             : 
    1272           0 :                 OUStringList lList;
    1273           0 :                 lList << aVal;
    1274           0 :                 if (! impl_isValidPath(lList))
    1275           0 :                     throw css::lang::IllegalArgumentException();
    1276           0 :                 aChangePath.lUserPaths = lList;
    1277             :              }
    1278           0 :              break;
    1279             : 
    1280             :         case IDGROUP_WRITE_PATH :
    1281             :              {
    1282           0 :                 OUString sVal;
    1283           0 :                 aVal >>= sVal;
    1284           0 :                 if (! impl_isValidPath(sVal))
    1285           0 :                     throw css::lang::IllegalArgumentException();
    1286           0 :                 aChangePath.sWritePath = sVal;
    1287             :              }
    1288           0 :              break;
    1289             :     }
    1290             : 
    1291             :     // TODO check if path has at least one path value set
    1292             :     // At least it depends from the feature using this path, if an empty path list is allowed.
    1293             : 
    1294             :     // first we should try to store the changed (copied!) path ...
    1295             :     // In case an error occurs on saving time an exception is thrown ...
    1296             :     // If no exception occurs we can update our internal cache (means
    1297             :     // we can overwrite pOrgPath !
    1298           0 :     impl_storePath(aChangePath);
    1299           0 :     pOrgPath->takeOver(aChangePath);
    1300           0 : }
    1301             : 
    1302           0 : bool PathSettings::impl_isValidPath(const OUStringList& lPath) const
    1303             : {
    1304           0 :     OUStringList::const_iterator pIt;
    1305           0 :     for (  pIt  = lPath.begin();
    1306           0 :            pIt != lPath.end();
    1307             :          ++pIt                 )
    1308             :     {
    1309           0 :         const OUString& rVal = *pIt;
    1310           0 :         if (! impl_isValidPath(rVal))
    1311           0 :             return false;
    1312             :     }
    1313             : 
    1314           0 :     return true;
    1315             : }
    1316             : 
    1317           0 : bool PathSettings::impl_isValidPath(const OUString& sPath) const
    1318             : {
    1319             :     // allow empty path to reset a path.
    1320             : // idea by LLA to support empty paths
    1321             : //    if (sPath.getLength() == 0)
    1322             : //    {
    1323             : //        return sal_True;
    1324             : //    }
    1325             : 
    1326           0 :     return (! INetURLObject(sPath).HasError());
    1327             : }
    1328             : 
    1329       33879 : OUString impl_extractBaseFromPropName(const OUString& sPropName)
    1330             : {
    1331       33879 :     sal_Int32 i = sPropName.indexOf(POSTFIX_INTERNAL_PATHS);
    1332       33879 :     if (i > -1)
    1333         160 :         return sPropName.copy(0, i);
    1334       33719 :     i = sPropName.indexOf(POSTFIX_USER_PATHS);
    1335       33719 :     if (i > -1)
    1336         158 :         return sPropName.copy(0, i);
    1337       33561 :     i = sPropName.indexOf(POSTFIX_WRITE_PATH);
    1338       33561 :     if (i > -1)
    1339         158 :         return sPropName.copy(0, i);
    1340             : 
    1341       33403 :     return sPropName;
    1342             : }
    1343             : 
    1344           0 : PathSettings::PathInfo* PathSettings::impl_getPathAccess(sal_Int32 nHandle)
    1345             : {
    1346             :     // SAFE ->
    1347           0 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1348             : 
    1349           0 :     if (nHandle > (m_lPropDesc.getLength()-1))
    1350           0 :         return 0;
    1351             : 
    1352           0 :     const css::beans::Property&            rProp = m_lPropDesc[nHandle];
    1353           0 :           OUString                  sProp = impl_extractBaseFromPropName(rProp.Name);
    1354           0 :           PathSettings::PathHash::iterator rPath = m_lPaths.find(sProp);
    1355             : 
    1356           0 :     if (rPath != m_lPaths.end())
    1357           0 :        return &(rPath->second);
    1358             : 
    1359           0 :     return 0;
    1360             :     // <- SAFE
    1361             : }
    1362             : 
    1363       33879 : const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
    1364             : {
    1365             :     // SAFE ->
    1366       33879 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1367             : 
    1368       33879 :     if (nHandle > (m_lPropDesc.getLength()-1))
    1369           0 :         return 0;
    1370             : 
    1371       33879 :     const css::beans::Property&                  rProp = m_lPropDesc[nHandle];
    1372       67758 :           OUString                        sProp = impl_extractBaseFromPropName(rProp.Name);
    1373       33879 :           PathSettings::PathHash::const_iterator rPath = m_lPaths.find(sProp);
    1374             : 
    1375       33879 :     if (rPath != m_lPaths.end())
    1376       33879 :        return &(rPath->second);
    1377             : 
    1378       33879 :     return 0;
    1379             :     // <- SAFE
    1380             : }
    1381             : 
    1382           0 : sal_Bool SAL_CALL PathSettings::convertFastPropertyValue(      css::uno::Any& aConvertedValue,
    1383             :                                                                css::uno::Any& aOldValue      ,
    1384             :                                                                sal_Int32      nHandle        ,
    1385             :                                                          const css::uno::Any& aValue         )
    1386             :     throw(css::lang::IllegalArgumentException)
    1387             : {
    1388             :     // throws NoSuchElementException !
    1389           0 :     css::uno::Any aCurrentVal = impl_getPathValue(nHandle);
    1390             : 
    1391             :     return PropHelper::willPropertyBeChanged(
    1392             :                 aCurrentVal,
    1393             :                 aValue,
    1394             :                 aOldValue,
    1395           0 :                 aConvertedValue);
    1396             : }
    1397             : 
    1398           0 : void SAL_CALL PathSettings::setFastPropertyValue_NoBroadcast(      sal_Int32      nHandle,
    1399             :                                                              const css::uno::Any& aValue )
    1400             :     throw(css::uno::Exception, std::exception)
    1401             : {
    1402             :     // throws NoSuchElement- and IllegalArgumentException !
    1403           0 :     impl_setPathValue(nHandle, aValue);
    1404           0 : }
    1405             : 
    1406       33879 : void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
    1407             :                                                  sal_Int32      nHandle) const
    1408             : {
    1409       33879 :     aValue = impl_getPathValue(nHandle);
    1410       33879 : }
    1411             : 
    1412       37972 : ::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
    1413             : {
    1414       37972 :     return *m_pPropHelp;
    1415             : }
    1416             : 
    1417         307 : css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
    1418             :     throw(css::uno::RuntimeException, std::exception)
    1419             : {
    1420             :     return css::uno::Reference< css::beans::XPropertySetInfo >(
    1421         307 :             ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()));
    1422             : }
    1423             : 
    1424       14736 : css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
    1425             : {
    1426       14736 :     css::uno::Reference< css::util::XStringSubstitution > xSubst;
    1427             :     { // SAFE ->
    1428       14736 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1429       14736 :     xSubst = m_xSubstitution;
    1430             :     }
    1431             : 
    1432       14736 :     if (! xSubst.is())
    1433             :     {
    1434             :         // create the needed substitution service.
    1435             :         // We must replace all used variables inside readed path values.
    1436             :         // In case we can't do so ... the whole office can't work really.
    1437             :         // That's why it seems to be OK to throw a RuntimeException then.
    1438         307 :         xSubst = css::util::PathSubstitution::create(m_xContext);
    1439             : 
    1440             :         { // SAFE ->
    1441         307 :         osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1442         307 :         m_xSubstitution = xSubst;
    1443             :         }
    1444             :     }
    1445             : 
    1446       14736 :     return xSubst;
    1447             : }
    1448             : 
    1449        7368 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
    1450             : {
    1451        7368 :     const OUString CFG_NODE_OLD("org.openoffice.Office.Common/Path/Current");
    1452             : 
    1453        7368 :     css::uno::Reference< css::container::XNameAccess > xCfg;
    1454             :     { // SAFE ->
    1455        7368 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1456        7368 :     xCfg = m_xCfgOld;
    1457             :     } // <- SAFE
    1458             : 
    1459        7368 :     if (! xCfg.is())
    1460             :     {
    1461         614 :         xCfg = css::uno::Reference< css::container::XNameAccess >(
    1462             :                    ::comphelper::ConfigurationHelper::openConfig(
    1463             :                         m_xContext,
    1464             :                         CFG_NODE_OLD,
    1465             :                         ::comphelper::ConfigurationHelper::E_STANDARD), // not readonly! Sometimes we need write access there !!!
    1466         307 :                    css::uno::UNO_QUERY_THROW);
    1467             : 
    1468             :         { // SAFE ->
    1469         307 :         osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1470         307 :         m_xCfgOld = xCfg;
    1471             :         }
    1472             :     }
    1473             : 
    1474        7368 :     return xCfg;
    1475             : }
    1476             : 
    1477        7675 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
    1478             : {
    1479        7675 :     const OUString CFG_NODE_NEW("org.openoffice.Office.Paths/Paths");
    1480             : 
    1481        7675 :     css::uno::Reference< css::container::XNameAccess > xCfg;
    1482             :     { // SAFE ->
    1483        7675 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1484        7675 :     xCfg = m_xCfgNew;
    1485             :     } // <- SAFE
    1486             : 
    1487        7675 :     if (! xCfg.is())
    1488             :     {
    1489         614 :         xCfg = css::uno::Reference< css::container::XNameAccess >(
    1490             :                    ::comphelper::ConfigurationHelper::openConfig(
    1491             :                         m_xContext,
    1492             :                         CFG_NODE_NEW,
    1493             :                         ::comphelper::ConfigurationHelper::E_STANDARD),
    1494         307 :                    css::uno::UNO_QUERY_THROW);
    1495             : 
    1496             :         { // SAFE ->
    1497         307 :         osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1498         307 :         m_xCfgNew = xCfg;
    1499         307 :         m_xCfgNewListener = new WeakChangesListener(this);
    1500             :         }
    1501             : 
    1502         307 :         css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
    1503         307 :         xBroadcaster->addChangesListener(m_xCfgNewListener);
    1504             :     }
    1505             : 
    1506        7675 :     return xCfg;
    1507             : }
    1508             : 
    1509         307 : struct Instance {
    1510         307 :     explicit Instance(
    1511             :         css::uno::Reference<css::uno::XComponentContext> const & context):
    1512             :         instance(
    1513         307 :             static_cast<cppu::OWeakObject *>(new PathSettings(context)))
    1514             :     {
    1515             :         // fill cache
    1516             :         static_cast<PathSettings *>(static_cast<cppu::OWeakObject *>
    1517         307 :                 (instance.get()))->impl_readAll();
    1518         307 :     }
    1519             : 
    1520             :     css::uno::Reference<css::uno::XInterface> instance;
    1521             : };
    1522             : 
    1523             : struct Singleton:
    1524             :     public rtl::StaticWithArg<
    1525             :         Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
    1526             : {};
    1527             : 
    1528             : }
    1529             : 
    1530             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    1531        1021 : com_sun_star_comp_framework_PathSettings_get_implementation(
    1532             :     css::uno::XComponentContext *context,
    1533             :     css::uno::Sequence<css::uno::Any> const &)
    1534             : {
    1535             :     return cppu::acquire(static_cast<cppu::OWeakObject *>(
    1536        1021 :                 Singleton::get(context).instance.get()));
    1537             : }
    1538             : 
    1539             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10