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