LCOV - code coverage report
Current view: top level - framework/source/services - pathsettings.cxx (source / functions) Hit Total Coverage
Test: commit 0e63ca4fde4e446f346e35849c756a30ca294aab Lines: 285 669 42.6 %
Date: 2014-04-11 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        9311 : sal_Int32 impl_getPropGroup(sal_Int32 nID)
      74             : {
      75        9311 :     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       17376 :     struct PathInfo
      93             :     {
      94             :         public:
      95             : 
      96       10440 :             PathInfo()
      97             :                 : sPathName     ()
      98             :                 , lInternalPaths()
      99             :                 , lUserPaths    ()
     100             :                 , sWritePath    ()
     101             :                 , bIsSinglePath (false)
     102       10440 :                 , bIsReadonly   (false)
     103       10440 :             {}
     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        3542 :     virtual void SAL_CALL acquire() throw () SAL_OVERRIDE
     211        3542 :         { OWeakObject::acquire(); }
     212        3540 :     virtual void SAL_CALL release() throw () SAL_OVERRIDE
     213        3540 :         { 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          77 :     virtual OUString SAL_CALL getBasePathShareLayer() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     325          77 :         { 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          67 :     virtual OUString SAL_CALL getBasePathUserLayer() throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
     329          67 :         { 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         601 :     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         601 :         { 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(const 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         145 : 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         145 :     ,  m_bIgnoreEvents(false)
     464             : {
     465         145 : }
     466             : 
     467         432 : PathSettings::~PathSettings()
     468             : {
     469         144 :     disposing();
     470         288 : }
     471             : 
     472         288 : void SAL_CALL PathSettings::disposing()
     473             : {
     474         288 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
     475             : 
     476             :     css::uno::Reference< css::util::XChangesNotifier >
     477         576 :         xBroadcaster(m_xCfgNew, css::uno::UNO_QUERY);
     478         288 :     if (xBroadcaster.is())
     479         144 :         xBroadcaster->removeChangesListener(m_xCfgNewListener);
     480             : 
     481         288 :     m_xSubstitution.clear();
     482         288 :     m_xCfgOld.clear();
     483         288 :     m_xCfgNew.clear();
     484         288 :     m_xCfgNewListener.clear();
     485             : 
     486         288 :     delete m_pPropHelp;
     487         576 :     m_pPropHelp = 0;
     488         288 : }
     489             : 
     490        1212 : css::uno::Any SAL_CALL PathSettings::queryInterface( const css::uno::Type& _rType )
     491             :     throw(css::uno::RuntimeException, std::exception)
     492             : {
     493        1212 :     css::uno::Any aRet = PathSettings_BASE::queryInterface( _rType );
     494        1212 :     if ( !aRet.hasValue() )
     495         145 :         aRet = ::cppu::OPropertySetHelper::queryInterface( _rType );
     496        1212 :     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         144 : OUString PathSettings::getStringProperty(const OUString& p1)
     548             :     throw(css::uno::RuntimeException)
     549             : {
     550         144 :     css::uno::Any a = ::cppu::OPropertySetHelper::getPropertyValue(p1);
     551         144 :     OUString s;
     552         144 :     a >>= s;
     553         144 :     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         145 : void PathSettings::impl_readAll()
     563             : {
     564             :     try
     565             :     {
     566             :         // TODO think about me
     567         145 :         css::uno::Reference< css::container::XNameAccess > xCfg    = fa_getCfgNew();
     568         290 :         css::uno::Sequence< OUString >              lPaths = xCfg->getElementNames();
     569             : 
     570         145 :         sal_Int32 c = lPaths.getLength();
     571        3625 :         for (sal_Int32 i = 0; i < c; ++i)
     572             :         {
     573        3480 :             const OUString& sPath = lPaths[i];
     574        3480 :             impl_updatePath(sPath, false);
     575         145 :         }
     576             :     }
     577           0 :     catch(const css::uno::RuntimeException& )
     578             :     {
     579             :     }
     580             : 
     581         145 :     impl_rebuildPropertyDescriptor();
     582         145 : }
     583             : 
     584             : // NO substitution here ! It's done outside ...
     585        3480 : OUStringList PathSettings::impl_readOldFormat(const OUString& sPath)
     586             : {
     587        3480 :     css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
     588        3480 :     OUStringList aPathVal;
     589             : 
     590        3480 :     if( xCfg->hasByName(sPath) )
     591             :     {
     592        3335 :         css::uno::Any aVal( xCfg->getByName(sPath) );
     593             : 
     594        6670 :         OUString                       sStringVal;
     595        6670 :         css::uno::Sequence< OUString > lStringListVal;
     596             : 
     597        3335 :         if (aVal >>= sStringVal)
     598             :         {
     599        2320 :             aPathVal.push_back(sStringVal);
     600             :         }
     601        1015 :         else if (aVal >>= lStringListVal)
     602             :         {
     603        1015 :             aPathVal << lStringListVal;
     604        3335 :         }
     605             :     }
     606             : 
     607        3480 :     return aPathVal;
     608             : }
     609             : 
     610             : // NO substitution here ! It's done outside ...
     611        3480 : PathSettings::PathInfo PathSettings::impl_readNewFormat(const OUString& sPath)
     612             : {
     613        3480 :     const OUString CFGPROP_INTERNALPATHS("InternalPaths");
     614        6960 :     const OUString CFGPROP_ISSINGLEPATH("IsSinglePath");
     615             : 
     616        6960 :     css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
     617             : 
     618             :     // get access to the "queried" path
     619        6960 :     css::uno::Reference< css::container::XNameAccess > xPath;
     620        3480 :     xCfg->getByName(sPath) >>= xPath;
     621             : 
     622        3480 :     PathSettings::PathInfo aPathVal;
     623             : 
     624             :     // read internal path list
     625        6960 :     css::uno::Reference< css::container::XNameAccess > xIPath;
     626        3480 :     xPath->getByName(CFGPROP_INTERNALPATHS) >>= xIPath;
     627        3480 :     aPathVal.lInternalPaths << xIPath->getElementNames();
     628             : 
     629             :     // read user defined path list
     630        3480 :     aPathVal.lUserPaths << xPath->getByName(CFGPROP_USERPATHS);
     631             : 
     632             :     // read the writeable path
     633        3480 :     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        3480 :     OUStringList::iterator aI = aPathVal.lUserPaths.find(aPathVal.sWritePath);
     638        3480 :     if (aI != aPathVal.lUserPaths.end())
     639         145 :         aPathVal.lUserPaths.erase(aI);
     640             : 
     641             :     // read state props
     642        3480 :     xPath->getByName(CFGPROP_ISSINGLEPATH) >>= aPathVal.bIsSinglePath;
     643             : 
     644             :     // analyze finalized/mandatory states
     645        3480 :     aPathVal.bIsReadonly = false;
     646        6960 :     css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
     647        3480 :     if (xInfo.is())
     648             :     {
     649        3480 :         css::beans::Property aInfo = xInfo->getAsProperty();
     650        3480 :         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        3480 :         aPathVal.bIsReadonly = bFinalized;
     656             :     }
     657             : 
     658        6960 :     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 cant 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 then 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        3480 : void PathSettings::impl_mergeOldUserPaths(      PathSettings::PathInfo& rPath,
     707             :                                           const OUStringList&           lOld )
     708             : {
     709        3480 :     OUStringList::const_iterator pIt;
     710       23055 :     for (  pIt  = lOld.begin();
     711       15370 :            pIt != lOld.end();
     712             :          ++pIt                )
     713             :     {
     714        4205 :         const OUString& sOld = *pIt;
     715             : 
     716        4205 :         if (rPath.bIsSinglePath)
     717             :         {
     718             :             SAL_WARN_IF(lOld.size()>1, "fwk", "PathSettings::impl_mergeOldUserPaths(): Single path has more then one path value inside old configuration (Common.xcu)!");
     719         725 :             if (! rPath.sWritePath.equals(sOld))
     720           0 :                rPath.sWritePath = sOld;
     721             :         }
     722             :         else
     723             :         {
     724        6960 :             if (
     725       20988 :                 (  rPath.lInternalPaths.findConst(sOld) == rPath.lInternalPaths.end()) &&
     726       20988 :                 (  rPath.lUserPaths.findConst(sOld)     == rPath.lUserPaths.end()    ) &&
     727        1196 :                 (! rPath.sWritePath.equals(sOld)                                     )
     728             :                )
     729          36 :                rPath.lUserPaths.push_back(sOld);
     730             :         }
     731             :     }
     732        3480 : }
     733             : 
     734        3480 : PathSettings::EChangeOp PathSettings::impl_updatePath(const OUString& sPath          ,
     735             :                                                             bool         bNotifyListener)
     736             : {
     737             :     // SAFE ->
     738        3480 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
     739             : 
     740        3480 :     PathSettings::PathInfo* pPathOld = 0;
     741        3480 :     PathSettings::PathInfo* pPathNew = 0;
     742        3480 :     PathSettings::EChangeOp eOp      = PathSettings::E_UNDEFINED;
     743        6960 :     PathSettings::PathInfo  aPath;
     744             : 
     745             :     try
     746             :     {
     747        3480 :         aPath = impl_readNewFormat(sPath);
     748        3480 :         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        3480 :         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        3480 :         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        3480 :         impl_subst(lOldVals, fa_getSubstitution(), false);
     772        3480 :         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 cant 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        3480 :     PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
     784        3480 :     if (eOp == PathSettings::E_UNDEFINED)
     785             :     {
     786        3480 :         if (pPath != m_lPaths.end())
     787           0 :             eOp = PathSettings::E_CHANGED;
     788             :         else
     789        3480 :             eOp = PathSettings::E_ADDED;
     790             :     }
     791             : 
     792        3480 :     switch(eOp)
     793             :     {
     794             :         case PathSettings::E_ADDED :
     795             :              {
     796        3480 :                 if (bNotifyListener)
     797             :                 {
     798           0 :                     pPathOld = 0;
     799           0 :                     pPathNew = &aPath;
     800           0 :                     impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     801             :                 }
     802        3480 :                 m_lPaths[sPath] = aPath;
     803             :              }
     804        3480 :              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        6960 :     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 cant 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       10440 : void PathSettings::impl_subst(      OUStringList&                                          lVals   ,
     961             :                               const css::uno::Reference< css::util::XStringSubstitution >& xSubst  ,
     962             :                                     bool                                               bReSubst)
     963             : {
     964       10440 :     OUStringList::iterator pIt;
     965             : 
     966       52200 :     for (  pIt  = lVals.begin();
     967       34800 :            pIt != lVals.end();
     968             :          ++pIt                 )
     969             :     {
     970        6960 :         const OUString& sOld = *pIt;
     971        6960 :               OUString  sNew;
     972        6960 :         if (bReSubst)
     973           0 :             sNew = xSubst->reSubstituteVariables(sOld);
     974             :         else
     975        6960 :             sNew = xSubst->substituteVariables(sOld, sal_False);
     976             : 
     977        6960 :         *pIt = sNew;
     978        6960 :     }
     979       10440 : }
     980             : 
     981        3480 : void PathSettings::impl_subst(PathSettings::PathInfo& aPath   ,
     982             :                               bool                bReSubst)
     983             : {
     984        3480 :     css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();
     985             : 
     986        3480 :     impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
     987        3480 :     impl_subst(aPath.lUserPaths    , xSubst, bReSubst);
     988        3480 :     if (bReSubst)
     989           0 :         aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
     990             :     else
     991        3480 :         aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, sal_False);
     992        3480 : }
     993             : 
     994        9071 : OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
     995             : {
     996        9071 :     OUStringList::const_iterator pIt;
     997        9071 :     OUStringList                 lTemp;
     998        9071 :     lTemp.reserve(rPath.lInternalPaths.size() + rPath.lUserPaths.size() + 1);
     999             : 
    1000       43848 :     for (  pIt  = rPath.lInternalPaths.begin();
    1001       29232 :            pIt != rPath.lInternalPaths.end();
    1002             :          ++pIt                                 )
    1003             :     {
    1004        5545 :         lTemp.push_back(*pIt);
    1005             :     }
    1006       27315 :     for (  pIt  = rPath.lUserPaths.begin();
    1007       18210 :            pIt != rPath.lUserPaths.end();
    1008             :          ++pIt                             )
    1009             :     {
    1010          34 :         lTemp.push_back(*pIt);
    1011             :     }
    1012             : 
    1013        9071 :     if (!rPath.sWritePath.isEmpty())
    1014        8877 :         lTemp.push_back(rPath.sWritePath);
    1015             : 
    1016       18142 :     OUStringBuffer sPathVal(256);
    1017       56125 :     for (  pIt  = lTemp.begin();
    1018       47054 :            pIt != lTemp.end();
    1019             :                                )
    1020             :     {
    1021       14456 :         sPathVal.append(*pIt);
    1022       14456 :         ++pIt;
    1023       14456 :         if (pIt != lTemp.end())
    1024        5385 :             sPathVal.appendAscii(";");
    1025             :     }
    1026             : 
    1027       18142 :     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(const PathSettings::PathInfo& rPath,
    1046             :                                                OUStringList&           lList)
    1047             : {
    1048           0 :     OUStringList::const_iterator pIt;
    1049           0 :     for (  pIt  = rPath.lInternalPaths.begin();
    1050           0 :            pIt != rPath.lInternalPaths.end();
    1051             :          ++pIt                                 )
    1052             :     {
    1053           0 :         const OUString& rItem = *pIt;
    1054           0 :         OUStringList::iterator pItem = lList.find(rItem);
    1055           0 :         if (pItem != lList.end())
    1056           0 :             lList.erase(pItem);
    1057             :     }
    1058           0 :     for (  pIt  = rPath.lUserPaths.begin();
    1059           0 :            pIt != rPath.lUserPaths.end();
    1060             :          ++pIt                             )
    1061             :     {
    1062           0 :         const OUString& rItem = *pIt;
    1063           0 :         OUStringList::iterator pItem = lList.find(rItem);
    1064           0 :         if (pItem != lList.end())
    1065           0 :             lList.erase(pItem);
    1066             :     }
    1067             : 
    1068           0 :     OUStringList::iterator pItem = lList.find(rPath.sWritePath);
    1069           0 :     if (pItem != lList.end())
    1070           0 :         lList.erase(pItem);
    1071           0 : }
    1072             : 
    1073         145 : void PathSettings::impl_rebuildPropertyDescriptor()
    1074             : {
    1075             :     // SAFE ->
    1076         145 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1077             : 
    1078         145 :     sal_Int32 c = (sal_Int32)m_lPaths.size();
    1079         145 :     sal_Int32 i = 0;
    1080         145 :     m_lPropDesc.realloc(c*IDGROUP_COUNT);
    1081             : 
    1082         145 :     PathHash::const_iterator pIt;
    1083       10875 :     for (  pIt  = m_lPaths.begin();
    1084        7250 :            pIt != m_lPaths.end();
    1085             :          ++pIt                     )
    1086             :     {
    1087        3480 :         const PathSettings::PathInfo& rPath = pIt->second;
    1088        3480 :               css::beans::Property*   pProp = 0;
    1089             : 
    1090        3480 :         pProp             = &(m_lPropDesc[i]);
    1091        3480 :         pProp->Name       = rPath.sPathName;
    1092        3480 :         pProp->Handle     = i;
    1093        3480 :         pProp->Type       = ::getCppuType((OUString*)0);
    1094        3480 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
    1095        3480 :         if (rPath.bIsReadonly)
    1096           0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
    1097        3480 :         ++i;
    1098             : 
    1099        3480 :         pProp             = &(m_lPropDesc[i]);
    1100        3480 :         pProp->Name       = rPath.sPathName+POSTFIX_INTERNAL_PATHS;
    1101        3480 :         pProp->Handle     = i;
    1102        3480 :         pProp->Type       = ::getCppuType((css::uno::Sequence< OUString >*)0);
    1103             :         pProp->Attributes = css::beans::PropertyAttribute::BOUND   |
    1104        3480 :                             css::beans::PropertyAttribute::READONLY;
    1105        3480 :         ++i;
    1106             : 
    1107        3480 :         pProp             = &(m_lPropDesc[i]);
    1108        3480 :         pProp->Name       = rPath.sPathName+POSTFIX_USER_PATHS;
    1109        3480 :         pProp->Handle     = i;
    1110        3480 :         pProp->Type       = ::getCppuType((css::uno::Sequence< OUString >*)0);
    1111        3480 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
    1112        3480 :         if (rPath.bIsReadonly)
    1113           0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
    1114        3480 :         ++i;
    1115             : 
    1116        3480 :         pProp             = &(m_lPropDesc[i]);
    1117        3480 :         pProp->Name       = rPath.sPathName+POSTFIX_WRITE_PATH;
    1118        3480 :         pProp->Handle     = i;
    1119        3480 :         pProp->Type       = ::getCppuType((OUString*)0);
    1120        3480 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
    1121        3480 :         if (rPath.bIsReadonly)
    1122           0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
    1123        3480 :         ++i;
    1124             :     }
    1125             : 
    1126         145 :     delete m_pPropHelp;
    1127         145 :     m_pPropHelp = new ::cppu::OPropertyArrayHelper(m_lPropDesc, sal_False); // false => not sorted ... must be done inside helper
    1128             : 
    1129             :     // <- SAFE
    1130         145 : }
    1131             : 
    1132        9311 : css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
    1133             : {
    1134        9311 :     const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
    1135        9311 :     if (! pPath)
    1136           0 :         throw css::lang::IllegalArgumentException();
    1137             : 
    1138        9311 :     css::uno::Any aVal;
    1139        9311 :     switch(impl_getPropGroup(nID))
    1140             :     {
    1141             :         case IDGROUP_OLDSTYLE :
    1142             :              {
    1143        9071 :                 OUString sVal = impl_convertPath2OldStyle(*pPath);
    1144        9071 :                 aVal <<= sVal;
    1145             :              }
    1146        9071 :              break;
    1147             : 
    1148             :         case IDGROUP_INTERNAL_PATHS :
    1149             :              {
    1150          80 :                 aVal <<= pPath->lInternalPaths.getAsConstList();
    1151             :              }
    1152          80 :              break;
    1153             : 
    1154             :         case IDGROUP_USER_PATHS :
    1155             :              {
    1156          80 :                 aVal <<= pPath->lUserPaths.getAsConstList();
    1157             :              }
    1158          80 :              break;
    1159             : 
    1160             :         case IDGROUP_WRITE_PATH :
    1161             :              {
    1162          80 :                 aVal <<= pPath->sWritePath;
    1163             :              }
    1164          80 :              break;
    1165             :     }
    1166             : 
    1167        9311 :     return aVal;
    1168             : }
    1169             : 
    1170           0 : void PathSettings::impl_setPathValue(      sal_Int32      nID ,
    1171             :                                      const css::uno::Any& aVal)
    1172             : {
    1173           0 :     PathSettings::PathInfo* pOrgPath = impl_getPathAccess(nID);
    1174           0 :     if (! pOrgPath)
    1175           0 :         throw css::container::NoSuchElementException();
    1176             : 
    1177             :     // We work on a copied path ... so we can be sure that errors during this operation
    1178             :     // does not make our internal cache invalid  .-)
    1179           0 :     PathSettings::PathInfo aChangePath(*pOrgPath);
    1180             : 
    1181           0 :     switch(impl_getPropGroup(nID))
    1182             :     {
    1183             :         case IDGROUP_OLDSTYLE :
    1184             :              {
    1185           0 :                 OUString sVal;
    1186           0 :                 aVal >>= sVal;
    1187           0 :                 OUStringList lList = impl_convertOldStyle2Path(sVal);
    1188           0 :                 impl_subst(lList, fa_getSubstitution(), false);
    1189           0 :                 impl_purgeKnownPaths(aChangePath, lList);
    1190           0 :                 if (! impl_isValidPath(lList))
    1191           0 :                     throw css::lang::IllegalArgumentException();
    1192             : 
    1193           0 :                 if (aChangePath.bIsSinglePath)
    1194             :                 {
    1195             :                     SAL_WARN_IF(lList.size()>1, "fwk", "PathSettings::impl_setPathValue(): You try to set more then path value for a defined SINGLE_PATH!");
    1196           0 :                     if ( !lList.empty() )
    1197           0 :                         aChangePath.sWritePath = *(lList.begin());
    1198             :                     else
    1199           0 :                         aChangePath.sWritePath = OUString();
    1200             :                 }
    1201             :                 else
    1202             :                 {
    1203           0 :                     OUStringList::const_iterator pIt;
    1204           0 :                     for (  pIt  = lList.begin();
    1205           0 :                            pIt != lList.end();
    1206             :                          ++pIt                 )
    1207             :                     {
    1208           0 :                         aChangePath.lUserPaths.push_back(*pIt);
    1209             :                     }
    1210           0 :                 }
    1211             :              }
    1212           0 :              break;
    1213             : 
    1214             :         case IDGROUP_INTERNAL_PATHS :
    1215             :              {
    1216           0 :                 if (aChangePath.bIsSinglePath)
    1217             :                 {
    1218           0 :                     OUStringBuffer sMsg(256);
    1219           0 :                     sMsg.appendAscii("The path '"    );
    1220           0 :                     sMsg.append     (aChangePath.sPathName);
    1221           0 :                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths cant be set.");
    1222             :                     throw css::uno::Exception(sMsg.makeStringAndClear(),
    1223           0 :                                               static_cast< ::cppu::OWeakObject* >(this));
    1224             :                 }
    1225             : 
    1226           0 :                 OUStringList lList;
    1227           0 :                 lList << aVal;
    1228           0 :                 if (! impl_isValidPath(lList))
    1229           0 :                     throw css::lang::IllegalArgumentException();
    1230           0 :                 aChangePath.lInternalPaths = lList;
    1231             :              }
    1232           0 :              break;
    1233             : 
    1234             :         case IDGROUP_USER_PATHS :
    1235             :              {
    1236           0 :                 if (aChangePath.bIsSinglePath)
    1237             :                 {
    1238           0 :                     OUStringBuffer sMsg(256);
    1239           0 :                     sMsg.appendAscii("The path '"    );
    1240           0 :                     sMsg.append     (aChangePath.sPathName);
    1241           0 :                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths cant be set.");
    1242             :                     throw css::uno::Exception(sMsg.makeStringAndClear(),
    1243           0 :                                               static_cast< ::cppu::OWeakObject* >(this));
    1244             :                 }
    1245             : 
    1246           0 :                 OUStringList lList;
    1247           0 :                 lList << aVal;
    1248           0 :                 if (! impl_isValidPath(lList))
    1249           0 :                     throw css::lang::IllegalArgumentException();
    1250           0 :                 aChangePath.lUserPaths = lList;
    1251             :              }
    1252           0 :              break;
    1253             : 
    1254             :         case IDGROUP_WRITE_PATH :
    1255             :              {
    1256           0 :                 OUString sVal;
    1257           0 :                 aVal >>= sVal;
    1258           0 :                 if (! impl_isValidPath(sVal))
    1259           0 :                     throw css::lang::IllegalArgumentException();
    1260           0 :                 aChangePath.sWritePath = sVal;
    1261             :              }
    1262           0 :              break;
    1263             :     }
    1264             : 
    1265             :     // TODO check if path has at least one path value set
    1266             :     // At least it depends from the feature using this path, if an empty path list is allowed.
    1267             : 
    1268             :     // first we should try to store the changed (copied!) path ...
    1269             :     // In case an error occurs on saving time an exception is thrown ...
    1270             :     // If no exception occurs we can update our internal cache (means
    1271             :     // we can overwrite pOrgPath !
    1272           0 :     impl_storePath(aChangePath);
    1273           0 :     pOrgPath->takeOver(aChangePath);
    1274           0 : }
    1275             : 
    1276           0 : bool PathSettings::impl_isValidPath(const OUStringList& lPath) const
    1277             : {
    1278           0 :     OUStringList::const_iterator pIt;
    1279           0 :     for (  pIt  = lPath.begin();
    1280           0 :            pIt != lPath.end();
    1281             :          ++pIt                 )
    1282             :     {
    1283           0 :         const OUString& rVal = *pIt;
    1284           0 :         if (! impl_isValidPath(rVal))
    1285           0 :             return false;
    1286             :     }
    1287             : 
    1288           0 :     return true;
    1289             : }
    1290             : 
    1291           0 : bool PathSettings::impl_isValidPath(const OUString& sPath) const
    1292             : {
    1293             :     // allow empty path to reset a path.
    1294             : // idea by LLA to support empty paths
    1295             : //    if (sPath.getLength() == 0)
    1296             : //    {
    1297             : //        return sal_True;
    1298             : //    }
    1299             : 
    1300           0 :     return (! INetURLObject(sPath).HasError());
    1301             : }
    1302             : 
    1303        9311 : OUString impl_extractBaseFromPropName(const OUString& sPropName)
    1304             : {
    1305        9311 :     sal_Int32 i = sPropName.indexOf(POSTFIX_INTERNAL_PATHS);
    1306        9311 :     if (i > -1)
    1307          80 :         return sPropName.copy(0, i);
    1308        9231 :     i = sPropName.indexOf(POSTFIX_USER_PATHS);
    1309        9231 :     if (i > -1)
    1310          80 :         return sPropName.copy(0, i);
    1311        9151 :     i = sPropName.indexOf(POSTFIX_WRITE_PATH);
    1312        9151 :     if (i > -1)
    1313          80 :         return sPropName.copy(0, i);
    1314             : 
    1315        9071 :     return sPropName;
    1316             : }
    1317             : 
    1318           0 : PathSettings::PathInfo* PathSettings::impl_getPathAccess(sal_Int32 nHandle)
    1319             : {
    1320             :     // SAFE ->
    1321           0 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1322             : 
    1323           0 :     if (nHandle > (m_lPropDesc.getLength()-1))
    1324           0 :         return 0;
    1325             : 
    1326           0 :     const css::beans::Property&            rProp = m_lPropDesc[nHandle];
    1327           0 :           OUString                  sProp = impl_extractBaseFromPropName(rProp.Name);
    1328           0 :           PathSettings::PathHash::iterator rPath = m_lPaths.find(sProp);
    1329             : 
    1330           0 :     if (rPath != m_lPaths.end())
    1331           0 :        return &(rPath->second);
    1332             : 
    1333           0 :     return 0;
    1334             :     // <- SAFE
    1335             : }
    1336             : 
    1337        9311 : const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
    1338             : {
    1339             :     // SAFE ->
    1340        9311 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1341             : 
    1342        9311 :     if (nHandle > (m_lPropDesc.getLength()-1))
    1343           0 :         return 0;
    1344             : 
    1345        9311 :     const css::beans::Property&                  rProp = m_lPropDesc[nHandle];
    1346       18622 :           OUString                        sProp = impl_extractBaseFromPropName(rProp.Name);
    1347        9311 :           PathSettings::PathHash::const_iterator rPath = m_lPaths.find(sProp);
    1348             : 
    1349        9311 :     if (rPath != m_lPaths.end())
    1350        9311 :        return &(rPath->second);
    1351             : 
    1352        9311 :     return 0;
    1353             :     // <- SAFE
    1354             : }
    1355             : 
    1356           0 : sal_Bool SAL_CALL PathSettings::convertFastPropertyValue(      css::uno::Any& aConvertedValue,
    1357             :                                                                css::uno::Any& aOldValue      ,
    1358             :                                                                sal_Int32      nHandle        ,
    1359             :                                                          const css::uno::Any& aValue         )
    1360             :     throw(css::lang::IllegalArgumentException)
    1361             : {
    1362             :     // throws NoSuchElementException !
    1363           0 :     css::uno::Any aCurrentVal = impl_getPathValue(nHandle);
    1364             : 
    1365             :     return PropHelper::willPropertyBeChanged(
    1366             :                 aCurrentVal,
    1367             :                 aValue,
    1368             :                 aOldValue,
    1369           0 :                 aConvertedValue);
    1370             : }
    1371             : 
    1372           0 : void SAL_CALL PathSettings::setFastPropertyValue_NoBroadcast(      sal_Int32      nHandle,
    1373             :                                                              const css::uno::Any& aValue )
    1374             :     throw(css::uno::Exception, std::exception)
    1375             : {
    1376             :     // throws NoSuchElement- and IllegalArgumentException !
    1377           0 :     impl_setPathValue(nHandle, aValue);
    1378           0 : }
    1379             : 
    1380        9311 : void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
    1381             :                                                  sal_Int32      nHandle) const
    1382             : {
    1383        9311 :     aValue = impl_getPathValue(nHandle);
    1384        9311 : }
    1385             : 
    1386       10201 : ::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
    1387             : {
    1388       10201 :     return *m_pPropHelp;
    1389             : }
    1390             : 
    1391         145 : css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
    1392             :     throw(css::uno::RuntimeException, std::exception)
    1393             : {
    1394             :     return css::uno::Reference< css::beans::XPropertySetInfo >(
    1395         145 :             ::cppu::OPropertySetHelper::createPropertySetInfo(getInfoHelper()));
    1396             : }
    1397             : 
    1398        6960 : css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
    1399             : {
    1400        6960 :     css::uno::Reference< css::util::XStringSubstitution > xSubst;
    1401             :     { // SAFE ->
    1402        6960 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1403        6960 :     xSubst = m_xSubstitution;
    1404             :     }
    1405             : 
    1406        6960 :     if (! xSubst.is())
    1407             :     {
    1408             :         // create the needed substitution service.
    1409             :         // We must replace all used variables inside readed path values.
    1410             :         // In case we can't do so ... the whole office can't work really.
    1411             :         // That's why it seems to be OK to throw a RuntimeException then.
    1412         145 :         xSubst = css::util::PathSubstitution::create(m_xContext);
    1413             : 
    1414             :         { // SAFE ->
    1415         145 :         osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1416         145 :         m_xSubstitution = xSubst;
    1417             :         }
    1418             :     }
    1419             : 
    1420        6960 :     return xSubst;
    1421             : }
    1422             : 
    1423        3480 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
    1424             : {
    1425        3480 :     const OUString CFG_NODE_OLD("org.openoffice.Office.Common/Path/Current");
    1426             : 
    1427        3480 :     css::uno::Reference< css::container::XNameAccess > xCfg;
    1428             :     { // SAFE ->
    1429        3480 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1430        3480 :     xCfg = m_xCfgOld;
    1431             :     } // <- SAFE
    1432             : 
    1433        3480 :     if (! xCfg.is())
    1434             :     {
    1435         290 :         xCfg = css::uno::Reference< css::container::XNameAccess >(
    1436             :                    ::comphelper::ConfigurationHelper::openConfig(
    1437             :                         m_xContext,
    1438             :                         CFG_NODE_OLD,
    1439             :                         ::comphelper::ConfigurationHelper::E_STANDARD), // not readonly! Sometimes we need write access there !!!
    1440         145 :                    css::uno::UNO_QUERY_THROW);
    1441             : 
    1442             :         { // SAFE ->
    1443         145 :         osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1444         145 :         m_xCfgOld = xCfg;
    1445             :         }
    1446             :     }
    1447             : 
    1448        3480 :     return xCfg;
    1449             : }
    1450             : 
    1451        3625 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
    1452             : {
    1453        3625 :     const OUString CFG_NODE_NEW("org.openoffice.Office.Paths/Paths");
    1454             : 
    1455        3625 :     css::uno::Reference< css::container::XNameAccess > xCfg;
    1456             :     { // SAFE ->
    1457        3625 :     osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1458        3625 :     xCfg = m_xCfgNew;
    1459             :     } // <- SAFE
    1460             : 
    1461        3625 :     if (! xCfg.is())
    1462             :     {
    1463         290 :         xCfg = css::uno::Reference< css::container::XNameAccess >(
    1464             :                    ::comphelper::ConfigurationHelper::openConfig(
    1465             :                         m_xContext,
    1466             :                         CFG_NODE_NEW,
    1467             :                         ::comphelper::ConfigurationHelper::E_STANDARD),
    1468         145 :                    css::uno::UNO_QUERY_THROW);
    1469             : 
    1470             :         { // SAFE ->
    1471         145 :         osl::MutexGuard g(cppu::WeakComponentImplHelperBase::rBHelper.rMutex);
    1472         145 :         m_xCfgNew = xCfg;
    1473         145 :         m_xCfgNewListener = new WeakChangesListener(this);
    1474             :         }
    1475             : 
    1476         145 :         css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
    1477         145 :         xBroadcaster->addChangesListener(m_xCfgNewListener);
    1478             :     }
    1479             : 
    1480        3625 :     return xCfg;
    1481             : }
    1482             : 
    1483         145 : struct Instance {
    1484         145 :     explicit Instance(
    1485             :         css::uno::Reference<css::uno::XComponentContext> const & context):
    1486             :         instance(
    1487         145 :             static_cast<cppu::OWeakObject *>(new PathSettings(context)))
    1488             :     {
    1489             :         // fill cache
    1490             :         static_cast<PathSettings *>(static_cast<cppu::OWeakObject *>
    1491         145 :                 (instance.get()))->impl_readAll();
    1492         145 :     }
    1493             : 
    1494             :     css::uno::Reference<css::uno::XInterface> instance;
    1495             : };
    1496             : 
    1497             : struct Singleton:
    1498             :     public rtl::StaticWithArg<
    1499             :         Instance, css::uno::Reference<css::uno::XComponentContext>, Singleton>
    1500             : {};
    1501             : 
    1502             : }
    1503             : 
    1504             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    1505         502 : com_sun_star_comp_framework_PathSettings_get_implementation(
    1506             :     css::uno::XComponentContext *context,
    1507             :     css::uno::Sequence<css::uno::Any> const &)
    1508             : {
    1509             :     return cppu::acquire(static_cast<cppu::OWeakObject *>(
    1510         502 :                 Singleton::get(context).instance.get()));
    1511             : }
    1512             : 
    1513             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10