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