LCOV - code coverage report
Current view: top level - framework/source/services - pathsettings.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 316 503 62.8 %
Date: 2012-08-25 Functions: 38 48 79.2 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 307 976 31.5 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : /** Attention: stl headers must(!) be included at first. Otherwhise it can make trouble
      30                 :            :                with solaris headers ...
      31                 :            : */
      32                 :            : #include <vector>
      33                 :            : #include <services/pathsettings.hxx>
      34                 :            : #include <threadhelp/readguard.hxx>
      35                 :            : #include <threadhelp/writeguard.hxx>
      36                 :            : #include <services.h>
      37                 :            : 
      38                 :            : #include "helper/mischelper.hxx"
      39                 :            : 
      40                 :            : #include <com/sun/star/beans/Property.hpp>
      41                 :            : #include <com/sun/star/beans/XProperty.hpp>
      42                 :            : #include <com/sun/star/beans/PropertyAttribute.hpp>
      43                 :            : #include <com/sun/star/container/XContainer.hpp>
      44                 :            : #include <com/sun/star/beans/XPropertySet.hpp>
      45                 :            : #include <com/sun/star/util/XChangesNotifier.hpp>
      46                 :            : #include <com/sun/star/util/PathSubstitution.hpp>
      47                 :            : 
      48                 :            : #include <tools/urlobj.hxx>
      49                 :            : #include <rtl/ustrbuf.hxx>
      50                 :            : #include <rtl/logfile.hxx>
      51                 :            : 
      52                 :            : #include <comphelper/componentcontext.hxx>
      53                 :            : #include <comphelper/configurationhelper.hxx>
      54                 :            : #include <unotools/configpaths.hxx>
      55                 :            : 
      56                 :            : #include <fwkdllapi.h>
      57                 :            : 
      58                 :            : 
      59                 :            : #define CFGPROP_USERPATHS rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("UserPaths"))
      60                 :            : #define CFGPROP_WRITEPATH rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("WritePath"))
      61                 :            : 
      62                 :            : /*
      63                 :            :     0 : old style              "Template"              string using ";" as seperator
      64                 :            :     1 : internal paths         "Template_internal"     string list
      65                 :            :     2 : user paths             "Template_user"         string list
      66                 :            :     3 : write path             "Template_write"        string
      67                 :            :  */
      68                 :            : 
      69                 :            : #define POSTFIX_INTERNAL_PATHS rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_internal"))
      70                 :            : #define POSTFIX_USER_PATHS rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_user"))
      71                 :            : #define POSTFIX_WRITE_PATH rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("_writable"))
      72                 :            : 
      73                 :            : const sal_Int32 IDGROUP_OLDSTYLE        = 0;
      74                 :            : const sal_Int32 IDGROUP_INTERNAL_PATHS = 1;
      75                 :            : const sal_Int32 IDGROUP_USER_PATHS     = 2;
      76                 :            : const sal_Int32 IDGROUP_WRITE_PATH      = 3;
      77                 :            : 
      78                 :            : const sal_Int32 IDGROUP_COUNT           = 4;
      79                 :            : 
      80                 :       6417 : sal_Int32 impl_getPropGroup(sal_Int32 nID)
      81                 :            : {
      82                 :       6417 :     return (nID % IDGROUP_COUNT);
      83                 :            : }
      84                 :            : 
      85                 :            : 
      86                 :            : namespace framework
      87                 :            : {
      88                 :            : 
      89                 :            : //-----------------------------------------------------------------------------
      90                 :            : // XInterface, XTypeProvider, XServiceInfo
      91                 :            : 
      92 [ +  + ][ +  - ]:      10200 : DEFINE_XINTERFACE_7                     (   PathSettings                                             ,
      93                 :            :                                             OWeakObject                                              ,
      94                 :            :                                             DIRECT_INTERFACE ( css::lang::XTypeProvider              ),
      95                 :            :                                             DIRECT_INTERFACE ( css::lang::XServiceInfo               ),
      96                 :            :                                             DERIVED_INTERFACE( css::lang::XEventListener, css::util::XChangesListener),
      97                 :            :                                             DIRECT_INTERFACE ( css::util::XChangesListener           ),
      98                 :            :                                             DIRECT_INTERFACE ( css::beans::XPropertySet              ),
      99                 :            :                                             DIRECT_INTERFACE ( css::beans::XFastPropertySet          ),
     100                 :            :                                             DIRECT_INTERFACE ( css::beans::XMultiPropertySet        )
     101                 :            :                                         )
     102                 :            : 
     103 [ #  # ][ #  # ]:          0 : DEFINE_XTYPEPROVIDER_7                  (   PathSettings                                            ,
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     104                 :            :                                             css::lang::XTypeProvider                                ,
     105                 :            :                                             css::lang::XServiceInfo                                 ,
     106                 :            :                                             css::lang::XEventListener                               ,
     107                 :            :                                             css::util::XChangesListener                             ,
     108                 :            :                                             css::beans::XPropertySet                                ,
     109                 :            :                                             css::beans::XFastPropertySet                            ,
     110                 :            :                                             css::beans::XMultiPropertySet
     111                 :            :                                         )
     112                 :            : 
     113 [ +  - ][ +  - ]:       1165 : DEFINE_XSERVICEINFO_ONEINSTANCESERVICE  (   PathSettings                                            ,
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ #  # ][ #  # ]
     114                 :            :                                             ::cppu::OWeakObject                                     ,
     115                 :            :                                             SERVICENAME_PATHSETTINGS                                ,
     116                 :            :                                             IMPLEMENTATIONNAME_PATHSETTINGS
     117                 :            :                                         )
     118                 :            : 
     119                 :        233 : DEFINE_INIT_SERVICE                     (   PathSettings,
     120                 :            :                                             {
     121                 :            :                                                 /*Attention
     122                 :            :                                                     I think we don't need any mutex or lock here ... because we are called by our own static method impl_createInstance()
     123                 :            :                                                     to create a new instance of this class by our own supported service factory.
     124                 :            :                                                     see macro DEFINE_XSERVICEINFO_MULTISERVICE and "impl_initService()" for further informations!
     125                 :            :                                                 */
     126                 :            : 
     127                 :            :                                                 // fill cache
     128                 :            :                                                 impl_readAll();
     129                 :            :                                             }
     130                 :            :                                         )
     131                 :            : 
     132                 :            : //-----------------------------------------------------------------------------
     133                 :        233 : PathSettings::PathSettings( const css::uno::Reference< css::lang::XMultiServiceFactory >& xSMGR )
     134                 :            :     //  Init baseclasses first
     135                 :            :     //  Attention: Don't change order of initialization!
     136                 :            :     //      ThreadHelpBase is a struct with a lock as member. We can't use a lock as direct member!
     137                 :            :     //      We must garant right initialization and a valid value of this to initialize other baseclasses!
     138                 :            :     :   ThreadHelpBase()
     139         [ +  - ]:        233 :     ,   ::cppu::OBroadcastHelperVar< ::cppu::OMultiTypeInterfaceContainerHelper, ::cppu::OMultiTypeInterfaceContainerHelper::keyType >(m_aLock.getShareableOslMutex())
     140                 :            :     ,   ::cppu::OPropertySetHelper(*(static_cast< ::cppu::OBroadcastHelper* >(this)))
     141                 :            :     ,   ::cppu::OWeakObject()
     142                 :            :     // Init member
     143                 :            :     ,   m_xSMGR    (xSMGR)
     144                 :            :     ,   m_pPropHelp(0    )
     145 [ +  - ][ +  - ]:        466 :     ,  m_bIgnoreEvents(sal_False)
         [ +  - ][ +  - ]
                 [ +  - ]
     146                 :            : {
     147                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::PathSettings" );
     148                 :        233 : }
     149                 :            : 
     150                 :            : //-----------------------------------------------------------------------------
     151 [ +  - ][ +  - ]:        233 : PathSettings::~PathSettings()
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     152                 :            : {
     153         [ +  - ]:        233 :     css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(m_xCfgNew, css::uno::UNO_QUERY);
     154         [ +  - ]:        233 :     if (xBroadcaster.is())
     155 [ +  - ][ +  - ]:        233 :         xBroadcaster->removeChangesListener(m_xCfgNewListener);
     156         [ +  - ]:        233 :     if (m_pPropHelp)
     157 [ +  - ][ +  - ]:        233 :        delete m_pPropHelp;
     158         [ -  + ]:        466 : }
     159                 :            : 
     160                 :            : //-----------------------------------------------------------------------------
     161                 :          0 : void SAL_CALL PathSettings::changesOccurred(const css::util::ChangesEvent& aEvent)
     162                 :            :     throw (css::uno::RuntimeException)
     163                 :            : {
     164                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::changesOccurred" );
     165                 :            : 
     166                 :          0 :     sal_Int32 c                 = aEvent.Changes.getLength();
     167                 :          0 :     sal_Int32 i                 = 0;
     168                 :          0 :     sal_Bool  bUpdateDescriptor = sal_False;
     169                 :            : 
     170         [ #  # ]:          0 :     for (i=0; i<c; ++i)
     171                 :            :     {
     172                 :          0 :         const css::util::ElementChange& aChange = aEvent.Changes[i];
     173                 :            : 
     174                 :          0 :         ::rtl::OUString sChanged;
     175                 :          0 :         aChange.Accessor >>= sChanged;
     176                 :            : 
     177         [ #  # ]:          0 :         ::rtl::OUString sPath = ::utl::extractFirstFromConfigurationPath(sChanged);
     178         [ #  # ]:          0 :         if (!sPath.isEmpty())
     179                 :            :         {
     180         [ #  # ]:          0 :             PathSettings::EChangeOp eOp = impl_updatePath(sPath, sal_True);
     181 [ #  # ][ #  # ]:          0 :             if (
     182                 :            :                 (eOp == PathSettings::E_ADDED  ) ||
     183                 :            :                 (eOp == PathSettings::E_REMOVED)
     184                 :            :                )
     185                 :          0 :                 bUpdateDescriptor = sal_True;
     186                 :            :         }
     187                 :          0 :     }
     188                 :            : 
     189         [ #  # ]:          0 :     if (bUpdateDescriptor)
     190                 :          0 :         impl_rebuildPropertyDescriptor();
     191                 :          0 : }
     192                 :            : 
     193                 :            : //-----------------------------------------------------------------------------
     194                 :          0 : void SAL_CALL PathSettings::disposing(const css::lang::EventObject& aSource)
     195                 :            :     throw(css::uno::RuntimeException)
     196                 :            : {
     197                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::disposing" );
     198         [ #  # ]:          0 :     WriteGuard aWriteLock(m_aLock);
     199                 :            : 
     200 [ #  # ][ #  # ]:          0 :     if (aSource.Source == m_xCfgNew)
     201                 :          0 :         m_xCfgNew.clear();
     202                 :            : 
     203 [ #  # ][ #  # ]:          0 :     aWriteLock.unlock();
     204                 :          0 : }
     205                 :            : 
     206                 :            : //-----------------------------------------------------------------------------
     207                 :        233 : void PathSettings::impl_readAll()
     208                 :            : {
     209                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readAll" );
     210                 :            :     RTL_LOGFILE_CONTEXT(aLog, "framework (as96863) ::PathSettings::load config (all)");
     211                 :            : 
     212                 :            :     try
     213                 :            :     {
     214                 :            :         // TODO think about me
     215         [ +  - ]:        233 :         css::uno::Reference< css::container::XNameAccess > xCfg    = fa_getCfgNew();
     216 [ +  - ][ +  - ]:        233 :         css::uno::Sequence< ::rtl::OUString >              lPaths = xCfg->getElementNames();
     217                 :            : 
     218                 :        233 :         sal_Int32 c = lPaths.getLength();
     219         [ +  + ]:       5825 :         for (sal_Int32 i = 0; i < c; ++i)
     220                 :            :         {
     221         [ +  - ]:       5592 :             const ::rtl::OUString& sPath = lPaths[i];
     222         [ +  - ]:       5592 :             impl_updatePath(sPath, sal_False);
     223 [ +  - ][ #  # ]:        233 :         }
     224                 :            :     }
     225                 :          0 :     catch(const css::uno::RuntimeException& )
     226                 :            :     {
     227                 :            :     }
     228                 :            : 
     229                 :        233 :     impl_rebuildPropertyDescriptor();
     230                 :        233 : }
     231                 :            : 
     232                 :            : //-----------------------------------------------------------------------------
     233                 :            : // NO substitution here ! It's done outside ...
     234                 :       5592 : OUStringList PathSettings::impl_readOldFormat(const ::rtl::OUString& sPath)
     235                 :            : {
     236                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_readOldFormat" );
     237         [ +  - ]:       5592 :     css::uno::Reference< css::container::XNameAccess > xCfg( fa_getCfgOld() );
     238         [ +  - ]:       5592 :     OUStringList aPathVal;
     239                 :            : 
     240 [ +  - ][ +  - ]:       5592 :     if( xCfg->hasByName(sPath) )
                 [ +  + ]
     241                 :            :     {
     242 [ +  - ][ +  - ]:       5359 :         css::uno::Any aVal( xCfg->getByName(sPath) );
     243                 :            : 
     244                 :       5359 :         ::rtl::OUString                       sStringVal;
     245         [ +  - ]:       5359 :         css::uno::Sequence< ::rtl::OUString > lStringListVal;
     246                 :            : 
     247         [ +  + ]:       5359 :         if (aVal >>= sStringVal)
     248                 :            :         {
     249         [ +  - ]:       3728 :             aPathVal.push_back(sStringVal);
     250                 :            :         }
     251 [ +  - ][ +  - ]:       1631 :         else if (aVal >>= lStringListVal)
     252                 :            :         {
     253         [ +  - ]:       1631 :             aPathVal << lStringListVal;
     254         [ +  - ]:       5359 :         }
     255                 :            :     }
     256                 :            : 
     257                 :       5592 :     return aPathVal;
     258                 :            : }
     259                 :            : 
     260                 :            : //-----------------------------------------------------------------------------
     261                 :            : // NO substitution here ! It's done outside ...
     262                 :       5592 : PathSettings::PathInfo PathSettings::impl_readNewFormat(const ::rtl::OUString& sPath)
     263                 :            : {
     264         [ +  - ]:       5592 :     const ::rtl::OUString CFGPROP_INTERNALPATHS(RTL_CONSTASCII_USTRINGPARAM("InternalPaths"));
     265         [ +  - ]:       5592 :     const ::rtl::OUString CFGPROP_ISSINGLEPATH(RTL_CONSTASCII_USTRINGPARAM("IsSinglePath"));
     266                 :            : 
     267         [ +  - ]:       5592 :     css::uno::Reference< css::container::XNameAccess > xCfg = fa_getCfgNew();
     268                 :            : 
     269                 :            :     // get access to the "queried" path
     270                 :       5592 :     css::uno::Reference< css::container::XNameAccess > xPath;
     271 [ +  - ][ +  - ]:       5592 :     xCfg->getByName(sPath) >>= xPath;
                 [ +  - ]
     272                 :            : 
     273         [ +  - ]:       5592 :     PathSettings::PathInfo aPathVal;
     274                 :            : 
     275                 :            :     // read internal path list
     276                 :       5592 :     css::uno::Reference< css::container::XNameAccess > xIPath;
     277 [ +  - ][ +  - ]:       5592 :     xPath->getByName(CFGPROP_INTERNALPATHS) >>= xIPath;
                 [ +  - ]
     278 [ +  - ][ +  - ]:       5592 :     aPathVal.lInternalPaths << xIPath->getElementNames();
         [ +  - ][ +  - ]
     279                 :            : 
     280                 :            :     // read user defined path list
     281 [ +  - ][ +  - ]:       5592 :     aPathVal.lUserPaths << xPath->getByName(CFGPROP_USERPATHS);
         [ +  - ][ +  - ]
     282                 :            : 
     283                 :            :     // read the writeable path
     284 [ +  - ][ +  - ]:       5592 :     xPath->getByName(CFGPROP_WRITEPATH) >>= aPathVal.sWritePath;
                 [ +  - ]
     285                 :            : 
     286                 :            :     // read state props
     287 [ +  - ][ +  - ]:       5592 :     xPath->getByName(CFGPROP_ISSINGLEPATH) >>= aPathVal.bIsSinglePath;
     288                 :            : 
     289                 :            :     // analyze finalized/mandatory states
     290                 :       5592 :     aPathVal.bIsReadonly = sal_False;
     291         [ +  - ]:       5592 :     css::uno::Reference< css::beans::XProperty > xInfo(xPath, css::uno::UNO_QUERY);
     292         [ +  - ]:       5592 :     if (xInfo.is())
     293                 :            :     {
     294 [ +  - ][ +  - ]:       5592 :         css::beans::Property aInfo = xInfo->getAsProperty();
     295                 :       5592 :         sal_Bool bFinalized = ((aInfo.Attributes & css::beans::PropertyAttribute::READONLY  ) == css::beans::PropertyAttribute::READONLY  );
     296                 :            : 
     297                 :            :         // Note: Till we support finalized / mandatory on our API more in detail we handle
     298                 :            :         // all states simple as READONLY ! But because all realy needed paths are "mandatory" by default
     299                 :            :         // we have to handle "finalized" as the real "readonly" indicator .
     300                 :       5592 :         aPathVal.bIsReadonly = bFinalized;
     301                 :            :     }
     302                 :            : 
     303                 :       5592 :     return aPathVal;
     304                 :            : }
     305                 :            : 
     306                 :            : //-----------------------------------------------------------------------------
     307                 :          0 : void PathSettings::impl_storePath(const PathSettings::PathInfo& aPath)
     308                 :            : {
     309                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_storePath" );
     310                 :          0 :     m_bIgnoreEvents = sal_True;
     311                 :            : 
     312         [ #  # ]:          0 :     css::uno::Reference< css::container::XNameAccess > xCfgNew = fa_getCfgNew();
     313         [ #  # ]:          0 :     css::uno::Reference< css::container::XNameAccess > xCfgOld = fa_getCfgOld();
     314                 :            : 
     315                 :            :     // try to replace path-parts with well known and uspported variables.
     316                 :            :     // So an office can be moved easialy to another location without loosing
     317                 :            :     // it's related paths.
     318         [ #  # ]:          0 :     PathInfo aResubstPath(aPath);
     319         [ #  # ]:          0 :     impl_subst(aResubstPath, sal_True);
     320                 :            : 
     321                 :            :     // update new configuration
     322         [ #  # ]:          0 :     if (! aResubstPath.bIsSinglePath)
     323                 :            :     {
     324                 :            :         ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
     325                 :            :                                                             aResubstPath.sPathName,
     326                 :            :                                                             CFGPROP_USERPATHS,
     327 [ #  # ][ #  # ]:          0 :                                                             css::uno::makeAny(aResubstPath.lUserPaths.getAsConstList()));
         [ #  # ][ #  # ]
                 [ #  # ]
     328                 :            :     }
     329                 :            : 
     330                 :            :     ::comphelper::ConfigurationHelper::writeRelativeKey(xCfgNew,
     331                 :            :                                                         aResubstPath.sPathName,
     332                 :            :                                                         CFGPROP_WRITEPATH,
     333 [ #  # ][ #  # ]:          0 :                                                         css::uno::makeAny(aResubstPath.sWritePath));
                 [ #  # ]
     334                 :            : 
     335         [ #  # ]:          0 :     ::comphelper::ConfigurationHelper::flush(xCfgNew);
     336                 :            : 
     337                 :            :     // remove the whole path from the old configuration !
     338                 :            :     // Otherwise we cant make sure that the diff between new and old configuration
     339                 :            :     // on loading time realy represent an user setting !!!
     340                 :            : 
     341                 :            :     // Check if the given path exists inside the old configuration.
     342                 :            :     // Because our new configuration knows more then the list of old paths ... !
     343 [ #  # ][ #  # ]:          0 :     if (xCfgOld->hasByName(aResubstPath.sPathName))
                 [ #  # ]
     344                 :            :     {
     345         [ #  # ]:          0 :         css::uno::Reference< css::beans::XPropertySet > xProps(xCfgOld, css::uno::UNO_QUERY_THROW);
     346 [ #  # ][ #  # ]:          0 :         xProps->setPropertyValue(aResubstPath.sPathName, css::uno::Any());
     347         [ #  # ]:          0 :         ::comphelper::ConfigurationHelper::flush(xCfgOld);
     348                 :            :     }
     349                 :            : 
     350         [ #  # ]:          0 :     m_bIgnoreEvents = sal_False;
     351                 :          0 : }
     352                 :            : 
     353                 :            : //-----------------------------------------------------------------------------
     354                 :       5592 : void PathSettings::impl_mergeOldUserPaths(      PathSettings::PathInfo& rPath,
     355                 :            :                                           const OUStringList&           lOld )
     356                 :            : {
     357                 :            :     RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "framework", "Ocke.Janssen@sun.com", "PathSettings::impl_mergeOldUserPaths" );
     358                 :       5592 :     OUStringList::const_iterator pIt;
     359 [ +  - ][ +  + ]:      24698 :     for (  pIt  = lOld.begin();
     360                 :      12349 :            pIt != lOld.end()  ;
     361                 :            :          ++pIt                )
     362                 :            :     {
     363                 :       6757 :         const ::rtl::OUString& sOld = *pIt;
     364                 :            : 
     365         [ +  + ]:       6757 :         if (rPath.bIsSinglePath)
     366                 :            :         {
     367                 :            :             LOG_ASSERT2(lOld.size()>1, "PathSettings::impl_mergeOldUserPaths()", "Single path has more then one path value inside old configuration (Common.xcu)!")
     368         [ +  + ]:       1165 :             if (! rPath.sWritePath.equals(sOld))
     369                 :         63 :                rPath.sWritePath = sOld;
     370                 :            :         }
     371                 :            :         else
     372                 :            :         {
     373         [ +  + ]:      15486 :             if (
           [ +  -  +  + ]
                 [ +  + ]
     374 [ +  - ][ +  - ]:      11184 :                 (  rPath.lInternalPaths.findConst(sOld) == rPath.lInternalPaths.end()) &&
         [ +  - ][ +  - ]
           [ #  #  #  # ]
     375 [ +  - ][ +  - ]:       7743 :                 (  rPath.lUserPaths.findConst(sOld)     == rPath.lUserPaths.end()    ) &&
         [ +  + ][ +  + ]
           [ #  #  #  # ]
     376                 :       2151 :                 (! rPath.sWritePath.equals(sOld)                                     )
     377                 :            :                )
     378         [ +  - ]:        287 :                rPath.lUserPaths.push_back(sOld);
     379                 :            :         }
     380                 :            :     }
     381                 :       5592 : }
     382                 :            : 
     383                 :            : //-----------------------------------------------------------------------------
     384                 :       5592 : PathSettings::EChangeOp PathSettings::impl_updatePath(const ::rtl::OUString& sPath          ,
     385                 :            :                                                             sal_Bool         bNotifyListener)
     386                 :            : {
     387                 :            :     // SAFE ->
     388         [ +  - ]:       5592 :     WriteGuard aWriteLock(m_aLock);
     389                 :            : 
     390                 :       5592 :     PathSettings::PathInfo* pPathOld = 0;
     391                 :       5592 :     PathSettings::PathInfo* pPathNew = 0;
     392                 :       5592 :     PathSettings::EChangeOp eOp      = PathSettings::E_UNDEFINED;
     393         [ +  - ]:       5592 :     PathSettings::PathInfo  aPath;
     394                 :            : 
     395                 :            :     try
     396                 :            :     {
     397 [ +  - ][ +  - ]:       5592 :         aPath = impl_readNewFormat(sPath);
                 [ +  - ]
     398                 :       5592 :         aPath.sPathName = sPath;
     399                 :            :         // replace all might existing variables with real values
     400                 :            :         // Do it before these old paths will be compared against the
     401                 :            :         // new path configuration. Otherwise some striungs uses different variables ... but substitution
     402                 :            :         // will produce strings with same content (because some variables are redundant!)
     403         [ +  - ]:       5592 :         impl_subst(aPath, sal_False);
     404                 :            :     }
     405                 :          0 :     catch(const css::uno::RuntimeException&)
     406                 :          0 :         { throw; }
     407         [ #  # ]:          0 :     catch(const css::container::NoSuchElementException&)
     408                 :          0 :         { eOp = PathSettings::E_REMOVED; }
     409   [ #  #  #  # ]:          0 :     catch(const css::uno::Exception&)
     410                 :          0 :         { throw; }
     411                 :            : 
     412                 :            :     try
     413                 :            :     {
     414                 :            :         // migration of old user defined values on demand
     415                 :            :         // can be disabled for a new major
     416         [ +  - ]:       5592 :         OUStringList lOldVals = impl_readOldFormat(sPath);
     417                 :            :         // replace all might existing variables with real values
     418                 :            :         // Do it before these old paths will be compared against the
     419                 :            :         // new path configuration. Otherwise some striungs uses different variables ... but substitution
     420                 :            :         // will produce strings with same content (because some variables are redundant!)
     421 [ +  - ][ +  - ]:       5592 :         impl_subst(lOldVals, fa_getSubstitution(), sal_False);
     422 [ +  - ][ +  - ]:       5592 :         impl_mergeOldUserPaths(aPath, lOldVals);
     423                 :            :     }
     424      [ #  #  # ]:          0 :     catch(const css::uno::RuntimeException&)
     425                 :          0 :         { throw; }
     426                 :            :     // Normal(!) exceptions can be ignored!
     427                 :            :     // E.g. in case an addon installs a new path, which was not well known for an OOo 1.x installation
     428                 :            :     // we cant find a value for it inside the "old" configuration. So a NoSuchElementException
     429                 :            :     // will be normal .-)
     430         [ #  # ]:          0 :     catch(const css::uno::Exception&)
     431                 :            :         {}
     432                 :            : 
     433         [ +  - ]:       5592 :     PathSettings::PathHash::iterator pPath = m_lPaths.find(sPath);
     434         [ +  - ]:       5592 :     if (eOp == PathSettings::E_UNDEFINED)
     435                 :            :     {
     436 [ +  - ][ -  + ]:       5592 :         if (pPath != m_lPaths.end())
     437                 :          0 :             eOp = PathSettings::E_CHANGED;
     438                 :            :         else
     439                 :       5592 :             eOp = PathSettings::E_ADDED;
     440                 :            :     }
     441                 :            : 
     442   [ +  -  -  - ]:       5592 :     switch(eOp)
     443                 :            :     {
     444                 :            :         case PathSettings::E_ADDED :
     445                 :            :              {
     446         [ -  + ]:       5592 :                 if (bNotifyListener)
     447                 :            :                 {
     448                 :          0 :                     pPathOld = 0;
     449                 :          0 :                     pPathNew = &aPath;
     450         [ #  # ]:          0 :                     impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     451                 :            :                 }
     452 [ +  - ][ +  - ]:       5592 :                 m_lPaths[sPath] = aPath;
     453                 :            :              }
     454                 :       5592 :              break;
     455                 :            : 
     456                 :            :         case PathSettings::E_CHANGED :
     457                 :            :              {
     458         [ #  # ]:          0 :                 if (bNotifyListener)
     459                 :            :                 {
     460         [ #  # ]:          0 :                     pPathOld = &(pPath->second);
     461                 :          0 :                     pPathNew = &aPath;
     462         [ #  # ]:          0 :                     impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     463                 :            :                 }
     464 [ #  # ][ #  # ]:          0 :                 m_lPaths[sPath] = aPath;
     465                 :            :              }
     466                 :          0 :              break;
     467                 :            : 
     468                 :            :         case PathSettings::E_REMOVED :
     469                 :            :              {
     470 [ #  # ][ #  # ]:          0 :                 if (pPath != m_lPaths.end())
     471                 :            :                 {
     472         [ #  # ]:          0 :                     if (bNotifyListener)
     473                 :            :                     {
     474         [ #  # ]:          0 :                         pPathOld = &(pPath->second);
     475                 :          0 :                         pPathNew = 0;
     476         [ #  # ]:          0 :                         impl_notifyPropListener(eOp, sPath, pPathOld, pPathNew);
     477                 :            :                     }
     478         [ #  # ]:          0 :                     m_lPaths.erase(pPath);
     479                 :            :                 }
     480                 :            :              }
     481                 :          0 :              break;
     482                 :            : 
     483                 :            :         default: // to let compiler be happy
     484                 :          0 :              break;
     485                 :            :     }
     486                 :            : 
     487 [ +  - ][ +  - ]:       5592 :     return eOp;
     488                 :            : }
     489                 :            : 
     490                 :            : //-----------------------------------------------------------------------------
     491                 :          0 : css::uno::Sequence< sal_Int32 > PathSettings::impl_mapPathName2IDList(const ::rtl::OUString& sPath)
     492                 :            : {
     493                 :          0 :     ::rtl::OUString sOldStyleProp = sPath;
     494         [ #  # ]:          0 :     ::rtl::OUString sInternalProp = sPath+POSTFIX_INTERNAL_PATHS;
     495         [ #  # ]:          0 :     ::rtl::OUString sUserProp     = sPath+POSTFIX_USER_PATHS;
     496         [ #  # ]:          0 :     ::rtl::OUString sWriteProp    = sPath+POSTFIX_WRITE_PATH;
     497                 :            : 
     498                 :            :     // Attention: The default set of IDs is fix and must follow these schema.
     499                 :            :     // Otherwhise the outside code ant work for new added properties.
     500                 :            :     // Why ?
     501                 :            :     // The outside code must fire N events for every changed property.
     502                 :            :     // And the knowing about packaging of variables of the structure PathInfo
     503                 :            :     // follow these group IDs ! But if such ID isnt in the range of [0..IDGROUP_COUNT]
     504                 :            :     // the outside cant determine the right group ... and cant fire the right events .-)
     505                 :            : 
     506         [ #  # ]:          0 :     css::uno::Sequence< sal_Int32 > lIDs(IDGROUP_COUNT);
     507         [ #  # ]:          0 :     lIDs[0] = IDGROUP_OLDSTYLE       ;
     508         [ #  # ]:          0 :     lIDs[1] = IDGROUP_INTERNAL_PATHS;
     509         [ #  # ]:          0 :     lIDs[2] = IDGROUP_USER_PATHS    ;
     510         [ #  # ]:          0 :     lIDs[3] = IDGROUP_WRITE_PATH     ;
     511                 :            : 
     512                 :          0 :     sal_Int32 c = m_lPropDesc.getLength();
     513                 :          0 :     sal_Int32 i = 0;
     514         [ #  # ]:          0 :     for (i=0; i<c; ++i)
     515                 :            :     {
     516         [ #  # ]:          0 :         const css::beans::Property& rProp = m_lPropDesc[i];
     517                 :            : 
     518         [ #  # ]:          0 :         if (rProp.Name.equals(sOldStyleProp))
     519         [ #  # ]:          0 :             lIDs[IDGROUP_OLDSTYLE] = rProp.Handle;
     520                 :            :         else
     521         [ #  # ]:          0 :         if (rProp.Name.equals(sInternalProp))
     522         [ #  # ]:          0 :             lIDs[IDGROUP_INTERNAL_PATHS] = rProp.Handle;
     523                 :            :         else
     524         [ #  # ]:          0 :         if (rProp.Name.equals(sUserProp))
     525         [ #  # ]:          0 :             lIDs[IDGROUP_USER_PATHS] = rProp.Handle;
     526                 :            :         else
     527         [ #  # ]:          0 :         if (rProp.Name.equals(sWriteProp))
     528         [ #  # ]:          0 :             lIDs[IDGROUP_WRITE_PATH] = rProp.Handle;
     529                 :            :     }
     530                 :            : 
     531                 :          0 :     return lIDs;
     532                 :            : }
     533                 :            : 
     534                 :            : //-----------------------------------------------------------------------------
     535                 :          0 : void PathSettings::impl_notifyPropListener(      PathSettings::EChangeOp /*eOp*/     ,
     536                 :            :                                            const ::rtl::OUString&        sPath   ,
     537                 :            :                                            const PathSettings::PathInfo* pPathOld,
     538                 :            :                                            const PathSettings::PathInfo* pPathNew)
     539                 :            : {
     540         [ #  # ]:          0 :     css::uno::Sequence< sal_Int32 >     lHandles(1);
     541         [ #  # ]:          0 :     css::uno::Sequence< css::uno::Any > lOldVals(1);
     542         [ #  # ]:          0 :     css::uno::Sequence< css::uno::Any > lNewVals(1);
     543                 :            : 
     544         [ #  # ]:          0 :     css::uno::Sequence< sal_Int32 > lIDs   = impl_mapPathName2IDList(sPath);
     545                 :          0 :     sal_Int32                       c      = lIDs.getLength();
     546                 :          0 :     sal_Int32                       i      = 0;
     547                 :          0 :     sal_Int32                       nMaxID = m_lPropDesc.getLength()-1;
     548         [ #  # ]:          0 :     for (i=0; i<c; ++i)
     549                 :            :     {
     550         [ #  # ]:          0 :         sal_Int32 nID = lIDs[i];
     551                 :            : 
     552 [ #  # ][ #  # ]:          0 :         if (
     553                 :            :             (nID < 0     ) ||
     554                 :            :             (nID > nMaxID)
     555                 :            :            )
     556                 :          0 :            continue;
     557                 :            : 
     558         [ #  # ]:          0 :         lHandles[0] = nID;
     559   [ #  #  #  #  :          0 :         switch(impl_getPropGroup(nID))
                      # ]
     560                 :            :         {
     561                 :            :             case IDGROUP_OLDSTYLE :
     562                 :            :                  {
     563         [ #  # ]:          0 :                     if (pPathOld)
     564                 :            :                     {
     565         [ #  # ]:          0 :                         ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathOld);
     566 [ #  # ][ #  # ]:          0 :                         lOldVals[0] <<= sVal;
     567                 :            :                     }
     568         [ #  # ]:          0 :                     if (pPathNew)
     569                 :            :                     {
     570         [ #  # ]:          0 :                         ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPathNew);
     571 [ #  # ][ #  # ]:          0 :                         lNewVals[0] <<= sVal;
     572                 :            :                     }
     573                 :            :                  }
     574                 :          0 :                  break;
     575                 :            : 
     576                 :            :             case IDGROUP_INTERNAL_PATHS :
     577                 :            :                  {
     578         [ #  # ]:          0 :                     if (pPathOld)
     579 [ #  # ][ #  # ]:          0 :                         lOldVals[0] <<= pPathOld->lInternalPaths.getAsConstList();
         [ #  # ][ #  # ]
     580         [ #  # ]:          0 :                     if (pPathNew)
     581 [ #  # ][ #  # ]:          0 :                         lNewVals[0] <<= pPathNew->lInternalPaths.getAsConstList();
         [ #  # ][ #  # ]
     582                 :            :                  }
     583                 :          0 :                  break;
     584                 :            : 
     585                 :            :             case IDGROUP_USER_PATHS :
     586                 :            :                  {
     587         [ #  # ]:          0 :                     if (pPathOld)
     588 [ #  # ][ #  # ]:          0 :                         lOldVals[0] <<= pPathOld->lUserPaths.getAsConstList();
         [ #  # ][ #  # ]
     589         [ #  # ]:          0 :                     if (pPathNew)
     590 [ #  # ][ #  # ]:          0 :                         lNewVals[0] <<= pPathNew->lUserPaths.getAsConstList();
         [ #  # ][ #  # ]
     591                 :            :                  }
     592                 :          0 :                  break;
     593                 :            : 
     594                 :            :             case IDGROUP_WRITE_PATH :
     595                 :            :                  {
     596         [ #  # ]:          0 :                     if (pPathOld)
     597 [ #  # ][ #  # ]:          0 :                         lOldVals[0] <<= pPathOld->sWritePath;
     598         [ #  # ]:          0 :                     if (pPathNew)
     599 [ #  # ][ #  # ]:          0 :                         lNewVals[0] <<= pPathNew->sWritePath;
     600                 :            :                  }
     601                 :          0 :                  break;
     602                 :            :         }
     603                 :            : 
     604                 :            :         fire(lHandles.getArray(),
     605         [ #  # ]:          0 :              lNewVals.getArray(),
     606         [ #  # ]:          0 :              lOldVals.getArray(),
     607                 :            :              1,
     608 [ #  # ][ #  # ]:          0 :              sal_False);
     609 [ #  # ][ #  # ]:          0 :     }
         [ #  # ][ #  # ]
     610                 :          0 : }
     611                 :            : 
     612                 :            : //-----------------------------------------------------------------------------
     613                 :      16778 : void PathSettings::impl_subst(      OUStringList&                                          lVals   ,
     614                 :            :                               const css::uno::Reference< css::util::XStringSubstitution >& xSubst  ,
     615                 :            :                                     sal_Bool                                               bReSubst)
     616                 :            : {
     617                 :      16778 :     OUStringList::iterator pIt;
     618                 :            : 
     619 [ +  - ][ +  + ]:      55756 :     for (  pIt  = lVals.begin();
     620                 :      27878 :            pIt != lVals.end()  ;
     621                 :            :          ++pIt                 )
     622                 :            :     {
     623                 :      11100 :         const ::rtl::OUString& sOld = *pIt;
     624                 :      11100 :               ::rtl::OUString  sNew ;
     625         [ -  + ]:      11100 :         if (bReSubst)
     626 [ #  # ][ #  # ]:          0 :             sNew = xSubst->reSubstituteVariables(sOld);
     627                 :            :         else
     628 [ +  - ][ +  - ]:      11100 :             sNew = xSubst->substituteVariables(sOld, sal_False);
     629                 :            : 
     630                 :      11100 :         *pIt = sNew;
     631                 :      11100 :     }
     632                 :      16778 : }
     633                 :            : 
     634                 :            : //-----------------------------------------------------------------------------
     635                 :       5592 : void PathSettings::impl_subst(PathSettings::PathInfo& aPath   ,
     636                 :            :                               sal_Bool                bReSubst)
     637                 :            : {
     638         [ +  - ]:       5592 :     css::uno::Reference< css::util::XStringSubstitution > xSubst = fa_getSubstitution();
     639                 :            : 
     640         [ +  - ]:       5592 :     impl_subst(aPath.lInternalPaths, xSubst, bReSubst);
     641         [ +  - ]:       5592 :     impl_subst(aPath.lUserPaths    , xSubst, bReSubst);
     642         [ -  + ]:       5592 :     if (bReSubst)
     643 [ #  # ][ #  # ]:          0 :         aPath.sWritePath = xSubst->reSubstituteVariables(aPath.sWritePath);
     644                 :            :     else
     645 [ +  - ][ +  - ]:       5592 :         aPath.sWritePath = xSubst->substituteVariables(aPath.sWritePath, sal_False);
     646                 :       5592 : }
     647                 :            : 
     648                 :            : //-----------------------------------------------------------------------------
     649                 :       5995 : ::rtl::OUString PathSettings::impl_convertPath2OldStyle(const PathSettings::PathInfo& rPath) const
     650                 :            : {
     651                 :       5995 :     OUStringList::const_iterator pIt;
     652         [ +  - ]:       5995 :     OUStringList                 lTemp;
     653         [ +  - ]:       5995 :     lTemp.reserve(rPath.lInternalPaths.size() + rPath.lUserPaths.size() + 1);
     654                 :            : 
     655 [ +  - ][ +  + ]:      16860 :     for (  pIt  = rPath.lInternalPaths.begin();
     656                 :       8430 :            pIt != rPath.lInternalPaths.end()  ;
     657                 :            :          ++pIt                                 )
     658                 :            :     {
     659         [ +  - ]:       2435 :         lTemp.push_back(*pIt);
     660                 :            :     }
     661 [ +  - ][ +  + ]:      12108 :     for (  pIt  = rPath.lUserPaths.begin();
     662                 :       6054 :            pIt != rPath.lUserPaths.end()  ;
     663                 :            :          ++pIt                             )
     664                 :            :     {
     665         [ +  - ]:         59 :         lTemp.push_back(*pIt);
     666                 :            :     }
     667                 :            : 
     668         [ +  + ]:       5995 :     if (!rPath.sWritePath.isEmpty())
     669         [ +  - ]:       5437 :         lTemp.push_back(rPath.sWritePath);
     670                 :            : 
     671                 :       5995 :     ::rtl::OUStringBuffer sPathVal(256);
     672 [ +  - ][ +  + ]:      19921 :     for (  pIt  = lTemp.begin();
                 [ +  - ]
     673                 :      13926 :            pIt != lTemp.end()  ;
     674                 :            :                                )
     675                 :            :     {
     676         [ +  - ]:       7931 :         sPathVal.append(*pIt);
     677                 :       7931 :         ++pIt;
     678 [ +  + ][ +  - ]:       7931 :         if (pIt != lTemp.end())
     679         [ +  - ]:       1936 :             sPathVal.appendAscii(";");
     680                 :            :     }
     681                 :            : 
     682 [ +  - ][ +  - ]:       5995 :     return sPathVal.makeStringAndClear();
     683                 :            : }
     684                 :            : 
     685                 :            : //-----------------------------------------------------------------------------
     686                 :          2 : OUStringList PathSettings::impl_convertOldStyle2Path(const ::rtl::OUString& sOldStylePath) const
     687                 :            : {
     688         [ +  - ]:          2 :     OUStringList lList;
     689                 :          2 :     sal_Int32    nToken = 0;
     690         [ -  + ]:          2 :     do
     691                 :            :     {
     692                 :          2 :         ::rtl::OUString sToken = sOldStylePath.getToken(0, ';', nToken);
     693         [ +  - ]:          2 :         if (!sToken.isEmpty())
     694         [ +  - ]:          2 :             lList.push_back(sToken);
     695                 :            :     }
     696                 :            :     while(nToken >= 0);
     697                 :            : 
     698                 :          2 :     return lList;
     699                 :            : }
     700                 :            : 
     701                 :            : //-----------------------------------------------------------------------------
     702                 :          2 : void PathSettings::impl_purgeKnownPaths(const PathSettings::PathInfo& rPath,
     703                 :            :                                                OUStringList&           lList)
     704                 :            : {
     705                 :          2 :     OUStringList::const_iterator pIt;
     706 [ +  - ][ +  + ]:         12 :     for (  pIt  = rPath.lInternalPaths.begin();
     707                 :          6 :            pIt != rPath.lInternalPaths.end()  ;
     708                 :            :          ++pIt                                 )
     709                 :            :     {
     710                 :          4 :         const ::rtl::OUString& rItem = *pIt;
     711         [ +  - ]:          4 :         OUStringList::iterator pItem = lList.find(rItem);
     712 [ +  - ][ -  + ]:          4 :         if (pItem != lList.end())
     713         [ #  # ]:          0 :             lList.erase(pItem);
     714                 :            :     }
     715 [ +  - ][ +  + ]:          8 :     for (  pIt  = rPath.lUserPaths.begin();
     716                 :          4 :            pIt != rPath.lUserPaths.end()  ;
     717                 :            :          ++pIt                             )
     718                 :            :     {
     719                 :          2 :         const ::rtl::OUString& rItem = *pIt;
     720         [ +  - ]:          2 :         OUStringList::iterator pItem = lList.find(rItem);
     721 [ +  - ][ -  + ]:          2 :         if (pItem != lList.end())
     722         [ #  # ]:          0 :             lList.erase(pItem);
     723                 :            :     }
     724                 :            : 
     725         [ +  - ]:          2 :     OUStringList::iterator pItem = lList.find(rPath.sWritePath);
     726 [ +  - ][ -  + ]:          2 :     if (pItem != lList.end())
     727         [ #  # ]:          0 :         lList.erase(pItem);
     728                 :          2 : }
     729                 :            : 
     730                 :            : //-----------------------------------------------------------------------------
     731                 :        233 : void PathSettings::impl_rebuildPropertyDescriptor()
     732                 :            : {
     733                 :            :     // SAFE ->
     734         [ +  - ]:        233 :     WriteGuard aWriteLock(m_aLock);
     735                 :            : 
     736                 :        233 :     sal_Int32 c = (sal_Int32)m_lPaths.size();
     737                 :        233 :     sal_Int32 i = 0;
     738         [ +  - ]:        233 :     m_lPropDesc.realloc(c*IDGROUP_COUNT);
     739                 :            : 
     740                 :        233 :     PathHash::const_iterator pIt;
     741 [ +  + ][ +  - ]:      11650 :     for (  pIt  = m_lPaths.begin();
     742         [ +  - ]:       5825 :            pIt != m_lPaths.end()  ;
     743                 :            :          ++pIt                     )
     744                 :            :     {
     745         [ +  - ]:       5592 :         const PathSettings::PathInfo& rPath = pIt->second;
     746                 :       5592 :               css::beans::Property*   pProp = 0;
     747                 :            : 
     748         [ +  - ]:       5592 :         pProp             = &(m_lPropDesc[i]);
     749                 :       5592 :         pProp->Name       = rPath.sPathName;
     750                 :       5592 :         pProp->Handle     = i;
     751         [ +  - ]:       5592 :         pProp->Type       = ::getCppuType((::rtl::OUString*)0);
     752                 :       5592 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
     753         [ -  + ]:       5592 :         if (rPath.bIsReadonly)
     754                 :          0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
     755                 :       5592 :         ++i;
     756                 :            : 
     757         [ +  - ]:       5592 :         pProp             = &(m_lPropDesc[i]);
     758         [ +  - ]:       5592 :         pProp->Name       = rPath.sPathName+POSTFIX_INTERNAL_PATHS;
     759                 :       5592 :         pProp->Handle     = i;
     760         [ +  - ]:       5592 :         pProp->Type       = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
     761                 :            :         pProp->Attributes = css::beans::PropertyAttribute::BOUND   |
     762                 :       5592 :                             css::beans::PropertyAttribute::READONLY;
     763                 :       5592 :         ++i;
     764                 :            : 
     765         [ +  - ]:       5592 :         pProp             = &(m_lPropDesc[i]);
     766         [ +  - ]:       5592 :         pProp->Name       = rPath.sPathName+POSTFIX_USER_PATHS;
     767                 :       5592 :         pProp->Handle     = i;
     768         [ +  - ]:       5592 :         pProp->Type       = ::getCppuType((css::uno::Sequence< ::rtl::OUString >*)0);
     769                 :       5592 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
     770         [ -  + ]:       5592 :         if (rPath.bIsReadonly)
     771                 :          0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
     772                 :       5592 :         ++i;
     773                 :            : 
     774         [ +  - ]:       5592 :         pProp             = &(m_lPropDesc[i]);
     775         [ +  - ]:       5592 :         pProp->Name       = rPath.sPathName+POSTFIX_WRITE_PATH;
     776                 :       5592 :         pProp->Handle     = i;
     777         [ +  - ]:       5592 :         pProp->Type       = ::getCppuType((::rtl::OUString*)0);
     778                 :       5592 :         pProp->Attributes = css::beans::PropertyAttribute::BOUND;
     779         [ -  + ]:       5592 :         if (rPath.bIsReadonly)
     780                 :          0 :             pProp->Attributes |= css::beans::PropertyAttribute::READONLY;
     781                 :       5592 :         ++i;
     782                 :            :     }
     783                 :            : 
     784         [ -  + ]:        233 :     if (m_pPropHelp)
     785 [ #  # ][ #  # ]:          0 :        delete m_pPropHelp;
     786         [ +  - ]:        233 :     m_pPropHelp = new ::cppu::OPropertyArrayHelper(m_lPropDesc, sal_False); // false => not sorted ... must be done inside helper
     787                 :            : 
     788 [ +  - ][ +  - ]:        233 :     aWriteLock.unlock();
     789                 :            :     // <- SAFE
     790                 :        233 : }
     791                 :            : 
     792                 :            : //-----------------------------------------------------------------------------
     793                 :       6415 : css::uno::Any PathSettings::impl_getPathValue(sal_Int32 nID) const
     794                 :            : {
     795                 :       6415 :     const PathSettings::PathInfo* pPath = impl_getPathAccessConst(nID);
     796         [ -  + ]:       6415 :     if (! pPath)
     797         [ #  # ]:          0 :         throw css::container::NoSuchElementException();
     798                 :            : 
     799                 :       6415 :     css::uno::Any aVal;
     800   [ +  +  +  +  :       6415 :     switch(impl_getPropGroup(nID))
                      - ]
     801                 :            :     {
     802                 :            :         case IDGROUP_OLDSTYLE :
     803                 :            :              {
     804         [ +  - ]:       5995 :                 ::rtl::OUString sVal = impl_convertPath2OldStyle(*pPath);
     805         [ +  - ]:       5995 :                 aVal <<= sVal;
     806                 :            :              }
     807                 :       5995 :              break;
     808                 :            : 
     809                 :            :         case IDGROUP_INTERNAL_PATHS :
     810                 :            :              {
     811 [ +  - ][ +  - ]:        140 :                 aVal <<= pPath->lInternalPaths.getAsConstList();
                 [ +  - ]
     812                 :            :              }
     813                 :        140 :              break;
     814                 :            : 
     815                 :            :         case IDGROUP_USER_PATHS :
     816                 :            :              {
     817 [ +  - ][ +  - ]:        140 :                 aVal <<= pPath->lUserPaths.getAsConstList();
                 [ +  - ]
     818                 :            :              }
     819                 :        140 :              break;
     820                 :            : 
     821                 :            :         case IDGROUP_WRITE_PATH :
     822                 :            :              {
     823         [ +  - ]:        140 :                 aVal <<= pPath->sWritePath;
     824                 :            :              }
     825                 :        140 :              break;
     826                 :            :     }
     827                 :            : 
     828                 :       6415 :     return aVal;
     829                 :            : }
     830                 :            : 
     831                 :            : //-----------------------------------------------------------------------------
     832                 :          2 : void PathSettings::impl_setPathValue(      sal_Int32      nID ,
     833                 :            :                                      const css::uno::Any& aVal)
     834                 :            : {
     835         [ +  - ]:          2 :     PathSettings::PathInfo* pOrgPath = impl_getPathAccess(nID);
     836         [ -  + ]:          2 :     if (! pOrgPath)
     837         [ #  # ]:          0 :         throw css::container::NoSuchElementException();
     838                 :            : 
     839                 :            :     // We work on a copied path ... so we can be sure that errors during this operation
     840                 :            :     // does not make our internal cache invalid  .-)
     841         [ +  - ]:          2 :     PathSettings::PathInfo aChangePath(*pOrgPath);
     842                 :            : 
     843   [ +  -  -  -  :          2 :     switch(impl_getPropGroup(nID))
                      - ]
     844                 :            :     {
     845                 :            :         case IDGROUP_OLDSTYLE :
     846                 :            :              {
     847                 :          2 :                 ::rtl::OUString sVal;
     848                 :          2 :                 aVal >>= sVal;
     849         [ +  - ]:          2 :                 OUStringList lList = impl_convertOldStyle2Path(sVal);
     850 [ +  - ][ +  - ]:          2 :                 impl_subst(lList, fa_getSubstitution(), sal_False);
     851         [ +  - ]:          2 :                 impl_purgeKnownPaths(aChangePath, lList);
     852 [ +  - ][ +  - ]:          2 :                 if (! impl_isValidPath(lList))
     853         [ +  - ]:          2 :                     throw css::lang::IllegalArgumentException();
     854                 :            : 
     855         [ #  # ]:          0 :                 if (aChangePath.bIsSinglePath)
     856                 :            :                 {
     857                 :            :                     LOG_ASSERT2(lList.size()>1, "PathSettings::impl_setPathValue()", "You try to set more then path value for a defined SINGLE_PATH!")
     858         [ #  # ]:          0 :                     if ( !lList.empty() )
     859                 :          0 :                         aChangePath.sWritePath = *(lList.begin());
     860                 :            :                     else
     861                 :          0 :                         aChangePath.sWritePath = ::rtl::OUString();
     862                 :            :                 }
     863                 :            :                 else
     864                 :            :                 {
     865                 :          0 :                     OUStringList::const_iterator pIt;
     866 [ #  # ][ #  # ]:          0 :                     for (  pIt  = lList.begin();
                 [ #  # ]
     867                 :          0 :                            pIt != lList.end()  ;
     868                 :            :                          ++pIt                 )
     869                 :            :                     {
     870         [ #  # ]:          0 :                         aChangePath.lUserPaths.push_back(*pIt);
     871                 :            :                     }
     872         [ #  # ]:          2 :                 }
     873                 :            :              }
     874                 :          0 :              break;
     875                 :            : 
     876                 :            :         case IDGROUP_INTERNAL_PATHS :
     877                 :            :              {
     878         [ #  # ]:          0 :                 if (aChangePath.bIsSinglePath)
     879                 :            :                 {
     880                 :          0 :                     ::rtl::OUStringBuffer sMsg(256);
     881         [ #  # ]:          0 :                     sMsg.appendAscii("The path '"    );
     882         [ #  # ]:          0 :                     sMsg.append     (aChangePath.sPathName);
     883         [ #  # ]:          0 :                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths cant be set.");
     884                 :            :                     throw css::uno::Exception(sMsg.makeStringAndClear(),
     885 [ #  # ][ #  # ]:          0 :                                               static_cast< ::cppu::OWeakObject* >(this));
                 [ #  # ]
     886                 :            :                 }
     887                 :            : 
     888         [ #  # ]:          0 :                 OUStringList lList;
     889         [ #  # ]:          0 :                 lList << aVal;
     890 [ #  # ][ #  # ]:          0 :                 if (! impl_isValidPath(lList))
     891         [ #  # ]:          0 :                     throw css::lang::IllegalArgumentException();
     892 [ #  # ][ #  # ]:          0 :                 aChangePath.lInternalPaths = lList;
     893                 :            :              }
     894                 :          0 :              break;
     895                 :            : 
     896                 :            :         case IDGROUP_USER_PATHS :
     897                 :            :              {
     898         [ #  # ]:          0 :                 if (aChangePath.bIsSinglePath)
     899                 :            :                 {
     900                 :          0 :                     ::rtl::OUStringBuffer sMsg(256);
     901         [ #  # ]:          0 :                     sMsg.appendAscii("The path '"    );
     902         [ #  # ]:          0 :                     sMsg.append     (aChangePath.sPathName);
     903         [ #  # ]:          0 :                     sMsg.appendAscii("' is defined as SINGLE_PATH. It's sub set of internal paths cant be set.");
     904                 :            :                     throw css::uno::Exception(sMsg.makeStringAndClear(),
     905 [ #  # ][ #  # ]:          0 :                                               static_cast< ::cppu::OWeakObject* >(this));
                 [ #  # ]
     906                 :            :                 }
     907                 :            : 
     908         [ #  # ]:          0 :                 OUStringList lList;
     909         [ #  # ]:          0 :                 lList << aVal;
     910 [ #  # ][ #  # ]:          0 :                 if (! impl_isValidPath(lList))
     911         [ #  # ]:          0 :                     throw css::lang::IllegalArgumentException();
     912 [ #  # ][ #  # ]:          0 :                 aChangePath.lUserPaths = lList;
     913                 :            :              }
     914                 :          0 :              break;
     915                 :            : 
     916                 :            :         case IDGROUP_WRITE_PATH :
     917                 :            :              {
     918                 :          0 :                 ::rtl::OUString sVal;
     919                 :          0 :                 aVal >>= sVal;
     920 [ #  # ][ #  # ]:          0 :                 if (! impl_isValidPath(sVal))
     921         [ #  # ]:          0 :                     throw css::lang::IllegalArgumentException();
     922                 :          0 :                 aChangePath.sWritePath = sVal;
     923                 :            :              }
     924                 :          0 :              break;
     925                 :            :     }
     926                 :            : 
     927                 :            :     // TODO check if path has at least one path value set
     928                 :            :     // At least it depends from the feature using this path, if an empty path list is allowed.
     929                 :            : 
     930                 :            :     // first we should try to store the changed (copied!) path ...
     931                 :            :     // In case an error occure on saving time an exception is thrown ...
     932                 :            :     // If no exception occures we can update our internal cache (means
     933                 :            :     // we can overwrite pOrgPath !
     934         [ #  # ]:          0 :     impl_storePath(aChangePath);
     935 [ #  # ][ #  # ]:          2 :     pOrgPath->takeOver(aChangePath);
     936                 :          0 : }
     937                 :            : 
     938                 :            : //-----------------------------------------------------------------------------
     939                 :          2 : sal_Bool PathSettings::impl_isValidPath(const OUStringList& lPath) const
     940                 :            : {
     941                 :          2 :     OUStringList::const_iterator pIt;
     942 [ +  - ][ +  - ]:          4 :     for (  pIt  = lPath.begin();
     943                 :          2 :            pIt != lPath.end()  ;
     944                 :            :          ++pIt                 )
     945                 :            :     {
     946                 :          2 :         const ::rtl::OUString& rVal = *pIt;
     947 [ +  - ][ +  - ]:          2 :         if (! impl_isValidPath(rVal))
     948                 :          2 :             return sal_False;
     949                 :            :     }
     950                 :            : 
     951                 :          2 :     return sal_True;
     952                 :            : }
     953                 :            : 
     954                 :            : //-----------------------------------------------------------------------------
     955                 :          2 : sal_Bool PathSettings::impl_isValidPath(const ::rtl::OUString& sPath) const
     956                 :            : {
     957                 :            :     // allow empty path to reset a path.
     958                 :            : // idea by LLA to support empty paths
     959                 :            : //    if (sPath.getLength() == 0)
     960                 :            : //    {
     961                 :            : //        return sal_True;
     962                 :            : //    }
     963                 :            : 
     964                 :          2 :     return (! INetURLObject(sPath).HasError());
     965                 :            : }
     966                 :            : 
     967                 :            : //-----------------------------------------------------------------------------
     968                 :       6417 : ::rtl::OUString impl_extractBaseFromPropName(const ::rtl::OUString& sPropName)
     969                 :            : {
     970                 :       6417 :     sal_Int32 i = -1;
     971                 :            : 
     972                 :       6417 :     i = sPropName.indexOf(POSTFIX_INTERNAL_PATHS);
     973         [ +  + ]:       6417 :     if (i > -1)
     974                 :        140 :         return sPropName.copy(0, i);
     975                 :       6277 :     i = sPropName.indexOf(POSTFIX_USER_PATHS);
     976         [ +  + ]:       6277 :     if (i > -1)
     977                 :        140 :         return sPropName.copy(0, i);
     978                 :       6137 :     i = sPropName.indexOf(POSTFIX_WRITE_PATH);
     979         [ +  + ]:       6137 :     if (i > -1)
     980                 :        140 :         return sPropName.copy(0, i);
     981                 :            : 
     982                 :       6417 :     return sPropName;
     983                 :            : }
     984                 :            : 
     985                 :            : //-----------------------------------------------------------------------------
     986                 :          2 : PathSettings::PathInfo* PathSettings::impl_getPathAccess(sal_Int32 nHandle)
     987                 :            : {
     988                 :            :     // SAFE ->
     989         [ +  - ]:          2 :     ReadGuard aReadLock(m_aLock);
     990                 :            : 
     991         [ -  + ]:          2 :     if (nHandle > (m_lPropDesc.getLength()-1))
     992                 :          0 :         return 0;
     993                 :            : 
     994         [ +  - ]:          2 :     const css::beans::Property&            rProp = m_lPropDesc[nHandle];
     995         [ +  - ]:          2 :           ::rtl::OUString                  sProp = impl_extractBaseFromPropName(rProp.Name);
     996         [ +  - ]:          2 :           PathSettings::PathHash::iterator rPath = m_lPaths.find(sProp);
     997                 :            : 
     998 [ +  - ][ +  - ]:          2 :     if (rPath != m_lPaths.end())
     999         [ +  - ]:          2 :        return &(rPath->second);
    1000                 :            : 
    1001         [ +  - ]:          2 :     return 0;
    1002                 :            :     // <- SAFE
    1003                 :            : }
    1004                 :            : 
    1005                 :            : //-----------------------------------------------------------------------------
    1006                 :       6415 : const PathSettings::PathInfo* PathSettings::impl_getPathAccessConst(sal_Int32 nHandle) const
    1007                 :            : {
    1008                 :            :     // SAFE ->
    1009         [ +  - ]:       6415 :     ReadGuard aReadLock(m_aLock);
    1010                 :            : 
    1011         [ -  + ]:       6415 :     if (nHandle > (m_lPropDesc.getLength()-1))
    1012                 :          0 :         return 0;
    1013                 :            : 
    1014                 :       6415 :     const css::beans::Property&                  rProp = m_lPropDesc[nHandle];
    1015         [ +  - ]:       6415 :           ::rtl::OUString                        sProp = impl_extractBaseFromPropName(rProp.Name);
    1016         [ +  - ]:       6415 :           PathSettings::PathHash::const_iterator rPath = m_lPaths.find(sProp);
    1017                 :            : 
    1018         [ +  - ]:       6415 :     if (rPath != m_lPaths.end())
    1019         [ +  - ]:       6415 :        return &(rPath->second);
    1020                 :            : 
    1021         [ +  - ]:       6415 :     return 0;
    1022                 :            :     // <- SAFE
    1023                 :            : }
    1024                 :            : 
    1025                 :            : //-----------------------------------------------------------------------------
    1026                 :          2 : sal_Bool SAL_CALL PathSettings::convertFastPropertyValue(      css::uno::Any& aConvertedValue,
    1027                 :            :                                                                css::uno::Any& aOldValue      ,
    1028                 :            :                                                                sal_Int32      nHandle        ,
    1029                 :            :                                                          const css::uno::Any& aValue         )
    1030                 :            :     throw(css::lang::IllegalArgumentException)
    1031                 :            : {
    1032                 :            :     // throws NoSuchElementException !
    1033         [ +  - ]:          2 :     css::uno::Any aCurrentVal = impl_getPathValue(nHandle);
    1034                 :            : 
    1035                 :            :     return PropHelper::willPropertyBeChanged(
    1036                 :            :                 aCurrentVal,
    1037                 :            :                 aValue,
    1038                 :            :                 aOldValue,
    1039                 :          2 :                 aConvertedValue);
    1040                 :            : }
    1041                 :            : 
    1042                 :            : //-----------------------------------------------------------------------------
    1043                 :          2 : void SAL_CALL PathSettings::setFastPropertyValue_NoBroadcast(      sal_Int32      nHandle,
    1044                 :            :                                                              const css::uno::Any& aValue )
    1045                 :            :     throw(css::uno::Exception)
    1046                 :            : {
    1047                 :            :     // throws NoSuchElement- and IllegalArgumentException !
    1048                 :          2 :     impl_setPathValue(nHandle, aValue);
    1049                 :          0 : }
    1050                 :            : 
    1051                 :            : //-----------------------------------------------------------------------------
    1052                 :       6413 : void SAL_CALL PathSettings::getFastPropertyValue(css::uno::Any& aValue ,
    1053                 :            :                                                  sal_Int32      nHandle) const
    1054                 :            : {
    1055                 :       6413 :     aValue = impl_getPathValue(nHandle);
    1056                 :       6413 : }
    1057                 :            : 
    1058                 :            : //-----------------------------------------------------------------------------
    1059                 :       8008 : ::cppu::IPropertyArrayHelper& SAL_CALL PathSettings::getInfoHelper()
    1060                 :            : {
    1061                 :       8008 :     return *m_pPropHelp;
    1062                 :            : }
    1063                 :            : 
    1064                 :            : //-----------------------------------------------------------------------------
    1065                 :        233 : css::uno::Reference< css::beans::XPropertySetInfo > SAL_CALL PathSettings::getPropertySetInfo()
    1066                 :            :     throw(css::uno::RuntimeException)
    1067                 :            : {
    1068                 :        233 :     return css::uno::Reference< css::beans::XPropertySetInfo >(createPropertySetInfo(getInfoHelper()));
    1069                 :            : }
    1070                 :            : 
    1071                 :            : //-----------------------------------------------------------------------------
    1072                 :      11186 : css::uno::Reference< css::util::XStringSubstitution > PathSettings::fa_getSubstitution()
    1073                 :            : {
    1074                 :            :     // SAFE ->
    1075         [ +  - ]:      11186 :     ReadGuard aReadLock(m_aLock);
    1076                 :      11186 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR  = m_xSMGR;
    1077                 :      11186 :     css::uno::Reference< css::util::XStringSubstitution >  xSubst = m_xSubstitution;
    1078         [ +  - ]:      11186 :     aReadLock.unlock();
    1079                 :            :     // <- SAFE
    1080                 :            : 
    1081         [ +  + ]:      11186 :     if (! xSubst.is())
    1082                 :            :     {
    1083                 :            :         // create the needed substitution service.
    1084                 :            :         // We must replace all used variables inside readed path values.
    1085                 :            :         // In case we can't do so ... the whole office can't work really.
    1086                 :            :         // That's why it seams to be OK to throw a RuntimeException then.
    1087 [ +  - ][ +  - ]:        233 :         css::uno::Reference< css::uno::XComponentContext > xContext( comphelper::ComponentContext(xSMGR).getUNOContext() );
                 [ +  - ]
    1088 [ +  - ][ +  - ]:        233 :         xSubst = css::util::PathSubstitution::create(xContext);
    1089                 :            : 
    1090                 :            :         // SAFE ->
    1091         [ +  - ]:        233 :         WriteGuard aWriteLock(m_aLock);
    1092         [ +  - ]:        233 :         m_xSubstitution = xSubst;
    1093 [ +  - ][ +  - ]:        233 :         aWriteLock.unlock();
    1094                 :            :     }
    1095                 :            : 
    1096         [ +  - ]:      11186 :     return xSubst;
    1097                 :            : }
    1098                 :            : 
    1099                 :            : //-----------------------------------------------------------------------------
    1100                 :       5592 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgOld()
    1101                 :            : {
    1102         [ +  - ]:       5592 :     const ::rtl::OUString CFG_NODE_OLD(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Common/Path/Current"));
    1103                 :            : 
    1104                 :            :     // SAFE ->
    1105         [ +  - ]:       5592 :     ReadGuard aReadLock(m_aLock);
    1106                 :       5592 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
    1107                 :       5592 :     css::uno::Reference< css::container::XNameAccess >     xCfg  = m_xCfgOld;
    1108         [ +  - ]:       5592 :     aReadLock.unlock();
    1109                 :            :     // <- SAFE
    1110                 :            : 
    1111         [ +  + ]:       5592 :     if (! xCfg.is())
    1112                 :            :     {
    1113                 :            :         xCfg = css::uno::Reference< css::container::XNameAccess >(
    1114                 :            :                    ::comphelper::ConfigurationHelper::openConfig(
    1115                 :            :                         xSMGR,
    1116                 :            :                         CFG_NODE_OLD,
    1117                 :            :                         ::comphelper::ConfigurationHelper::E_STANDARD), // not readonly! Somtimes we need write access there !!!
    1118 [ +  - ][ +  - ]:        233 :                    css::uno::UNO_QUERY_THROW);
                 [ +  - ]
    1119                 :            : 
    1120                 :            :         // SAFE ->
    1121         [ +  - ]:        233 :         WriteGuard aWriteLock(m_aLock);
    1122         [ +  - ]:        233 :         m_xCfgOld = xCfg;
    1123 [ +  - ][ +  - ]:        233 :         aWriteLock.unlock();
    1124                 :            :     }
    1125                 :            : 
    1126         [ +  - ]:       5592 :     return xCfg;
    1127                 :            : }
    1128                 :            : 
    1129                 :            : //-----------------------------------------------------------------------------
    1130                 :       5825 : css::uno::Reference< css::container::XNameAccess > PathSettings::fa_getCfgNew()
    1131                 :            : {
    1132         [ +  - ]:       5825 :     const ::rtl::OUString CFG_NODE_NEW(RTL_CONSTASCII_USTRINGPARAM("org.openoffice.Office.Paths/Paths"));
    1133                 :            : 
    1134                 :            :     // SAFE ->
    1135         [ +  - ]:       5825 :     ReadGuard aReadLock(m_aLock);
    1136                 :       5825 :     css::uno::Reference< css::lang::XMultiServiceFactory > xSMGR = m_xSMGR;
    1137                 :       5825 :     css::uno::Reference< css::container::XNameAccess >     xCfg  = m_xCfgNew;
    1138         [ +  - ]:       5825 :     aReadLock.unlock();
    1139                 :            :     // <- SAFE
    1140                 :            : 
    1141         [ +  + ]:       5825 :     if (! xCfg.is())
    1142                 :            :     {
    1143                 :            :         xCfg = css::uno::Reference< css::container::XNameAccess >(
    1144                 :            :                    ::comphelper::ConfigurationHelper::openConfig(
    1145                 :            :                         xSMGR,
    1146                 :            :                         CFG_NODE_NEW,
    1147                 :            :                         ::comphelper::ConfigurationHelper::E_STANDARD),
    1148 [ +  - ][ +  - ]:        233 :                    css::uno::UNO_QUERY_THROW);
                 [ +  - ]
    1149                 :            : 
    1150                 :            :         // SAFE ->
    1151         [ +  - ]:        233 :         WriteGuard aWriteLock(m_aLock);
    1152         [ +  - ]:        233 :         m_xCfgNew = xCfg;
    1153 [ +  - ][ +  - ]:        233 :         m_xCfgNewListener = new WeakChangesListener(this);
         [ +  - ][ +  - ]
    1154         [ +  - ]:        233 :         aWriteLock.unlock();
    1155                 :            : 
    1156         [ +  - ]:        233 :         css::uno::Reference< css::util::XChangesNotifier > xBroadcaster(xCfg, css::uno::UNO_QUERY_THROW);
    1157 [ +  - ][ +  - ]:        233 :         xBroadcaster->addChangesListener(m_xCfgNewListener);
                 [ +  - ]
    1158                 :            :     }
    1159                 :            : 
    1160         [ +  - ]:       5825 :     return xCfg;
    1161                 :            : }
    1162                 :            : 
    1163                 :            : } // namespace framework
    1164                 :            : 
    1165                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10