LCOV - code coverage report
Current view: top level - svl/source/items - itemset.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 623 764 81.5 %
Date: 2014-11-03 Functions: 42 48 87.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             : 
      21             : #include <string.h>
      22             : 
      23             : #include <cstdarg>
      24             : 
      25             : #include <svl/itemset.hxx>
      26             : #include <svl/itempool.hxx>
      27             : #include <svl/itemiter.hxx>
      28             : #include <svl/whiter.hxx>
      29             : #include <svl/nranges.hxx>
      30             : #include "whassert.hxx"
      31             : 
      32             : #include <tools/stream.hxx>
      33             : #include <tools/solar.h>
      34             : #include <rtl/string.hxx>
      35             : 
      36             : // STATIC DATA
      37             : 
      38             : static const sal_uInt16 nInitCount = 10; // Single USHORTs => 5 pairs without '0'
      39             : #if OSL_DEBUG_LEVEL > 1
      40             : static sal_uLong nRangesCopyCount = 0;   // How often have ranges been copied?
      41             : #endif
      42             : 
      43             : #include "nranges.cxx"
      44             : #include "poolio.hxx"
      45             : 
      46             : 
      47             : #ifdef DBG_UTIL
      48             : 
      49             : 
      50             : const sal_Char *DbgCheckItemSet( const void* pVoid )
      51             : {
      52             :     const SfxItemSet *pSet = (const SfxItemSet*) pVoid;
      53             :     SfxWhichIter aIter( *pSet );
      54             :     sal_uInt16 nCount = 0, n = 0;
      55             :     for ( sal_uInt16 nWh = aIter.FirstWhich(); nWh; nWh = aIter.NextWhich(), ++n )
      56             :     {
      57             :         const SfxPoolItem *pItem = pSet->_aItems[n];
      58             :         if ( pItem )
      59             :         {
      60             :             ++nCount;
      61             :             DBG_ASSERT( IsInvalidItem(pItem) ||
      62             :                         pItem->Which() == 0 || pItem->Which() == nWh,
      63             :                         "SfxItemSet: invalid which-id" );
      64             :             DBG_ASSERT( IsInvalidItem(pItem) || !pItem->Which() ||
      65             :                     !SfxItemPool::IsWhich(pItem->Which()) ||
      66             :                     pSet->GetPool()->IsItemFlag(nWh, SFX_ITEM_NOT_POOLABLE) ||
      67             :                     SFX_ITEMS_NULL != pSet->GetPool()->GetSurrogate(pItem),
      68             :                     "SfxItemSet: item in set which is not in pool" );
      69             :         }
      70             : 
      71             :     }
      72             :     DBG_ASSERT( pSet->_nCount == nCount, "wrong SfxItemSet::nCount detected" );
      73             : 
      74             :     return 0;
      75             : }
      76             : 
      77             : #endif
      78             : 
      79             : /**
      80             :  * Ctor for a SfxItemSet with exactly the Which Ranges, which are known to
      81             :  * the supplied SfxItemPool.
      82             :  *
      83             :  * For Sfx programmers: an SfxItemSet constructed in this way cannot
      84             :  * contain any Items with SlotIds as Which values.
      85             :  */
      86       34505 : SfxItemSet::SfxItemSet
      87             : (
      88             :     SfxItemPool&    rPool,       /* Target Pool for the SfxPoolItems which are
      89             :                                     added to this SfxItemSet */
      90             :     bool        bTotalRanges    /* Take over complete pool ranges? */
      91             : )
      92             : :   _pPool( &rPool ),
      93             :     _pParent( 0 ),
      94       34505 :     _nCount( 0 )
      95             : {
      96             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "no Master Pool" );
      97             : //  DBG_ASSERT( bTotalRanges || abs( &bTotalRanges - this ) < 1000,
      98             : //              "please use suitable ranges" );
      99             : #if defined DBG_UTIL && defined SFX_ITEMSET_NO_DEFAULT_CTOR
     100             :     if ( !bTotalRanges )
     101             :         *(int*)0 = 0; // GPF
     102             : #else
     103             :     (void) bTotalRanges; // avoid warnings
     104             : #endif
     105             : 
     106       34505 :     _pWhichRanges = (sal_uInt16*) _pPool->GetFrozenIdRanges();
     107             :     DBG_ASSERT( _pWhichRanges, "don't create ItemSets with full range before FreezeIdRanges()" );
     108       34505 :     if ( !_pWhichRanges )
     109           0 :         _pPool->FillItemIdRanges_Impl( _pWhichRanges );
     110             : 
     111       34505 :     const sal_uInt16 nSize = TotalCount();
     112       34505 :     _aItems = new const SfxPoolItem* [ nSize ];
     113       34505 :     memset( (void*) _aItems, 0, nSize * sizeof( SfxPoolItem* ) );
     114       34505 : }
     115             : 
     116             : 
     117             : 
     118     2965664 : SfxItemSet::SfxItemSet( SfxItemPool& rPool, sal_uInt16 nWhich1, sal_uInt16 nWhich2 ):
     119             :     _pPool( &rPool ),
     120             :     _pParent( 0 ),
     121     2965664 :     _nCount( 0 )
     122             : {
     123             :     DBG_ASSERT( nWhich1 <= nWhich2, "Invalid range" );
     124             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "no Master Pool" );
     125             : 
     126     2965664 :     InitRanges_Impl(nWhich1, nWhich2);
     127     2965664 : }
     128             : 
     129             : 
     130             : 
     131     2966022 : void SfxItemSet::InitRanges_Impl(sal_uInt16 nWh1, sal_uInt16 nWh2)
     132             : {
     133     2966022 :     _pWhichRanges = new sal_uInt16[ 3 ];
     134     2966022 :     *(_pWhichRanges+0) = nWh1;
     135     2966022 :     *(_pWhichRanges+1) = nWh2;
     136     2966022 :     *(_pWhichRanges+2) = 0;
     137     2966022 :     const sal_uInt16 nRg = nWh2 - nWh1 + 1;
     138     2966022 :     _aItems = new const SfxPoolItem* [ nRg ];
     139     2966022 :     memset( (void*) _aItems, 0, nRg * sizeof( SfxPoolItem* ) );
     140     2966022 : }
     141             : 
     142             : 
     143             : 
     144      667597 : void SfxItemSet::InitRanges_Impl(va_list pArgs, sal_uInt16 nWh1, sal_uInt16 nWh2, sal_uInt16 nNull)
     145             : {
     146      667597 :     sal_uInt16 nSize = InitializeRanges_Impl( _pWhichRanges, pArgs, nWh1, nWh2, nNull );
     147      667597 :     _aItems = new const SfxPoolItem* [ nSize ];
     148      667597 :     memset( (void*) _aItems, 0, sizeof( SfxPoolItem* ) * nSize );
     149      667597 : }
     150             : 
     151             : 
     152             : 
     153      667955 : SfxItemSet::SfxItemSet( SfxItemPool& rPool,
     154             :                         USHORT_ARG nWh1, USHORT_ARG nWh2, USHORT_ARG nNull, ... ):
     155             :     _pPool( &rPool ),
     156             :     _pParent( 0 ),
     157             :     _pWhichRanges( 0 ),
     158      667955 :     _nCount( 0 )
     159             : {
     160             :     DBG_ASSERT( nWh1 <= nWh2, "Invalid range" );
     161             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "no Master Pool" );
     162             : 
     163      667955 :     if(!nNull)
     164             :         InitRanges_Impl(
     165         358 :             sal::static_int_cast< sal_uInt16 >(nWh1),
     166         716 :             sal::static_int_cast< sal_uInt16 >(nWh2));
     167             :     else {
     168             :         va_list pArgs;
     169      667597 :         va_start( pArgs, nNull );
     170             :         InitRanges_Impl(
     171      667597 :             pArgs, sal::static_int_cast< sal_uInt16 >(nWh1),
     172      667597 :             sal::static_int_cast< sal_uInt16 >(nWh2),
     173     2002791 :             sal::static_int_cast< sal_uInt16 >(nNull));
     174      667597 :         va_end(pArgs);
     175             :     }
     176      667955 : }
     177             : 
     178             : 
     179             : 
     180     8726034 : void SfxItemSet::InitRanges_Impl(const sal_uInt16 *pWhichPairTable)
     181             : {
     182             :     #if OSL_DEBUG_LEVEL > 1
     183             :     OSL_TRACE("SfxItemSet: Ranges-CopyCount==%ul", ++nRangesCopyCount);
     184             :     #endif
     185             : 
     186     8726034 :     sal_uInt16 nCnt = 0;
     187     8726034 :     const sal_uInt16* pPtr = pWhichPairTable;
     188    47855238 :     while( *pPtr )
     189             :     {
     190    30403170 :         nCnt += ( *(pPtr+1) - *pPtr ) + 1;
     191    30403170 :         pPtr += 2;
     192             :     }
     193             : 
     194     8726034 :     _aItems = new const SfxPoolItem* [ nCnt ];
     195     8726034 :     memset( (void*) _aItems, 0, sizeof( SfxPoolItem* ) * nCnt );
     196             : 
     197     8726034 :     std::ptrdiff_t cnt = pPtr - pWhichPairTable +1;
     198     8726034 :     _pWhichRanges = new sal_uInt16[ cnt ];
     199     8726034 :     memcpy( _pWhichRanges, pWhichPairTable, sizeof( sal_uInt16 ) * cnt );
     200     8726034 : }
     201             : 
     202             : 
     203             : 
     204             : 
     205     8786185 : SfxItemSet::SfxItemSet( SfxItemPool& rPool, const sal_uInt16* pWhichPairTable )
     206             :     : _pPool(&rPool)
     207             :     , _pParent(0)
     208             :     , _aItems(0)
     209             :     , _pWhichRanges(0)
     210     8786185 :     , _nCount(0)
     211             : {
     212             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "no Master Pool" );
     213             : 
     214             :     // pWhichPairTable == 0 ist f"ur das SfxAllEnumItemSet
     215     8786185 :     if ( pWhichPairTable )
     216     8726034 :         InitRanges_Impl(pWhichPairTable);
     217     8786185 : }
     218             : 
     219     7409380 : SfxItemSet::SfxItemSet( const SfxItemSet& rASet ):
     220             :     _pPool( rASet._pPool ),
     221             :     _pParent( rASet._pParent ),
     222     7409380 :     _nCount( rASet._nCount )
     223             : {
     224             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "no Master Pool" );
     225             : 
     226             :     // Calculate the attribute count
     227     7409380 :     sal_uInt16 nCnt = 0;
     228     7409380 :     sal_uInt16* pPtr = rASet._pWhichRanges;
     229    66934649 :     while( *pPtr )
     230             :     {
     231    52115889 :         nCnt += ( *(pPtr+1) - *pPtr ) + 1;
     232    52115889 :         pPtr += 2;
     233             :     }
     234             : 
     235     7409380 :     _aItems = new const SfxPoolItem* [ nCnt ];
     236             : 
     237             :     // Copy attributes
     238     7409380 :     SfxItemArray ppDst = _aItems, ppSrc = rASet._aItems;
     239   560289918 :     for( sal_uInt16 n = nCnt; n; --n, ++ppDst, ++ppSrc )
     240  1128951821 :         if ( 0 == *ppSrc ||                 // Current Default?
     241   576068971 :              IsInvalidItem(*ppSrc) ||       // DontCare?
     242    23188433 :              IsStaticDefaultItem(*ppSrc) )  // Defaults that are not to be pooled?
     243             :             // Just copy the pointer
     244   529768125 :             *ppDst = *ppSrc;
     245    23112413 :         else if ( _pPool->IsItemFlag( **ppSrc, SFX_ITEM_POOLABLE ) )
     246             :         {
     247             :             // Just copy the pointer and increase RefCount
     248    20077530 :             *ppDst = *ppSrc;
     249    20077530 :             ( (SfxPoolItem*) (*ppDst) )->AddRef();
     250             :         }
     251     3034883 :         else if ( !(*ppSrc)->Which() )
     252           0 :             *ppDst = (*ppSrc)->Clone();
     253             :         else
     254             :             // !IsPoolable() => assign via Pool
     255     3034883 :             *ppDst = &_pPool->Put( **ppSrc );
     256             : 
     257             :     // Copy the WhichRanges
     258             :     #if OSL_DEBUG_LEVEL > 1
     259             :     OSL_TRACE("SfxItemSet: Ranges-CopyCount==%ul", ++nRangesCopyCount);
     260             :     #endif
     261     7409380 :     std::ptrdiff_t cnt = pPtr - rASet._pWhichRanges+1;
     262     7409380 :     _pWhichRanges = new sal_uInt16[ cnt ];
     263     7409380 :     memcpy( _pWhichRanges, rASet._pWhichRanges, sizeof( sal_uInt16 ) * cnt);
     264     7409380 : }
     265             : 
     266             : 
     267             : 
     268    22195095 : SfxItemSet::~SfxItemSet()
     269             : {
     270    19858972 :     sal_uInt16 nCount = TotalCount();
     271    19858972 :     if( Count() )
     272             :     {
     273    11017897 :         SfxItemArray ppFnd = _aItems;
     274  1248175208 :         for( sal_uInt16 nCnt = nCount; nCnt; --nCnt, ++ppFnd )
     275  1237157311 :             if( *ppFnd && !IsInvalidItem(*ppFnd) )
     276             :             {
     277    45531845 :                 if( !(*ppFnd)->Which() )
     278       13081 :                     delete (SfxPoolItem*) *ppFnd;
     279             :                 else {
     280             :                     // Still multiple references present, so just alter the RefCount
     281    45518764 :                     if ( 1 < (*ppFnd)->GetRefCount() && !IsDefaultItem(*ppFnd) )
     282    39225506 :                         (*ppFnd)->ReleaseRef();
     283             :                     else
     284     6293258 :                         if ( !IsDefaultItem(*ppFnd) )
     285             :                             // Delete from Pool
     286     5602586 :                             _pPool->Remove( **ppFnd );
     287             :                 }
     288             :             }
     289             :     }
     290             : 
     291             :     // FIXME: could be delete[] (SfxPoolItem **)_aItems;
     292    19858972 :     delete[] _aItems;
     293    19858972 :     if ( _pWhichRanges != _pPool->GetFrozenIdRanges() )
     294    19824543 :         delete[] _pWhichRanges;
     295    19858972 :     _pWhichRanges = 0; // for invariant-testing
     296    22195095 : }
     297             : 
     298             : 
     299             : /**
     300             :  * Delete single Items or all Items (nWhich == 0)
     301             :  */
     302     9190982 : sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
     303             : {
     304     9190982 :     if( !Count() )
     305     3448442 :         return 0;
     306             : 
     307     5742540 :     sal_uInt16 nDel = 0;
     308     5742540 :     SfxItemArray ppFnd = _aItems;
     309             : 
     310     5742540 :     if( nWhich )
     311             :     {
     312     4833870 :         const sal_uInt16* pPtr = _pWhichRanges;
     313    15055708 :         while( *pPtr )
     314             :         {
     315             :             // Within this range?
     316    10087457 :             if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     317             :             {
     318             :                 // Actually set?
     319     4699489 :                 ppFnd += nWhich - *pPtr;
     320     4699489 :                 if( *ppFnd )
     321             :                 {
     322             :                     // Due to the assertions in the sub calls, we need to do the following
     323      295279 :                     --_nCount;
     324      295279 :                     const SfxPoolItem *pItemToClear = *ppFnd;
     325      295279 :                     *ppFnd = 0;
     326             : 
     327      295279 :                     if ( !IsInvalidItem(pItemToClear) )
     328             :                     {
     329      295279 :                         if ( nWhich <= SFX_WHICH_MAX )
     330             :                         {
     331             :                             const SfxPoolItem& rNew = _pParent
     332      107380 :                                     ? _pParent->Get( nWhich, true )
     333      373072 :                                     : _pPool->GetDefaultItem( nWhich );
     334             : 
     335      265692 :                             Changed( *pItemToClear, rNew );
     336             :                         }
     337      295279 :                         if ( pItemToClear->Which() )
     338      295279 :                             _pPool->Remove( *pItemToClear );
     339             :                     }
     340      295279 :                     ++nDel;
     341             :                 }
     342             : 
     343             :                 // found => break
     344     4699489 :                 break;
     345             :             }
     346     5387968 :             ppFnd += *(pPtr+1) - *pPtr + 1;
     347     5387968 :             pPtr += 2;
     348             :         }
     349             :     }
     350             :     else
     351             :     {
     352      908670 :         nDel = _nCount;
     353             : 
     354      908670 :         sal_uInt16* pPtr = _pWhichRanges;
     355    13899650 :         while( *pPtr )
     356             :         {
     357   124371378 :             for( nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     358   112289068 :                 if( *ppFnd )
     359             :                 {
     360             :                     // Due to the assertions in the sub calls, we need to do this
     361     3290068 :                     --_nCount;
     362     3290068 :                     const SfxPoolItem *pItemToClear = *ppFnd;
     363     3290068 :                     *ppFnd = 0;
     364             : 
     365     3290068 :                     if ( !IsInvalidItem(pItemToClear) )
     366             :                     {
     367     3289762 :                         if ( nWhich <= SFX_WHICH_MAX )
     368             :                         {
     369             :                             const SfxPoolItem& rNew = _pParent
     370     1500082 :                                     ? _pParent->Get( nWhich, true )
     371     3912952 :                                     : _pPool->GetDefaultItem( nWhich );
     372             : 
     373     2412870 :                             Changed( *pItemToClear, rNew );
     374             :                         }
     375             : 
     376             :                         // #i32448#
     377             :                         // Take care of disabled items, too.
     378     3289762 :                         if (!pItemToClear->m_nWhich)
     379             :                         {
     380             :                             // item is disabled, delete it
     381           0 :                             delete pItemToClear;
     382             :                         }
     383             :                         else
     384             :                         {
     385             :                             // remove item from pool
     386     3289762 :                             _pPool->Remove( *pItemToClear );
     387             :                         }
     388             :                     }
     389             :                 }
     390    12082310 :             pPtr += 2;
     391             :         }
     392             :     }
     393     5742540 :     return nDel;
     394             : }
     395             : 
     396             : 
     397             : 
     398      355583 : void SfxItemSet::ClearInvalidItems( bool bHardDefault )
     399             : {
     400      355583 :     sal_uInt16* pPtr = _pWhichRanges;
     401      355583 :     SfxItemArray ppFnd = _aItems;
     402      355583 :     if ( bHardDefault )
     403           0 :         while( *pPtr )
     404             :         {
     405           0 :             for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     406           0 :                 if ( IsInvalidItem(*ppFnd) )
     407           0 :                      *ppFnd = &_pPool->Put( _pPool->GetDefaultItem(nWhich) );
     408           0 :             pPtr += 2;
     409             :         }
     410             :     else
     411     6582561 :         while( *pPtr )
     412             :         {
     413    56682694 :             for( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     414    50811299 :                 if( IsInvalidItem(*ppFnd) )
     415             :                 {
     416        1214 :                     *ppFnd = 0;
     417        1214 :                     --_nCount;
     418             :                 }
     419     5871395 :             pPtr += 2;
     420             :         }
     421      355583 : }
     422             : 
     423           0 : void SfxItemSet::InvalidateDefaultItems()
     424             : {
     425           0 :     sal_uInt16* pPtr = _pWhichRanges;
     426           0 :     SfxItemArray ppFnd = _aItems;
     427             : 
     428           0 :     while( *pPtr )
     429             :     {
     430           0 :         for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     431           0 :             if ( *ppFnd && *ppFnd != reinterpret_cast<SfxPoolItem *>(-1) && **ppFnd == _pPool->GetDefaultItem( nWhich ) )
     432             :             {
     433           0 :                 _pPool->Remove( **ppFnd );
     434           0 :                 *ppFnd = reinterpret_cast<SfxPoolItem*>(-1);
     435             :             }
     436           0 :         pPtr += 2;
     437             :     }
     438           0 : }
     439             : 
     440           0 : void SfxItemSet::InvalidateAllItems()
     441             : {
     442             :     DBG_ASSERT( !_nCount, "There are still Items set" );
     443             : 
     444           0 :     memset( (void*)_aItems, -1, ( _nCount = TotalCount() ) * sizeof( SfxPoolItem*) );
     445           0 : }
     446             : 
     447             : 
     448             : 
     449   197655943 : SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich,
     450             :                                         bool bSrchInParent,
     451             :                                         const SfxPoolItem **ppItem ) const
     452             : {
     453             :     // Find the range in which the Which is located
     454   197655943 :     const SfxItemSet* pAktSet = this;
     455   197655943 :     SfxItemState eRet = SfxItemState::UNKNOWN;
     456   177105948 :     do
     457             :     {
     458   235308370 :         SfxItemArray ppFnd = pAktSet->_aItems;
     459   235308370 :         const sal_uInt16* pPtr = pAktSet->_pWhichRanges;
     460   235308370 :         if (pPtr)
     461             :         {
     462   699934533 :             while ( *pPtr )
     463             :             {
     464   444875787 :                 if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     465             :                 {
     466             :                     // Within this range
     467   215557994 :                     ppFnd += nWhich - *pPtr;
     468   215557994 :                     if ( !*ppFnd )
     469             :                     {
     470   187319731 :                         eRet = SfxItemState::DEFAULT;
     471   187319731 :                         if( !bSrchInParent )
     472    29964159 :                             return eRet; // Not present
     473   157355572 :                         break; // Keep searching in the parents!
     474             :                     }
     475             : 
     476    28238263 :                     if ( reinterpret_cast<SfxPoolItem*>(-1) == *ppFnd )
     477             :                         // Different ones are present
     478         694 :                         return SfxItemState::DONTCARE;
     479             : 
     480    28237569 :                     if ( (*ppFnd)->Type() == TYPE(SfxVoidItem) )
     481       20222 :                         return SfxItemState::DISABLED;
     482             : 
     483    28217347 :                     if (ppItem)
     484             :                     {
     485    15621293 :                         *ppItem = *ppFnd;
     486             :                     }
     487    28217347 :                     return SfxItemState::SET;
     488             :                 }
     489   229317793 :                 ppFnd += *(pPtr+1) - *pPtr + 1;
     490   229317793 :                 pPtr += 2;
     491             :             }
     492             :         }
     493   177105948 :     } while( bSrchInParent && 0 != ( pAktSet = pAktSet->_pParent ));
     494   139453521 :     return eRet;
     495             : }
     496             : 
     497     6928274 : bool SfxItemSet::HasItem(sal_uInt16 nWhich, const SfxPoolItem** ppItem) const
     498             : {
     499     6928274 :     bool bRet = SfxItemState::SET == GetItemState(nWhich, true, ppItem);
     500     6928274 :     if (!bRet && ppItem)
     501       54739 :         *ppItem = NULL;
     502     6928274 :     return bRet;
     503             : }
     504             : 
     505             : 
     506             : 
     507    37642088 : const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
     508             : {
     509    37642088 :     if ( !nWhich )
     510         122 :         return 0; //FIXME: Only because of Outliner bug
     511             : 
     512    37641966 :     SfxItemArray ppFnd = _aItems;
     513    37641966 :     const sal_uInt16* pPtr = _pWhichRanges;
     514   124532308 :     while( *pPtr )
     515             :     {
     516    81155799 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     517             :         {
     518             :             // Within this range
     519    31907423 :             ppFnd += nWhich - *pPtr;
     520    31907423 :             if( *ppFnd ) // Already one present
     521             :             {
     522             :                 // Same Item already present?
     523     8399849 :                 if ( *ppFnd == &rItem )
     524     5332089 :                     return 0;
     525             : 
     526             :                 // Will 'dontcare' or 'disabled' be overwritten with some real value?
     527     3067760 :                 if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
     528             :                 {
     529          18 :                     *ppFnd = &_pPool->Put( rItem, nWhich );
     530          18 :                     return *ppFnd;
     531             :                 }
     532             : 
     533             :                 // Turns into disabled?
     534     3067742 :                 if( !rItem.Which() )
     535             :                 {
     536          14 :                     *ppFnd = rItem.Clone(_pPool);
     537          14 :                     return 0;
     538             :                 }
     539             :                 else
     540             :                 {
     541             :                     // Same value already present?
     542     3067728 :                     if ( rItem == **ppFnd )
     543     1721681 :                         return 0;
     544             : 
     545             :                     // Add the new one, remove the old one
     546     1346047 :                     const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich );
     547     1346047 :                     const SfxPoolItem* pOld = *ppFnd;
     548     1346047 :                     *ppFnd = &rNew;
     549     1346047 :                     if(nWhich <= SFX_WHICH_MAX)
     550     1329422 :                         Changed( *pOld, rNew );
     551     1346047 :                     _pPool->Remove( *pOld );
     552             :                 }
     553             :             }
     554             :             else
     555             :             {
     556    23507574 :                 ++_nCount;
     557    23507574 :                 if( !rItem.Which() )
     558       13067 :                     *ppFnd = rItem.Clone(_pPool);
     559             :                 else {
     560    23494507 :                     const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich );
     561    23494507 :                     *ppFnd = &rNew;
     562    23494507 :                     if (nWhich <= SFX_WHICH_MAX )
     563             :                     {
     564             :                         const SfxPoolItem& rOld = _pParent
     565     2902569 :                             ? _pParent->Get( nWhich, true )
     566    25102134 :                             : _pPool->GetDefaultItem( nWhich );
     567    22199565 :                         Changed( rOld, rNew );
     568             :                     }
     569             :                 }
     570             :             }
     571             :             SFX_ASSERT( !_pPool->IsItemFlag(nWhich, SFX_ITEM_POOLABLE) ||
     572             :                         rItem.ISA(SfxSetItem) || **ppFnd == rItem,
     573             :                         nWhich, "putted Item unequal" );
     574    24853621 :             return *ppFnd;
     575             :         }
     576    49248376 :         ppFnd += *(pPtr+1) - *pPtr + 1;
     577    49248376 :         pPtr += 2;
     578             :     }
     579     5734543 :     return 0;
     580             : }
     581             : 
     582             : 
     583             : 
     584     3088331 : bool SfxItemSet::Put( const SfxItemSet& rSet, bool bInvalidAsDefault )
     585             : {
     586     3088331 :     bool bRet = false;
     587     3088331 :     if( rSet.Count() )
     588             :     {
     589     2775242 :         SfxItemArray ppFnd = rSet._aItems;
     590     2775242 :         const sal_uInt16* pPtr = rSet._pWhichRanges;
     591    20528426 :         while ( *pPtr )
     592             :         {
     593   340915316 :             for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     594   325937374 :                 if( *ppFnd )
     595             :                 {
     596    14519761 :                     if ( IsInvalidItem( *ppFnd ) )
     597             :                     {
     598          48 :                         if ( bInvalidAsDefault )
     599           0 :                             bRet |= 0 != ClearItem( nWhich );
     600             :                             // FIXME: Caused a SEGFAULT on non Windows-platforms:
     601             :                             // bRet |= 0 != Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
     602             :                         else
     603          48 :                             InvalidateItem( nWhich );
     604             :                     }
     605             :                     else
     606    14519713 :                         bRet |= 0 != Put( **ppFnd, nWhich );
     607             :                 }
     608    14977942 :             pPtr += 2;
     609             :         }
     610             :     }
     611     3088331 :     return bRet;
     612             : }
     613             : 
     614             : 
     615             : /**
     616             :  * This method takes the Items from the 'rSet' and adds to '*this'.
     617             :  * Which ranges in '*this' that are non-existent in 'rSet' will not
     618             :  * be altered. The Which range of '*this' is also not changed.
     619             :  *
     620             :  * Items set in 'rSet' are also set in '*this'.
     621             :  * Default (0 pointer) and Invalid (-1 pointer) Items are processed
     622             :  * according to their parameter 'eDontCareAs' and 'eDefaultAs':
     623             :  *
     624             :  * SfxItemState::SET:       Hard set to the default of the Pool
     625             :  * SfxItemState::DEFAULT:   Deleted (0 pointer)
     626             :  * SfxItemState::DONTCARE:  Invalid (-1 pointer)
     627             :  *
     628             :  * NB: All other values for 'eDontCareAs' and 'eDefaultAs' are invalid
     629             :  */
     630        1252 : void SfxItemSet::PutExtended
     631             : (
     632             :     const SfxItemSet&   rSet,           // Source of the Items to be put
     633             :     SfxItemState        eDontCareAs,    // What will happen to the DontCare Items
     634             :     SfxItemState        eDefaultAs      // What will happen to the Default Items
     635             : )
     636             : {
     637             :     // don't "optimize" with "if( rSet.Count()" because of dont-care + defaults
     638        1252 :     SfxItemArray ppFnd = rSet._aItems;
     639        1252 :     const sal_uInt16* pPtr = rSet._pWhichRanges;
     640        3788 :     while ( *pPtr )
     641             :     {
     642       71276 :         for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     643       69992 :             if( *ppFnd )
     644             :             {
     645         190 :                 if ( IsInvalidItem( *ppFnd ) )
     646             :                 {
     647             :                     // Item ist DontCare:
     648           0 :                     switch ( eDontCareAs )
     649             :                     {
     650             :                         case SfxItemState::SET:
     651           0 :                             Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
     652           0 :                             break;
     653             : 
     654             :                         case SfxItemState::DEFAULT:
     655           0 :                             ClearItem( nWhich );
     656           0 :                             break;
     657             : 
     658             :                         case SfxItemState::DONTCARE:
     659           0 :                             InvalidateItem( nWhich );
     660           0 :                             break;
     661             : 
     662             :                         default:
     663             :                             OSL_FAIL( "invalid Argument for eDontCareAs" );
     664             :                     }
     665             :                 }
     666             :                 else
     667             :                     // Item is set:
     668         190 :                     Put( **ppFnd, nWhich );
     669             :             }
     670             :             else
     671             :             {
     672             :                 // Item is default:
     673       69802 :                 switch ( eDefaultAs )
     674             :                 {
     675             :                     case SfxItemState::SET:
     676       68250 :                         Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
     677       68250 :                         break;
     678             : 
     679             :                     case SfxItemState::DEFAULT:
     680        1552 :                         ClearItem( nWhich );
     681        1552 :                         break;
     682             : 
     683             :                     case SfxItemState::DONTCARE:
     684           0 :                         InvalidateItem( nWhich );
     685           0 :                         break;
     686             : 
     687             :                     default:
     688             :                         OSL_FAIL( "invalid Argument for eDefaultAs" );
     689             :                 }
     690             :             }
     691        1284 :         pPtr += 2;
     692             :     }
     693        1252 : }
     694             : 
     695             : 
     696             : /**
     697             :  * Expands the ranges of settable items by 'nFrom' to 'nTo'. Keeps state of
     698             :  * items which are new ranges too.
     699             :  */
     700       51040 : void SfxItemSet::MergeRange( sal_uInt16 nFrom, sal_uInt16 nTo )
     701             : {
     702             :     // special case: exactly one sal_uInt16 which is already included?
     703       51040 :     SfxItemState eItemState = GetItemState(nFrom, false);
     704       51040 :     if ( nFrom == nTo && ( eItemState == SfxItemState::DEFAULT || eItemState == SfxItemState::SET ) )
     705       51040 :         return;
     706             : 
     707             :     // merge new range
     708       51040 :     SfxUShortRanges aRanges( _pWhichRanges );
     709       51040 :     aRanges += SfxUShortRanges( nFrom, nTo );
     710       51040 :     SetRanges( aRanges );
     711             : }
     712             : 
     713             : 
     714             : /**
     715             :  * Modifies the ranges of settable items. Keeps state of items which
     716             :  * are new ranges too.
     717             :  */
     718       51040 : void SfxItemSet::SetRanges( const sal_uInt16 *pNewRanges )
     719             : {
     720             :     // Identical Ranges?
     721       51040 :     if ( _pWhichRanges == pNewRanges )
     722           0 :         return;
     723       51040 :     const sal_uInt16* pOld = _pWhichRanges;
     724       51040 :     const sal_uInt16* pNew = pNewRanges;
     725      280720 :     while ( *pOld == *pNew )
     726             :     {
     727      178640 :         if ( !*pOld && !*pNew )
     728           0 :             return;
     729      178640 :         ++pOld, ++pNew;
     730             :     }
     731             : 
     732             :     // create new item-array (by iterating through all new ranges)
     733       51040 :     sal_uLong        nSize = Capacity_Impl(pNewRanges);
     734       51040 :     SfxItemArray aNewItems = new const SfxPoolItem* [ nSize ];
     735       51040 :     sal_uInt16 nNewCount = 0;
     736       51040 :     if ( _nCount == 0 )
     737       51040 :         memset( aNewItems, 0, nSize * sizeof( SfxPoolItem* ) );
     738             :     else
     739             :     {
     740           0 :         sal_uInt16 n = 0;
     741           0 :         for ( const sal_uInt16 *pRange = pNewRanges; *pRange; pRange += 2 )
     742             :         {
     743             :             // iterate through all ids in the range
     744           0 :             for ( sal_uInt16 nWID = *pRange; nWID <= pRange[1]; ++nWID, ++n )
     745             :             {
     746             :                 // direct move of pointer (not via pool)
     747           0 :                 SfxItemState eState = GetItemState( nWID, false, aNewItems+n );
     748           0 :                 if ( SfxItemState::SET == eState )
     749             :                 {
     750             :                     // increment new item count and possibly increment ref count
     751           0 :                     ++nNewCount;
     752           0 :                     aNewItems[n]->AddRef();
     753             :                 }
     754           0 :                 else if ( SfxItemState::DISABLED == eState )
     755             :                 {
     756             :                     // put "disabled" item
     757           0 :                     ++nNewCount;
     758           0 :                     aNewItems[n] = new SfxVoidItem(0);
     759             :                 }
     760           0 :                 else if ( SfxItemState::DONTCARE == eState )
     761             :                 {
     762           0 :                     ++nNewCount;
     763           0 :                     aNewItems[n] = reinterpret_cast<SfxPoolItem*>(-1);
     764             :                 }
     765             :                 else
     766             :                 {
     767             :                     // default
     768           0 :                     aNewItems[n] = 0;
     769             :                 }
     770             :             }
     771             :         }
     772             :         // free old items
     773           0 :         sal_uInt16 nOldTotalCount = TotalCount();
     774           0 :         for ( sal_uInt16 nItem = 0; nItem < nOldTotalCount; ++nItem )
     775             :         {
     776           0 :             const SfxPoolItem *pItem = _aItems[nItem];
     777           0 :             if ( pItem && !IsInvalidItem(pItem) && pItem->Which() )
     778           0 :                 _pPool->Remove(*pItem);
     779             :         }
     780             :     }
     781             : 
     782             :     // replace old items-array and ranges
     783       51040 :     delete[] _aItems;
     784       51040 :     _aItems = aNewItems;
     785       51040 :     _nCount = nNewCount;
     786             : 
     787       51040 :     if( pNewRanges == GetPool()->GetFrozenIdRanges() )
     788             :     {
     789           0 :         delete[] _pWhichRanges;
     790           0 :         _pWhichRanges = ( sal_uInt16* ) pNewRanges;
     791             :     }
     792             :     else
     793             :     {
     794       51040 :         sal_uInt16 nCount = Count_Impl(pNewRanges) + 1;
     795       51040 :         if ( _pWhichRanges != _pPool->GetFrozenIdRanges() )
     796       51040 :             delete[] _pWhichRanges;
     797       51040 :         _pWhichRanges = new sal_uInt16[ nCount ];
     798       51040 :         memcpy( _pWhichRanges, pNewRanges, sizeof( sal_uInt16 ) * nCount );
     799             :     }
     800             : }
     801             : 
     802             : 
     803             : /**
     804             :  * The SfxItemSet takes over exactly those SfxPoolItems that are
     805             :  * set in rSet and are in their own Which range. All others are removed.
     806             :  * The SfxItemPool is retained, such that SfxPoolItems that have been
     807             :  * taken over, are moved from the rSet's SfxItemPool to the SfxItemPool
     808             :  * of *this.
     809             :  *
     810             :  * SfxPoolItems in rSet, for which holds 'IsInvalidItem() == true' are
     811             :  * taken over as invalid items.
     812             :  *
     813             :  * @return bool true
     814             :  *              SfxPoolItems have been taken over
     815             :  *
     816             :  *              false
     817             :  *              No SfxPoolItems have been taken over, because
     818             :  *              e.g. the Which ranges of SfxItemSets are not intersecting
     819             :  *              or the intersection does not contain SfxPoolItems that are
     820             :  *              set in rSet
     821             :  */
     822     1477958 : bool SfxItemSet::Set
     823             : (
     824             :     const SfxItemSet&   rSet,   /*  The SfxItemSet, whose SfxPoolItems are
     825             :                                     to been taken over */
     826             : 
     827             :     bool                bDeep   /*  true (default)
     828             : 
     829             :                                     The SfxPoolItems from the parents that may
     830             :                                     be present in rSet, are also taken over into
     831             :                                     this SfxPoolItemSet
     832             : 
     833             :                                     false
     834             :                                     The SfxPoolItems from the parents of
     835             :                                     rSet are not taken into account */
     836             : )
     837             : {
     838     1477958 :     bool bRet = false;
     839     1477958 :     if ( _nCount )
     840      227840 :         ClearItem();
     841     1477958 :     if ( bDeep )
     842             :     {
     843     1464246 :         SfxWhichIter aIter(*this);
     844     1464246 :         sal_uInt16 nWhich = aIter.FirstWhich();
     845    68462936 :         while ( nWhich )
     846             :         {
     847             :             const SfxPoolItem* pItem;
     848    65534444 :             if( SfxItemState::SET == rSet.GetItemState( nWhich, true, &pItem ) )
     849     8967567 :                 bRet |= 0 != Put( *pItem, pItem->Which() );
     850    65534444 :             nWhich = aIter.NextWhich();
     851     1464246 :         }
     852             :     }
     853             :     else
     854       13712 :         bRet = Put(rSet, false);
     855             : 
     856     1477958 :     return bRet;
     857             : }
     858             : 
     859             : /**
     860             :  * This method eases accessing single Items in the SfxItemSet.
     861             :  * Type checking is done via assertion, which makes client code
     862             :  * much more readable.
     863             :  *
     864             :  * The PRODUCT version returns 0, if the Item found is not of the
     865             :  * specified class.
     866             :  *
     867             :  * @returns 0 if the ItemSet does not contain an Item with the Id 'nWhich'
     868             :  */
     869      255822 : const SfxPoolItem* SfxItemSet::GetItem
     870             : (
     871             :     sal_uInt16          nId,            // SlotId or the Item's WhichId
     872             :     bool                bSrchInParent,  // sal_True: also search in Parent ItemSets
     873             :     TypeId              aItemType       // != 0 =>  RTTI check using assertion
     874             : )   const
     875             : {
     876             :     // Convert to WhichId
     877      255822 :     sal_uInt16 nWhich = GetPool()->GetWhich(nId);
     878             : 
     879             :     // Is the Item set or 'bDeep == true' available?
     880      255822 :     const SfxPoolItem *pItem = 0;
     881      255822 :     SfxItemState eState = GetItemState( nWhich, bSrchInParent, &pItem );
     882      255822 :     if ( bSrchInParent && SfxItemState::DEFAULT == eState &&
     883             :          nWhich <= SFX_WHICH_MAX )
     884       36662 :         pItem = &_pPool->GetDefaultItem(nWhich);
     885             : 
     886      255822 :     if ( pItem )
     887             :     {
     888             :         // Does the type match?
     889      107504 :         if ( !aItemType || pItem->IsA(aItemType) )
     890      107504 :             return pItem;
     891             : 
     892             :         // Else report error
     893             :         OSL_FAIL( "invalid argument type" );
     894             :     }
     895             : 
     896             :     // No Item of wrong type found
     897      148318 :     return 0;
     898             : }
     899             : 
     900             : 
     901             : 
     902             : 
     903   127273018 : const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const
     904             : {
     905             :     // Search the Range in which the Which is located in:
     906   127273018 :     const SfxItemSet* pAktSet = this;
     907   192742590 :     do
     908             :     {
     909   218714389 :         if( pAktSet->Count() )
     910             :         {
     911   103611978 :             SfxItemArray ppFnd = pAktSet->_aItems;
     912   103611978 :             const sal_uInt16* pPtr = pAktSet->_pWhichRanges;
     913   299538198 :             while( *pPtr )
     914             :             {
     915   195192286 :                 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     916             :                 {
     917             :                     // In this Range
     918   102878044 :                     ppFnd += nWhich - *pPtr;
     919   102878044 :                     if( *ppFnd )
     920             :                     {
     921    25971799 :                         if( reinterpret_cast<SfxPoolItem*>(-1) == *ppFnd ) {
     922             :                             //FIXME: The following code is duplicated further down
     923             :                             SFX_ASSERT(_pPool, nWhich, "no Pool, but status is ambiguous");
     924             :                             //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich);
     925             :                             //!return aDefault;
     926         810 :                             return _pPool->GetDefaultItem( nWhich );
     927             :                         }
     928             : #ifdef DBG_UTIL
     929             :                         const SfxPoolItem *pItem = *ppFnd;
     930             :                         if ( pItem->ISA(SfxVoidItem) || !pItem->Which() )
     931             :                             DBG_WARNING( "SFX_WARNING: Getting disabled Item" );
     932             : #endif
     933    25970989 :                         return **ppFnd;
     934             :                     }
     935    76906245 :                     break; // Continue with Parent
     936             :                 }
     937    92314242 :                 ppFnd += *(pPtr+1) - *pPtr + 1;
     938    92314242 :                 pPtr += 2;
     939             :             }
     940             :         }
     941             : //TODO: Search until end of Range: What are we supposed to do now? To the Parent or Default??
     942             : //      if( !*pPtr )            // Until the end of the search Range?
     943             : //      break;
     944   192742590 :     } while( bSrchInParent && 0 != ( pAktSet = pAktSet->_pParent ));
     945             : 
     946             :     // Get the Default from the Pool and return
     947             :     SFX_ASSERT(_pPool, nWhich, "no Pool, but status is ambiguous");
     948   101301219 :     const SfxPoolItem *pItem = &_pPool->GetDefaultItem( nWhich );
     949   101301219 :     return *pItem;
     950             : }
     951             : 
     952             : /**
     953             :  * Notification callback
     954             :  */
     955    24045623 : void SfxItemSet::Changed( const SfxPoolItem&, const SfxPoolItem& )
     956             : {
     957    24045623 : }
     958             : 
     959             : 
     960             : 
     961    23026100 : sal_uInt16 SfxItemSet::TotalCount() const
     962             : {
     963    23026100 :     sal_uInt16 nRet = 0;
     964    23026100 :     sal_uInt16* pPtr = _pWhichRanges;
     965   156228547 :     while( *pPtr )
     966             :     {
     967   110176347 :         nRet += ( *(pPtr+1) - *pPtr ) + 1;
     968   110176347 :         pPtr += 2;
     969             :     }
     970    23026100 :     return nRet;
     971             : }
     972             : 
     973             : 
     974             : /**
     975             :  * Only retain the Items that are also present in rSet
     976             :  * (nevermind their value).
     977             :  */
     978       66052 : void SfxItemSet::Intersect( const SfxItemSet& rSet )
     979             : {
     980             :     DBG_ASSERT(_pPool, "Not implemented without Pool");
     981       66052 :     if( !Count() ) // None set?
     982       21090 :         return;
     983             : 
     984             :     // Delete all Items not contained in rSet
     985       44962 :     if( !rSet.Count() )
     986             :     {
     987           0 :         ClearItem(); // Delete everything
     988           0 :         return;
     989             :     }
     990             : 
     991             :     // Test whether the Which Ranges are different
     992       44962 :     bool bEqual = true;
     993       44962 :     sal_uInt16* pWh1 = _pWhichRanges;
     994       44962 :     sal_uInt16* pWh2 = rSet._pWhichRanges;
     995       44962 :     sal_uInt16 nSize = 0;
     996             : 
     997      315414 :     for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
     998             :     {
     999      270452 :         if( *pWh1 != *pWh2 )
    1000             :         {
    1001           0 :             bEqual = false;
    1002           0 :             break;
    1003             :         }
    1004      270452 :         if( n & 1 )
    1005      135226 :             nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
    1006             :     }
    1007       44962 :     bEqual = *pWh1 == *pWh2; // Also check for 0
    1008             : 
    1009             :     // If the Ranges are identical, we can easily process it
    1010       44962 :     if( bEqual )
    1011             :     {
    1012       44962 :         SfxItemArray ppFnd1 = _aItems;
    1013       44962 :         SfxItemArray ppFnd2 = rSet._aItems;
    1014             : 
    1015     2933410 :         for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
    1016     2888448 :             if( *ppFnd1 && !*ppFnd2 )
    1017             :             {
    1018             :                 // Delete from Pool
    1019       49122 :                 if( !IsInvalidItem( *ppFnd1 ) )
    1020             :                 {
    1021       49122 :                     sal_uInt16 nWhich = (*ppFnd1)->Which();
    1022       49122 :                     if(nWhich <= SFX_WHICH_MAX)
    1023             :                     {
    1024             :                         const SfxPoolItem& rNew = _pParent
    1025       49122 :                             ? _pParent->Get( nWhich, true )
    1026       98244 :                             : _pPool->GetDefaultItem( nWhich );
    1027             : 
    1028       49122 :                         Changed( **ppFnd1, rNew );
    1029             :                     }
    1030       49122 :                     _pPool->Remove( **ppFnd1 );
    1031             :                 }
    1032       49122 :                 *ppFnd1 = 0;
    1033       49122 :                 --_nCount;
    1034             :             }
    1035             :     }
    1036             :     else
    1037             :     {
    1038           0 :         SfxItemIter aIter( *this );
    1039           0 :         const SfxPoolItem* pItem = aIter.GetCurItem();
    1040             :         while( true )
    1041             :         {
    1042           0 :             sal_uInt16 nWhich = IsInvalidItem( pItem )
    1043           0 :                                 ? GetWhichByPos( aIter.GetCurPos() )
    1044           0 :                                 : pItem->Which();
    1045           0 :             if( SfxItemState::UNKNOWN == rSet.GetItemState( nWhich, false ) )
    1046           0 :                 ClearItem( nWhich );        // Delete
    1047           0 :             if( aIter.IsAtEnd() )
    1048           0 :                 break;
    1049           0 :             pItem = aIter.NextItem();
    1050           0 :         }
    1051             :     }
    1052             : }
    1053             : 
    1054             : 
    1055             : 
    1056     1703450 : void SfxItemSet::Differentiate( const SfxItemSet& rSet )
    1057             : {
    1058     1703450 :     if( !Count() || !rSet.Count() )// None set?
    1059     2151119 :         return;
    1060             : 
    1061             :    // Test whether the Which Ranges are different
    1062     1255781 :     bool bEqual = true;
    1063     1255781 :     sal_uInt16* pWh1 = _pWhichRanges;
    1064     1255781 :     sal_uInt16* pWh2 = rSet._pWhichRanges;
    1065     1255781 :     sal_uInt16 nSize = 0;
    1066             : 
    1067     2697231 :     for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
    1068             :     {
    1069     2574678 :         if( *pWh1 != *pWh2 )
    1070             :         {
    1071     1133228 :             bEqual = false;
    1072     1133228 :             break;
    1073             :         }
    1074     1441450 :         if( n & 1 )
    1075      720725 :             nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
    1076             :     }
    1077     1255781 :     bEqual = *pWh1 == *pWh2; // Also test for 0
    1078             : 
    1079             :     // If the Ranges are identical, we can easily process it
    1080     1255781 :     if( bEqual )
    1081             :     {
    1082      122553 :         SfxItemArray ppFnd1 = _aItems;
    1083      122553 :         SfxItemArray ppFnd2 = rSet._aItems;
    1084             : 
    1085    11955961 :         for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
    1086    11833408 :             if( *ppFnd1 && *ppFnd2 )
    1087             :             {
    1088             :                 // Delete from Pool
    1089      105003 :                 if( !IsInvalidItem( *ppFnd1 ) )
    1090             :                 {
    1091      105003 :                     sal_uInt16 nWhich = (*ppFnd1)->Which();
    1092      105003 :                     if(nWhich <= SFX_WHICH_MAX)
    1093             :                     {
    1094             :                         const SfxPoolItem& rNew = _pParent
    1095           0 :                             ? _pParent->Get( nWhich, true )
    1096      105003 :                             : _pPool->GetDefaultItem( nWhich );
    1097             : 
    1098      105003 :                         Changed( **ppFnd1, rNew );
    1099             :                     }
    1100      105003 :                     _pPool->Remove( **ppFnd1 );
    1101             :                 }
    1102      105003 :                 *ppFnd1 = 0;
    1103      105003 :                 --_nCount;
    1104             :             }
    1105             :     }
    1106             :     else
    1107             :     {
    1108     1133228 :         SfxItemIter aIter( *this );
    1109     1133228 :         const SfxPoolItem* pItem = aIter.GetCurItem();
    1110             :         while( true )
    1111             :         {
    1112     1186390 :             sal_uInt16 nWhich = IsInvalidItem( pItem )
    1113           0 :                                 ? GetWhichByPos( aIter.GetCurPos() )
    1114     1186390 :                                 : pItem->Which();
    1115     1186390 :             if( SfxItemState::SET == rSet.GetItemState( nWhich, false ) )
    1116       50492 :                 ClearItem( nWhich ); // Delete
    1117     1186390 :             if( aIter.IsAtEnd() )
    1118     1133228 :                 break;
    1119       53162 :             pItem = aIter.NextItem();
    1120     1133228 :         }
    1121             : 
    1122             :     }
    1123             : }
    1124             : 
    1125             : 
    1126             : /**
    1127             :  * Decision table for MergeValue(s)
    1128             :  *
    1129             :  * Principles:
    1130             :  * 1. If the Which value in the 1st set is "unknown", there's never any action
    1131             :  * 2. If the Which value in the 2nd set is "unknown", it's made the "default"
    1132             :  * 3. For comparisons the values of the "default" Items are take into account
    1133             :  *
    1134             :  * 1st Item    2nd Item    Values  bIgnoreDefs       Remove      Assign       Add
    1135             :  *
    1136             :  * set         set         ==      sal_False           -           -           -
    1137             :  * default     set         ==      sal_False           -           -           -
    1138             :  * dontcare    set         ==      sal_False           -           -           -
    1139             :  * unknown     set         ==      sal_False           -           -           -
    1140             :  * set         default     ==      sal_False           -           -           -
    1141             :  * default     default     ==      sal_False           -           -           -
    1142             :  * dontcare    default     ==      sal_False           -           -           -
    1143             :  * unknown     default     ==      sal_False           -           -           -
    1144             :  * set         dontcare    ==      sal_False        1st Item       -1          -
    1145             :  * default     dontcare    ==      sal_False           -           -1          -
    1146             :  * dontcare    dontcare    ==      sal_False           -           -           -
    1147             :  * unknown     dontcare    ==      sal_False           -           -           -
    1148             :  * set         unknown     ==      sal_False        1st Item       -1          -
    1149             :  * default     unknown     ==      sal_False           -           -           -
    1150             :  * dontcare    unknown     ==      sal_False           -           -           -
    1151             :  * unknown     unknown     ==      sal_False           -           -           -
    1152             :  *
    1153             :  * set         set         !=      sal_False        1st Item       -1          -
    1154             :  * default     set         !=      sal_False           -           -1          -
    1155             :  * dontcare    set         !=      sal_False           -           -           -
    1156             :  * unknown     set         !=      sal_False           -           -           -
    1157             :  * set         default     !=      sal_False        1st Item       -1          -
    1158             :  * default     default     !=      sal_False           -           -           -
    1159             :  * dontcare    default     !=      sal_False           -           -           -
    1160             :  * unknown     default     !=      sal_False           -           -           -
    1161             :  * set         dontcare    !=      sal_False        1st Item       -1          -
    1162             :  * default     dontcare    !=      sal_False           -           -1          -
    1163             :  * dontcare    dontcare    !=      sal_False           -           -           -
    1164             :  * unknown     dontcare    !=      sal_False           -           -           -
    1165             :  * set         unknown     !=      sal_False        1st Item       -1          -
    1166             :  * default     unknown     !=      sal_False           -           -           -
    1167             :  * dontcare    unknown     !=      sal_False           -           -           -
    1168             :  * unknown     unknown     !=      sal_False           -           -           -
    1169             :  *
    1170             :  * set         set         ==      sal_True            -           -           -
    1171             :  * default     set         ==      sal_True            -       2nd Item     2nd Item
    1172             :  * dontcare    set         ==      sal_True            -           -           -
    1173             :  * unknown     set         ==      sal_True            -           -           -
    1174             :  * set         default     ==      sal_True            -           -           -
    1175             :  * default     default     ==      sal_True            -           -           -
    1176             :  * dontcare    default     ==      sal_True            -           -           -
    1177             :  * unknown     default     ==      sal_True            -           -           -
    1178             :  * set         dontcare    ==      sal_True            -           -           -
    1179             :  * default     dontcare    ==      sal_True            -           -1          -
    1180             :  * dontcare    dontcare    ==      sal_True            -           -           -
    1181             :  * unknown     dontcare    ==      sal_True            -           -           -
    1182             :  * set         unknown     ==      sal_True            -           -           -
    1183             :  * default     unknown     ==      sal_True            -           -           -
    1184             :  * dontcare    unknown     ==      sal_True            -           -           -
    1185             :  * unknown     unknown     ==      sal_True            -           -           -
    1186             :  *
    1187             :  * set         set         !=      sal_True         1st Item       -1          -
    1188             :  * default     set         !=      sal_True            -        2nd Item    2nd Item
    1189             :  * dontcare    set         !=      sal_True            -           -           -
    1190             :  * unknown     set         !=      sal_True            -           -           -
    1191             :  * set         default     !=      sal_True            -           -           -
    1192             :  * default     default     !=      sal_True            -           -           -
    1193             :  * dontcare    default     !=      sal_True            -           -           -
    1194             :  * unknown     default     !=      sal_True            -           -           -
    1195             :  * set         dontcare    !=      sal_True         1st Item       -1          -
    1196             :  * default     dontcare    !=      sal_True            -           -1          -
    1197             :  * dontcare    dontcare    !=      sal_True            -           -           -
    1198             :  * unknown     dontcare    !=      sal_True            -           -           -
    1199             :  * set         unknown     !=      sal_True            -           -           -
    1200             :  * default     unknown     !=      sal_True            -           -           -
    1201             :  * dontcare    unknown     !=      sal_True            -           -           -
    1202             :  * unknown     unknown     !=      sal_True            -           -           -
    1203             :  */
    1204      810648 : static void MergeItem_Impl( SfxItemPool *_pPool, sal_uInt16 &rCount,
    1205             :                             const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2,
    1206             :                             bool bIgnoreDefaults )
    1207             : {
    1208             :     assert(ppFnd1 != 0 && "Merging to 0-Item");
    1209             : 
    1210             :     // 1st Item is Default?
    1211      810648 :     if ( !*ppFnd1 )
    1212             :     {
    1213      683600 :         if ( IsInvalidItem(pFnd2) )
    1214             :             // Decision table: default, dontcare, doesn't matter, doesn't matter
    1215          96 :             *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1216             : 
    1217      683544 :         else if ( pFnd2 && !bIgnoreDefaults &&
    1218          40 :                   _pPool->GetDefaultItem(pFnd2->Which()) != *pFnd2 )
    1219             :             // Decision table: default, set, !=, sal_False
    1220          40 :             *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1221             : 
    1222      683464 :         else if ( pFnd2 && bIgnoreDefaults )
    1223             :             // Decision table: default, set, doesn't matter, sal_True
    1224        1656 :             *ppFnd1 = &_pPool->Put( *pFnd2 );
    1225             : 
    1226      683600 :         if ( *ppFnd1 )
    1227        1792 :             ++rCount;
    1228             :     }
    1229             : 
    1230             :     // 1st Item set?
    1231      127048 :     else if ( !IsInvalidItem(*ppFnd1) )
    1232             :     {
    1233       98002 :         if ( !pFnd2 )
    1234             :         {
    1235             :             // 2nd Item is Default
    1236        2908 :             if ( !bIgnoreDefaults &&
    1237        1454 :                  **ppFnd1 != _pPool->GetDefaultItem((*ppFnd1)->Which()) )
    1238             :             {
    1239             :                 // Decision table: set, default, !=, sal_False
    1240        1454 :                 _pPool->Remove( **ppFnd1 );
    1241        1454 :                 *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1242             :             }
    1243             :         }
    1244       96548 :         else if ( IsInvalidItem(pFnd2) )
    1245             :         {
    1246             :             // 2nd Item is dontcare
    1247         192 :             if ( !bIgnoreDefaults ||
    1248           0 :                  **ppFnd1 != _pPool->GetDefaultItem( (*ppFnd1)->Which()) )
    1249             :             {
    1250             :                 // Decision table: set, dontcare, doesn't matter, sal_False
    1251             :                 // or:             set, dontcare, !=, sal_True
    1252         192 :                 _pPool->Remove( **ppFnd1 );
    1253         192 :                 *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1254             :             }
    1255             :         }
    1256             :         else
    1257             :         {
    1258             :             // 2nd Item is set
    1259       96356 :             if ( **ppFnd1 != *pFnd2 )
    1260             :             {
    1261             :                 // Decision table: set, set, !=, doesn't matter
    1262         860 :                 _pPool->Remove( **ppFnd1 );
    1263         860 :                 *ppFnd1 = reinterpret_cast<SfxPoolItem*>(-1);
    1264             :             }
    1265             :         }
    1266             :     }
    1267      810648 : }
    1268             : 
    1269       15850 : void SfxItemSet::MergeValues( const SfxItemSet& rSet, bool bIgnoreDefaults )
    1270             : {
    1271             :     // WARNING! When making changes/fixing bugs, always update the table above!!
    1272             :     DBG_ASSERT( GetPool() == rSet.GetPool(), "MergeValues with different Pools" );
    1273             : 
    1274             :     // Test if the which Ranges are different
    1275       15850 :     bool bEqual = true;
    1276       15850 :     sal_uInt16* pWh1 = _pWhichRanges;
    1277       15850 :     sal_uInt16* pWh2 = rSet._pWhichRanges;
    1278       15850 :     sal_uInt16 nSize = 0;
    1279             : 
    1280       71666 :     for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
    1281             :     {
    1282       55816 :         if( *pWh1 != *pWh2 )
    1283             :         {
    1284           0 :             bEqual = false;
    1285           0 :             break;
    1286             :         }
    1287       55816 :         if( n & 1 )
    1288       27908 :             nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
    1289             :     }
    1290       15850 :     bEqual = *pWh1 == *pWh2; // Also check for 0
    1291             : 
    1292             :     // If the Ranges match, they are easier to process!
    1293       15850 :     if( bEqual )
    1294             :     {
    1295       15850 :         SfxItemArray ppFnd1 = _aItems;
    1296       15850 :         SfxItemArray ppFnd2 = rSet._aItems;
    1297             : 
    1298      824842 :         for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
    1299      808992 :             MergeItem_Impl( _pPool, _nCount, ppFnd1, *ppFnd2, bIgnoreDefaults );
    1300             :     }
    1301             :     else
    1302             :     {
    1303           0 :         SfxWhichIter aIter( rSet );
    1304             :         sal_uInt16 nWhich;
    1305           0 :         while( 0 != ( nWhich = aIter.NextWhich() ) )
    1306             :         {
    1307           0 :             const SfxPoolItem* pItem = 0;
    1308           0 :             rSet.GetItemState( nWhich, true, &pItem );
    1309           0 :             if( !pItem )
    1310             :             {
    1311             :                 // Not set, so default
    1312           0 :                 if ( !bIgnoreDefaults )
    1313           0 :                     MergeValue( rSet.GetPool()->GetDefaultItem( nWhich ), bIgnoreDefaults );
    1314             :             }
    1315           0 :             else if( IsInvalidItem( pItem ) )
    1316             :                 // dont care
    1317           0 :                 InvalidateItem( nWhich );
    1318             :             else
    1319           0 :                 MergeValue( *pItem, bIgnoreDefaults );
    1320           0 :         }
    1321             :     }
    1322       15850 : }
    1323             : 
    1324             : 
    1325             : 
    1326        1656 : void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, bool bIgnoreDefaults )
    1327             : {
    1328        1656 :     SfxItemArray ppFnd = _aItems;
    1329        1656 :     const sal_uInt16* pPtr = _pWhichRanges;
    1330        1656 :     const sal_uInt16 nWhich = rAttr.Which();
    1331        3752 :     while( *pPtr )
    1332             :     {
    1333             :         // In this Range??
    1334        2096 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1335             :         {
    1336        1656 :             ppFnd += nWhich - *pPtr;
    1337        1656 :             MergeItem_Impl( _pPool, _nCount, ppFnd, &rAttr, bIgnoreDefaults );
    1338        1656 :             break;
    1339             :         }
    1340         440 :         ppFnd += *(pPtr+1) - *pPtr + 1;
    1341         440 :         pPtr += 2;
    1342             :     }
    1343        1656 : }
    1344             : 
    1345             : 
    1346             : 
    1347       12692 : void SfxItemSet::InvalidateItem( sal_uInt16 nWhich )
    1348             : {
    1349       12692 :     SfxItemArray ppFnd = _aItems;
    1350       12692 :     const sal_uInt16* pPtr = _pWhichRanges;
    1351       55808 :     while( *pPtr )
    1352             :     {
    1353       33742 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1354             :         {
    1355             :             // In this Range?
    1356        3318 :             ppFnd += nWhich - *pPtr;
    1357             : 
    1358        3318 :             if( *ppFnd ) // Set for me
    1359             :             {
    1360        1780 :                 if( reinterpret_cast<SfxPoolItem*>(-1) != *ppFnd ) // Not yet dontcare!
    1361             :                 {
    1362         970 :                     _pPool->Remove( **ppFnd );
    1363         970 :                     *ppFnd = reinterpret_cast<SfxPoolItem*>(-1);
    1364             :                 }
    1365             :             }
    1366             :             else
    1367             :             {
    1368        1538 :                 *ppFnd = reinterpret_cast<SfxPoolItem*>(-1);
    1369        1538 :                 ++_nCount;
    1370             :             }
    1371        3318 :             break;
    1372             :         }
    1373       30424 :         ppFnd += *(pPtr+1) - *pPtr + 1;
    1374       30424 :         pPtr += 2;
    1375             :     }
    1376       12692 : }
    1377             : 
    1378             : 
    1379             : 
    1380      310392 : sal_uInt16 SfxItemSet::GetWhichByPos( sal_uInt16 nPos ) const
    1381             : {
    1382      310392 :     sal_uInt16 n = 0;
    1383      310392 :     sal_uInt16* pPtr  = _pWhichRanges;
    1384      985274 :     while( *pPtr )
    1385             :     {
    1386      674882 :         n = ( *(pPtr+1) - *pPtr ) + 1;
    1387      674882 :         if( nPos < n )
    1388      310392 :             return *(pPtr)+nPos;
    1389      364490 :         nPos = nPos - n;
    1390      364490 :         pPtr += 2;
    1391             :     }
    1392             :     DBG_ASSERT( false, "We're wrong here" );
    1393           0 :     return 0;
    1394             : }
    1395             : 
    1396             : 
    1397             : /**
    1398             :  * Saves the SfxItemSet instance to the supplied Stream.
    1399             :  * The surrogates as well as the ones with 'bDirect == true' are saved
    1400             :  * to the stream in the following way:
    1401             :  *
    1402             :  *  sal_uInt16  ... Count of the set Items
    1403             :  *  Count*  _pPool->StoreItem()
    1404             :  *
    1405             :  *  @see SfxItemPool::StoreItem() const
    1406             :  *  @see SfxItemSet::Load(SvStream&,bool,const SfxItemPool*)
    1407             :  */
    1408       10776 : SvStream &SfxItemSet::Store
    1409             : (
    1410             :     SvStream&   rStream,        // Target stream for normal Items
    1411             :     bool        bDirect         /* true: Save Items directly
    1412             :                                    false: Surrogates */
    1413             : )   const
    1414             : {
    1415             :     DBG_ASSERT( _pPool, "No Pool" );
    1416             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "no Master Pool" );
    1417             : 
    1418             :     // Remember position of the count (to be able to correct it, if need be)
    1419       10776 :     sal_uLong nCountPos = rStream.Tell();
    1420       10776 :     rStream.WriteUInt16( _nCount );
    1421             : 
    1422             :     // If there's nothing to save, don't construct an ItemIter
    1423       10776 :     if ( _nCount )
    1424             :     {
    1425             :         // Keep record of how many Items are really saved
    1426         656 :         sal_uInt16 nWrittenCount = 0; // Count of Items streamed in 'rStream'
    1427             : 
    1428             :         // Iterate over all set Items
    1429         656 :         SfxItemIter aIter(*this);
    1430       18424 :         for ( const SfxPoolItem *pItem = aIter.FirstItem();
    1431             :               pItem;
    1432             :               pItem = aIter.NextItem() )
    1433             :         {
    1434             :             // Let Items (if need be as a Surrogate) be saved via Pool
    1435             :             DBG_ASSERT( !IsInvalidItem(pItem), "can't store invalid items" );
    1436       35536 :             if ( !IsInvalidItem(pItem) &&
    1437       17768 :                  _pPool->StoreItem( rStream, *pItem, bDirect ) )
    1438             :                 // Item was streamed in 'rStream'
    1439       17768 :                 ++nWrittenCount;
    1440             :         }
    1441             : 
    1442             :         // Fewer written than read (e.g. old format)
    1443         656 :         if ( nWrittenCount != _nCount )
    1444             :         {
    1445             :             // Store real count in the stream
    1446           0 :             sal_uLong nPos = rStream.Tell();
    1447           0 :             rStream.Seek( nCountPos );
    1448           0 :             rStream.WriteUInt16( nWrittenCount );
    1449           0 :             rStream.Seek( nPos );
    1450         656 :         }
    1451             :     }
    1452             : 
    1453       10776 :     return rStream;
    1454             : }
    1455             : 
    1456             : 
    1457             : /**
    1458             :  * This method loads an SfxItemSet from a stream.
    1459             :  * If the SfxItemPool was loaded without RefCounts the loaded Item
    1460             :  * references are counted, else we assume the they were accounted for
    1461             :  * when loadig the SfxItemPool.
    1462             :  *
    1463             :  * @see SfxItemSet::Store(Stream&,bool) const
    1464             :  */
    1465           0 : SvStream &SfxItemSet::Load
    1466             : (
    1467             :     SvStream&           rStream,    //  Stream we're loading from
    1468             : 
    1469             :     bool                bDirect,    /*  true
    1470             :                                         Items are directly read form the stream
    1471             :                                         and not via Surrogates
    1472             : 
    1473             :                                         false (default)
    1474             :                                         Items are read via Surrogates */
    1475             : 
    1476             :     const SfxItemPool*  pRefPool    /*  Pool that can resolve the Surrogates
    1477             :                                         (e.g. when inserting documents) */
    1478             : )
    1479             : {
    1480             :     DBG_ASSERT( _pPool, "No Pool");
    1481             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "No Master Pool");
    1482             : 
    1483             :     // No RefPool => Resolve Surrogates with ItemSet's Pool
    1484           0 :     if ( !pRefPool )
    1485           0 :         pRefPool = _pPool;
    1486             : 
    1487             :     // Load Item count and as many Items
    1488           0 :     sal_uInt16 nCount = 0;
    1489           0 :     rStream.ReadUInt16( nCount );
    1490           0 :     for ( sal_uInt16 i = 0; i < nCount; ++i )
    1491             :     {
    1492             :         // Load Surrogate/Item and resolve Surrogate
    1493             :         const SfxPoolItem *pItem =
    1494           0 :                 _pPool->LoadItem( rStream, bDirect, pRefPool );
    1495             : 
    1496             :         // Did we load an Item or resolve a Surrogate?
    1497           0 :         if ( pItem )
    1498             :         {
    1499             :             // Find position for Item pointer in the set
    1500           0 :             sal_uInt16 nWhich = pItem->Which();
    1501           0 :             SfxItemArray ppFnd = _aItems;
    1502           0 :             const sal_uInt16* pPtr = _pWhichRanges;
    1503           0 :             while ( *pPtr )
    1504             :             {
    1505             :                 // In this Range??
    1506           0 :                 if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1507             :                 {
    1508             :                     // Remember Item pointer in the set
    1509           0 :                     ppFnd += nWhich - *pPtr;
    1510             :                     SFX_ASSERT( !*ppFnd, nWhich, "Item is present twice");
    1511           0 :                     *ppFnd = pItem;
    1512           0 :                     ++_nCount;
    1513           0 :                     break;
    1514             :                 }
    1515             : 
    1516             :                 // In the range array and Item array to the next Which range
    1517           0 :                 ppFnd += *(pPtr+1) - *pPtr + 1;
    1518           0 :                 pPtr += 2;
    1519             :             }
    1520             :         }
    1521             :     }
    1522             : 
    1523           0 :     return rStream;
    1524             : }
    1525             : 
    1526             : 
    1527             : 
    1528      945959 : bool SfxItemSet::operator==(const SfxItemSet &rCmp) const
    1529             : {
    1530             :     // Values we can get quickly need to be the same
    1531     2835485 :     if ( _pParent != rCmp._pParent ||
    1532     1695034 :          _pPool != rCmp._pPool ||
    1533      749075 :          Count() != rCmp.Count() )
    1534      508016 :         return false;
    1535             : 
    1536             :     // Counting Ranges takes longer; they also need to be the same, however
    1537      437943 :     sal_uInt16 nCount1 = TotalCount();
    1538      437943 :     sal_uInt16 nCount2 = rCmp.TotalCount();
    1539      437943 :     if ( nCount1 != nCount2 )
    1540        3658 :         return false;
    1541             : 
    1542             :     // Are the Ranges themselves unequal?
    1543      972848 :     for ( sal_uInt16 nRange = 0; _pWhichRanges[nRange]; nRange += 2 )
    1544     1077126 :         if ( _pWhichRanges[nRange] != rCmp._pWhichRanges[nRange] ||
    1545      538563 :              _pWhichRanges[nRange+1] != rCmp._pWhichRanges[nRange+1] )
    1546             :         {
    1547             :             // We must use the slow method then
    1548           0 :             SfxWhichIter aIter( *this );
    1549           0 :             for ( sal_uInt16 nWh = aIter.FirstWhich();
    1550             :                   nWh;
    1551             :                   nWh = aIter.NextWhich() )
    1552             :             {
    1553             :                 // If the pointer of the poolable Items are unequal, the Items must match
    1554           0 :                 const SfxPoolItem *pItem1 = 0, *pItem2 = 0;
    1555           0 :                 if ( GetItemState( nWh, false, &pItem1 ) !=
    1556           0 :                         rCmp.GetItemState( nWh, false, &pItem2 ) ||
    1557           0 :                      ( pItem1 != pItem2 &&
    1558           0 :                         ( !pItem1 || IsInvalidItem(pItem1) ||
    1559           0 :                           ( _pPool->IsItemFlag(*pItem1, SFX_ITEM_POOLABLE) &&
    1560           0 :                             *pItem1 != *pItem2 ) ) ) )
    1561           0 :                     return false;
    1562             :             }
    1563             : 
    1564           0 :             return true;
    1565             :         }
    1566             : 
    1567             :     // Are all pointers the same?
    1568      434285 :     if ( 0 == memcmp( _aItems, rCmp._aItems, nCount1 * sizeof(_aItems[0]) ) )
    1569      410424 :         return true;
    1570             : 
    1571             :     // We need to compare each one separately then
    1572       23861 :     const SfxPoolItem **ppItem1 = (const SfxPoolItem**) _aItems;
    1573       23861 :     const SfxPoolItem **ppItem2 = (const SfxPoolItem**) rCmp._aItems;
    1574      391819 :     for ( sal_uInt16 nPos = 0; nPos < nCount1; ++nPos )
    1575             :     {
    1576             :         // If the pointers of the poolable Items are not the same, the Items
    1577             :         // must match
    1578      451889 :         if ( *ppItem1 != *ppItem2 &&
    1579      119993 :              ( ( !*ppItem1 || !*ppItem2 ) ||
    1580      118305 :                ( IsInvalidItem(*ppItem1) || IsInvalidItem(*ppItem2) ) ||
    1581       60101 :                ( _pPool->IsItemFlag(**ppItem1, SFX_ITEM_POOLABLE) ) ||
    1582       20666 :                  **ppItem1 != **ppItem2 ) )
    1583       21685 :             return false;
    1584             : 
    1585      367958 :         ++ppItem1;
    1586      367958 :         ++ppItem2;
    1587             :     }
    1588             : 
    1589        2176 :     return true;
    1590             : }
    1591             : 
    1592             : 
    1593             : 
    1594      857137 : SfxItemSet *SfxItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const
    1595             : {
    1596      857137 :     if ( pToPool && pToPool != _pPool )
    1597             :     {
    1598       13461 :         SfxItemSet *pNewSet = new SfxItemSet( *pToPool, _pWhichRanges );
    1599       13461 :         if ( bItems )
    1600             :         {
    1601         108 :             SfxWhichIter aIter(*pNewSet);
    1602         108 :             sal_uInt16 nWhich = aIter.FirstWhich();
    1603        2364 :             while ( nWhich )
    1604             :             {
    1605             :                 const SfxPoolItem* pItem;
    1606        2148 :                 if ( SfxItemState::SET == GetItemState( nWhich, false, &pItem ) )
    1607          12 :                     pNewSet->Put( *pItem, pItem->Which() );
    1608        2148 :                 nWhich = aIter.NextWhich();
    1609         108 :             }
    1610             :         }
    1611       13461 :         return pNewSet;
    1612             :     }
    1613             :     else
    1614             :         return bItems
    1615      825048 :                 ? new SfxItemSet(*this)
    1616     1668724 :                 : new SfxItemSet(*_pPool, _pWhichRanges);
    1617             : }
    1618             : 
    1619             : 
    1620             : 
    1621     2435420 : int SfxItemSet::PutDirect(const SfxPoolItem &rItem)
    1622             : {
    1623     2435420 :     SfxItemArray ppFnd = _aItems;
    1624     2435420 :     const sal_uInt16* pPtr = _pWhichRanges;
    1625     2435420 :     const sal_uInt16 nWhich = rItem.Which();
    1626             : #ifdef DBG_UTIL
    1627             :     IsPoolDefaultItem(&rItem) || _pPool->GetSurrogate(&rItem);
    1628             :         // Only cause assertion in the callees
    1629             : #endif
    1630     6168576 :     while( *pPtr )
    1631             :     {
    1632     3733156 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1633             :         {
    1634             :             // In this Range?
    1635     2435420 :             ppFnd += nWhich - *pPtr;
    1636     2435420 :             const SfxPoolItem* pOld = *ppFnd;
    1637     2435420 :             if( pOld ) // One already present
    1638             :             {
    1639         728 :                 if( rItem == **ppFnd )
    1640           0 :                     return sal_False; // Already present!
    1641         728 :                 _pPool->Remove( *pOld );
    1642             :             }
    1643             :             else
    1644     2434692 :                 ++_nCount;
    1645             : 
    1646             :             // Add the new one
    1647     2435420 :             if( IsPoolDefaultItem(&rItem) )
    1648      174522 :                 *ppFnd = &_pPool->Put( rItem );
    1649             :             else
    1650             :             {
    1651     2260898 :                 *ppFnd = &rItem;
    1652     2260898 :                 if( !IsStaticDefaultItem( &rItem ) )
    1653     1643402 :                     rItem.AddRef();
    1654             :             }
    1655             : 
    1656     2435420 :             return sal_True;
    1657             :         }
    1658     1297736 :         ppFnd += *(pPtr+1) - *pPtr + 1;
    1659     1297736 :         pPtr += 2;
    1660             :     }
    1661           0 :     return sal_False;
    1662             : }
    1663             : 
    1664             : 
    1665             : 
    1666       60151 : SfxAllItemSet::SfxAllItemSet( SfxItemPool &rPool )
    1667             : :   SfxItemSet(rPool, (const sal_uInt16*) 0),
    1668             :     aDefault(0),
    1669       60151 :     nFree(nInitCount)
    1670             : {
    1671             :     // Initially no Items
    1672       60151 :     _aItems = 0;
    1673             : 
    1674             :     // Allocate nInitCount pairs at USHORTs for Ranges
    1675       60151 :     _pWhichRanges = new sal_uInt16[ nInitCount + 1 ];
    1676       60151 :     memset( _pWhichRanges, 0, ( nInitCount + 1 ) * sizeof(sal_uInt16) );
    1677       60151 : }
    1678             : 
    1679             : 
    1680             : 
    1681             : 
    1682             : 
    1683        1370 : SfxAllItemSet::SfxAllItemSet(const SfxItemSet &rCopy)
    1684             : :   SfxItemSet(rCopy),
    1685             :     aDefault(0),
    1686        1370 :     nFree(0)
    1687             : {
    1688        1370 : }
    1689             : 
    1690             : 
    1691             : 
    1692             : 
    1693             : /**
    1694             :  * Explicitly define this ctor to avoid auto-generation by the compiler.
    1695             :  * The compiler does not take the ctor with the 'const SfxItemSet&'!
    1696             :  */
    1697        5954 : SfxAllItemSet::SfxAllItemSet(const SfxAllItemSet &rCopy)
    1698             : :   SfxItemSet(rCopy),
    1699             :     aDefault(0),
    1700        5954 :     nFree(0)
    1701             : {
    1702        5954 : }
    1703             : 
    1704             : 
    1705             : /**
    1706             :  * This internal function creates a new WhichRanges array, which is copied
    1707             :  * from the 'nOldSize'-USHORTs long 'pUS'. It has new USHORTs at the end instead
    1708             :  * of 'nIncr'.
    1709             :  * The terminating sal_uInt16 with the '0' is neither accounted for in 'nOldSize'
    1710             :  * nor in 'nIncr', but always explicitly added.
    1711             :  *
    1712             :  * @returns the new WhichRanges array (the old 'pUS' is freed)
    1713             :  */
    1714       21858 : static sal_uInt16 *AddRanges_Impl(
    1715             :     sal_uInt16 *pUS, std::ptrdiff_t nOldSize, sal_uInt16 nIncr)
    1716             : {
    1717             :     // Create new WhichRanges array
    1718       21858 :     sal_uInt16 *pNew = new sal_uInt16[ nOldSize + nIncr + 1 ];
    1719             : 
    1720             :     // Take over the old Ranges
    1721       21858 :     memcpy( pNew, pUS, nOldSize * sizeof(sal_uInt16) );
    1722             : 
    1723             :     // Initialize the new one to 0
    1724       21858 :     memset( pNew + nOldSize, 0, ( nIncr + 1 ) * sizeof(sal_uInt16) );
    1725             : 
    1726             :     // Free the old array
    1727       21858 :     delete[] pUS;
    1728             : 
    1729       21858 :     return pNew;
    1730             : }
    1731             : 
    1732             : 
    1733             : /**
    1734             :  * This internal function creates a new ItemArray, which is copied from 'pItems',
    1735             :  * but has room for a new ItemPointer at 'nPos'.
    1736             :  *
    1737             :  * @returns the new ItemArray (the old 'pItems' is freed)
    1738             :  */
    1739      181786 : static SfxItemArray AddItem_Impl(SfxItemArray pItems, sal_uInt16 nOldSize, sal_uInt16 nPos)
    1740             : {
    1741             :     // Create new ItemArray
    1742      181786 :     SfxItemArray pNew = new const SfxPoolItem*[nOldSize+1];
    1743             : 
    1744             :     // Was there one before?
    1745      181786 :     if ( pItems )
    1746             :     {
    1747             :         // Copy all Items before nPos
    1748      143558 :         if ( nPos )
    1749      143558 :             memcpy( (void*) pNew, pItems, nPos * sizeof(SfxPoolItem *) );
    1750             : 
    1751             :         // Copy all Items after nPos
    1752      143558 :         if ( nPos < nOldSize )
    1753        4704 :             memcpy( (void*) (pNew + nPos + 1), pItems + nPos,
    1754        7056 :                     (nOldSize-nPos) * sizeof(SfxPoolItem *) );
    1755             :     }
    1756             : 
    1757             :     // Initialize new Item
    1758      181786 :     *(pNew + nPos) = 0;
    1759             : 
    1760             :     // Free old ItemArray
    1761      181786 :     delete[] pItems;
    1762             : 
    1763      181786 :     return pNew;
    1764             : }
    1765             : 
    1766             : 
    1767             : /**
    1768             :  * Putting with automatic extension of the WhichId with the ID of the Item.
    1769             :  */
    1770      242791 : const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
    1771             : {
    1772      242791 :     sal_uInt16 nPos = 0; // Position for 'rItem' in '_aItems'
    1773      242791 :     const sal_uInt16 nItemCount = TotalCount();
    1774             : 
    1775             :     // Let's see first whether there's a suitable Range already
    1776      242791 :     sal_uInt16 *pPtr = _pWhichRanges;
    1777     1268457 :     while ( *pPtr )
    1778             :     {
    1779             :         // WhichId is within this Range?
    1780      843880 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1781             :         {
    1782             :             // Insert
    1783       61005 :             nPos += nWhich - *pPtr;
    1784       61005 :             break;
    1785             :         }
    1786             : 
    1787             :         // Carry over the position of the Item in _aItems
    1788      782875 :         nPos += *(pPtr+1) - *pPtr + 1;
    1789             : 
    1790             :         // To the next Range
    1791      782875 :         pPtr += 2;
    1792             :     }
    1793             : 
    1794             :     // WhichId not yet present?
    1795      242791 :     if ( !*pPtr )
    1796             :     {
    1797             :         // Let's see if we can attach it somewhere
    1798      181786 :         pPtr = _pWhichRanges;
    1799      181786 :         nPos = 0;
    1800      913785 :         while ( *pPtr )
    1801             :         {
    1802             :             // WhichId is right before this Range?
    1803      552591 :             if ( (nWhich+1) == *pPtr )
    1804             :             {
    1805             :                 // Range grows downwards
    1806        1162 :                 (*pPtr)--;
    1807             : 
    1808             :                 // Make room before first Item of this Range
    1809        1162 :                 _aItems = AddItem_Impl(_aItems, nItemCount, nPos);
    1810        1162 :                 break;
    1811             :             }
    1812             : 
    1813             :             // WhichId is right after this Range?
    1814      551429 :             else if ( (nWhich-1) == *(pPtr+1) )
    1815             :             {
    1816             :                 // Range grows upwards?
    1817        1216 :                 (*(pPtr+1))++;
    1818             : 
    1819             :                 // Make room after last Item of this Range
    1820        1216 :                 nPos += nWhich - *pPtr;
    1821        1216 :                 _aItems = AddItem_Impl(_aItems, nItemCount, nPos);
    1822        1216 :                 break;
    1823             :             }
    1824             : 
    1825             :             // Carry over position of the Item in _aItems
    1826      550213 :             nPos += *(pPtr+1) - *pPtr + 1;
    1827             : 
    1828             :             // To the next Range
    1829      550213 :             pPtr += 2;
    1830             :         }
    1831             :     }
    1832             : 
    1833             :     // No extensible Range found?
    1834      242791 :     if ( !*pPtr )
    1835             :     {
    1836             :         // No room left in _pWhichRanges? => Expand!
    1837      179408 :         std::ptrdiff_t nSize = pPtr - _pWhichRanges;
    1838      179408 :         if( !nFree )
    1839             :         {
    1840       21858 :             _pWhichRanges = AddRanges_Impl(_pWhichRanges, nSize, nInitCount);
    1841       21858 :             nFree += nInitCount;
    1842             :         }
    1843             : 
    1844             :         // Attach new WhichRange
    1845      179408 :         pPtr = _pWhichRanges + nSize;
    1846      179408 :         *pPtr++ = nWhich;
    1847      179408 :         *pPtr = nWhich;
    1848      179408 :         nFree -= 2;
    1849             : 
    1850             :         // Expand ItemArray
    1851      179408 :         nPos = nItemCount;
    1852      179408 :         _aItems = AddItem_Impl(_aItems, nItemCount, nPos);
    1853             :     }
    1854             : 
    1855             :     // Add new Item to Pool
    1856      242791 :     const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich );
    1857             : 
    1858             :     // Remember old Item
    1859      242791 :     bool bIncrementCount = false;
    1860      242791 :     const SfxPoolItem* pOld = *( _aItems + nPos );
    1861      242791 :     if ( reinterpret_cast< SfxPoolItem* >( -1 ) == pOld ) // state "dontcare"
    1862           0 :         pOld = NULL;
    1863      242791 :     if ( !pOld )
    1864             :     {
    1865      181816 :         bIncrementCount = true;
    1866             :         pOld = _pParent ?
    1867           0 :                 &_pParent->Get( nWhich, true )
    1868      181816 :                 : nWhich <= SFX_WHICH_MAX ? &_pPool->GetDefaultItem( nWhich ) : 0;
    1869             :     }
    1870             : 
    1871             :     // Add new Item to ItemSet
    1872      242791 :     *(_aItems + nPos) = &rNew;
    1873             : 
    1874             :     // Send Changed Notification
    1875      242791 :     if ( pOld )
    1876             :     {
    1877       60975 :         Changed( *pOld, rNew );
    1878       60975 :         if ( !IsDefaultItem(pOld) )
    1879       60975 :             _pPool->Remove( *pOld );
    1880             :     }
    1881             : 
    1882      242791 :     if ( bIncrementCount )
    1883      181816 :         ++_nCount;
    1884             : 
    1885      242791 :     return &rNew;
    1886             : }
    1887             : 
    1888             : 
    1889             : /**
    1890             :  * Disable Item
    1891             :  * Using a VoidItem with Which value 0
    1892             :  */
    1893      347984 : void SfxItemSet::DisableItem(sal_uInt16 nWhich)
    1894             : {
    1895      347984 :     Put( SfxVoidItem(0), nWhich );
    1896      347984 : }
    1897             : 
    1898             : 
    1899             : 
    1900           0 : SfxItemSet *SfxAllItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const
    1901             : {
    1902           0 :     if ( pToPool && pToPool != _pPool )
    1903             :     {
    1904           0 :         SfxAllItemSet *pNewSet = new SfxAllItemSet( *pToPool );
    1905           0 :         if ( bItems )
    1906           0 :             pNewSet->Set( *this );
    1907           0 :         return pNewSet;
    1908             :     }
    1909             :     else
    1910           0 :         return bItems ? new SfxAllItemSet(*this) : new SfxAllItemSet(*_pPool);
    1911             : }
    1912             : 
    1913             : 
    1914             : 
    1915           0 : sal_Int32 SfxItemSet::getHash() const
    1916             : {
    1917           0 :     return stringify().hashCode();
    1918             : }
    1919             : 
    1920             : 
    1921             : 
    1922           0 : OString SfxItemSet::stringify() const
    1923             : {
    1924           0 :     SvMemoryStream aStream;
    1925           0 :     SfxItemSet aSet(*this);
    1926           0 :     aSet.InvalidateDefaultItems();
    1927           0 :     aSet.Store(aStream, true);
    1928           0 :     aStream.Flush();
    1929             :     return OString(
    1930           0 :         static_cast<char const *>(aStream.GetData()), aStream.GetEndOfData());
    1931             : }
    1932             : 
    1933             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10