LCOV - code coverage report
Current view: top level - svl/source/items - itemset.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 763 0.0 %
Date: 2014-04-14 Functions: 0 48 0.0 %
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; // einzelne USHORTs => 5 Paare ohne '0'
      39             : #if OSL_DEBUG_LEVEL > 1
      40             : static sal_uLong nRangesCopyCount = 0;   // wie oft wurden Ranges kopiert
      41             : #endif
      42             : 
      43             : #include "nranges.cxx"
      44             : 
      45             : 
      46             : #ifdef DBG_UTIL
      47             : 
      48             : 
      49             : const sal_Char *DbgCheckItemSet( const void* pVoid )
      50             : {
      51             :     const SfxItemSet *pSet = (const SfxItemSet*) pVoid;
      52             :     SfxWhichIter aIter( *pSet );
      53             :     sal_uInt16 nCount = 0, n = 0;
      54             :     for ( sal_uInt16 nWh = aIter.FirstWhich(); nWh; nWh = aIter.NextWhich(), ++n )
      55             :     {
      56             :         const SfxPoolItem *pItem = pSet->_aItems[n];
      57             :         if ( pItem )
      58             :         {
      59             :             ++nCount;
      60             :             DBG_ASSERT( IsInvalidItem(pItem) ||
      61             :                         pItem->Which() == 0 || pItem->Which() == nWh,
      62             :                         "SfxItemSet: invalid which-id" );
      63             :             DBG_ASSERT( IsInvalidItem(pItem) || !pItem->Which() ||
      64             :                     !SfxItemPool::IsWhich(pItem->Which()) ||
      65             :                     pSet->GetPool()->IsItemFlag(nWh, SFX_ITEM_NOT_POOLABLE) ||
      66             :                     SFX_ITEMS_NULL != pSet->GetPool()->GetSurrogate(pItem),
      67             :                     "SfxItemSet: item in set which is not in pool" );
      68             :         }
      69             : 
      70             :     }
      71             :     DBG_ASSERT( pSet->_nCount == nCount, "wrong SfxItemSet::nCount detected" );
      72             : 
      73             :     return 0;
      74             : }
      75             : 
      76             : #endif
      77             : 
      78             : 
      79           0 : SfxItemSet::SfxItemSet
      80             : (
      81             :     SfxItemPool&    rPool,          /* der Pool, in dem die SfxPoolItems,
      82             :                                        welche in dieses SfxItemSet gelangen,
      83             :                                        aufgenommen werden sollen */
      84             :     bool        bTotalRanges    /* komplette Pool-Ranges uebernehmen,
      85             :                                        muss auf sal_True gesetzt werden */
      86             : )
      87             : /*  [Beschreibung]
      88             : 
      89             :     Konstruktor fuer ein SfxItemSet mit genau den Which-Bereichen, welche
      90             :     dem angegebenen <SfxItemPool> bekannt sind.
      91             : 
      92             : 
      93             :     [Anmerkung]
      94             : 
      95             :     F"ur Sfx-Programmierer ein derart konstruiertes SfxItemSet kann
      96             :     keinerlei Items mit Slot-Ids als Which-Werte aufnehmen!
      97             : */
      98             : 
      99             : :   _pPool( &rPool ),
     100             :     _pParent( 0 ),
     101           0 :     _nCount( 0 )
     102             : {
     103             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
     104             :     DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
     105             : //  DBG_ASSERT( bTotalRanges || abs( &bTotalRanges - this ) < 1000,
     106             : //              "please use suitable ranges" );
     107             : #if defined DBG_UTIL && defined SFX_ITEMSET_NO_DEFAULT_CTOR
     108             :     if ( !bTotalRanges )
     109             :         *(int*)0 = 0; // GPF
     110             : #else
     111             :     (void) bTotalRanges; // avoid warnings
     112             : #endif
     113             : 
     114           0 :     _pWhichRanges = (sal_uInt16*) _pPool->GetFrozenIdRanges();
     115             :     DBG_ASSERT( _pWhichRanges, "don't create ItemSets with full range before FreezeIdRanges()" );
     116           0 :     if ( !_pWhichRanges )
     117           0 :         _pPool->FillItemIdRanges_Impl( _pWhichRanges );
     118             : 
     119           0 :     const sal_uInt16 nSize = TotalCount();
     120           0 :     _aItems = new const SfxPoolItem* [ nSize ];
     121           0 :     memset( (void*) _aItems, 0, nSize * sizeof( SfxPoolItem* ) );
     122           0 : }
     123             : 
     124             : 
     125             : 
     126           0 : SfxItemSet::SfxItemSet( SfxItemPool& rPool, sal_uInt16 nWhich1, sal_uInt16 nWhich2 ):
     127             :     _pPool( &rPool ),
     128             :     _pParent( 0 ),
     129           0 :     _nCount( 0 )
     130             : {
     131             :     DBG_ASSERT( nWhich1 <= nWhich2, "Ungueltiger Bereich" );
     132             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
     133             :     DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
     134             : 
     135           0 :     InitRanges_Impl(nWhich1, nWhich2);
     136           0 : }
     137             : 
     138             : 
     139             : 
     140           0 : void SfxItemSet::InitRanges_Impl(sal_uInt16 nWh1, sal_uInt16 nWh2)
     141             : {
     142           0 :     _pWhichRanges = new sal_uInt16[ 3 ];
     143           0 :     *(_pWhichRanges+0) = nWh1;
     144           0 :     *(_pWhichRanges+1) = nWh2;
     145           0 :     *(_pWhichRanges+2) = 0;
     146           0 :     const sal_uInt16 nRg = nWh2 - nWh1 + 1;
     147           0 :     _aItems = new const SfxPoolItem* [ nRg ];
     148           0 :     memset( (void*) _aItems, 0, nRg * sizeof( SfxPoolItem* ) );
     149           0 : }
     150             : 
     151             : 
     152             : 
     153           0 : void SfxItemSet::InitRanges_Impl(va_list pArgs, sal_uInt16 nWh1, sal_uInt16 nWh2, sal_uInt16 nNull)
     154             : {
     155           0 :     sal_uInt16 nSize = InitializeRanges_Impl( _pWhichRanges, pArgs, nWh1, nWh2, nNull );
     156           0 :     _aItems = new const SfxPoolItem* [ nSize ];
     157           0 :     memset( (void*) _aItems, 0, sizeof( SfxPoolItem* ) * nSize );
     158           0 : }
     159             : 
     160             : 
     161             : 
     162           0 : SfxItemSet::SfxItemSet( SfxItemPool& rPool,
     163             :                         USHORT_ARG nWh1, USHORT_ARG nWh2, USHORT_ARG nNull, ... ):
     164             :     _pPool( &rPool ),
     165             :     _pParent( 0 ),
     166             :     _pWhichRanges( 0 ),
     167           0 :     _nCount( 0 )
     168             : {
     169             :     DBG_ASSERT( nWh1 <= nWh2, "Ungueltiger Bereich" );
     170             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
     171             :     DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
     172             : 
     173           0 :     if(!nNull)
     174             :         InitRanges_Impl(
     175           0 :             sal::static_int_cast< sal_uInt16 >(nWh1),
     176           0 :             sal::static_int_cast< sal_uInt16 >(nWh2));
     177             :     else {
     178             :         va_list pArgs;
     179           0 :         va_start( pArgs, nNull );
     180             :         InitRanges_Impl(
     181           0 :             pArgs, sal::static_int_cast< sal_uInt16 >(nWh1),
     182           0 :             sal::static_int_cast< sal_uInt16 >(nWh2),
     183           0 :             sal::static_int_cast< sal_uInt16 >(nNull));
     184           0 :         va_end(pArgs);
     185             :     }
     186           0 : }
     187             : 
     188             : 
     189             : 
     190           0 : void SfxItemSet::InitRanges_Impl(const sal_uInt16 *pWhichPairTable)
     191             : {
     192             :     #if OSL_DEBUG_LEVEL > 1
     193             :     OSL_TRACE("SfxItemSet: Ranges-CopyCount==%ul", ++nRangesCopyCount);
     194             :     #endif
     195             : 
     196           0 :     sal_uInt16 nCnt = 0;
     197           0 :     const sal_uInt16* pPtr = pWhichPairTable;
     198           0 :     while( *pPtr )
     199             :     {
     200           0 :         nCnt += ( *(pPtr+1) - *pPtr ) + 1;
     201           0 :         pPtr += 2;
     202             :     }
     203             : 
     204           0 :     _aItems = new const SfxPoolItem* [ nCnt ];
     205           0 :     memset( (void*) _aItems, 0, sizeof( SfxPoolItem* ) * nCnt );
     206             : 
     207           0 :     std::ptrdiff_t cnt = pPtr - pWhichPairTable +1;
     208           0 :     _pWhichRanges = new sal_uInt16[ cnt ];
     209           0 :     memcpy( _pWhichRanges, pWhichPairTable, sizeof( sal_uInt16 ) * cnt );
     210           0 : }
     211             : 
     212             : 
     213             : 
     214             : 
     215           0 : SfxItemSet::SfxItemSet( SfxItemPool& rPool, const sal_uInt16* pWhichPairTable )
     216             :     : _pPool(&rPool)
     217             :     , _pParent(0)
     218             :     , _aItems(0)
     219             :     , _pWhichRanges(0)
     220           0 :     , _nCount(0)
     221             : {
     222             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
     223             :     DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
     224             : 
     225             :     // pWhichPairTable == 0 ist f"ur das SfxAllEnumItemSet
     226           0 :     if ( pWhichPairTable )
     227           0 :         InitRanges_Impl(pWhichPairTable);
     228           0 : }
     229             : 
     230           0 : SfxItemSet::SfxItemSet( const SfxItemSet& rASet ):
     231             :     _pPool( rASet._pPool ),
     232             :     _pParent( rASet._pParent ),
     233           0 :     _nCount( rASet._nCount )
     234             : {
     235             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
     236             :     DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
     237             :     DBG( ++*_pChildCount(_pParent) );
     238             : 
     239             :     // errechne die Anzahl von Attributen
     240           0 :     sal_uInt16 nCnt = 0;
     241           0 :     sal_uInt16* pPtr = rASet._pWhichRanges;
     242           0 :     while( *pPtr )
     243             :     {
     244           0 :         nCnt += ( *(pPtr+1) - *pPtr ) + 1;
     245           0 :         pPtr += 2;
     246             :     }
     247             : 
     248           0 :     _aItems = new const SfxPoolItem* [ nCnt ];
     249             : 
     250             :     // Attribute kopieren
     251           0 :     SfxItemArray ppDst = _aItems, ppSrc = rASet._aItems;
     252           0 :     for( sal_uInt16 n = nCnt; n; --n, ++ppDst, ++ppSrc )
     253           0 :         if ( 0 == *ppSrc ||                 // aktueller Default?
     254           0 :              IsInvalidItem(*ppSrc) ||       // Dont Care?
     255           0 :              IsStaticDefaultItem(*ppSrc) )  // nicht zu poolende Defaults
     256             :             // einfach Pointer kopieren
     257           0 :             *ppDst = *ppSrc;
     258           0 :         else if ( _pPool->IsItemFlag( **ppSrc, SFX_ITEM_POOLABLE ) )
     259             :         {
     260             :             // einfach Pointer kopieren und Ref-Count erh"ohen
     261           0 :             *ppDst = *ppSrc;
     262           0 :             ( (SfxPoolItem*) (*ppDst) )->AddRef();
     263             :         }
     264           0 :         else if ( !(*ppSrc)->Which() )
     265           0 :             *ppDst = (*ppSrc)->Clone();
     266             :         else
     267             :             // !IsPoolable() => via Pool zuweisen
     268           0 :             *ppDst = &_pPool->Put( **ppSrc );
     269             : 
     270             :     // dann noch die Which Ranges kopieren
     271             :     #if OSL_DEBUG_LEVEL > 1
     272             :     OSL_TRACE("SfxItemSet: Ranges-CopyCount==%ul", ++nRangesCopyCount);
     273             :     #endif
     274           0 :     std::ptrdiff_t cnt = pPtr - rASet._pWhichRanges+1;
     275           0 :     _pWhichRanges = new sal_uInt16[ cnt ];
     276           0 :     memcpy( _pWhichRanges, rASet._pWhichRanges, sizeof( sal_uInt16 ) * cnt);
     277           0 : }
     278             : 
     279             : 
     280             : 
     281           0 : SfxItemSet::~SfxItemSet()
     282             : {
     283             : #ifdef DBG_UTIL
     284             :     DBG( DBG_ASSERT( 0 == *_pChildCount(this), "SfxItemSet: deleting parent-itemset" ) )
     285             : #endif
     286             : 
     287           0 :     sal_uInt16 nCount = TotalCount();
     288           0 :     if( Count() )
     289             :     {
     290           0 :         SfxItemArray ppFnd = _aItems;
     291           0 :         for( sal_uInt16 nCnt = nCount; nCnt; --nCnt, ++ppFnd )
     292           0 :             if( *ppFnd && !IsInvalidItem(*ppFnd) )
     293             :             {
     294           0 :                 if( !(*ppFnd)->Which() )
     295           0 :                     delete (SfxPoolItem*) *ppFnd;
     296             :                 else {
     297             :                     // noch mehrer Referenzen vorhanden, also nur den
     298             :                     // ReferenzCounter manipulieren
     299           0 :                     if ( 1 < (*ppFnd)->GetRefCount() && !IsDefaultItem(*ppFnd) )
     300           0 :                         (*ppFnd)->ReleaseRef();
     301             :                     else
     302           0 :                         if ( !IsDefaultItem(*ppFnd) )
     303             :                             // aus dem Pool loeschen
     304           0 :                             _pPool->Remove( **ppFnd );
     305             :                 }
     306             :             }
     307             :     }
     308             : 
     309             :     // FIXME: could be delete[] (SfxPoolItem **)_aItems;
     310           0 :     delete[] _aItems;
     311           0 :     if ( _pWhichRanges != _pPool->GetFrozenIdRanges() )
     312           0 :         delete[] _pWhichRanges;
     313           0 :     _pWhichRanges = 0; // for invariant-testing
     314             : 
     315             :     DBG( --*_pChildCount(_pParent) );
     316             :     DBG( delete _pChildCount(this); _pChildCountDtor );
     317           0 : }
     318             : 
     319             : 
     320             : 
     321           0 : sal_uInt16 SfxItemSet::ClearItem( sal_uInt16 nWhich )
     322             : 
     323             : // einzelnes Item oder alle Items (nWhich==0) l"oschen
     324             : 
     325             : {
     326           0 :     if( !Count() )
     327           0 :         return 0;
     328             : 
     329           0 :     sal_uInt16 nDel = 0;
     330           0 :     SfxItemArray ppFnd = _aItems;
     331             : 
     332           0 :     if( nWhich )
     333             :     {
     334           0 :         const sal_uInt16* pPtr = _pWhichRanges;
     335           0 :         while( *pPtr )
     336             :         {
     337             :             // in diesem Bereich?
     338           0 :             if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     339             :             {
     340             :                 // "uberhaupt gesetzt?
     341           0 :                 ppFnd += nWhich - *pPtr;
     342           0 :                 if( *ppFnd )
     343             :                 {
     344             :                     // wegen der Assertions ins Sub-Calls mu\s das hier sein
     345           0 :                     --_nCount;
     346           0 :                     const SfxPoolItem *pItemToClear = *ppFnd;
     347           0 :                     *ppFnd = 0;
     348             : 
     349           0 :                     if ( !IsInvalidItem(pItemToClear) )
     350             :                     {
     351           0 :                         if ( nWhich <= SFX_WHICH_MAX )
     352             :                         {
     353             :                             const SfxPoolItem& rNew = _pParent
     354           0 :                                     ? _pParent->Get( nWhich, true )
     355           0 :                                     : _pPool->GetDefaultItem( nWhich );
     356             : 
     357           0 :                             Changed( *pItemToClear, rNew );
     358             :                         }
     359           0 :                         if ( pItemToClear->Which() )
     360           0 :                             _pPool->Remove( *pItemToClear );
     361             :                     }
     362           0 :                     ++nDel;
     363             :                 }
     364             : 
     365             :                 // gefunden => raus
     366           0 :                 break;
     367             :             }
     368           0 :             ppFnd += *(pPtr+1) - *pPtr + 1;
     369           0 :             pPtr += 2;
     370             :         }
     371             :     }
     372             :     else
     373             :     {
     374           0 :         nDel = _nCount;
     375             : 
     376           0 :         sal_uInt16* pPtr = _pWhichRanges;
     377           0 :         while( *pPtr )
     378             :         {
     379           0 :             for( nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     380           0 :                 if( *ppFnd )
     381             :                 {
     382             :                     // wegen der Assertions ins Sub-Calls mu\s das hier sein
     383           0 :                     --_nCount;
     384           0 :                     const SfxPoolItem *pItemToClear = *ppFnd;
     385           0 :                     *ppFnd = 0;
     386             : 
     387           0 :                     if ( !IsInvalidItem(pItemToClear) )
     388             :                     {
     389           0 :                         if ( nWhich <= SFX_WHICH_MAX )
     390             :                         {
     391             :                             const SfxPoolItem& rNew = _pParent
     392           0 :                                     ? _pParent->Get( nWhich, true )
     393           0 :                                     : _pPool->GetDefaultItem( nWhich );
     394             : 
     395           0 :                             Changed( *pItemToClear, rNew );
     396             :                         }
     397             : 
     398             :                         // #i32448#
     399             :                         // Take care of disabled items, too.
     400           0 :                         if (!pItemToClear->m_nWhich)
     401             :                         {
     402             :                             // item is disabled, delete it
     403           0 :                             delete pItemToClear;
     404             :                         }
     405             :                         else
     406             :                         {
     407             :                             // remove item from pool
     408           0 :                             _pPool->Remove( *pItemToClear );
     409             :                         }
     410             :                     }
     411             :                 }
     412           0 :             pPtr += 2;
     413             :         }
     414             :     }
     415           0 :     return nDel;
     416             : }
     417             : 
     418             : 
     419             : 
     420           0 : void SfxItemSet::ClearInvalidItems( bool bHardDefault )
     421             : {
     422           0 :     sal_uInt16* pPtr = _pWhichRanges;
     423           0 :     SfxItemArray ppFnd = _aItems;
     424           0 :     if ( bHardDefault )
     425           0 :         while( *pPtr )
     426             :         {
     427           0 :             for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     428           0 :                 if ( IsInvalidItem(*ppFnd) )
     429           0 :                      *ppFnd = &_pPool->Put( _pPool->GetDefaultItem(nWhich) );
     430           0 :             pPtr += 2;
     431             :         }
     432             :     else
     433           0 :         while( *pPtr )
     434             :         {
     435           0 :             for( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     436           0 :                 if( IsInvalidItem(*ppFnd) )
     437             :                 {
     438           0 :                     *ppFnd = 0;
     439           0 :                     --_nCount;
     440             :                 }
     441           0 :             pPtr += 2;
     442             :         }
     443           0 : }
     444             : 
     445           0 : void SfxItemSet::InvalidateDefaultItems()
     446             : {
     447           0 :     sal_uInt16* pPtr = _pWhichRanges;
     448           0 :     SfxItemArray ppFnd = _aItems;
     449             : 
     450           0 :     while( *pPtr )
     451             :     {
     452           0 :         for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     453           0 :             if ( *ppFnd && *ppFnd != (SfxPoolItem *)-1 && **ppFnd == _pPool->GetDefaultItem( nWhich ) )
     454             :             {
     455           0 :                 _pPool->Remove( **ppFnd );
     456           0 :                 *ppFnd = (SfxPoolItem*)-1;
     457             :             }
     458           0 :         pPtr += 2;
     459             :     }
     460           0 : }
     461             : 
     462           0 : void SfxItemSet::InvalidateAllItems()
     463             : {
     464             :     DBG_ASSERT( !_nCount, "Es sind noch Items gesetzt" );
     465             : 
     466           0 :     memset( (void*)_aItems, -1, ( _nCount = TotalCount() ) * sizeof( SfxPoolItem*) );
     467           0 : }
     468             : 
     469             : 
     470             : 
     471           0 : SfxItemState SfxItemSet::GetItemState( sal_uInt16 nWhich,
     472             :                                         bool bSrchInParent,
     473             :                                         const SfxPoolItem **ppItem ) const
     474             : {
     475             :     // suche den Bereich in dem das Which steht:
     476           0 :     const SfxItemSet* pAktSet = this;
     477           0 :     SfxItemState eRet = SFX_ITEM_UNKNOWN;
     478           0 :     do
     479             :     {
     480           0 :         SfxItemArray ppFnd = pAktSet->_aItems;
     481           0 :         const sal_uInt16* pPtr = pAktSet->_pWhichRanges;
     482           0 :         if (pPtr)
     483             :         {
     484           0 :             while ( *pPtr )
     485             :             {
     486           0 :                 if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     487             :                 {
     488             :                     // in diesem Bereich
     489           0 :                     ppFnd += nWhich - *pPtr;
     490           0 :                     if ( !*ppFnd )
     491             :                     {
     492           0 :                         eRet = SFX_ITEM_DEFAULT;
     493           0 :                         if( !bSrchInParent )
     494           0 :                             return eRet;  // nicht vorhanden
     495           0 :                         break; // JP: in den Parents weitersuchen !!!
     496             :                     }
     497             : 
     498           0 :                     if ( (SfxPoolItem*) -1 == *ppFnd )
     499             :                         // Unterschiedlich vorhanden
     500           0 :                         return SFX_ITEM_DONTCARE;
     501             : 
     502           0 :                     if ( (*ppFnd)->Type() == TYPE(SfxVoidItem) )
     503           0 :                         return SFX_ITEM_DISABLED;
     504             : 
     505           0 :                     if (ppItem)
     506             :                     {
     507             :                         #ifdef DBG_UTIL
     508             :                         const SfxPoolItem *pItem = *ppFnd;
     509             :                         DBG_ASSERT( !pItem->ISA(SfxSetItem) ||
     510             :                                 0 != &((const SfxSetItem*)pItem)->GetItemSet(),
     511             :                                 "SetItem without ItemSet" );
     512             :                         #endif
     513           0 :                         *ppItem = *ppFnd;
     514             :                     }
     515           0 :                     return SFX_ITEM_SET;
     516             :                 }
     517           0 :                 ppFnd += *(pPtr+1) - *pPtr + 1;
     518           0 :                 pPtr += 2;
     519             :             }
     520             :         }
     521           0 :     } while( bSrchInParent && 0 != ( pAktSet = pAktSet->_pParent ));
     522           0 :     return eRet;
     523             : }
     524             : 
     525           0 : bool SfxItemSet::HasItem(sal_uInt16 nWhich, const SfxPoolItem** ppItem) const
     526             : {
     527           0 :     bool bRet = SFX_ITEM_SET == GetItemState(nWhich, true, ppItem);
     528           0 :     if (!bRet && ppItem)
     529           0 :         *ppItem = NULL;
     530           0 :     return bRet;
     531             : }
     532             : 
     533             : 
     534             : 
     535           0 : const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
     536             : {
     537             :     DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
     538             :             0 != &((const SfxSetItem&)rItem).GetItemSet(),
     539             :             "SetItem without ItemSet" );
     540           0 :     if ( !nWhich )
     541           0 :         return 0; //! nur wegen Outliner-Bug
     542           0 :     SfxItemArray ppFnd = _aItems;
     543           0 :     const sal_uInt16* pPtr = _pWhichRanges;
     544           0 :     while( *pPtr )
     545             :     {
     546           0 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     547             :         {
     548             :             // in diesem Bereich
     549           0 :             ppFnd += nWhich - *pPtr;
     550           0 :             if( *ppFnd )        // schon einer vorhanden
     551             :             {
     552             :                 // selbes Item bereits vorhanden?
     553           0 :                 if ( *ppFnd == &rItem )
     554           0 :                     return 0;
     555             : 
     556             :                 // wird dontcare oder disabled mit was echtem ueberschrieben?
     557           0 :                 if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
     558             :                 {
     559           0 :                     *ppFnd = &_pPool->Put( rItem, nWhich );
     560           0 :                     return *ppFnd;
     561             :                 }
     562             : 
     563             :                 // wird disabled?
     564           0 :                 if( !rItem.Which() )
     565             :                 {
     566           0 :                     *ppFnd = rItem.Clone(_pPool);
     567           0 :                     return 0;
     568             :                 }
     569             :                 else
     570             :                 {
     571             :                     // selber Wert bereits vorhanden?
     572           0 :                     if ( rItem == **ppFnd )
     573           0 :                         return 0;
     574             : 
     575             :                     // den neuen eintragen, den alten austragen
     576           0 :                     const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich );
     577           0 :                     const SfxPoolItem* pOld = *ppFnd;
     578           0 :                     *ppFnd = &rNew;
     579           0 :                     if(nWhich <= SFX_WHICH_MAX)
     580           0 :                         Changed( *pOld, rNew );
     581           0 :                     _pPool->Remove( *pOld );
     582             :                 }
     583             :             }
     584             :             else
     585             :             {
     586           0 :                 ++_nCount;
     587           0 :                 if( !rItem.Which() )
     588           0 :                     *ppFnd = rItem.Clone(_pPool);
     589             :                 else {
     590           0 :                     const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich );
     591           0 :                     *ppFnd = &rNew;
     592           0 :                     if (nWhich <= SFX_WHICH_MAX )
     593             :                     {
     594             :                         const SfxPoolItem& rOld = _pParent
     595           0 :                             ? _pParent->Get( nWhich, true )
     596           0 :                             : _pPool->GetDefaultItem( nWhich );
     597           0 :                         Changed( rOld, rNew );
     598             :                     }
     599             :                 }
     600             :             }
     601             :             SFX_ASSERT( !_pPool->IsItemFlag(nWhich, SFX_ITEM_POOLABLE) ||
     602             :                         rItem.ISA(SfxSetItem) || **ppFnd == rItem,
     603             :                         nWhich, "putted Item unequal" );
     604           0 :             return *ppFnd;
     605             :         }
     606           0 :         ppFnd += *(pPtr+1) - *pPtr + 1;
     607           0 :         pPtr += 2;
     608             :     }
     609           0 :     return 0;
     610             : }
     611             : 
     612             : 
     613             : 
     614           0 : bool SfxItemSet::Put( const SfxItemSet& rSet, bool bInvalidAsDefault )
     615             : {
     616           0 :     bool bRet = false;
     617           0 :     if( rSet.Count() )
     618             :     {
     619           0 :         SfxItemArray ppFnd = rSet._aItems;
     620           0 :         const sal_uInt16* pPtr = rSet._pWhichRanges;
     621           0 :         while ( *pPtr )
     622             :         {
     623           0 :             for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     624           0 :                 if( *ppFnd )
     625             :                 {
     626           0 :                     if ( IsInvalidItem( *ppFnd ) )
     627             :                     {
     628           0 :                         if ( bInvalidAsDefault )
     629           0 :                             bRet |= 0 != ClearItem( nWhich );
     630             :                             // gab GPF bei non.WIDs:
     631             :                             // bRet |= 0 != Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
     632             :                         else
     633           0 :                             InvalidateItem( nWhich );
     634             :                     }
     635             :                     else
     636           0 :                         bRet |= 0 != Put( **ppFnd, nWhich );
     637             :                 }
     638           0 :             pPtr += 2;
     639             :         }
     640             :     }
     641           0 :     return bRet;
     642             : }
     643             : 
     644             : 
     645             : 
     646           0 : void SfxItemSet::PutExtended
     647             : (
     648             :     const SfxItemSet&   rSet,           // Quelle der zu puttenden Items
     649             :     SfxItemState        eDontCareAs,    // was mit DontCare-Items passiert
     650             :     SfxItemState        eDefaultAs      // was mit Default-Items passiert
     651             : )
     652             : 
     653             : /*  [Beschreibung]
     654             : 
     655             :     Diese Methode "ubernimmt die Items aus 'rSet' in '*this'. Die
     656             :     Which-Bereiche in '*this', die in 'rSet' nicht vorkommen bleiben unver-
     657             :     "andert. Der Which-Bereich von '*this' bleibt auch unver"andert.
     658             : 
     659             :     In 'rSet' gesetzte Items werden auch in '*this*' gesetzt. Default-
     660             :     (0 Pointer) und Invalid- (-1 Pointer) Items werden je nach Parameter
     661             :     ('eDontCareAs' und 'eDefaultAs' behandelt:
     662             : 
     663             :     SFX_ITEM_SET:       hart auf Default des Pools gesetzt
     664             :     SFX_ITEM_DEFAULT:   gel"oscht (0 Pointer)
     665             :     SFX_ITEM_DONTCARE:  invalidiert (-1 Pointer)
     666             : 
     667             :     Alle anderen Werte f"ur 'eDontCareAs' und 'eDefaultAs' sind ung"ultig.
     668             : */
     669             : 
     670             : {
     671             :     // don't "optimize" with "if( rSet.Count()" because of dont-care + defaults
     672           0 :     SfxItemArray ppFnd = rSet._aItems;
     673           0 :     const sal_uInt16* pPtr = rSet._pWhichRanges;
     674           0 :     while ( *pPtr )
     675             :     {
     676           0 :         for ( sal_uInt16 nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
     677           0 :             if( *ppFnd )
     678             :             {
     679           0 :                 if ( IsInvalidItem( *ppFnd ) )
     680             :                 {
     681             :                     // Item ist DontCare:
     682           0 :                     switch ( eDontCareAs )
     683             :                     {
     684             :                         case SFX_ITEM_SET:
     685           0 :                             Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
     686           0 :                             break;
     687             : 
     688             :                         case SFX_ITEM_DEFAULT:
     689           0 :                             ClearItem( nWhich );
     690           0 :                             break;
     691             : 
     692             :                         case SFX_ITEM_DONTCARE:
     693           0 :                             InvalidateItem( nWhich );
     694           0 :                             break;
     695             : 
     696             :                         default:
     697             :                             OSL_FAIL( "invalid Argument for eDontCareAs" );
     698             :                     }
     699             :                 }
     700             :                 else
     701             :                     // Item ist gesetzt:
     702           0 :                     Put( **ppFnd, nWhich );
     703             :             }
     704             :             else
     705             :             {
     706             :                 // Item ist Default:
     707           0 :                 switch ( eDefaultAs )
     708             :                 {
     709             :                     case SFX_ITEM_SET:
     710           0 :                         Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
     711           0 :                         break;
     712             : 
     713             :                     case SFX_ITEM_DEFAULT:
     714           0 :                         ClearItem( nWhich );
     715           0 :                         break;
     716             : 
     717             :                     case SFX_ITEM_DONTCARE:
     718           0 :                         InvalidateItem( nWhich );
     719           0 :                         break;
     720             : 
     721             :                     default:
     722             :                         OSL_FAIL( "invalid Argument for eDefaultAs" );
     723             :                 }
     724             :             }
     725           0 :         pPtr += 2;
     726             :     }
     727           0 : }
     728             : 
     729             : 
     730             : 
     731           0 : void SfxItemSet::MergeRange( sal_uInt16 nFrom, sal_uInt16 nTo )
     732             : /** <H3>Description</H3>
     733             : 
     734             :     Expands the ranges of settable items by 'nFrom' to 'nTo'. Keeps state of
     735             :     items which are new ranges too.
     736             : */
     737             : 
     738             : {
     739             :     // special case: exactly one sal_uInt16 which is already included?
     740           0 :     if ( nFrom == nTo && SFX_ITEM_AVAILABLE <= GetItemState(nFrom, false) )
     741           0 :         return;
     742             : 
     743             :     // merge new range
     744           0 :     SfxUShortRanges aRanges( _pWhichRanges );
     745           0 :     aRanges += SfxUShortRanges( nFrom, nTo );
     746           0 :     SetRanges( aRanges );
     747             : }
     748             : 
     749             : 
     750             : 
     751           0 : void SfxItemSet::SetRanges( const sal_uInt16 *pNewRanges )
     752             : 
     753             : /** <H3>Description</H3>
     754             : 
     755             :     Modifies the ranges of settable items. Keeps state of items which
     756             :     are new ranges too.
     757             : */
     758             : 
     759             : {
     760             :     // identische Ranges?
     761           0 :     if ( _pWhichRanges == pNewRanges )
     762           0 :         return;
     763           0 :     const sal_uInt16* pOld = _pWhichRanges;
     764           0 :     const sal_uInt16* pNew = pNewRanges;
     765           0 :     while ( *pOld == *pNew )
     766             :     {
     767           0 :         if ( !*pOld && !*pNew )
     768           0 :             return;
     769           0 :         ++pOld, ++pNew;
     770             :     }
     771             : 
     772             :     // create new item-array (by iterating through all new ranges)
     773           0 :     sal_uLong        nSize = Capacity_Impl(pNewRanges);
     774           0 :     SfxItemArray aNewItems = new const SfxPoolItem* [ nSize ];
     775           0 :     sal_uInt16 nNewCount = 0;
     776           0 :     if ( _nCount == 0 )
     777           0 :         memset( aNewItems, 0, nSize * sizeof( SfxPoolItem* ) );
     778             :     else
     779             :     {
     780           0 :         sal_uInt16 n = 0;
     781           0 :         for ( const sal_uInt16 *pRange = pNewRanges; *pRange; pRange += 2 )
     782             :         {
     783             :             // iterate through all ids in the range
     784           0 :             for ( sal_uInt16 nWID = *pRange; nWID <= pRange[1]; ++nWID, ++n )
     785             :             {
     786             :                 // direct move of pointer (not via pool)
     787           0 :                 SfxItemState eState = GetItemState( nWID, false, aNewItems+n );
     788           0 :                 if ( SFX_ITEM_SET == eState )
     789             :                 {
     790             :                     // increment new item count and possibly increment ref count
     791           0 :                     ++nNewCount;
     792           0 :                     aNewItems[n]->AddRef();
     793             :                 }
     794           0 :                 else if ( SFX_ITEM_DISABLED == eState )
     795             :                 {
     796             :                     // put "disabled" item
     797           0 :                     ++nNewCount;
     798           0 :                     aNewItems[n] = new SfxVoidItem(0);
     799             :                 }
     800           0 :                 else if ( SFX_ITEM_DONTCARE == eState )
     801             :                 {
     802           0 :                     ++nNewCount;
     803           0 :                     aNewItems[n] = (SfxPoolItem*)-1;
     804             :                 }
     805             :                 else
     806             :                 {
     807             :                     // default
     808           0 :                     aNewItems[n] = 0;
     809             :                 }
     810             :             }
     811             :         }
     812             :         // free old items
     813           0 :         sal_uInt16 nOldTotalCount = TotalCount();
     814           0 :         for ( sal_uInt16 nItem = 0; nItem < nOldTotalCount; ++nItem )
     815             :         {
     816           0 :             const SfxPoolItem *pItem = _aItems[nItem];
     817           0 :             if ( pItem && !IsInvalidItem(pItem) && pItem->Which() )
     818           0 :                 _pPool->Remove(*pItem);
     819             :         }
     820             :     }
     821             : 
     822             :     // replace old items-array and ranges
     823           0 :     delete[] _aItems;
     824           0 :     _aItems = aNewItems;
     825           0 :     _nCount = nNewCount;
     826             : 
     827           0 :     if( pNewRanges == GetPool()->GetFrozenIdRanges() )
     828             :     {
     829           0 :         delete[] _pWhichRanges;
     830           0 :         _pWhichRanges = ( sal_uInt16* ) pNewRanges;
     831             :     }
     832             :     else
     833             :     {
     834           0 :         sal_uInt16 nCount = Count_Impl(pNewRanges) + 1;
     835           0 :         if ( _pWhichRanges != _pPool->GetFrozenIdRanges() )
     836           0 :             delete[] _pWhichRanges;
     837           0 :         _pWhichRanges = new sal_uInt16[ nCount ];
     838           0 :         memcpy( _pWhichRanges, pNewRanges, sizeof( sal_uInt16 ) * nCount );
     839             :     }
     840             : }
     841             : 
     842             : 
     843             : 
     844           0 : bool SfxItemSet::Set
     845             : (
     846             :     const SfxItemSet&   rSet,   /*  das SfxItemSet, dessen SfxPoolItems
     847             :                                     "ubernommen werden sollen */
     848             : 
     849             :     bool                bDeep   /*  true (default)
     850             :                                     auch die SfxPoolItems aus den ggf. an
     851             :                                     rSet vorhandenen Parents werden direkt
     852             :                                     in das SfxItemSet "ubernommen
     853             : 
     854             :                                     false
     855             :                                     die SfxPoolItems aus den Parents von
     856             :                                     rSet werden nicht ber"ucksichtigt */
     857             : )
     858             : 
     859             : /*  [Beschreibung]
     860             : 
     861             :     Das SfxItemSet nimmt genau die SfxPoolItems an, die auch in
     862             :     rSet gesetzt sind und im eigenen <Which-Bereich> liegen. Alle
     863             :     anderen werden entfernt. Der SfxItemPool wird dabei beibehalten,
     864             :     so da"s die "ubernommenen SfxPoolItems dabei ggf. vom SfxItemPool
     865             :     von rSet in den SfxItemPool von *this "ubernommen werden.
     866             : 
     867             :     SfxPoolItems, f"ur die in rSet IsInvalidItem() == sal_True gilt,
     868             :     werden als Invalid-Item "ubernommen.
     869             : 
     870             : 
     871             :     [R"uckgabewert]
     872             : 
     873             :     bool                            true
     874             :                                     es wurden SfxPoolItems "ubernommen
     875             : 
     876             :                                     false
     877             :                                     es wurden keine SfxPoolItems "ubernommen,
     878             :                                     da z.B. die Which-Bereiche der SfxItemSets
     879             :                                     keine Schnittmenge haben oder in der
     880             :                                     Schnittmenge keine SfxPoolItems in rSet
     881             :                                     gesetzt sind
     882             : 
     883             : */
     884             : 
     885             : {
     886           0 :     bool bRet = false;
     887           0 :     if ( _nCount )
     888           0 :         ClearItem();
     889           0 :     if ( bDeep )
     890             :     {
     891           0 :         SfxWhichIter aIter(*this);
     892           0 :         sal_uInt16 nWhich = aIter.FirstWhich();
     893           0 :         while ( nWhich )
     894             :         {
     895             :             const SfxPoolItem* pItem;
     896           0 :             if( SFX_ITEM_SET == rSet.GetItemState( nWhich, true, &pItem ) )
     897           0 :                 bRet |= 0 != Put( *pItem, pItem->Which() );
     898           0 :             nWhich = aIter.NextWhich();
     899           0 :         }
     900             :     }
     901             :     else
     902           0 :         bRet = Put(rSet, false);
     903             : 
     904           0 :     return bRet;
     905             : }
     906             : 
     907             : 
     908           0 : const SfxPoolItem* SfxItemSet::GetItem
     909             : (
     910             :     sal_uInt16              nId,            // Slot-Id oder Which-Id des Items
     911             :     bool                bSrchInParent,  // sal_True: auch in Parent-ItemSets suchen
     912             :     TypeId              aItemType       // != 0 =>  RTTI Pruefung mit Assertion
     913             : )   const
     914             : 
     915             : /*  [Beschreibung]
     916             : 
     917             :     Mit dieser Methode wird der Zugriff auf einzelne Items im
     918             :     SfxItemSet wesentlich vereinfacht. Insbesondere wird die Typpr"ufung
     919             :     (per Assertion) durchgef"uhrt, wodurch die Applikations-Sourcen
     920             :     wesentlich "ubersichtlicher werden. In der PRODUCT-Version wird
     921             :     eine 0 zur"uckgegeben, wenn das gefundene Item nicht von der
     922             :     angegebenen Klasse ist. Ist kein Item mit der Id 'nWhich' in dem ItemSet,
     923             :     so wird 0 zurueckgegeben.
     924             : */
     925             : 
     926             : {
     927             :     // ggf. in Which-Id umrechnen
     928           0 :     sal_uInt16 nWhich = GetPool()->GetWhich(nId);
     929             : 
     930             :     // ist das Item gesetzt oder bei bDeep==sal_True verf"ugbar?
     931           0 :     const SfxPoolItem *pItem = 0;
     932           0 :     SfxItemState eState = GetItemState( nWhich, bSrchInParent, &pItem );
     933           0 :     if ( bSrchInParent && SFX_ITEM_AVAILABLE == eState &&
     934             :          nWhich <= SFX_WHICH_MAX )
     935           0 :         pItem = &_pPool->GetDefaultItem(nWhich);
     936           0 :     if ( pItem )
     937             :     {
     938             :         // stimmt der Typ "uberein?
     939           0 :         if ( !aItemType || pItem->IsA(aItemType) )
     940           0 :             return pItem;
     941             : 
     942             :         // sonst Fehler melden
     943             :         OSL_FAIL( "invalid argument type" );
     944             :     }
     945             : 
     946             :     // kein Item gefunden oder falschen Typ gefunden
     947           0 :     return 0;
     948             : }
     949             : 
     950             : 
     951             : 
     952             : 
     953           0 : const SfxPoolItem& SfxItemSet::Get( sal_uInt16 nWhich, bool bSrchInParent) const
     954             : {
     955             :     // suche den Bereich in dem das Which steht:
     956           0 :     const SfxItemSet* pAktSet = this;
     957           0 :     do
     958             :     {
     959           0 :         if( pAktSet->Count() )
     960             :         {
     961           0 :             SfxItemArray ppFnd = pAktSet->_aItems;
     962           0 :             const sal_uInt16* pPtr = pAktSet->_pWhichRanges;
     963           0 :             while( *pPtr )
     964             :             {
     965           0 :                 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
     966             :                 {
     967             :                     // in diesem Bereich
     968           0 :                     ppFnd += nWhich - *pPtr;
     969           0 :                     if( *ppFnd )
     970             :                     {
     971           0 :                         if( (SfxPoolItem*)-1 == *ppFnd ) {
     972             :                             //?MI: folgender code ist Doppelt (unten)
     973             :                             SFX_ASSERT(_pPool, nWhich, "kein Pool, aber Status uneindeutig");
     974             :                             //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich);
     975             :                             //!return aDefault;
     976           0 :                             return _pPool->GetDefaultItem( nWhich );
     977             :                         }
     978             : #ifdef DBG_UTIL
     979             :                         const SfxPoolItem *pItem = *ppFnd;
     980             :                         DBG_ASSERT( !pItem->ISA(SfxSetItem) ||
     981             :                                 0 != &((const SfxSetItem*)pItem)->GetItemSet(),
     982             :                                 "SetItem without ItemSet" );
     983             :                         if ( pItem->ISA(SfxVoidItem) || !pItem->Which() )
     984             :                             DBG_WARNING( "SFX_WARNING: Getting disabled Item" );
     985             : #endif
     986           0 :                         return **ppFnd;
     987             :                     }
     988           0 :                     break;          // dann beim Parent suchen
     989             :                 }
     990           0 :                 ppFnd += *(pPtr+1) - *pPtr + 1;
     991           0 :                 pPtr += 2;
     992             :             }
     993             :         }
     994             : // bis zum Ende vom Such-Bereich: was nun ? zum Parent, oder Default ??
     995             : //      if( !*pPtr )            // bis zum Ende vom Such-Bereich ?
     996             : //      break;
     997           0 :     } while( bSrchInParent && 0 != ( pAktSet = pAktSet->_pParent ));
     998             : 
     999             :     // dann das Default vom Pool holen und returnen
    1000             :     SFX_ASSERT(_pPool, nWhich, "kein Pool, aber Status uneindeutig");
    1001           0 :     const SfxPoolItem *pItem = &_pPool->GetDefaultItem( nWhich );
    1002             :     DBG_ASSERT( !pItem->ISA(SfxSetItem) ||
    1003             :             0 != &((const SfxSetItem*)pItem)->GetItemSet(),
    1004             :             "SetItem without ItemSet" );
    1005           0 :     return *pItem;
    1006             : }
    1007             : 
    1008             :     // Notification-Callback
    1009             : 
    1010             : 
    1011           0 : void SfxItemSet::Changed( const SfxPoolItem&, const SfxPoolItem& )
    1012             : {
    1013           0 : }
    1014             : 
    1015             : 
    1016             : 
    1017           0 : sal_uInt16 SfxItemSet::TotalCount() const
    1018             : {
    1019           0 :     sal_uInt16 nRet = 0;
    1020           0 :     sal_uInt16* pPtr = _pWhichRanges;
    1021           0 :     while( *pPtr )
    1022             :     {
    1023           0 :         nRet += ( *(pPtr+1) - *pPtr ) + 1;
    1024           0 :         pPtr += 2;
    1025             :     }
    1026           0 :     return nRet;
    1027             : }
    1028             : 
    1029             : 
    1030             : // behalte nur die Items, die auch in rSet enthalten sein (Wert egal)
    1031             : 
    1032           0 : void SfxItemSet::Intersect( const SfxItemSet& rSet )
    1033             : {
    1034             :     DBG_ASSERT(_pPool, "nicht implementiert ohne Pool");
    1035           0 :     if( !Count() )       // gar keine gesetzt ?
    1036           0 :         return;
    1037             : 
    1038             :     // loesche alle Items, die im rSet nicht mehr vorhanden sind
    1039           0 :     if( !rSet.Count() )
    1040             :     {
    1041           0 :         ClearItem();        // alles loeschen
    1042           0 :         return;
    1043             :     }
    1044             : 
    1045             :     // teste mal, ob sich die Which-Bereiche unterscheiden.
    1046           0 :     bool bEqual = true;
    1047           0 :     sal_uInt16* pWh1 = _pWhichRanges;
    1048           0 :     sal_uInt16* pWh2 = rSet._pWhichRanges;
    1049           0 :     sal_uInt16 nSize = 0;
    1050             : 
    1051           0 :     for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
    1052             :     {
    1053           0 :         if( *pWh1 != *pWh2 )
    1054             :         {
    1055           0 :             bEqual = false;
    1056           0 :             break;
    1057             :         }
    1058           0 :         if( n & 1 )
    1059           0 :             nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
    1060             :     }
    1061           0 :     bEqual = *pWh1 == *pWh2;        // auch die 0 abpruefen
    1062             : 
    1063             :     // sind die Bereiche identisch, ist es einfacher zu handhaben !
    1064           0 :     if( bEqual )
    1065             :     {
    1066           0 :         SfxItemArray ppFnd1 = _aItems;
    1067           0 :         SfxItemArray ppFnd2 = rSet._aItems;
    1068             : 
    1069           0 :         for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
    1070           0 :             if( *ppFnd1 && !*ppFnd2 )
    1071             :             {
    1072             :                 // aus dem Pool loeschen
    1073           0 :                 if( !IsInvalidItem( *ppFnd1 ) )
    1074             :                 {
    1075           0 :                     sal_uInt16 nWhich = (*ppFnd1)->Which();
    1076           0 :                     if(nWhich <= SFX_WHICH_MAX)
    1077             :                     {
    1078             :                         const SfxPoolItem& rNew = _pParent
    1079           0 :                             ? _pParent->Get( nWhich, true )
    1080           0 :                             : _pPool->GetDefaultItem( nWhich );
    1081             : 
    1082           0 :                         Changed( **ppFnd1, rNew );
    1083             :                     }
    1084           0 :                     _pPool->Remove( **ppFnd1 );
    1085             :                 }
    1086           0 :                 *ppFnd1 = 0;
    1087           0 :                 --_nCount;
    1088             :             }
    1089             :     }
    1090             :     else
    1091             :     {
    1092           0 :         SfxItemIter aIter( *this );
    1093           0 :         const SfxPoolItem* pItem = aIter.GetCurItem();
    1094             :         while( true )
    1095             :         {
    1096           0 :             sal_uInt16 nWhich = IsInvalidItem( pItem )
    1097           0 :                                 ? GetWhichByPos( aIter.GetCurPos() )
    1098           0 :                                 : pItem->Which();
    1099           0 :             if( 0 == rSet.GetItemState( nWhich, false ) )
    1100           0 :                 ClearItem( nWhich );        // loeschen
    1101           0 :             if( aIter.IsAtEnd() )
    1102           0 :                 break;
    1103           0 :             pItem = aIter.NextItem();
    1104           0 :         }
    1105             :     }
    1106             : }
    1107             : 
    1108             : 
    1109             : 
    1110           0 : void SfxItemSet::Differentiate( const SfxItemSet& rSet )
    1111             : {
    1112           0 :     if( !Count() || !rSet.Count() )  // gar keine gesetzt ?
    1113           0 :         return;
    1114             : 
    1115             :     // teste mal, ob sich die Which-Bereiche unterscheiden.
    1116           0 :     bool bEqual = true;
    1117           0 :     sal_uInt16* pWh1 = _pWhichRanges;
    1118           0 :     sal_uInt16* pWh2 = rSet._pWhichRanges;
    1119           0 :     sal_uInt16 nSize = 0;
    1120             : 
    1121           0 :     for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
    1122             :     {
    1123           0 :         if( *pWh1 != *pWh2 )
    1124             :         {
    1125           0 :             bEqual = false;
    1126           0 :             break;
    1127             :         }
    1128           0 :         if( n & 1 )
    1129           0 :             nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
    1130             :     }
    1131           0 :     bEqual = *pWh1 == *pWh2;        // auch die 0 abpruefen
    1132             : 
    1133             :     // sind die Bereiche identisch, ist es einfacher zu handhaben !
    1134           0 :     if( bEqual )
    1135             :     {
    1136           0 :         SfxItemArray ppFnd1 = _aItems;
    1137           0 :         SfxItemArray ppFnd2 = rSet._aItems;
    1138             : 
    1139           0 :         for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
    1140           0 :             if( *ppFnd1 && *ppFnd2 )
    1141             :             {
    1142             :                 // aus dem Pool loeschen
    1143           0 :                 if( !IsInvalidItem( *ppFnd1 ) )
    1144             :                 {
    1145           0 :                     sal_uInt16 nWhich = (*ppFnd1)->Which();
    1146           0 :                     if(nWhich <= SFX_WHICH_MAX)
    1147             :                     {
    1148             :                         const SfxPoolItem& rNew = _pParent
    1149           0 :                             ? _pParent->Get( nWhich, true )
    1150           0 :                             : _pPool->GetDefaultItem( nWhich );
    1151             : 
    1152           0 :                         Changed( **ppFnd1, rNew );
    1153             :                     }
    1154           0 :                     _pPool->Remove( **ppFnd1 );
    1155             :                 }
    1156           0 :                 *ppFnd1 = 0;
    1157           0 :                 --_nCount;
    1158             :             }
    1159             :     }
    1160             :     else
    1161             :     {
    1162           0 :         SfxItemIter aIter( *this );
    1163           0 :         const SfxPoolItem* pItem = aIter.GetCurItem();
    1164             :         while( true )
    1165             :         {
    1166           0 :             sal_uInt16 nWhich = IsInvalidItem( pItem )
    1167           0 :                                 ? GetWhichByPos( aIter.GetCurPos() )
    1168           0 :                                 : pItem->Which();
    1169           0 :             if( SFX_ITEM_SET == rSet.GetItemState( nWhich, false ) )
    1170           0 :                 ClearItem( nWhich );        // loeschen
    1171           0 :             if( aIter.IsAtEnd() )
    1172           0 :                 break;
    1173           0 :             pItem = aIter.NextItem();
    1174           0 :         }
    1175             : 
    1176             :     }
    1177             : }
    1178             : 
    1179             : 
    1180             : /* Entscheidungstabelle fuer MergeValue[s]
    1181             : 
    1182             : Grundsaetze:
    1183             :     1. Ist der Which-Wert im 1.Set "unknown", dann folgt niemals eine Aktion.
    1184             :     2. Ist der Which-Wert im 2.Set "unknown", dann gilt er als "default".
    1185             :     3. Es gelten fuer Vergleiche die Werte der "default"-Items.
    1186             : 
    1187             : 1.-Item     2.-Item     Values  bIgnoreDefs     Remove      Assign      Add
    1188             : 
    1189             : set         set         ==      sal_False           -           -           -
    1190             : default     set         ==      sal_False           -           -           -
    1191             : dontcare    set         ==      sal_False           -           -           -
    1192             : unknown     set         ==      sal_False           -           -           -
    1193             : set         default     ==      sal_False           -           -           -
    1194             : default     default     ==      sal_False           -           -           -
    1195             : dontcare    default     ==      sal_False           -           -           -
    1196             : unknown     default     ==      sal_False           -           -           -
    1197             : set         dontcare    ==      sal_False           1.-Item     -1          -
    1198             : default     dontcare    ==      sal_False           -           -1          -
    1199             : dontcare    dontcare    ==      sal_False           -           -           -
    1200             : unknown     dontcare    ==      sal_False           -           -           -
    1201             : set         unknown     ==      sal_False           1.-Item     -1          -
    1202             : default     unknown     ==      sal_False           -           -           -
    1203             : dontcare    unknown     ==      sal_False           -           -           -
    1204             : unknown     unknown     ==      sal_False           -           -           -
    1205             : 
    1206             : set         set         !=      sal_False           1.-Item     -1          -
    1207             : default     set         !=      sal_False           -           -1          -
    1208             : dontcare    set         !=      sal_False           -           -           -
    1209             : unknown     set         !=      sal_False           -           -           -
    1210             : set         default     !=      sal_False           1.-Item     -1          -
    1211             : default     default     !=      sal_False           -           -           -
    1212             : dontcare    default     !=      sal_False           -           -           -
    1213             : unknown     default     !=      sal_False           -           -           -
    1214             : set         dontcare    !=      sal_False           1.-Item     -1          -
    1215             : default     dontcare    !=      sal_False           -           -1          -
    1216             : dontcare    dontcare    !=      sal_False           -           -           -
    1217             : unknown     dontcare    !=      sal_False           -           -           -
    1218             : set         unknown     !=      sal_False           1.-Item     -1          -
    1219             : default     unknown     !=      sal_False           -           -           -
    1220             : dontcare    unknown     !=      sal_False           -           -           -
    1221             : unknown     unknown     !=      sal_False           -           -           -
    1222             : 
    1223             : set         set         ==      sal_True            -           -           -
    1224             : default     set         ==      sal_True            -           2.-Item     2.-Item
    1225             : dontcare    set         ==      sal_True            -           -           -
    1226             : unknown     set         ==      sal_True            -           -           -
    1227             : set         default     ==      sal_True            -           -           -
    1228             : default     default     ==      sal_True            -           -           -
    1229             : dontcare    default     ==      sal_True            -           -           -
    1230             : unknown     default     ==      sal_True            -           -           -
    1231             : set         dontcare    ==      sal_True            -           -           -
    1232             : default     dontcare    ==      sal_True            -           -1          -
    1233             : dontcare    dontcare    ==      sal_True            -           -           -
    1234             : unknown     dontcare    ==      sal_True            -           -           -
    1235             : set         unknown     ==      sal_True            -           -           -
    1236             : default     unknown     ==      sal_True            -           -           -
    1237             : dontcare    unknown     ==      sal_True            -           -           -
    1238             : unknown     unknown     ==      sal_True            -           -           -
    1239             : 
    1240             : set         set         !=      sal_True            1.-Item     -1          -
    1241             : default     set         !=      sal_True            -           2.-Item     2.-Item
    1242             : dontcare    set         !=      sal_True            -           -           -
    1243             : unknown     set         !=      sal_True            -           -           -
    1244             : set         default     !=      sal_True            -           -           -
    1245             : default     default     !=      sal_True            -           -           -
    1246             : dontcare    default     !=      sal_True            -           -           -
    1247             : unknown     default     !=      sal_True            -           -           -
    1248             : set         dontcare    !=      sal_True            1.-Item     -1          -
    1249             : default     dontcare    !=      sal_True            -           -1          -
    1250             : dontcare    dontcare    !=      sal_True            -           -           -
    1251             : unknown     dontcare    !=      sal_True            -           -           -
    1252             : set         unknown     !=      sal_True            -           -           -
    1253             : default     unknown     !=      sal_True            -           -           -
    1254             : dontcare    unknown     !=      sal_True            -           -           -
    1255             : unknown     unknown     !=      sal_True            -           -           -
    1256             : */
    1257             : 
    1258             : 
    1259           0 : static void MergeItem_Impl( SfxItemPool *_pPool, sal_uInt16 &rCount,
    1260             :                             const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2,
    1261             :                             bool bIgnoreDefaults )
    1262             : {
    1263             :     DBG_ASSERT( ppFnd1 != 0, "Merging to 0-Item" );
    1264             : 
    1265             :     // 1. Item ist default?
    1266           0 :     if ( !*ppFnd1 )
    1267             :     {
    1268           0 :         if ( IsInvalidItem(pFnd2) )
    1269             :             // Entscheidungstabelle: default, dontcare, egal, egal
    1270           0 :             *ppFnd1 = (SfxPoolItem*) -1;
    1271             : 
    1272           0 :         else if ( pFnd2 && !bIgnoreDefaults &&
    1273           0 :                   _pPool->GetDefaultItem(pFnd2->Which()) != *pFnd2 )
    1274             :             // Entscheidungstabelle: default, set, !=, sal_False
    1275           0 :             *ppFnd1 = (SfxPoolItem*) -1;
    1276             : 
    1277           0 :         else if ( pFnd2 && bIgnoreDefaults )
    1278             :             // Entscheidungstabelle: default, set, egal, sal_True
    1279           0 :             *ppFnd1 = &_pPool->Put( *pFnd2 );
    1280             : 
    1281           0 :         if ( *ppFnd1 )
    1282           0 :             ++rCount;
    1283             :     }
    1284             : 
    1285             :     // 1. Item ist gesetzt?
    1286           0 :     else if ( !IsInvalidItem(*ppFnd1) )
    1287             :     {
    1288           0 :         if ( !pFnd2 )
    1289             :         {
    1290             :             // 2. Item ist default
    1291           0 :             if ( !bIgnoreDefaults &&
    1292           0 :                  **ppFnd1 != _pPool->GetDefaultItem((*ppFnd1)->Which()) )
    1293             :             {
    1294             :                 // Entscheidungstabelle: set, default, !=, sal_False
    1295           0 :                 _pPool->Remove( **ppFnd1 );
    1296           0 :                 *ppFnd1 = (SfxPoolItem*) -1;
    1297             :             }
    1298             :         }
    1299           0 :         else if ( IsInvalidItem(pFnd2) )
    1300             :         {
    1301             :             // 2. Item ist dontcare
    1302           0 :             if ( !bIgnoreDefaults ||
    1303           0 :                  **ppFnd1 != _pPool->GetDefaultItem( (*ppFnd1)->Which()) )
    1304             :             {
    1305             :                 // Entscheidungstabelle: set, dontcare, egal, sal_False
    1306             :                 // oder:                 set, dontcare, !=, sal_True
    1307           0 :                 _pPool->Remove( **ppFnd1 );
    1308           0 :                 *ppFnd1 = (SfxPoolItem*) -1;
    1309             :             }
    1310             :         }
    1311             :         else
    1312             :         {
    1313             :             // 2. Item ist gesetzt
    1314           0 :             if ( **ppFnd1 != *pFnd2 )
    1315             :             {
    1316             :                 // Entscheidungstabelle: set, set, !=, egal
    1317           0 :                 _pPool->Remove( **ppFnd1 );
    1318           0 :                 *ppFnd1 = (SfxPoolItem*) -1;
    1319             :             }
    1320             :         }
    1321             :     }
    1322           0 : }
    1323             : 
    1324             : 
    1325             : 
    1326           0 : void SfxItemSet::MergeValues( const SfxItemSet& rSet, bool bIgnoreDefaults )
    1327             : {
    1328             :     // Achtung!!! Bei Aenderungen/Bugfixes immer obenstehende Tabelle pflegen!
    1329             :     DBG_ASSERT( GetPool() == rSet.GetPool(), "MergeValues mit verschiedenen Pools" );
    1330             : 
    1331             :     // teste mal, ob sich die Which-Bereiche unterscheiden.
    1332           0 :     bool bEqual = true;
    1333           0 :     sal_uInt16* pWh1 = _pWhichRanges;
    1334           0 :     sal_uInt16* pWh2 = rSet._pWhichRanges;
    1335           0 :     sal_uInt16 nSize = 0;
    1336             : 
    1337           0 :     for( sal_uInt16 n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
    1338             :     {
    1339           0 :         if( *pWh1 != *pWh2 )
    1340             :         {
    1341           0 :             bEqual = false;
    1342           0 :             break;
    1343             :         }
    1344           0 :         if( n & 1 )
    1345           0 :             nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
    1346             :     }
    1347           0 :     bEqual = *pWh1 == *pWh2; // auch die 0 abpruefen
    1348             : 
    1349             :     // sind die Bereiche identisch, ist es effizieter zu handhaben !
    1350           0 :     if( bEqual )
    1351             :     {
    1352           0 :         SfxItemArray ppFnd1 = _aItems;
    1353           0 :         SfxItemArray ppFnd2 = rSet._aItems;
    1354             : 
    1355           0 :         for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
    1356           0 :             MergeItem_Impl( _pPool, _nCount, ppFnd1, *ppFnd2, bIgnoreDefaults );
    1357             :     }
    1358             :     else
    1359             :     {
    1360           0 :         SfxWhichIter aIter( rSet );
    1361             :         sal_uInt16 nWhich;
    1362           0 :         while( 0 != ( nWhich = aIter.NextWhich() ) )
    1363             :         {
    1364           0 :             const SfxPoolItem* pItem = 0;
    1365           0 :             rSet.GetItemState( nWhich, true, &pItem );
    1366           0 :             if( !pItem )
    1367             :             {
    1368             :                 // nicht gesetzt, also default
    1369           0 :                 if ( !bIgnoreDefaults )
    1370           0 :                     MergeValue( rSet.GetPool()->GetDefaultItem( nWhich ), bIgnoreDefaults );
    1371             :             }
    1372           0 :             else if( IsInvalidItem( pItem ) )
    1373             :                 // dont care
    1374           0 :                 InvalidateItem( nWhich );
    1375             :             else
    1376           0 :                 MergeValue( *pItem, bIgnoreDefaults );
    1377           0 :         }
    1378             :     }
    1379           0 : }
    1380             : 
    1381             : 
    1382             : 
    1383           0 : void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, bool bIgnoreDefaults )
    1384             : {
    1385           0 :     SfxItemArray ppFnd = _aItems;
    1386           0 :     const sal_uInt16* pPtr = _pWhichRanges;
    1387           0 :     const sal_uInt16 nWhich = rAttr.Which();
    1388           0 :     while( *pPtr )
    1389             :     {
    1390             :         // in diesem Bereich?
    1391           0 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1392             :         {
    1393           0 :             ppFnd += nWhich - *pPtr;
    1394           0 :             MergeItem_Impl( _pPool, _nCount, ppFnd, &rAttr, bIgnoreDefaults );
    1395           0 :             break;
    1396             :         }
    1397           0 :         ppFnd += *(pPtr+1) - *pPtr + 1;
    1398           0 :         pPtr += 2;
    1399             :     }
    1400           0 : }
    1401             : 
    1402             : 
    1403             : 
    1404           0 : void SfxItemSet::InvalidateItem( sal_uInt16 nWhich )
    1405             : {
    1406           0 :     SfxItemArray ppFnd = _aItems;
    1407           0 :     const sal_uInt16* pPtr = _pWhichRanges;
    1408           0 :     while( *pPtr )
    1409             :     {
    1410           0 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1411             :         {
    1412             :             // in diesem Bereich
    1413           0 :             ppFnd += nWhich - *pPtr;
    1414             : 
    1415           0 :             if( *ppFnd )    // bei mir gesetzt
    1416             :             {
    1417           0 :                 if( (SfxPoolItem*)-1 != *ppFnd )        // noch nicht dontcare !
    1418             :                 {
    1419           0 :                     _pPool->Remove( **ppFnd );
    1420           0 :                     *ppFnd = (SfxPoolItem*)-1;
    1421             :                 }
    1422             :             }
    1423             :             else
    1424             :             {
    1425           0 :                 *ppFnd = (SfxPoolItem*)-1;
    1426           0 :                 ++_nCount;
    1427             :             }
    1428           0 :             break;
    1429             :         }
    1430           0 :         ppFnd += *(pPtr+1) - *pPtr + 1;
    1431           0 :         pPtr += 2;
    1432             :     }
    1433           0 : }
    1434             : 
    1435             : 
    1436             : 
    1437           0 : sal_uInt16 SfxItemSet::GetWhichByPos( sal_uInt16 nPos ) const
    1438             : {
    1439           0 :     sal_uInt16 n = 0;
    1440           0 :     sal_uInt16* pPtr  = _pWhichRanges;
    1441           0 :     while( *pPtr )
    1442             :     {
    1443           0 :         n = ( *(pPtr+1) - *pPtr ) + 1;
    1444           0 :         if( nPos < n )
    1445           0 :             return *(pPtr)+nPos;
    1446           0 :         nPos = nPos - n;
    1447           0 :         pPtr += 2;
    1448             :     }
    1449             :     DBG_ASSERT( false, "Hier sind wir falsch" );
    1450           0 :     return 0;
    1451             : }
    1452             : 
    1453             : 
    1454             : 
    1455           0 : SvStream &SfxItemSet::Store
    1456             : (
    1457             :     SvStream&   rStream,        // Zielstream f"ur normale Items
    1458             :     bool        bDirect         // TRUE: Items direkt speicher, FALSE: Surrogate
    1459             : )   const
    1460             : 
    1461             : /*  [Beschreibung]
    1462             : 
    1463             :     Speichert die <SfxItemSet>-Instanz in den angegebenen Stream. Dabei
    1464             :     werden die Surrorage der gesetzten <SfxPoolItem>s bzw. ('bDirect==sal_True')
    1465             :     die gesetzten Items selbst wie folgt im Stream abgelegt:
    1466             : 
    1467             :             sal_uInt16              (Count) Anzahl der gesetzten Items
    1468             :     Count*  _pPool->StoreItem()  siehe <SfxItemPool::StoreItem()const>
    1469             : 
    1470             : 
    1471             :     [Querverweise]
    1472             : 
    1473             :     <SfxItemSet::Load(SvStream&,bool,const SfxItemPool*)>
    1474             : */
    1475             : 
    1476             : {
    1477             :     DBG_ASSERT( _pPool, "Kein Pool" );
    1478             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
    1479             : 
    1480             :     // Position des Counts merken, um ggf. zu korrigieren
    1481           0 :     sal_uLong nCountPos = rStream.Tell();
    1482           0 :     rStream.WriteUInt16( _nCount );
    1483             : 
    1484             :     // wenn nichts zu speichern ist, auch keinen ItemIter aufsetzen!
    1485           0 :     if ( _nCount )
    1486             :     {
    1487             :         // mitz"ahlen wieviel Items tats"achlich gespeichert werden
    1488           0 :         sal_uInt16 nWrittenCount = 0;  // Anzahl in 'rStream' gestreamter Items
    1489             : 
    1490             :         // "uber alle gesetzten Items iterieren
    1491           0 :         SfxItemIter aIter(*this);
    1492           0 :         for ( const SfxPoolItem *pItem = aIter.FirstItem();
    1493             :               pItem;
    1494             :               pItem = aIter.NextItem() )
    1495             :         {
    1496             :             // Item (ggf. als Surrogat) via Pool speichern lassen
    1497             :             DBG_ASSERT( !IsInvalidItem(pItem), "can't store invalid items" );
    1498           0 :             if ( !IsInvalidItem(pItem) &&
    1499           0 :                  _pPool->StoreItem( rStream, *pItem, bDirect ) )
    1500             :                 // Item wurde in 'rStream' gestreamt
    1501           0 :                 ++nWrittenCount;
    1502             :         };
    1503             : 
    1504             :         // weniger geschrieben als enthalten (z.B. altes Format)
    1505           0 :         if ( nWrittenCount != _nCount )
    1506             :         {
    1507             :             // tats"achlichen Count im Stream ablegen
    1508           0 :             sal_uLong nPos = rStream.Tell();
    1509           0 :             rStream.Seek( nCountPos );
    1510           0 :             rStream.WriteUInt16( nWrittenCount );
    1511           0 :             rStream.Seek( nPos );
    1512           0 :         }
    1513             :     }
    1514             : 
    1515           0 :     return rStream;
    1516             : }
    1517             : 
    1518             : 
    1519             : 
    1520           0 : SvStream &SfxItemSet::Load
    1521             : (
    1522             :     SvStream&           rStream,    //  Stream, aus dem geladen werden soll
    1523             : 
    1524             :     bool                bDirect,    /*  TRUE
    1525             :                                         Items werden direkt aus dem Stream
    1526             :                                         gelesen, nicht "uber Surrogate
    1527             : 
    1528             :                                         sal_False (default)
    1529             :                                         Items werden "uber Surrogate gelesen */
    1530             : 
    1531             :     const SfxItemPool*  pRefPool    /*  Pool, der die Surrogate aufl"osen kann
    1532             :                                         (z.B. zum Einf"ugen von Dokumenten) */
    1533             : )
    1534             : 
    1535             : /*  [Beschreibung]
    1536             : 
    1537             :     Diese Methode l"adt ein <SfxItemSet> aus einem Stream. Falls der
    1538             :     <SfxItemPool> ohne Ref-Counts geladen wurde, werden die geladenen
    1539             :     Item-Referenzen in den Items hochgez"ahlt, ansonsten wird vorausgesetzt,
    1540             :     da\s sie schon beim Laden des SfxItemPools ber"ucksichtigt waren.
    1541             : 
    1542             :     [Querverweise]
    1543             : 
    1544             :     <SfxItemSet::Store(Stream&,bool)const>
    1545             : */
    1546             : 
    1547             : {
    1548             :     DBG_ASSERT( _pPool, "Kein Pool");
    1549             :     DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "Kein Master-Pool");
    1550             : 
    1551             :     // kein Ref-Pool => Surrogate mit Pool des ItemSets aufl"osen
    1552           0 :     if ( !pRefPool )
    1553           0 :         pRefPool = _pPool;
    1554             : 
    1555             :     // Anzahl der zu ladenden Items laden und dann ebensoviele Items
    1556           0 :     sal_uInt16 nCount = 0;
    1557           0 :     rStream.ReadUInt16( nCount );
    1558           0 :     for ( sal_uInt16 i = 0; i < nCount; ++i )
    1559             :     {
    1560             :         // Surrogat/Item laden und (Surrogat) aufl"osen lassen
    1561             :         const SfxPoolItem *pItem =
    1562           0 :                 _pPool->LoadItem( rStream, bDirect, pRefPool );
    1563             : 
    1564             :         // konnte ein Item geladen oder via Surrogat aufgel"ost werden?
    1565           0 :         if ( pItem )
    1566             :         {
    1567             :             // Position f"ur Item-Pointer im Set suchen
    1568           0 :             sal_uInt16 nWhich = pItem->Which();
    1569           0 :             SfxItemArray ppFnd = _aItems;
    1570           0 :             const sal_uInt16* pPtr = _pWhichRanges;
    1571           0 :             while ( *pPtr )
    1572             :             {
    1573             :                 // in diesem Bereich?
    1574           0 :                 if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1575             :                 {
    1576             :                     // Item-Pointer im Set merken
    1577           0 :                     ppFnd += nWhich - *pPtr;
    1578             :                     SFX_ASSERT( !*ppFnd, nWhich, "Item doppelt eingetragen");
    1579           0 :                     *ppFnd = pItem;
    1580           0 :                     ++_nCount;
    1581           0 :                     break;
    1582             :                 }
    1583             : 
    1584             :                 // im Range-Array und Item-Array zum n"achsten Which-Range
    1585           0 :                 ppFnd += *(pPtr+1) - *pPtr + 1;
    1586           0 :                 pPtr += 2;
    1587             :             }
    1588             :         }
    1589             :     }
    1590             : 
    1591           0 :     return rStream;
    1592             : }
    1593             : 
    1594             : 
    1595             : 
    1596           0 : bool SfxItemSet::operator==(const SfxItemSet &rCmp) const
    1597             : {
    1598             :     // besonders schnell zu ermittelnde Werte muessen gleich sein
    1599           0 :     if ( _pParent != rCmp._pParent ||
    1600           0 :          _pPool != rCmp._pPool ||
    1601           0 :          Count() != rCmp.Count() )
    1602           0 :         return false;
    1603             : 
    1604             :     // Ranges durchzaehlen lassen dauert laenger, muss aber auch gleich sein
    1605           0 :     sal_uInt16 nCount1 = TotalCount();
    1606           0 :     sal_uInt16 nCount2 = rCmp.TotalCount();
    1607           0 :     if ( nCount1 != nCount2 )
    1608           0 :         return false;
    1609             : 
    1610             :     // sind die Ranges selbst ungleich?
    1611           0 :     for ( sal_uInt16 nRange = 0; _pWhichRanges[nRange]; nRange += 2 )
    1612           0 :         if ( _pWhichRanges[nRange] != rCmp._pWhichRanges[nRange] ||
    1613           0 :              _pWhichRanges[nRange+1] != rCmp._pWhichRanges[nRange+1] )
    1614             :         {
    1615             :             // dann m"ussen wir die langsame Methode verwenden
    1616           0 :             SfxWhichIter aIter( *this );
    1617           0 :             for ( sal_uInt16 nWh = aIter.FirstWhich();
    1618             :                   nWh;
    1619             :                   nWh = aIter.NextWhich() )
    1620             :             {
    1621             :                 // wenn die Pointer von poolable Items ungleich sind,
    1622             :                 // muessen die Items gleich sein
    1623           0 :                 const SfxPoolItem *pItem1 = 0, *pItem2 = 0;
    1624           0 :                 if ( GetItemState( nWh, false, &pItem1 ) !=
    1625           0 :                         rCmp.GetItemState( nWh, false, &pItem2 ) ||
    1626           0 :                      ( pItem1 != pItem2 &&
    1627           0 :                         ( !pItem1 || IsInvalidItem(pItem1) ||
    1628           0 :                           ( _pPool->IsItemFlag(*pItem1, SFX_ITEM_POOLABLE) &&
    1629           0 :                             *pItem1 != *pItem2 ) ) ) )
    1630           0 :                     return false;
    1631             :             }
    1632             : 
    1633           0 :             return true;
    1634             :         }
    1635             : 
    1636             :     // Pointer alle gleich?
    1637           0 :     if ( 0 == memcmp( _aItems, rCmp._aItems, nCount1 * sizeof(_aItems[0]) ) )
    1638           0 :         return true;
    1639             : 
    1640             :     // dann werden wir wohl alle einzeln vergleichen muessen
    1641           0 :     const SfxPoolItem **ppItem1 = (const SfxPoolItem**) _aItems;
    1642           0 :     const SfxPoolItem **ppItem2 = (const SfxPoolItem**) rCmp._aItems;
    1643           0 :     for ( sal_uInt16 nPos = 0; nPos < nCount1; ++nPos )
    1644             :     {
    1645             :         // wenn die Pointer von poolable Items ungleich sind,
    1646             :         // muessen die Items gleich sein
    1647           0 :         if ( *ppItem1 != *ppItem2 &&
    1648           0 :              ( ( !*ppItem1 || !*ppItem2 ) ||
    1649           0 :                ( IsInvalidItem(*ppItem1) || IsInvalidItem(*ppItem2) ) ||
    1650           0 :                ( _pPool->IsItemFlag(**ppItem1, SFX_ITEM_POOLABLE) ) ||
    1651           0 :                  **ppItem1 != **ppItem2 ) )
    1652           0 :             return false;
    1653             : 
    1654           0 :         ++ppItem1;
    1655           0 :         ++ppItem2;
    1656             :     }
    1657             : 
    1658           0 :     return true;
    1659             : }
    1660             : 
    1661             : 
    1662             : 
    1663           0 : SfxItemSet *SfxItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const
    1664             : {
    1665           0 :     if ( pToPool && pToPool != _pPool )
    1666             :     {
    1667           0 :         SfxItemSet *pNewSet = new SfxItemSet( *pToPool, _pWhichRanges );
    1668           0 :         if ( bItems )
    1669             :         {
    1670           0 :             SfxWhichIter aIter(*pNewSet);
    1671           0 :             sal_uInt16 nWhich = aIter.FirstWhich();
    1672           0 :             while ( nWhich )
    1673             :             {
    1674             :                 const SfxPoolItem* pItem;
    1675           0 :                 if ( SFX_ITEM_SET == GetItemState( nWhich, false, &pItem ) )
    1676           0 :                     pNewSet->Put( *pItem, pItem->Which() );
    1677           0 :                 nWhich = aIter.NextWhich();
    1678           0 :             }
    1679             :         }
    1680           0 :         return pNewSet;
    1681             :     }
    1682             :     else
    1683             :         return bItems
    1684           0 :                 ? new SfxItemSet(*this)
    1685           0 :                 : new SfxItemSet(*_pPool, _pWhichRanges);
    1686             : }
    1687             : 
    1688             : 
    1689             : 
    1690           0 : int SfxItemSet::PutDirect(const SfxPoolItem &rItem)
    1691             : {
    1692           0 :     SfxItemArray ppFnd = _aItems;
    1693           0 :     const sal_uInt16* pPtr = _pWhichRanges;
    1694           0 :     const sal_uInt16 nWhich = rItem.Which();
    1695             : #ifdef DBG_UTIL
    1696             :     IsPoolDefaultItem(&rItem) || _pPool->GetSurrogate(&rItem);
    1697             :         // nur Assertion in den callees provozieren
    1698             : #endif
    1699           0 :     while( *pPtr )
    1700             :     {
    1701           0 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1702             :         {
    1703             :             // in diesem Bereich
    1704           0 :             ppFnd += nWhich - *pPtr;
    1705           0 :             const SfxPoolItem* pOld = *ppFnd;
    1706           0 :             if( pOld )      // schon einer vorhanden
    1707             :             {
    1708           0 :                 if( rItem == **ppFnd )
    1709           0 :                     return sal_False;       // schon vorhanden !
    1710           0 :                 _pPool->Remove( *pOld );
    1711             :             }
    1712             :             else
    1713           0 :                 ++_nCount;
    1714             : 
    1715             :             // den neuen eintragen
    1716           0 :             if( IsPoolDefaultItem(&rItem) )
    1717           0 :                 *ppFnd = &_pPool->Put( rItem );
    1718             :             else
    1719             :             {
    1720           0 :                 *ppFnd = &rItem;
    1721           0 :                 if( !IsStaticDefaultItem( &rItem ) )
    1722           0 :                     rItem.AddRef();
    1723             :             }
    1724             : 
    1725           0 :             return sal_True;
    1726             :         }
    1727           0 :         ppFnd += *(pPtr+1) - *pPtr + 1;
    1728           0 :         pPtr += 2;
    1729             :     }
    1730           0 :     return sal_False;
    1731             : }
    1732             : 
    1733             : 
    1734             : 
    1735           0 : SfxAllItemSet::SfxAllItemSet( SfxItemPool &rPool )
    1736             : :   SfxItemSet(rPool, (const sal_uInt16*) 0),
    1737             :     aDefault(0),
    1738           0 :     nFree(nInitCount)
    1739             : {
    1740             :     // initial keine Items
    1741           0 :     _aItems = 0;
    1742             : 
    1743             :     // nInitCount Paare an USHORTs fuer Ranges allozieren
    1744           0 :     _pWhichRanges = new sal_uInt16[ nInitCount + 1 ];
    1745           0 :     memset( _pWhichRanges, 0, ( nInitCount + 1 ) * sizeof(sal_uInt16) );
    1746           0 : }
    1747             : 
    1748             : 
    1749             : 
    1750             : 
    1751             : 
    1752           0 : SfxAllItemSet::SfxAllItemSet(const SfxItemSet &rCopy)
    1753             : :   SfxItemSet(rCopy),
    1754             :     aDefault(0),
    1755           0 :     nFree(0)
    1756             : {
    1757           0 : }
    1758             : 
    1759             : 
    1760             : 
    1761             : 
    1762             : 
    1763           0 : SfxAllItemSet::SfxAllItemSet(const SfxAllItemSet &rCopy)
    1764             : :   SfxItemSet(rCopy),
    1765             :     aDefault(0),
    1766           0 :     nFree(0)
    1767             : /*  [Anmerkung]
    1768             : 
    1769             :     Der mu\s sein, da sonst vom Compiler einer generiert wird, er nimmt
    1770             :     nicht den Ctor mit der 'const SfxItemSet&'!
    1771             : */
    1772             : {
    1773           0 : }
    1774             : 
    1775             : 
    1776             : 
    1777           0 : static sal_uInt16 *AddRanges_Impl(
    1778             :     sal_uInt16 *pUS, std::ptrdiff_t nOldSize, sal_uInt16 nIncr)
    1779             : 
    1780             : /*  Diese interne Funktion erzeugt ein neues Which-Range-Array, welches von
    1781             :     dem 'nOldSize'-USHORTs langen 'pUS' kopiert wird und hinten an Platz
    1782             :     f"ur 'nIncr' neue USHORTs hat. Das terminierende sal_uInt16 mit der '0'
    1783             :     wird weder in 'nOldSize' noch in 'nIncr' mitgez"ahlt, sondern implizit
    1784             :     hinzugerechnet.
    1785             : 
    1786             :     Das neue Which-Range-Array wird als Returnwert zur"uckgegeben, das alte
    1787             :     'pUS' freigegeben.
    1788             : */
    1789             : 
    1790             : {
    1791             :     // neues Which-Range-Array anlegen
    1792           0 :     sal_uInt16 *pNew = new sal_uInt16[ nOldSize + nIncr + 1 ];
    1793             : 
    1794             :     // die alten Ranges "ubernehmen
    1795           0 :     memcpy( pNew, pUS, nOldSize * sizeof(sal_uInt16) );
    1796             : 
    1797             :     // die neuen auf 0 initialisieren
    1798           0 :     memset( pNew + nOldSize, 0, ( nIncr + 1 ) * sizeof(sal_uInt16) );
    1799             : 
    1800             :     // das alte Array freigeben
    1801           0 :     delete[] pUS;
    1802             : 
    1803           0 :     return pNew;
    1804             : }
    1805             : 
    1806             : 
    1807             : 
    1808           0 : static SfxItemArray AddItem_Impl(SfxItemArray pItems, sal_uInt16 nOldSize, sal_uInt16 nPos)
    1809             : 
    1810             : /*  Diese interne Funktion erzeugt ein neues ItemArray, welches von 'pItems'
    1811             :     kopiert wird, an der Position 'nPos' jedoch Platz f"ur einen neuen
    1812             :     ItemPointer hat.
    1813             : 
    1814             :     Das neue ItemArray wird als Returnwert zur"uckgegeben, das alte 'pItems'
    1815             :     wird freigegeben.
    1816             : */
    1817             : 
    1818             : {
    1819             :     // neues ItemArray anlegen
    1820           0 :     SfxItemArray pNew = new const SfxPoolItem*[nOldSize+1];
    1821             : 
    1822             :     // war schon vorher eins da?
    1823           0 :     if ( pItems )
    1824             :     {
    1825             :         // alte Items vor nPos kopieren
    1826           0 :         if ( nPos )
    1827           0 :             memcpy( (void*) pNew, pItems, nPos * sizeof(SfxPoolItem *) );
    1828             : 
    1829             :         // alte Items hinter nPos kopieren
    1830           0 :         if ( nPos < nOldSize )
    1831           0 :             memcpy( (void*) (pNew + nPos + 1), pItems + nPos,
    1832           0 :                     (nOldSize-nPos) * sizeof(SfxPoolItem *) );
    1833             :     }
    1834             : 
    1835             :     // neues Item initialisieren
    1836           0 :     *(pNew + nPos) = 0;
    1837             : 
    1838             :     // altes ItemArray freigeben
    1839           0 :     delete[] pItems;
    1840             : 
    1841           0 :     return pNew;
    1842             : }
    1843             : 
    1844             : 
    1845             : 
    1846           0 : const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
    1847             : 
    1848             : // Putten mit automatischer Erweiterung der Whichs-Ids um die ID
    1849             : // des Items.
    1850             : 
    1851             : {
    1852           0 :     sal_uInt16 nPos = 0; // Position f"ur 'rItem' in '_aItems'
    1853           0 :     const sal_uInt16 nItemCount = TotalCount();
    1854             : 
    1855             :     // erstmal sehen, ob es schon einen passenden Bereich gibt
    1856           0 :     sal_uInt16 *pPtr = _pWhichRanges;
    1857           0 :     while ( *pPtr )
    1858             :     {
    1859             :         // Which-Id liegt in diesem Bereich?
    1860           0 :         if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
    1861             :         {
    1862             :             // Einfuegen
    1863           0 :             nPos += nWhich - *pPtr;
    1864           0 :             break;
    1865             :         }
    1866             : 
    1867             :         // Position des Items in _aItems mitf"uhren
    1868           0 :         nPos += *(pPtr+1) - *pPtr + 1;
    1869             : 
    1870             :         // zum n"achsten Bereich
    1871           0 :         pPtr += 2;
    1872             :     }
    1873             : 
    1874             :     // Which-Id noch nicht vorhanden?
    1875           0 :     if ( !*pPtr )
    1876             :     {
    1877             :         // suchen, ob man sie irgendwo dranpacken kann
    1878           0 :         pPtr = _pWhichRanges;
    1879           0 :         nPos = 0;
    1880           0 :         while ( *pPtr )
    1881             :         {
    1882             :             // Which-Id liegt exakt vor diesem Bereich?
    1883           0 :             if ( (nWhich+1) == *pPtr )
    1884             :             {
    1885             :                 // Bereich waechst nach unten
    1886           0 :                 (*pPtr)--;
    1887             : 
    1888             :                 // vor erstem Item dieses Bereichs Platz schaffen
    1889           0 :                 _aItems = AddItem_Impl(_aItems, nItemCount, nPos);
    1890           0 :                 break;
    1891             :             }
    1892             : 
    1893             :             // Which-Id liegt exakt hinter diesem Bereich?
    1894           0 :             else if ( (nWhich-1) == *(pPtr+1) )
    1895             :             {
    1896             :                 // Bereich waechst nach oben
    1897           0 :                 (*(pPtr+1))++;
    1898             : 
    1899             :                 // hinter letztem Item dieses Bereichs Platz schaffen
    1900           0 :                 nPos += nWhich - *pPtr;
    1901           0 :                 _aItems = AddItem_Impl(_aItems, nItemCount, nPos);
    1902           0 :                 break;
    1903             :             }
    1904             : 
    1905             :             // Position des Items in _aItems mitf"uhren
    1906           0 :             nPos += *(pPtr+1) - *pPtr + 1;
    1907             : 
    1908             :             // zum n"achsten Bereich
    1909           0 :             pPtr += 2;
    1910             :         }
    1911             :     }
    1912             : 
    1913             :     // keinen erweiterbaren Bereich gefunden?
    1914           0 :     if ( !*pPtr )
    1915             :     {
    1916             :         // kein Platz mehr in _pWhichRanges => erweitern
    1917           0 :         std::ptrdiff_t nSize = pPtr - _pWhichRanges;
    1918           0 :         if( !nFree )
    1919             :         {
    1920           0 :             _pWhichRanges = AddRanges_Impl(_pWhichRanges, nSize, nInitCount);
    1921           0 :             nFree += nInitCount;
    1922             :         }
    1923             : 
    1924             :         // neuen Which-Range anh"angen
    1925           0 :         pPtr = _pWhichRanges + nSize;
    1926           0 :         *pPtr++ = nWhich;
    1927           0 :         *pPtr = nWhich;
    1928           0 :         nFree -= 2;
    1929             : 
    1930             :         // Itemarray vergroessern
    1931           0 :         nPos = nItemCount;
    1932           0 :         _aItems = AddItem_Impl(_aItems, nItemCount, nPos);
    1933             :     }
    1934             : 
    1935             :     // neues Item in Pool aufnehmen
    1936           0 :     const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich );
    1937             : 
    1938             :     // altes Item merken
    1939           0 :     bool bIncrementCount = false;
    1940           0 :     const SfxPoolItem* pOld = *( _aItems + nPos );
    1941           0 :     if ( reinterpret_cast< SfxPoolItem* >( -1 ) == pOld )   // state "dontcare"
    1942           0 :         pOld = NULL;
    1943           0 :     if ( !pOld )
    1944             :     {
    1945           0 :         bIncrementCount = true;
    1946             :         pOld = _pParent ?
    1947           0 :                 &_pParent->Get( nWhich, true )
    1948           0 :                 : nWhich <= SFX_WHICH_MAX ? &_pPool->GetDefaultItem( nWhich ) : 0;
    1949             :     }
    1950             : 
    1951             :     // neue Item in ItemSet aufnehmen
    1952           0 :     *(_aItems + nPos) = &rNew;
    1953             : 
    1954             :     // Changed Notification versenden
    1955           0 :     if ( pOld )
    1956             :     {
    1957           0 :         Changed( *pOld, rNew );
    1958           0 :         if ( !IsDefaultItem(pOld) )
    1959           0 :             _pPool->Remove( *pOld );
    1960             :     }
    1961             : 
    1962           0 :     if ( bIncrementCount )
    1963           0 :         ++_nCount;
    1964             : 
    1965           0 :     return &rNew;
    1966             : }
    1967             : 
    1968             : 
    1969             : // Item disablen, wenn durch ein VoidItem mit dem Which-Wert 0 ausgedrueckt
    1970             : 
    1971           0 : void SfxItemSet::DisableItem(sal_uInt16 nWhich)
    1972             : {
    1973           0 :     Put( SfxVoidItem(0), nWhich );
    1974           0 : }
    1975             : 
    1976             : 
    1977             : 
    1978           0 : SfxItemSet *SfxAllItemSet::Clone(bool bItems, SfxItemPool *pToPool ) const
    1979             : {
    1980           0 :     if ( pToPool && pToPool != _pPool )
    1981             :     {
    1982           0 :         SfxAllItemSet *pNewSet = new SfxAllItemSet( *pToPool );
    1983           0 :         if ( bItems )
    1984           0 :             pNewSet->Set( *this );
    1985           0 :         return pNewSet;
    1986             :     }
    1987             :     else
    1988           0 :         return bItems ? new SfxAllItemSet(*this) : new SfxAllItemSet(*_pPool);
    1989             : }
    1990             : 
    1991             : 
    1992             : 
    1993           0 : sal_Int32 SfxItemSet::getHash() const
    1994             : {
    1995           0 :     return stringify().hashCode();
    1996             : }
    1997             : 
    1998             : 
    1999             : 
    2000           0 : OString SfxItemSet::stringify() const
    2001             : {
    2002           0 :     SvMemoryStream aStream;
    2003           0 :     SfxItemSet aSet(*this);
    2004           0 :     aSet.InvalidateDefaultItems();
    2005           0 :     aSet.Store(aStream, true);
    2006           0 :     aStream.Flush();
    2007             :     return OString(
    2008           0 :         static_cast<char const *>(aStream.GetData()), aStream.GetEndOfData());
    2009             : }
    2010             : 
    2011             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10