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