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