LCOV - code coverage report
Current view: top level - libreoffice/framework/source/services - pathsettings.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 254 503 50.5 %
Date: 2012-12-27 Functions: 30 48 62.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10