LCOV - code coverage report
Current view: top level - comphelper/source/property - propagg.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 385 432 89.1 %
Date: 2012-08-25 Functions: 41 46 89.1 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 324 582 55.7 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*
       3                 :            :  * This file is part of the LibreOffice project.
       4                 :            :  *
       5                 :            :  * This Source Code Form is subject to the terms of the Mozilla Public
       6                 :            :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7                 :            :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8                 :            :  *
       9                 :            :  * This file incorporates work covered by the following license notice:
      10                 :            :  *
      11                 :            :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12                 :            :  *   contributor license agreements. See the NOTICE file distributed
      13                 :            :  *   with this work for additional information regarding copyright
      14                 :            :  *   ownership. The ASF licenses this file to you under the Apache
      15                 :            :  *   License, Version 2.0 (the "License"); you may not use this file
      16                 :            :  *   except in compliance with the License. You may obtain a copy of
      17                 :            :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18                 :            :  */
      19                 :            : 
      20                 :            : #include "comphelper/propagg.hxx"
      21                 :            : #include "comphelper/property.hxx"
      22                 :            : #include <cppuhelper/queryinterface.hxx>
      23                 :            : #include <osl/diagnose.h>
      24                 :            : #include <com/sun/star/beans/PropertyAttribute.hpp>
      25                 :            : 
      26                 :            : #if OSL_DEBUG_LEVEL > 0
      27                 :            : #include <typeinfo>
      28                 :            : #include <rtl/strbuf.hxx>
      29                 :            : #endif
      30                 :            : 
      31                 :            : #include <algorithm>
      32                 :            : #include <set>
      33                 :            : 
      34                 :            : //.........................................................................
      35                 :            : namespace comphelper
      36                 :            : {
      37                 :            : //.........................................................................
      38                 :            : 
      39                 :            :     using namespace ::com::sun::star::uno;
      40                 :            :     using namespace ::com::sun::star::lang;
      41                 :            :     using namespace ::com::sun::star::beans;
      42                 :            : 
      43                 :            :     using namespace internal;
      44                 :            : 
      45                 :            :     //------------------------------------------------------------------------------
      46                 :            :     namespace
      47                 :            :     {
      48                 :     173465 :         const Property* lcl_findPropertyByName( const Sequence< Property >& _rProps, const ::rtl::OUString& _rName )
      49                 :            :         {
      50                 :     173465 :             sal_Int32 nLen = _rProps.getLength();
      51                 :     173465 :             const Property* pProperties = _rProps.getConstArray();
      52                 :     173465 :             Property aNameProp(_rName, 0, Type(), 0);
      53         [ +  - ]:     173465 :             const Property* pResult = ::std::lower_bound(pProperties, pProperties + nLen, aNameProp, PropertyCompareByName());
      54 [ +  - ][ +  + ]:     173465 :             if ( pResult && ( pResult == pProperties + nLen || pResult->Name != _rName) )
         [ +  + ][ +  + ]
      55                 :        455 :                 pResult = NULL;
      56                 :            : 
      57                 :     173465 :             return pResult;
      58                 :            :         }
      59                 :            :     }
      60                 :            : //==================================================================
      61                 :            : //= OPropertyArrayAggregationHelper
      62                 :            : //==================================================================
      63                 :            : 
      64                 :            : //------------------------------------------------------------------------------
      65                 :       1324 : OPropertyArrayAggregationHelper::OPropertyArrayAggregationHelper(
      66                 :            :         const  Sequence< Property >& _rProperties, const  Sequence< Property >& _rAggProperties,
      67                 :            :         IPropertyInfoService* _pInfoService, sal_Int32 _nFirstAggregateId )
      68 [ +  - ][ +  - ]:       1324 :     :m_aProperties( _rProperties )
      69                 :            : {
      70                 :       1324 :     sal_Int32 nDelegatorProps = _rProperties.getLength();
      71                 :       1324 :     sal_Int32 nAggregateProps = _rAggProperties.getLength();
      72                 :            : 
      73                 :            :     // make room for all properties
      74                 :       1324 :     sal_Int32 nMergedProps = nDelegatorProps + nAggregateProps;
      75         [ +  - ]:       1324 :     m_aProperties.realloc( nMergedProps );
      76                 :            : 
      77                 :       1324 :     const   Property* pAggregateProps   = _rAggProperties.getConstArray();
      78                 :       1324 :     const   Property* pDelegateProps    = _rProperties.getConstArray();
      79         [ +  - ]:       1324 :             Property* pMergedProps = m_aProperties.getArray();
      80                 :            : 
      81                 :            :     // if properties are present both at the delegatee and the aggregate, then the former are supposed to win.
      82                 :            :     // So, we'll need an existence check.
      83         [ +  - ]:       1324 :     ::std::set< ::rtl::OUString > aDelegatorProps;
      84                 :            : 
      85                 :            :     // create the map for the delegator properties
      86                 :       1324 :     sal_Int32 nMPLoop = 0;
      87         [ +  + ]:      29484 :     for ( ; nMPLoop < nDelegatorProps; ++nMPLoop, ++pDelegateProps )
      88                 :            :     {
      89         [ +  - ]:      28160 :         m_aPropertyAccessors[ pDelegateProps->Handle ] = OPropertyAccessor( -1, nMPLoop, sal_False );
      90                 :            :         OSL_ENSURE( aDelegatorProps.find( pDelegateProps->Name ) == aDelegatorProps.end(),
      91                 :            :             "OPropertyArrayAggregationHelper::OPropertyArrayAggregationHelper: duplicate delegatee property!" );
      92         [ +  - ]:      28160 :         aDelegatorProps.insert( pDelegateProps->Name );
      93                 :            :     }
      94                 :            : 
      95                 :            :     // create the map for the aggregate properties
      96                 :       1324 :     sal_Int32 nAggregateHandle = _nFirstAggregateId;
      97                 :       1324 :     pMergedProps += nDelegatorProps;
      98         [ +  + ]:      67365 :     for ( ; nMPLoop < nMergedProps; ++pAggregateProps )
      99                 :            :     {
     100                 :            :         // if the aggregate property is present at the delegatee already, ignore it
     101 [ +  - ][ +  + ]:      66041 :         if ( aDelegatorProps.find( pAggregateProps->Name ) != aDelegatorProps.end() )
     102                 :            :         {
     103                 :        206 :             --nMergedProps;
     104                 :        206 :             continue;
     105                 :            :         }
     106                 :            : 
     107                 :            :         // next aggregate property - remember it
     108                 :      65835 :         *pMergedProps = *pAggregateProps;
     109                 :            : 
     110                 :            :         // determine the handle for the property which we will expose to the outside world
     111                 :      65835 :         sal_Int32 nHandle = -1;
     112                 :            :         // ask the infor service first
     113         [ +  + ]:      65835 :         if ( _pInfoService )
     114         [ +  - ]:      65063 :             nHandle = _pInfoService->getPreferedPropertyId( pMergedProps->Name );
     115                 :            : 
     116         [ +  + ]:      65835 :         if ( -1 == nHandle )
     117                 :            :             // no handle from the info service -> default
     118                 :      39398 :             nHandle = nAggregateHandle++;
     119                 :            :         else
     120                 :            :         {   // check if we alread have a property with the given handle
     121                 :      26437 :             const  Property* pPropsTilNow = m_aProperties.getConstArray();
     122         [ +  + ]:    1221947 :             for ( sal_Int32 nCheck = 0; nCheck < nMPLoop; ++nCheck, ++pPropsTilNow )
     123         [ -  + ]:    1195510 :                 if ( pPropsTilNow->Handle == nHandle )
     124                 :            :                 {   // conflicts -> use another one (which we don't check anymore, assuming _nFirstAggregateId was large enough)
     125                 :          0 :                     nHandle = nAggregateHandle++;
     126                 :          0 :                     break;
     127                 :            :                 }
     128                 :            :         }
     129                 :            : 
     130                 :            :         // remember the accessor for this property
     131         [ +  - ]:      65835 :         m_aPropertyAccessors[ nHandle ] = OPropertyAccessor( pMergedProps->Handle, nMPLoop, sal_True );
     132                 :      65835 :         pMergedProps->Handle = nHandle;
     133                 :            : 
     134                 :      65835 :         ++nMPLoop;
     135                 :      65835 :         ++pMergedProps;
     136                 :            :     }
     137         [ +  - ]:       1324 :     m_aProperties.realloc( nMergedProps );
     138         [ +  - ]:       1324 :     pMergedProps = m_aProperties.getArray();    // reset, needed again below
     139                 :            : 
     140                 :            :     // sort the properties by name
     141         [ +  - ]:       1324 :     ::std::sort( pMergedProps, pMergedProps+nMergedProps, PropertyCompareByName());
     142                 :            : 
     143         [ +  - ]:       1324 :     pMergedProps = m_aProperties.getArray();
     144                 :            : 
     145                 :            :     // sync the map positions
     146         [ +  + ]:      95319 :     for ( nMPLoop = 0; nMPLoop < nMergedProps; ++nMPLoop, ++pMergedProps )
     147         [ +  - ]:      95319 :         m_aPropertyAccessors[ pMergedProps->Handle ].nPos = nMPLoop;
     148                 :       1324 : }
     149                 :            : 
     150                 :            : //------------------------------------------------------------------
     151                 :     101552 : OPropertyArrayAggregationHelper::PropertyOrigin OPropertyArrayAggregationHelper::classifyProperty( const ::rtl::OUString& _rName )
     152                 :            : {
     153                 :     101552 :     PropertyOrigin eOrigin = UNKNOWN_PROPERTY;
     154                 :            :     // look up the name
     155                 :     101552 :     const Property* pPropertyDescriptor = lcl_findPropertyByName( m_aProperties, _rName );
     156         [ +  - ]:     101552 :     if ( pPropertyDescriptor )
     157                 :            :     {
     158                 :            :         // look up the handle for this name
     159         [ +  - ]:     101552 :         ConstPropertyAccessorMapIterator aPos = m_aPropertyAccessors.find( pPropertyDescriptor->Handle );
     160                 :            :         OSL_ENSURE( m_aPropertyAccessors.end() != aPos, "OPropertyArrayAggregationHelper::classifyProperty: should have this handle in my map!" );
     161         [ +  - ]:     101552 :         if ( m_aPropertyAccessors.end() != aPos )
     162                 :            :         {
     163                 :     101552 :             eOrigin = aPos->second.bAggregate ? AGGREGATE_PROPERTY : DELEGATOR_PROPERTY;
     164                 :            :         }
     165                 :            :     }
     166                 :     101552 :     return eOrigin;
     167                 :            : }
     168                 :            : 
     169                 :            : //------------------------------------------------------------------
     170                 :          0 : Property OPropertyArrayAggregationHelper::getPropertyByName( const ::rtl::OUString& _rPropertyName ) throw( UnknownPropertyException )
     171                 :            : {
     172                 :          0 :     const Property* pProperty = findPropertyByName( _rPropertyName );
     173                 :            : 
     174         [ #  # ]:          0 :     if ( !pProperty )
     175         [ #  # ]:          0 :         throw  UnknownPropertyException();
     176                 :            : 
     177                 :          0 :     return *pProperty;
     178                 :            : }
     179                 :            : 
     180                 :            : //------------------------------------------------------------------------------
     181                 :        266 : sal_Bool OPropertyArrayAggregationHelper::hasPropertyByName(const ::rtl::OUString& _rPropertyName)
     182                 :            : {
     183                 :        266 :     return NULL != findPropertyByName( _rPropertyName );
     184                 :            : }
     185                 :            : 
     186                 :            : //------------------------------------------------------------------------------
     187                 :      71913 : const Property* OPropertyArrayAggregationHelper::findPropertyByName(const :: rtl::OUString& _rName ) const
     188                 :            : {
     189                 :      71913 :     return lcl_findPropertyByName( m_aProperties, _rName );
     190                 :            : }
     191                 :            : 
     192                 :            : //------------------------------------------------------------------------------
     193                 :      71647 : sal_Int32 OPropertyArrayAggregationHelper::getHandleByName(const ::rtl::OUString& _rPropertyName)
     194                 :            : {
     195                 :      71647 :     const Property* pProperty = findPropertyByName( _rPropertyName );
     196         [ +  + ]:      71647 :     return pProperty ? pProperty->Handle : -1;
     197                 :            : }
     198                 :            : 
     199                 :            : //------------------------------------------------------------------------------
     200                 :      79309 : sal_Bool OPropertyArrayAggregationHelper::fillPropertyMembersByHandle(
     201                 :            :             ::rtl::OUString* _pPropName, sal_Int16* _pAttributes, sal_Int32 _nHandle)
     202                 :            : {
     203         [ +  - ]:      79309 :     ConstPropertyAccessorMapIterator i = m_aPropertyAccessors.find(_nHandle);
     204                 :      79309 :     sal_Bool bRet = i != m_aPropertyAccessors.end();
     205         [ +  + ]:      79309 :     if (bRet)
     206                 :            :     {
     207                 :      78892 :         const  ::com::sun::star::beans::Property& rProperty = m_aProperties.getConstArray()[(*i).second.nPos];
     208         [ +  + ]:      78892 :         if (_pPropName)
     209                 :      17516 :             *_pPropName = rProperty.Name;
     210         [ +  + ]:      78892 :         if (_pAttributes)
     211                 :      43398 :             *_pAttributes = rProperty.Attributes;
     212                 :            :     }
     213                 :      79309 :     return bRet;
     214                 :            : }
     215                 :            : 
     216                 :            : //------------------------------------------------------------------------------
     217                 :       1269 : sal_Bool OPropertyArrayAggregationHelper::getPropertyByHandle( sal_Int32 _nHandle, Property& _rProperty ) const
     218                 :            : {
     219         [ +  - ]:       1269 :     ConstPropertyAccessorMapIterator pos = m_aPropertyAccessors.find(_nHandle);
     220         [ +  - ]:       1269 :     if ( pos != m_aPropertyAccessors.end() )
     221                 :            :     {
     222                 :       1269 :         _rProperty = m_aProperties[ pos->second.nPos ];
     223                 :       1269 :         return sal_True;
     224                 :            :     }
     225                 :       1269 :     return sal_False;
     226                 :            : }
     227                 :            : 
     228                 :            : //------------------------------------------------------------------------------
     229                 :     174317 : sal_Bool OPropertyArrayAggregationHelper::fillAggregatePropertyInfoByHandle(
     230                 :            :             ::rtl::OUString* _pPropName, sal_Int32* _pOriginalHandle, sal_Int32 _nHandle) const
     231                 :            : {
     232         [ +  - ]:     174317 :     ConstPropertyAccessorMapIterator i = m_aPropertyAccessors.find(_nHandle);
     233 [ +  + ][ +  + ]:     174317 :     sal_Bool bRet = i != m_aPropertyAccessors.end() && (*i).second.bAggregate;
                 [ +  - ]
     234         [ +  + ]:     174317 :     if (bRet)
     235                 :            :     {
     236         [ +  - ]:     128738 :         if (_pOriginalHandle)
     237                 :     128738 :             *_pOriginalHandle = (*i).second.nOriginalHandle;
     238         [ +  + ]:     128738 :         if (_pPropName)
     239                 :            :         {
     240                 :            :             OSL_ENSURE((*i).second.nPos < m_aProperties.getLength(),"Invalid index for sequence!");
     241                 :     128236 :             const  ::com::sun::star::beans::Property& rProperty = m_aProperties.getConstArray()[(*i).second.nPos];
     242                 :     128236 :             *_pPropName = rProperty.Name;
     243                 :            :         }
     244                 :            :     }
     245                 :     174317 :     return bRet;
     246                 :            : }
     247                 :            : 
     248                 :            : 
     249                 :            : //------------------------------------------------------------------------------
     250                 :      42215 :  ::com::sun::star::uno::Sequence< ::com::sun::star::beans::Property> OPropertyArrayAggregationHelper::getProperties()
     251                 :            : {
     252                 :      42215 :     return m_aProperties;
     253                 :            : }
     254                 :            : 
     255                 :            : 
     256                 :            : //------------------------------------------------------------------------------
     257                 :       5471 : sal_Int32 OPropertyArrayAggregationHelper::fillHandles(
     258                 :            :         sal_Int32* _pHandles, const  ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropNames )
     259                 :            : {
     260                 :       5471 :     sal_Int32 nHitCount = 0;
     261                 :       5471 :     const ::rtl::OUString* pReqProps = _rPropNames.getConstArray();
     262                 :       5471 :     sal_Int32 nReqLen = _rPropNames.getLength();
     263                 :            : 
     264                 :            : #if OSL_DEBUG_LEVEL > 0
     265                 :            :     // assure that the sequence is sorted
     266                 :            :     {
     267                 :            :         const ::rtl::OUString* pLookup = _rPropNames.getConstArray();
     268                 :            :         const ::rtl::OUString* pEnd = _rPropNames.getConstArray() + _rPropNames.getLength() - 1;
     269                 :            :         for (; pLookup < pEnd; ++pLookup)
     270                 :            :         {
     271                 :            :             const ::rtl::OUString* pCompare = pLookup + 1;
     272                 :            :             const ::rtl::OUString* pCompareEnd = pEnd + 1;
     273                 :            :             for (; pCompare < pCompareEnd; ++pCompare)
     274                 :            :             {
     275                 :            :                 OSL_ENSURE(pLookup->compareTo(*pCompare) < 0, "OPropertyArrayAggregationHelper::fillHandles : property names are not sorted!");
     276                 :            :             }
     277                 :            :         }
     278                 :            :     }
     279                 :            : #endif
     280                 :            : 
     281                 :       5471 :     const  ::com::sun::star::beans::Property* pCur = m_aProperties.getConstArray();
     282                 :       5471 :     const  ::com::sun::star::beans::Property* pEnd = m_aProperties.getConstArray() + m_aProperties.getLength();
     283                 :            : 
     284         [ +  + ]:     125279 :     for( sal_Int32 i = 0; i < nReqLen; ++i )
     285                 :            :     {
     286                 :            :         // determine the logarithm
     287                 :     119808 :         sal_uInt32 n = (sal_uInt32)(pEnd - pCur);
     288                 :     119808 :         sal_Int32 nLog = 0;
     289         [ +  + ]:     747717 :         while( n )
     290                 :            :         {
     291                 :     627909 :             nLog += 1;
     292                 :     627909 :             n = n >> 1;
     293                 :            :         }
     294                 :            : 
     295                 :            :         // (Number of properties yet to be found) * (Log2 of properties yet to be searched)
     296         [ +  + ]:     119808 :         if( (nReqLen - i) * nLog >= pEnd - pCur )
     297                 :            :         {
     298                 :            :             // linear search is better
     299 [ +  - ][ +  + ]:     258176 :             while( pCur < pEnd && pReqProps[i] > pCur->Name )
                 [ +  + ]
     300                 :            :             {
     301                 :     147239 :                 pCur++;
     302                 :            :             }
     303 [ +  - ][ +  - ]:     110937 :             if( pCur < pEnd && pReqProps[i] == pCur->Name )
                 [ +  - ]
     304                 :            :             {
     305                 :     110937 :                 _pHandles[i] = pCur->Handle;
     306                 :     110937 :                 nHitCount++;
     307                 :            :             }
     308                 :            :             else
     309                 :          0 :                 _pHandles[i] = -1;
     310                 :            :         }
     311                 :            :         else
     312                 :            :         {
     313                 :            :             // binary search is better
     314                 :       8871 :             sal_Int32   nCompVal = 1;
     315                 :       8871 :             const  ::com::sun::star::beans::Property*  pOldEnd = pEnd--;
     316                 :       8871 :             const  ::com::sun::star::beans::Property*  pMid = pCur;
     317                 :            : 
     318 [ +  + ][ +  - ]:      43607 :             while( nCompVal != 0 && pCur <= pEnd )
                 [ +  + ]
     319                 :            :             {
     320                 :      34736 :                 pMid = (pEnd - pCur) / 2 + pCur;
     321                 :            : 
     322                 :      34736 :                 nCompVal = pReqProps[i].compareTo( pMid->Name );
     323                 :            : 
     324         [ +  + ]:      34736 :                 if( nCompVal > 0 )
     325                 :      11351 :                     pCur = pMid + 1;
     326                 :            :                 else
     327                 :      23385 :                     pEnd = pMid - 1;
     328                 :            :             }
     329                 :            : 
     330         [ +  - ]:       8871 :             if( nCompVal == 0 )
     331                 :            :             {
     332                 :       8871 :                 _pHandles[i] = pMid->Handle;
     333                 :       8871 :                 nHitCount++;
     334                 :       8871 :                 pCur = pMid +1;
     335                 :            :             }
     336         [ #  # ]:          0 :             else if( nCompVal > 0 )
     337                 :            :             {
     338                 :          0 :                 _pHandles[i] = -1;
     339                 :          0 :                 pCur = pMid + 1;
     340                 :            :             }
     341                 :            :             else
     342                 :            :             {
     343                 :          0 :                 _pHandles[i] = -1;
     344                 :          0 :                 pCur = pMid;
     345                 :            :             }
     346                 :       8871 :             pEnd = pOldEnd;
     347                 :            :         }
     348                 :            :     }
     349                 :       5471 :     return nHitCount;
     350                 :            : }
     351                 :            : 
     352                 :            : //==================================================================
     353                 :            : //= PropertyForwarder
     354                 :            : //==================================================================
     355                 :            : namespace internal
     356                 :            : {
     357                 :            :     class PropertyForwarder
     358                 :            :     {
     359                 :            :     private:
     360                 :            :         OPropertySetAggregationHelper&  m_rAggregationHelper;
     361                 :            :         ::std::set< sal_Int32 >         m_aProperties;
     362                 :            :         sal_Int32                       m_nCurrentlyForwarding;
     363                 :            : 
     364                 :            :     public:
     365                 :            :         PropertyForwarder( OPropertySetAggregationHelper& _rAggregationHelper );
     366                 :            :         ~PropertyForwarder();
     367                 :            : 
     368                 :            :         /** declares that the forwarder should be responsible for the given property
     369                 :            : 
     370                 :            :         @param _nHandle
     371                 :            :             the public handle (<em>not</em> the original handle!) of the property
     372                 :            :         */
     373                 :            :         void    takeResponsibilityFor( sal_Int32 _nHandle );
     374                 :            : 
     375                 :            :         /** checks whether the forwarder is responsible for the given property
     376                 :            :         */
     377                 :            :         bool    isResponsibleFor( sal_Int32 _nHandle );
     378                 :            : 
     379                 :            :         /// actually forwards a property value to the aggregate
     380                 :            :         void    doForward( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception );
     381                 :            : 
     382                 :       9983 :         sal_Int32 getCurrentlyForwardedProperty( ) const { return m_nCurrentlyForwarding; }
     383                 :            :     };
     384                 :            : 
     385                 :            :     //--------------------------------------------------------------------------
     386                 :       1487 :     PropertyForwarder::PropertyForwarder( OPropertySetAggregationHelper& _rAggregationHelper )
     387                 :            :         :m_rAggregationHelper( _rAggregationHelper )
     388                 :       1487 :         ,m_nCurrentlyForwarding( -1 )
     389                 :            :     {
     390                 :       1487 :     }
     391                 :            : 
     392                 :            :     //--------------------------------------------------------------------------
     393                 :       1368 :     PropertyForwarder::~PropertyForwarder()
     394                 :            :     {
     395                 :       1368 :     }
     396                 :            : 
     397                 :            :     //--------------------------------------------------------------------------
     398                 :        278 :     void PropertyForwarder::takeResponsibilityFor( sal_Int32 _nHandle )
     399                 :            :     {
     400                 :        278 :         m_aProperties.insert( _nHandle );
     401                 :        278 :     }
     402                 :            : 
     403                 :            :     //--------------------------------------------------------------------------
     404                 :       3004 :     bool PropertyForwarder::isResponsibleFor( sal_Int32 _nHandle )
     405                 :            :     {
     406 [ +  - ][ +  - ]:       3004 :         return m_aProperties.find( _nHandle ) != m_aProperties.end();
     407                 :            :     }
     408                 :            : 
     409                 :            :     //--------------------------------------------------------------------------
     410                 :        283 :     void PropertyForwarder::doForward( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
     411                 :            :     {
     412                 :            :         OSL_ENSURE( m_rAggregationHelper.m_xAggregateSet.is(), "PropertyForwarder::doForward: no property set!" );
     413         [ +  - ]:        283 :         if ( m_rAggregationHelper.m_xAggregateSet.is() )
     414                 :            :         {
     415                 :        283 :             m_rAggregationHelper.forwardingPropertyValue( _nHandle );
     416                 :            : 
     417                 :            :             OSL_ENSURE( m_nCurrentlyForwarding == -1, "PropertyForwarder::doForward: reentrance?" );
     418                 :        283 :             m_nCurrentlyForwarding = _nHandle;
     419                 :            : 
     420                 :            :             try
     421                 :            :             {
     422 [ +  - ][ +  - ]:        283 :                 m_rAggregationHelper.m_xAggregateSet->setPropertyValue( m_rAggregationHelper.getPropertyName( _nHandle ), _rValue );
                 [ +  - ]
     423                 :            :                     // TODO: cache the property name? (it's a O(log n) search)
     424                 :            :             }
     425         [ #  # ]:          0 :             catch( const Exception& )
     426                 :            :             {
     427         [ #  # ]:          0 :                 m_rAggregationHelper.forwardedPropertyValue( _nHandle, false );
     428                 :          0 :                 throw;
     429                 :            :             }
     430                 :            : 
     431                 :        283 :             m_nCurrentlyForwarding = -1;
     432                 :            : 
     433                 :        283 :             m_rAggregationHelper.forwardedPropertyValue( _nHandle, true );
     434                 :            :         }
     435                 :        283 :     }
     436                 :            : }
     437                 :            : 
     438                 :            : //==================================================================
     439                 :            : //= OPropertySetAggregationHelper
     440                 :            : //==================================================================
     441                 :            : 
     442                 :            : //------------------------------------------------------------------------------
     443                 :       1487 : OPropertySetAggregationHelper::OPropertySetAggregationHelper( ::cppu::OBroadcastHelper& rBHlp )
     444                 :            :     :OPropertyStateHelper( rBHlp )
     445                 :       1487 :     ,m_bListening( sal_False )
     446                 :            : {
     447 [ +  - ][ +  - ]:       1487 :     m_pForwarder = new PropertyForwarder( *this );
     448                 :       1487 : }
     449                 :            : 
     450                 :            : //------------------------------------------------------------------------------
     451                 :       1368 : OPropertySetAggregationHelper::~OPropertySetAggregationHelper()
     452                 :            : {
     453         [ +  - ]:       1368 :     delete m_pForwarder;
     454         [ -  + ]:       1368 : }
     455                 :            : 
     456                 :            : //------------------------------------------------------------------------------
     457                 :     154391 :  ::com::sun::star::uno::Any SAL_CALL OPropertySetAggregationHelper::queryInterface(const  ::com::sun::star::uno::Type& _rType) throw( ::com::sun::star::uno::RuntimeException)
     458                 :            : {
     459                 :     154391 :      ::com::sun::star::uno::Any aReturn = OPropertyStateHelper::queryInterface(_rType);
     460                 :            : 
     461         [ +  + ]:     154391 :     if ( !aReturn.hasValue() )
     462                 :            :         aReturn = cppu::queryInterface(_rType
     463                 :            :         ,static_cast< ::com::sun::star::beans::XPropertiesChangeListener*>(this)
     464                 :            :         ,static_cast< ::com::sun::star::beans::XVetoableChangeListener*>(this)
     465                 :            :         ,static_cast< ::com::sun::star::lang::XEventListener*>(static_cast< ::com::sun::star::beans::XPropertiesChangeListener*>(this))
     466         [ +  - ]:      92245 :         );
     467                 :            : 
     468                 :     154391 :     return aReturn;
     469                 :            : }
     470                 :            : 
     471                 :            : //------------------------------------------------------------------------------
     472                 :       1383 : void OPropertySetAggregationHelper::disposing()
     473                 :            : {
     474         [ +  - ]:       1383 :     osl::MutexGuard aGuard(rBHelper.rMutex);
     475                 :            : 
     476 [ +  + ][ +  + ]:       1383 :     if ( m_xAggregateSet.is() && m_bListening )
                 [ +  + ]
     477                 :            :     {
     478                 :            :         // register as a single listener
     479 [ +  - ][ +  - ]:       1111 :         m_xAggregateMultiSet->removePropertiesChangeListener(this);
                 [ +  - ]
     480 [ +  - ][ +  - ]:       1111 :         m_xAggregateSet->removeVetoableChangeListener(::rtl::OUString(), this);
                 [ +  - ]
     481                 :       1111 :         m_bListening = sal_False;
     482                 :            :     }
     483                 :            : 
     484 [ +  - ][ +  - ]:       1383 :     OPropertyStateHelper::disposing();
     485                 :       1383 : }
     486                 :            : 
     487                 :            : //------------------------------------------------------------------------------
     488                 :        288 : void SAL_CALL OPropertySetAggregationHelper::disposing(const  ::com::sun::star::lang::EventObject& _rSource) throw ( ::com::sun::star::uno::RuntimeException)
     489                 :            : {
     490                 :            :     OSL_ENSURE(m_xAggregateSet.is(), "OPropertySetAggregationHelper::disposing : don't have an aggregate anymore !");
     491         [ -  + ]:        288 :     if (_rSource.Source == m_xAggregateSet)
     492                 :          0 :         m_bListening = sal_False;
     493                 :        288 : }
     494                 :            : 
     495                 :            : //------------------------------------------------------------------------------
     496                 :       8784 : void SAL_CALL OPropertySetAggregationHelper::propertiesChange(const  ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyChangeEvent>& _rEvents) throw( ::com::sun::star::uno::RuntimeException)
     497                 :            : {
     498                 :            :     OSL_ENSURE(m_xAggregateSet.is(), "OPropertySetAggregationHelper::propertiesChange : have no aggregate !");
     499                 :            : 
     500                 :       8784 :     sal_Int32 nLen = _rEvents.getLength();
     501                 :       8784 :     cppu::IPropertyArrayHelper& rPH = getInfoHelper();
     502                 :            : 
     503         [ +  + ]:       8784 :     if (1 == nLen)
     504                 :            :     {
     505                 :       8271 :         const  ::com::sun::star::beans::PropertyChangeEvent& evt = _rEvents.getConstArray()[0];
     506                 :            :         OSL_ENSURE(!evt.PropertyName.isEmpty(), "OPropertySetAggregationHelper::propertiesChange : invalid event !");
     507                 :            :             // we had a bug where this assertion would have us saved a whole day :) (72514)
     508         [ +  - ]:       8271 :         sal_Int32 nHandle = rPH.getHandleByName( evt.PropertyName );
     509                 :            : 
     510                 :            :         // If nHandle is -1 the event marks a (aggregate) property which we hide to callers
     511                 :            :         // If isCurrentlyForwardingProperty( nHandle ) is <TRUE/>, then we ourself triggered
     512                 :            :         // setting this property. In this case, it will be notified later (by the OPropertySetHelper
     513                 :            :         // implementation)
     514                 :            : 
     515 [ +  - ][ +  - ]:       8271 :         if ( ( nHandle != -1 ) && !isCurrentlyForwardingProperty( nHandle ) )
         [ +  + ][ +  + ]
     516         [ +  - ]:       8271 :             fire(&nHandle, &evt.NewValue, &evt.OldValue, 1, sal_False);
     517                 :            :     }
     518                 :            :     else
     519                 :            :     {
     520                 :        513 :         sal_Int32* pHandles = new sal_Int32[nLen];
     521         [ +  + ]:       2225 :          ::com::sun::star::uno::Any* pNewValues = new  ::com::sun::star::uno::Any[nLen];
     522         [ +  + ]:       2225 :          ::com::sun::star::uno::Any* pOldValues = new  ::com::sun::star::uno::Any[nLen];
     523                 :            : 
     524                 :        513 :         const  ::com::sun::star::beans::PropertyChangeEvent* pEvents = _rEvents.getConstArray();
     525                 :        513 :         sal_Int32 nDest = 0;
     526         [ +  + ]:       2225 :         for (sal_Int32 nSource=0; nSource<nLen; ++nSource, ++pEvents)
     527                 :            :         {
     528                 :       1712 :             sal_Int32 nHandle = rPH.getHandleByName(pEvents->PropertyName);
     529 [ +  - ][ +  - ]:       1712 :             if ( ( nHandle != -1 ) && !isCurrentlyForwardingProperty( nHandle ) )
                 [ +  - ]
     530                 :            :             {   // same as above : -1 is valid (73247) ...
     531                 :       1712 :                 pHandles[nDest] = nHandle;
     532                 :       1712 :                 pNewValues[nDest] = pEvents->NewValue;
     533                 :       1712 :                 pOldValues[nDest] = pEvents->OldValue;
     534                 :       1712 :                 ++nDest;
     535                 :            :             }
     536                 :            :         }
     537                 :            : 
     538         [ +  + ]:        513 :         if (nDest)
     539                 :        407 :             fire(pHandles, pNewValues, pOldValues, nDest, sal_False);
     540                 :            : 
     541         [ +  - ]:        513 :         delete[] pHandles;
     542 [ +  - ][ +  + ]:       2225 :         delete[] pNewValues;
     543 [ +  - ][ +  + ]:       2225 :         delete[] pOldValues;
     544                 :            :     }
     545                 :       8784 : }
     546                 :            : 
     547                 :            : //------------------------------------------------------------------------------
     548                 :          0 : void SAL_CALL OPropertySetAggregationHelper::vetoableChange(const  ::com::sun::star::beans::PropertyChangeEvent& _rEvent) throw( ::com::sun::star::beans::PropertyVetoException,  ::com::sun::star::uno::RuntimeException)
     549                 :            : {
     550                 :            :     OSL_ENSURE(m_xAggregateSet.is(), "OPropertySetAggregationHelper::vetoableChange : have no aggregate !");
     551                 :            : 
     552         [ #  # ]:          0 :     cppu::IPropertyArrayHelper& rPH = getInfoHelper();
     553                 :            : 
     554         [ #  # ]:          0 :     sal_Int32 nHandle = rPH.getHandleByName(_rEvent.PropertyName);
     555         [ #  # ]:          0 :     fire(&nHandle, &_rEvent.NewValue, &_rEvent.OldValue, 1, sal_True);
     556                 :          0 : }
     557                 :            : 
     558                 :            : //------------------------------------------------------------------------------
     559                 :       1499 : void OPropertySetAggregationHelper::setAggregation(const  ::com::sun::star::uno::Reference<  ::com::sun::star::uno::XInterface >& _rxDelegate)
     560                 :            :         throw(  ::com::sun::star::lang::IllegalArgumentException )
     561                 :            : {
     562         [ +  - ]:       1499 :     osl::MutexGuard aGuard(rBHelper.rMutex);
     563                 :            : 
     564 [ -  + ][ #  # ]:       1499 :     if (m_bListening && m_xAggregateSet.is())
                 [ -  + ]
     565                 :            :     {
     566 [ #  # ][ #  # ]:          0 :         m_xAggregateMultiSet->removePropertiesChangeListener(this);
                 [ #  # ]
     567 [ #  # ][ #  # ]:          0 :         m_xAggregateSet->removeVetoableChangeListener(::rtl::OUString(), this);
                 [ #  # ]
     568                 :          0 :         m_bListening = sal_False;
     569                 :            :     }
     570                 :            : 
     571 [ +  - ][ +  - ]:       1499 :     m_xAggregateState       =  m_xAggregateState.query( _rxDelegate );
     572 [ +  - ][ +  - ]:       1499 :     m_xAggregateSet         =  m_xAggregateSet.query( _rxDelegate );
     573 [ +  - ][ +  - ]:       1499 :     m_xAggregateMultiSet    =  m_xAggregateMultiSet.query( _rxDelegate );
     574 [ +  - ][ +  - ]:       1499 :     m_xAggregateFastSet     =  m_xAggregateFastSet.query( _rxDelegate );
     575                 :            : 
     576                 :            :     // must support XPropertySet and XMultiPropertySet
     577 [ -  + ][ -  + ]:       1499 :     if ( m_xAggregateSet.is() && !m_xAggregateMultiSet.is() )
                 [ +  + ]
     578 [ #  # ][ +  - ]:       1499 :         throw  ::com::sun::star::lang::IllegalArgumentException();
     579                 :       1499 : }
     580                 :            : 
     581                 :            : //------------------------------------------------------------------------------
     582                 :       1780 : void OPropertySetAggregationHelper::startListening()
     583                 :            : {
     584         [ +  - ]:       1780 :     osl::MutexGuard aGuard(rBHelper.rMutex);
     585                 :            : 
     586 [ +  - ][ +  + ]:       1780 :     if (!m_bListening && m_xAggregateSet.is())
                 [ +  + ]
     587                 :            :     {
     588                 :            :         // register as a single listener
     589         [ +  - ]:       1198 :          ::com::sun::star::uno::Sequence< ::rtl::OUString > aPropertyNames;
     590 [ +  - ][ +  - ]:       1198 :         m_xAggregateMultiSet->addPropertiesChangeListener(aPropertyNames, this);
                 [ +  - ]
     591 [ +  - ][ +  - ]:       1198 :         m_xAggregateSet->addVetoableChangeListener(::rtl::OUString(), this);
                 [ +  - ]
     592                 :            : 
     593         [ +  - ]:       1198 :         m_bListening = sal_True;
     594         [ +  - ]:       1780 :     }
     595                 :       1780 : }
     596                 :            : 
     597                 :            : //------------------------------------------------------------------------------
     598                 :        245 : void SAL_CALL OPropertySetAggregationHelper::addVetoableChangeListener(const ::rtl::OUString& _rPropertyName,
     599                 :            :                                                                        const  ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener>& _rxListener)
     600                 :            :                                                                        throw( ::com::sun::star::beans::UnknownPropertyException,  ::com::sun::star::lang::WrappedTargetException,  ::com::sun::star::uno::RuntimeException)
     601                 :            : {
     602                 :        245 :     OPropertySetHelper::addVetoableChangeListener(_rPropertyName, _rxListener);
     603         [ -  + ]:        245 :     if (!m_bListening)
     604                 :          0 :         startListening();
     605                 :        245 : }
     606                 :            : 
     607                 :            : //------------------------------------------------------------------------------
     608                 :       7972 : void SAL_CALL OPropertySetAggregationHelper::addPropertyChangeListener(const ::rtl::OUString& _rPropertyName,
     609                 :            :                                                                        const  ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener>& _rxListener)
     610                 :            :                                                                        throw( ::com::sun::star::beans::UnknownPropertyException,  ::com::sun::star::lang::WrappedTargetException,  ::com::sun::star::uno::RuntimeException)
     611                 :            : {
     612                 :       7972 :     OPropertySetHelper::addPropertyChangeListener(_rPropertyName, _rxListener);
     613         [ +  + ]:       7972 :     if (!m_bListening)
     614                 :       1624 :         startListening();
     615                 :       7972 : }
     616                 :            : 
     617                 :            : //------------------------------------------------------------------------------
     618                 :        850 : void SAL_CALL OPropertySetAggregationHelper::addPropertiesChangeListener(const  ::com::sun::star::uno::Sequence< ::rtl::OUString >& _rPropertyNames,
     619                 :            :                                                                          const  ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertiesChangeListener>& _rxListener)
     620                 :            :                                                                          throw( ::com::sun::star::uno::RuntimeException)
     621                 :            : {
     622                 :        850 :     OPropertySetHelper::addPropertiesChangeListener(_rPropertyNames, _rxListener);
     623         [ +  + ]:        850 :     if (!m_bListening)
     624                 :        156 :         startListening();
     625                 :        850 : }
     626                 :            : 
     627                 :            : //------------------------------------------------------------------------------
     628                 :        502 : sal_Int32 OPropertySetAggregationHelper::getOriginalHandle(sal_Int32 nHandle) const
     629                 :            : {
     630         [ +  - ]:        502 :     OPropertyArrayAggregationHelper& rPH = (OPropertyArrayAggregationHelper&)const_cast<OPropertySetAggregationHelper*>(this)->getInfoHelper();
     631                 :        502 :     sal_Int32 nOriginalHandle = -1;
     632         [ +  - ]:        502 :     rPH.fillAggregatePropertyInfoByHandle(NULL, &nOriginalHandle, nHandle);
     633                 :        502 :     return nOriginalHandle;
     634                 :            : }
     635                 :            : 
     636                 :            : //--------------------------------------------------------------------------
     637                 :        962 : ::rtl::OUString OPropertySetAggregationHelper::getPropertyName( sal_Int32 _nHandle ) const
     638                 :            : {
     639         [ +  - ]:        962 :     OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( const_cast<OPropertySetAggregationHelper*>(this)->getInfoHelper() );
     640                 :        962 :     Property aProperty;
     641         [ +  - ]:        962 :     OSL_VERIFY( rPH.getPropertyByHandle( _nHandle, aProperty ) );
     642                 :        962 :     return aProperty.Name;
     643                 :            : }
     644                 :            : 
     645                 :            : //------------------------------------------------------------------------------
     646                 :      16168 : void SAL_CALL OPropertySetAggregationHelper::setFastPropertyValue(sal_Int32 _nHandle, const  ::com::sun::star::uno::Any& _rValue)
     647                 :            :         throw(   ::com::sun::star::beans::UnknownPropertyException,  ::com::sun::star::beans::PropertyVetoException,
     648                 :            :                  ::com::sun::star::lang::IllegalArgumentException,  ::com::sun::star::lang::WrappedTargetException,
     649                 :            :                  ::com::sun::star::uno::RuntimeException)
     650                 :            : {
     651         [ +  - ]:      16168 :     OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
     652                 :      16168 :     ::rtl::OUString aPropName;
     653                 :      16168 :     sal_Int32   nOriginalHandle = -1;
     654                 :            : 
     655                 :            :     // does the handle belong to the aggregation ?
     656 [ +  + ][ +  - ]:      16168 :     if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, _nHandle))
     657         [ +  + ]:       9904 :         if (m_xAggregateFastSet.is())
     658 [ +  - ][ +  + ]:       9338 :             m_xAggregateFastSet->setFastPropertyValue(nOriginalHandle, _rValue);
     659                 :            :         else
     660 [ +  - ][ +  - ]:        566 :             m_xAggregateSet->setPropertyValue(aPropName, _rValue);
     661                 :            :     else
     662         [ +  + ]:      16168 :         OPropertySetHelper::setFastPropertyValue(_nHandle, _rValue);
     663                 :      16094 : }
     664                 :            : 
     665                 :            : //------------------------------------------------------------------------------
     666                 :      84792 : void OPropertySetAggregationHelper::getFastPropertyValue( ::com::sun::star::uno::Any& rValue, sal_Int32 nHandle) const
     667                 :            : {
     668         [ +  - ]:      84792 :     OPropertyArrayAggregationHelper& rPH = (OPropertyArrayAggregationHelper&)const_cast<OPropertySetAggregationHelper*>(this)->getInfoHelper();
     669                 :      84792 :     ::rtl::OUString aPropName;
     670                 :      84792 :     sal_Int32   nOriginalHandle = -1;
     671                 :            : 
     672 [ +  + ][ +  - ]:      84792 :     if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
     673                 :            :     {
     674         [ +  - ]:      82378 :         if (m_xAggregateFastSet.is())
     675 [ +  - ][ +  - ]:      82378 :             rValue = m_xAggregateFastSet->getFastPropertyValue(nOriginalHandle);
     676                 :            :         else
     677 [ #  # ][ #  # ]:          0 :             rValue = m_xAggregateSet->getPropertyValue(aPropName);
     678                 :            :     }
     679 [ +  - ][ +  + ]:       2414 :     else if ( m_pForwarder->isResponsibleFor( nHandle ) )
     680                 :            :     {
     681                 :            :         // this is a property which has been "overwritten" in our instance (thus
     682                 :            :         // fillAggregatePropertyInfoByHandle didn't find it)
     683 [ +  - ][ +  - ]:        679 :         rValue = m_xAggregateSet->getPropertyValue( getPropertyName( nHandle ) );
                 [ +  - ]
     684                 :      84792 :     }
     685                 :      84792 : }
     686                 :            : 
     687                 :            : //------------------------------------------------------------------------------
     688                 :      68333 :  ::com::sun::star::uno::Any SAL_CALL OPropertySetAggregationHelper::getFastPropertyValue(sal_Int32 nHandle)
     689                 :            :         throw(   ::com::sun::star::beans::UnknownPropertyException,
     690                 :            :                  ::com::sun::star::lang::WrappedTargetException,
     691                 :            :                  ::com::sun::star::uno::RuntimeException)
     692                 :            : {
     693         [ +  - ]:      68333 :     OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
     694                 :      68333 :     ::rtl::OUString aPropName;
     695                 :      68333 :     sal_Int32   nOriginalHandle = -1;
     696                 :      68333 :      ::com::sun::star::uno::Any  aValue;
     697                 :            : 
     698 [ +  + ][ +  - ]:      68333 :     if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
     699                 :            :     {
     700         [ +  + ]:      32794 :         if (m_xAggregateFastSet.is())
     701 [ +  - ][ +  - ]:      20740 :             aValue = m_xAggregateFastSet->getFastPropertyValue(nOriginalHandle);
     702                 :            :         else
     703 [ +  - ][ +  - ]:      12054 :             aValue = m_xAggregateSet->getPropertyValue(aPropName);
     704                 :            :     }
     705                 :            :     else
     706         [ +  + ]:      35539 :         aValue = OPropertySetHelper::getFastPropertyValue(nHandle);
     707                 :            : 
     708                 :      68333 :     return aValue;
     709                 :            : }
     710                 :            : 
     711                 :            : //------------------------------------------------------------------------------
     712                 :       1582 : void SAL_CALL OPropertySetAggregationHelper::setPropertyValues(
     713                 :            :         const Sequence< ::rtl::OUString >& _rPropertyNames, const Sequence< Any >& _rValues )
     714                 :            :     throw ( PropertyVetoException, IllegalArgumentException, WrappedTargetException, RuntimeException )
     715                 :            : {
     716                 :            :     OSL_ENSURE( !rBHelper.bInDispose, "OPropertySetAggregationHelper::setPropertyValues : do not use within the dispose call !");
     717                 :            :     OSL_ENSURE( !rBHelper.bDisposed, "OPropertySetAggregationHelper::setPropertyValues : object is disposed" );
     718                 :            : 
     719                 :            :     // check where the properties come from
     720         [ +  + ]:       1582 :     if (!m_xAggregateSet.is())
     721                 :         98 :         OPropertySetHelper::setPropertyValues(_rPropertyNames, _rValues);
     722         [ +  + ]:       1484 :     else if (_rPropertyNames.getLength() == 1) // use the more efficient way
     723                 :            :     {
     724                 :            :         try
     725                 :            :         {
     726         [ +  - ]:         85 :             setPropertyValue( _rPropertyNames[0], _rValues[0] );
     727                 :            :         }
     728                 :          0 :         catch( const UnknownPropertyException& )
     729                 :            :         {
     730                 :            :             // by definition of XMultiPropertySet::setPropertyValues, unknown properties are to be ignored
     731                 :            :         #if OSL_DEBUG_LEVEL > 0
     732                 :            :             ::rtl::OStringBuffer aMessage;
     733                 :            :             aMessage.append( "OPropertySetAggregationHelper::setPropertyValues: unknown property '" );
     734                 :            :             aMessage.append( ::rtl::OUStringToOString( _rPropertyNames[0], RTL_TEXTENCODING_ASCII_US ) );
     735                 :            :             aMessage.append( "'" );
     736                 :            :             aMessage.append( "\n(implementation " );
     737                 :            :             aMessage.append( typeid( *this ).name() );
     738                 :            :             aMessage.append( ")" );
     739                 :            :             OSL_FAIL( aMessage.getStr() );
     740                 :            :         #endif
     741                 :            :         }
     742                 :            :     }
     743                 :            :     else
     744                 :            :     {
     745                 :       1399 :         OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
     746                 :            : 
     747                 :            :         // determine which properties belong to the aggregate, and which ones to the delegator
     748                 :       1399 :         const ::rtl::OUString* pNames = _rPropertyNames.getConstArray();
     749                 :       1399 :         sal_Int32 nAggCount(0);
     750                 :       1399 :         sal_Int32 nLen(_rPropertyNames.getLength());
     751                 :            : 
     752         [ +  + ]:      53071 :         for ( sal_Int32 i = 0; i < nLen; ++i, ++pNames )
     753                 :            :         {
     754                 :      51672 :             OPropertyArrayAggregationHelper::PropertyOrigin ePropOrg = rPH.classifyProperty( *pNames );
     755         [ -  + ]:      51672 :             if ( OPropertyArrayAggregationHelper::UNKNOWN_PROPERTY == ePropOrg )
     756 [ #  # ][ #  # ]:          0 :                 throw WrappedTargetException( ::rtl::OUString(), static_cast< XMultiPropertySet* >( this ), makeAny( UnknownPropertyException( ) ) );
         [ #  # ][ #  # ]
     757                 :            :                 // due to a flaw in the API design, this method is not allowed to throw an UnknownPropertyException
     758                 :            :                 // so we wrap it into a WrappedTargetException
     759                 :            : 
     760         [ +  + ]:      51672 :             if ( OPropertyArrayAggregationHelper::AGGREGATE_PROPERTY == ePropOrg )
     761                 :      40487 :                 ++nAggCount;
     762                 :            :         }
     763                 :            : 
     764                 :       1399 :         pNames = _rPropertyNames.getConstArray();   // reset, we'll need it again below ...
     765                 :            : 
     766                 :            :         // all properties belong to the aggregate
     767         [ +  + ]:       1399 :         if (nAggCount == nLen)
     768                 :         39 :             m_xAggregateMultiSet->setPropertyValues(_rPropertyNames, _rValues);
     769                 :            : 
     770                 :            :         // all properties belong to the aggregating object
     771         [ +  + ]:       1360 :         else if (nAggCount == 0)
     772                 :         73 :             OPropertySetHelper::setPropertyValues(_rPropertyNames, _rValues);
     773                 :            : 
     774                 :            :         // mixed
     775                 :            :         else
     776                 :            :         {
     777                 :       1287 :             const  ::com::sun::star::uno::Any* pValues = _rValues.getConstArray();
     778                 :       1287 :              ::com::sun::star::uno::Any* pConvertedValues = NULL;
     779                 :       1287 :              ::com::sun::star::uno::Any* pOldValues = NULL;
     780                 :       1287 :             sal_Int32*  pHandles = NULL;
     781                 :            : 
     782                 :            :             try
     783                 :            :             {
     784                 :            :                 // dividing the Names and _rValues
     785                 :            : 
     786                 :            :                 // aggregate's names
     787         [ +  - ]:       1287 :                 Sequence< ::rtl::OUString > AggPropertyNames( nAggCount );
     788         [ +  - ]:       1287 :                 ::rtl::OUString* pAggNames = AggPropertyNames.getArray();
     789                 :            :                 // aggregate's values
     790         [ +  - ]:       1287 :                 Sequence< Any >  AggValues( nAggCount );
     791         [ +  - ]:       1287 :                 Any* pAggValues = AggValues.getArray();
     792                 :            : 
     793                 :            :                 // delegator names
     794         [ +  - ]:       1287 :                 Sequence< ::rtl::OUString > DelPropertyNames( nLen - nAggCount );
     795         [ +  - ]:       1287 :                 ::rtl::OUString* pDelNames = DelPropertyNames.getArray();
     796                 :            : 
     797                 :            :                 // delegator values
     798         [ +  - ]:       1287 :                 Sequence< Any > DelValues( nLen - nAggCount );
     799         [ +  - ]:       1287 :                 Any* pDelValues = DelValues.getArray();
     800                 :            : 
     801         [ +  + ]:      51167 :                 for ( sal_Int32 i = 0; i < nLen; ++i, ++pNames, ++pValues )
     802                 :            :                 {
     803 [ +  - ][ +  + ]:      49880 :                     if ( OPropertyArrayAggregationHelper::AGGREGATE_PROPERTY == rPH.classifyProperty( *pNames ) )
     804                 :            :                     {
     805                 :      40272 :                         *pAggNames++ = *pNames;
     806                 :      40272 :                         *pAggValues++ = *pValues;
     807                 :            :                     }
     808                 :            :                     else
     809                 :            :                     {
     810                 :       9608 :                         *pDelNames++ = *pNames;
     811                 :       9608 :                         *pDelValues++ = *pValues;
     812                 :            :                     }
     813                 :            :                 }
     814                 :            : 
     815                 :            :                 // reset, needed below
     816         [ +  - ]:       1287 :                 pDelValues = DelValues.getArray();
     817                 :            : 
     818         [ +  - ]:       1287 :                 pHandles = new sal_Int32[ nLen - nAggCount ];
     819                 :            : 
     820                 :            :                 // get the map table
     821         [ +  - ]:       1287 :                 cppu::IPropertyArrayHelper& rPH2 = getInfoHelper();
     822                 :            : 
     823                 :            :                 // fill the handle array
     824         [ +  - ]:       1287 :                 sal_Int32 nHitCount = rPH2.fillHandles( pHandles, DelPropertyNames );
     825         [ +  - ]:       1287 :                 if (nHitCount != 0)
     826                 :            :                 {
     827                 :            : 
     828 [ +  - ][ +  + ]:      10895 :                      pConvertedValues = new  ::com::sun::star::uno::Any[ nHitCount ];
     829 [ +  - ][ +  + ]:      10895 :                      pOldValues = new  ::com::sun::star::uno::Any[ nHitCount ];
     830                 :       1287 :                     nHitCount = 0;
     831                 :            :                     sal_Int32 i;
     832                 :            : 
     833                 :            :                     {
     834                 :            :                     // must lock the mutex outside the loop. So all values are consistent.
     835         [ +  - ]:       1287 :                         osl::MutexGuard aGuard( rBHelper.rMutex );
     836         [ +  + ]:      10895 :                         for( i = 0; i < (nLen - nAggCount); ++i )
     837                 :            :                         {
     838         [ +  - ]:       9608 :                             if( pHandles[i] != -1 )
     839                 :            :                             {
     840                 :            :                                 sal_Int16 nAttributes;
     841         [ +  - ]:       9608 :                                 rPH2.fillPropertyMembersByHandle( NULL, &nAttributes, pHandles[i] );
     842         [ -  + ]:       9608 :                                 if( nAttributes &  ::com::sun::star::beans::PropertyAttribute::READONLY )
     843         [ #  # ]:          0 :                                     throw  ::com::sun::star::beans::PropertyVetoException();
     844                 :            :                                 // Will the property change?
     845         [ +  + ]:       9608 :                                 if( convertFastPropertyValue( pConvertedValues[ nHitCount ], pOldValues[nHitCount],
     846         [ +  - ]:       9608 :                                                             pHandles[i], pDelValues[i] ) )
     847                 :            :                                 {
     848                 :            :                                     // only increment if the property really change
     849                 :        716 :                                     pHandles[nHitCount]         = pHandles[i];
     850                 :       9608 :                                     nHitCount++;
     851                 :            :                                 }
     852                 :            :                             }
     853         [ +  - ]:       1287 :                         }
     854                 :            :                     // release guard to fire events
     855                 :            :                     }
     856                 :            : 
     857                 :            :                     // fire vetoable events
     858         [ +  - ]:       1287 :                     fire( pHandles, pConvertedValues, pOldValues, nHitCount, sal_True );
     859                 :            : 
     860                 :            :                     // setting the agg Properties
     861 [ +  - ][ +  - ]:       1287 :                     m_xAggregateMultiSet->setPropertyValues(AggPropertyNames, AggValues);
     862                 :            : 
     863                 :            :                     {
     864                 :            :                     // must lock the mutex outside the loop.
     865         [ +  - ]:       1287 :                         osl::MutexGuard aGuard( rBHelper.rMutex );
     866                 :            :                         // Loop over all changed properties
     867         [ +  + ]:       2003 :                         for( i = 0; i < nHitCount; i++ )
     868                 :            :                         {
     869                 :            :                             // Will the property change?
     870         [ +  - ]:        716 :                             setFastPropertyValue_NoBroadcast( pHandles[i], pConvertedValues[i] );
     871         [ +  - ]:       1287 :                         }
     872                 :            :                     // release guard to fire events
     873                 :            :                     }
     874                 :            : 
     875                 :            :                     // fire change events
     876         [ +  - ]:       1287 :                     fire( pHandles, pConvertedValues, pOldValues, nHitCount, sal_False );
     877                 :            :                 }
     878                 :            :                 else
     879 [ #  # ][ #  # ]:       1287 :                     m_xAggregateMultiSet->setPropertyValues(AggPropertyNames, AggValues);
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     880                 :            : 
     881                 :            :             }
     882         [ #  # ]:          0 :             catch(::com::sun::star::uno::Exception&)
     883                 :            :             {
     884         [ #  # ]:          0 :                 delete [] pHandles;
     885   [ #  #  #  # ]:          0 :                 delete [] pOldValues;
     886   [ #  #  #  # ]:          0 :                 delete [] pConvertedValues;
     887                 :          0 :                 throw;
     888                 :            :             }
     889                 :            : 
     890         [ +  - ]:       1287 :             delete [] pHandles;
     891 [ +  - ][ +  + ]:      10895 :             delete [] pOldValues;
     892 [ +  - ][ +  + ]:      10895 :             delete [] pConvertedValues;
     893                 :            :         }
     894                 :            :     }
     895         [ #  # ]:       1544 : }
     896                 :            : 
     897                 :            : // XPropertyState
     898                 :            : //------------------------------------------------------------------------------
     899                 :         76 :  ::com::sun::star::beans::PropertyState SAL_CALL OPropertySetAggregationHelper::getPropertyState(const ::rtl::OUString& _rPropertyName)
     900                 :            :             throw( ::com::sun::star::beans::UnknownPropertyException,  ::com::sun::star::uno::RuntimeException)
     901                 :            : {
     902         [ +  - ]:         76 :     OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
     903         [ +  - ]:         76 :     sal_Int32 nHandle = rPH.getHandleByName( _rPropertyName );
     904                 :            : 
     905         [ -  + ]:         76 :     if (nHandle == -1)
     906                 :            :     {
     907         [ #  # ]:          0 :         throw  ::com::sun::star::beans::UnknownPropertyException();
     908                 :            :     }
     909                 :            : 
     910                 :         76 :     ::rtl::OUString aPropName;
     911                 :         76 :     sal_Int32   nOriginalHandle = -1;
     912 [ +  + ][ +  - ]:         76 :     if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
     913                 :            :     {
     914         [ +  - ]:         64 :         if (m_xAggregateState.is())
     915 [ +  - ][ +  - ]:         64 :             return m_xAggregateState->getPropertyState(_rPropertyName);
     916                 :            :         else
     917                 :          0 :             return  ::com::sun::star::beans::PropertyState_DIRECT_VALUE;
     918                 :            :     }
     919                 :            :     else
     920         [ +  - ]:         76 :         return getPropertyStateByHandle(nHandle);
     921                 :            : }
     922                 :            : 
     923                 :            : //------------------------------------------------------------------------------
     924                 :         38 : void SAL_CALL OPropertySetAggregationHelper::setPropertyToDefault(const ::rtl::OUString& _rPropertyName)
     925                 :            :         throw( ::com::sun::star::beans::UnknownPropertyException,  ::com::sun::star::uno::RuntimeException)
     926                 :            : {
     927         [ +  - ]:         38 :     OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
     928         [ +  - ]:         38 :     sal_Int32 nHandle = rPH.getHandleByName(_rPropertyName);
     929         [ -  + ]:         38 :     if (nHandle == -1)
     930                 :            :     {
     931         [ #  # ]:          0 :         throw  ::com::sun::star::beans::UnknownPropertyException();
     932                 :            :     }
     933                 :            : 
     934                 :         38 :     ::rtl::OUString aPropName;
     935                 :         38 :     sal_Int32   nOriginalHandle = -1;
     936 [ +  + ][ +  - ]:         38 :     if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
     937                 :            :     {
     938         [ +  - ]:         32 :         if (m_xAggregateState.is())
     939 [ +  - ][ +  - ]:         32 :             m_xAggregateState->setPropertyToDefault(_rPropertyName);
     940                 :            :     }
     941                 :            :     else
     942                 :            :     {
     943                 :            :         try
     944                 :            :         {
     945         [ +  - ]:          6 :             setPropertyToDefaultByHandle( nHandle );
     946                 :            :         }
     947                 :          0 :         catch( const UnknownPropertyException& ) { throw; }
     948   [ #  #  #  # ]:          0 :         catch( const RuntimeException& ) { throw; }
     949         [ #  # ]:          0 :         catch( const Exception& )
     950                 :            :         {
     951                 :            :             OSL_FAIL( "OPropertySetAggregationHelper::setPropertyToDefault: caught an exception which is not allowed to leave here!" );
     952                 :            :         }
     953                 :         38 :     }
     954                 :         38 : }
     955                 :            : 
     956                 :            : //------------------------------------------------------------------------------
     957                 :         38 :  ::com::sun::star::uno::Any SAL_CALL OPropertySetAggregationHelper::getPropertyDefault(const ::rtl::OUString& aPropertyName)
     958                 :            :         throw( ::com::sun::star::beans::UnknownPropertyException,  ::com::sun::star::lang::WrappedTargetException,  ::com::sun::star::uno::RuntimeException)
     959                 :            : {
     960         [ +  - ]:         38 :     OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
     961         [ +  - ]:         38 :     sal_Int32 nHandle = rPH.getHandleByName( aPropertyName );
     962                 :            : 
     963         [ -  + ]:         38 :     if ( nHandle == -1 )
     964         [ #  # ]:          0 :         throw  ::com::sun::star::beans::UnknownPropertyException();
     965                 :            : 
     966                 :         38 :     ::rtl::OUString aPropName;
     967                 :         38 :     sal_Int32   nOriginalHandle = -1;
     968 [ +  + ][ +  - ]:         38 :     if (rPH.fillAggregatePropertyInfoByHandle(&aPropName, &nOriginalHandle, nHandle))
     969                 :            :     {
     970         [ +  - ]:         32 :         if (m_xAggregateState.is())
     971 [ +  - ][ +  - ]:         32 :             return m_xAggregateState->getPropertyDefault(aPropertyName);
     972                 :            :         else
     973                 :          0 :             return  ::com::sun::star::uno::Any();
     974                 :            :     }
     975                 :            :     else
     976         [ +  - ]:         38 :         return getPropertyDefaultByHandle(nHandle);
     977                 :            : }
     978                 :            : 
     979                 :            : //------------------------------------------------------------------------------
     980                 :        307 : sal_Bool SAL_CALL OPropertySetAggregationHelper::convertFastPropertyValue( Any& _rConvertedValue, Any& _rOldValue, sal_Int32 _nHandle, const Any& _rValue ) throw(IllegalArgumentException)
     981                 :            : {
     982                 :        307 :     sal_Bool bModified = sal_False;
     983                 :            : 
     984                 :            :     OSL_ENSURE( m_pForwarder->isResponsibleFor( _nHandle ), "OPropertySetAggregationHelper::convertFastPropertyValue: this is no forwarded property - did you use declareForwardedProperty for it?" );
     985         [ +  - ]:        307 :     if ( m_pForwarder->isResponsibleFor( _nHandle ) )
     986                 :            :     {
     987                 :            :         // need to determine the type of the property for conversion
     988         [ +  - ]:        307 :         OPropertyArrayAggregationHelper& rPH = static_cast< OPropertyArrayAggregationHelper& >( getInfoHelper() );
     989                 :        307 :         Property aProperty;
     990         [ +  - ]:        307 :         OSL_VERIFY( rPH.getPropertyByHandle( _nHandle, aProperty ) );
     991                 :            : 
     992                 :        307 :         Any aCurrentValue;
     993         [ +  - ]:        307 :         getFastPropertyValue( aCurrentValue, _nHandle );
     994         [ +  - ]:        307 :         bModified = tryPropertyValue( _rConvertedValue, _rOldValue, _rValue, aCurrentValue, aProperty.Type );
     995                 :            :     }
     996                 :            : 
     997                 :        307 :     return bModified;
     998                 :            : }
     999                 :            : 
    1000                 :            : //------------------------------------------------------------------------------
    1001                 :        283 : void SAL_CALL OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast( sal_Int32 _nHandle, const Any& _rValue ) throw ( Exception )
    1002                 :            : {
    1003                 :            :     OSL_ENSURE( m_pForwarder->isResponsibleFor( _nHandle ), "OPropertySetAggregationHelper::setFastPropertyValue_NoBroadcast: this is no forwarded property - did you use declareForwardedProperty for it?" );
    1004         [ +  - ]:        283 :     if ( m_pForwarder->isResponsibleFor( _nHandle ) )
    1005                 :        283 :         m_pForwarder->doForward( _nHandle, _rValue );
    1006                 :        283 : }
    1007                 :            : 
    1008                 :            : //------------------------------------------------------------------------------
    1009                 :        278 : void OPropertySetAggregationHelper::declareForwardedProperty( sal_Int32 _nHandle )
    1010                 :            : {
    1011                 :            :     OSL_ENSURE( !m_pForwarder->isResponsibleFor( _nHandle ), "OPropertySetAggregationHelper::declareForwardedProperty: already declared!" );
    1012                 :        278 :     m_pForwarder->takeResponsibilityFor( _nHandle );
    1013                 :        278 : }
    1014                 :            : 
    1015                 :            : //------------------------------------------------------------------------------
    1016                 :          0 : void SAL_CALL OPropertySetAggregationHelper::forwardingPropertyValue( sal_Int32 )
    1017                 :            : {
    1018                 :            :     // not interested in
    1019                 :          0 : }
    1020                 :            : 
    1021                 :            : //------------------------------------------------------------------------------
    1022                 :          0 : void SAL_CALL OPropertySetAggregationHelper::forwardedPropertyValue( sal_Int32, bool )
    1023                 :            : {
    1024                 :            :     // not interested in
    1025                 :          0 : }
    1026                 :            : 
    1027                 :            : //------------------------------------------------------------------------------
    1028                 :       9983 : bool OPropertySetAggregationHelper::isCurrentlyForwardingProperty( sal_Int32 _nHandle ) const
    1029                 :            : {
    1030                 :       9983 :     return m_pForwarder->getCurrentlyForwardedProperty() == _nHandle;
    1031                 :            : }
    1032                 :            : 
    1033                 :            : //.........................................................................
    1034                 :            : }   // namespace comphelper
    1035                 :            : //.........................................................................
    1036                 :            : 
    1037                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10