merge the formfield patch from ooo-build
[ooovba.git] / svtools / source / items1 / itemset.cxx
blob06997ea03b3c278275cbfb5f8eddf05c71f3c0c8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: itemset.cxx,v $
10 * $Revision: 1.9 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svtools.hxx"
34 #include <string.h>
36 #if STLPORT_VERSION>=321
37 #include <cstdarg>
38 #endif
40 #ifndef GCC
41 #endif
43 #define _SVSTDARR_USHORTS
44 #define _SVSTDARR_ULONGS
46 #include <svtools/svstdarr.hxx>
47 #include <svtools/itemset.hxx>
48 #include <svtools/itempool.hxx>
49 #include <svtools/itemiter.hxx>
50 #include "whiter.hxx"
51 #include <svtools/nranges.hxx>
52 #include "whassert.hxx"
54 #include <tools/stream.hxx>
55 #include <tools/solar.h>
57 // STATIC DATA -----------------------------------------------------------
59 static const USHORT nInitCount = 10; // einzelne USHORTs => 5 Paare ohne '0'
60 #ifdef DBG_UTIL
61 static ULONG nRangesCopyCount = 0; // wie oft wurden Ranges kopiert
62 #endif
64 DBG_NAME(SfxItemSet)
66 //========================================================================
68 #define NUMTYPE USHORT
69 #define SvNums SvUShorts
70 #define SfxNumRanges SfxUShortRanges
71 #include "nranges.cxx"
72 #undef NUMTYPE
73 #undef SvNums
74 #undef SfxNumRanges
76 #define NUMTYPE ULONG
77 #define SvNums SvULongs
78 #define SfxNumRanges SfxULongRanges
79 #include "nranges.cxx"
80 #undef NUMTYPE
81 #undef SvNums
82 #undef SfxNumRanges
84 //========================================================================
86 #ifdef DBG_UTIL
89 const sal_Char *DbgCheckItemSet( const void* pVoid )
91 const SfxItemSet *pSet = (const SfxItemSet*) pVoid;
92 SfxWhichIter aIter( *pSet );
93 USHORT nCount = 0, n = 0;
94 for ( USHORT nWh = aIter.FirstWhich(); nWh; nWh = aIter.NextWhich(), ++n )
96 const SfxPoolItem *pItem = pSet->_aItems[n];
97 if ( pItem )
99 ++nCount;
100 DBG_ASSERT( IsInvalidItem(pItem) ||
101 pItem->Which() == 0 || pItem->Which() == nWh,
102 "SfxItemSet: invalid which-id" );
103 DBG_ASSERT( IsInvalidItem(pItem) || !pItem->Which() ||
104 !SfxItemPool::IsWhich(pItem->Which()) ||
105 pSet->GetPool()->IsItemFlag(nWh, SFX_ITEM_NOT_POOLABLE) ||
106 SFX_ITEMS_NULL != pSet->GetPool()->GetSurrogate(pItem),
107 "SfxItemSet: item in set which is not in pool" );
111 DBG_ASSERT( pSet->_nCount == nCount, "wrong SfxItemSet::nCount detected" );
113 return 0;
116 #endif
117 // -----------------------------------------------------------------------
119 SfxItemSet::SfxItemSet
121 SfxItemPool& rPool, /* der Pool, in dem die SfxPoolItems,
122 welche in dieses SfxItemSet gelangen,
123 aufgenommen werden sollen */
124 BOOL
125 #ifdef DBG_UTIL
126 #ifdef SFX_ITEMSET_NO_DEFAULT_CTOR
128 bTotalRanges /* komplette Pool-Ranges uebernehmen,
129 muss auf TRUE gesetzt werden */
130 #endif
131 #endif
133 /* [Beschreibung]
135 Konstruktor fuer ein SfxItemSet mit genau den Which-Bereichen, welche
136 dem angegebenen <SfxItemPool> bekannt sind.
139 [Anmerkung]
141 F"ur Sfx-Programmierer ein derart konstruiertes SfxItemSet kann
142 keinerlei Items mit Slot-Ids als Which-Werte aufnehmen!
145 : _pPool( &rPool ),
146 _pParent( 0 ),
147 _nCount( 0 )
149 DBG_CTOR(SfxItemSet, DbgCheckItemSet);
150 DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
151 DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
152 // DBG_ASSERT( bTotalRanges || abs( &bTotalRanges - this ) < 1000,
153 // "please use suitable ranges" );
154 #ifdef DBG_UTIL
155 #ifdef SFX_ITEMSET_NO_DEFAULT_CTOR
156 if ( !bTotalRanges )
157 *(int*)0 = 0; // GPF
158 #endif
159 #endif
161 _pWhichRanges = (USHORT*) _pPool->GetFrozenIdRanges();
162 DBG_ASSERT( _pWhichRanges, "don't create ItemSets with full range before FreezeIdRanges()" );
163 if ( !_pWhichRanges )
164 _pPool->FillItemIdRanges_Impl( _pWhichRanges );
166 const USHORT nSize = TotalCount();
167 _aItems = new const SfxPoolItem* [ nSize ];
168 memset( (void*) _aItems, 0, nSize * sizeof( SfxPoolItem* ) );
171 // -----------------------------------------------------------------------
173 SfxItemSet::SfxItemSet( SfxItemPool& rPool, USHORT nWhich1, USHORT nWhich2 ):
174 _pPool( &rPool ),
175 _pParent( 0 ),
176 _nCount( 0 )
178 DBG_CTOR(SfxItemSet, DbgCheckItemSet);
179 DBG_ASSERT( nWhich1 <= nWhich2, "Ungueltiger Bereich" );
180 DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
181 DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
183 InitRanges_Impl(nWhich1, nWhich2);
186 // -----------------------------------------------------------------------
188 void SfxItemSet::InitRanges_Impl(USHORT nWh1, USHORT nWh2)
190 DBG_CHKTHIS(SfxItemSet, 0);
191 _pWhichRanges = new USHORT[ 3 ];
192 *(_pWhichRanges+0) = nWh1;
193 *(_pWhichRanges+1) = nWh2;
194 *(_pWhichRanges+2) = 0;
195 const USHORT nRg = nWh2 - nWh1 + 1;
196 _aItems = new const SfxPoolItem* [ nRg ];
197 memset( (void*) _aItems, 0, nRg * sizeof( SfxPoolItem* ) );
200 // -----------------------------------------------------------------------
202 void SfxItemSet::InitRanges_Impl(va_list pArgs, USHORT nWh1, USHORT nWh2, USHORT nNull)
204 DBG_CHKTHIS(SfxItemSet, 0);
206 USHORT nSize = InitializeRanges_Impl( _pWhichRanges, pArgs, nWh1, nWh2, nNull );
207 _aItems = new const SfxPoolItem* [ nSize ];
208 memset( (void*) _aItems, 0, sizeof( SfxPoolItem* ) * nSize );
211 // -----------------------------------------------------------------------
213 SfxItemSet::SfxItemSet( SfxItemPool& rPool,
214 USHORT_ARG nWh1, USHORT_ARG nWh2, USHORT_ARG nNull, ... ):
215 _pPool( &rPool ),
216 _pParent( 0 ),
217 _pWhichRanges( 0 ),
218 _nCount( 0 )
220 DBG_CTOR(SfxItemSet, DbgCheckItemSet);
221 DBG_ASSERT( nWh1 <= nWh2, "Ungueltiger Bereich" );
222 DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
223 DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
225 if(!nNull)
226 InitRanges_Impl(
227 sal::static_int_cast< USHORT >(nWh1),
228 sal::static_int_cast< USHORT >(nWh2));
229 else {
230 va_list pArgs;
231 va_start( pArgs, nNull );
232 InitRanges_Impl(
233 pArgs, sal::static_int_cast< USHORT >(nWh1),
234 sal::static_int_cast< USHORT >(nWh2),
235 sal::static_int_cast< USHORT >(nNull));
239 // -----------------------------------------------------------------------
241 void SfxItemSet::InitRanges_Impl(const USHORT *pWhichPairTable)
243 DBG_CHKTHIS(SfxItemSet, 0);
244 DBG_TRACE1("SfxItemSet: Ranges-CopyCount==%ul", ++nRangesCopyCount);
246 USHORT nCnt = 0;
247 const USHORT* pPtr = pWhichPairTable;
248 while( *pPtr )
250 nCnt += ( *(pPtr+1) - *pPtr ) + 1;
251 pPtr += 2;
254 _aItems = new const SfxPoolItem* [ nCnt ];
255 memset( (void*) _aItems, 0, sizeof( SfxPoolItem* ) * nCnt );
257 std::ptrdiff_t cnt = pPtr - pWhichPairTable +1;
258 _pWhichRanges = new USHORT[ cnt ];
259 memcpy( _pWhichRanges, pWhichPairTable, sizeof( USHORT ) * cnt );
263 // -----------------------------------------------------------------------
265 SfxItemSet::SfxItemSet( SfxItemPool& rPool, const USHORT* pWhichPairTable ):
266 _pPool( &rPool ),
267 _pParent( 0 ),
268 _pWhichRanges(0),
269 _nCount( 0 )
271 DBG_CTOR(SfxItemSet, 0);
272 DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
273 DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
275 // pWhichPairTable == 0 ist f"ur das SfxAllEnumItemSet
276 if ( pWhichPairTable )
277 InitRanges_Impl(pWhichPairTable);
280 // -----------------------------------------------------------------------
282 SfxItemSet::SfxItemSet( const SfxItemSet& rASet ):
283 _pPool( rASet._pPool ),
284 _pParent( rASet._pParent ),
285 _nCount( rASet._nCount )
287 DBG_CTOR(SfxItemSet, DbgCheckItemSet);
288 DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
289 DBG( _pChildCountCtor; *_pChildCount(this) = 0 );
290 DBG( ++*_pChildCount(_pParent) );
292 // errechne die Anzahl von Attributen
293 USHORT nCnt = 0;
294 USHORT* pPtr = rASet._pWhichRanges;
295 while( *pPtr )
297 nCnt += ( *(pPtr+1) - *pPtr ) + 1;
298 pPtr += 2;
301 _aItems = new const SfxPoolItem* [ nCnt ];
303 // Attribute kopieren
304 SfxItemArray ppDst = _aItems, ppSrc = rASet._aItems;
305 for( USHORT n = nCnt; n; --n, ++ppDst, ++ppSrc )
306 if ( 0 == *ppSrc || // aktueller Default?
307 IsInvalidItem(*ppSrc) || // Dont Care?
308 IsStaticDefaultItem(*ppSrc) ) // nicht zu poolende Defaults
309 // einfach Pointer kopieren
310 *ppDst = *ppSrc;
311 else if ( _pPool->IsItemFlag( **ppSrc, SFX_ITEM_POOLABLE ) )
313 // einfach Pointer kopieren und Ref-Count erh"ohen
314 *ppDst = *ppSrc;
315 ( (SfxPoolItem*) (*ppDst) )->AddRef();
317 else if ( !(*ppSrc)->Which() )
318 *ppDst = (*ppSrc)->Clone();
319 else
320 // !IsPoolable() => via Pool zuweisen
321 *ppDst = &_pPool->Put( **ppSrc );
323 // dann noch die Which Ranges kopieren
324 DBG_TRACE1("SfxItemSet: Ranges-CopyCount==%ul", ++nRangesCopyCount);
325 std::ptrdiff_t cnt = pPtr - rASet._pWhichRanges+1;
326 _pWhichRanges = new USHORT[ cnt ];
327 memcpy( _pWhichRanges, rASet._pWhichRanges, sizeof( USHORT ) * cnt);
330 // -----------------------------------------------------------------------
332 SfxItemSet::~SfxItemSet()
334 DBG_DTOR(SfxItemSet, DbgCheckItemSet);
335 #ifdef DBG_UTIL
336 DBG( DBG_ASSERT( 0 == *_pChildCount(this), "SfxItemSet: deleting parent-itemset" ) )
337 #endif
339 USHORT nCount = TotalCount();
340 if( Count() )
342 SfxItemArray ppFnd = _aItems;
343 for( USHORT nCnt = nCount; nCnt; --nCnt, ++ppFnd )
344 if( *ppFnd && !IsInvalidItem(*ppFnd) )
346 if( !(*ppFnd)->Which() )
347 delete (SfxPoolItem*) *ppFnd;
348 else {
349 // noch mehrer Referenzen vorhanden, also nur den
350 // ReferenzCounter manipulieren
351 if ( 1 < (*ppFnd)->GetRefCount() && !IsDefaultItem(*ppFnd) )
352 (*ppFnd)->ReleaseRef();
353 else
354 if ( !IsDefaultItem(*ppFnd) )
355 // aus dem Pool loeschen
356 _pPool->Remove( **ppFnd );
361 // FIXME: could be delete[] (SfxPoolItem **)_aItems;
362 delete[] _aItems;
363 if ( _pWhichRanges != _pPool->GetFrozenIdRanges() )
364 delete[] _pWhichRanges;
365 _pWhichRanges = 0; // for invariant-testing
367 DBG( --*_pChildCount(_pParent) );
368 DBG( delete _pChildCount(this); _pChildCountDtor );
371 // -----------------------------------------------------------------------
373 USHORT SfxItemSet::ClearItem( USHORT nWhich )
375 // einzelnes Item oder alle Items (nWhich==0) l"oschen
378 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
379 if( !Count() )
380 return 0;
382 USHORT nDel = 0;
383 SfxItemArray ppFnd = _aItems;
385 if( nWhich )
387 const USHORT* pPtr = _pWhichRanges;
388 while( *pPtr )
390 // in diesem Bereich?
391 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
393 // "uberhaupt gesetzt?
394 ppFnd += nWhich - *pPtr;
395 if( *ppFnd )
397 // wegen der Assertions ins Sub-Calls mu\s das hier sein
398 --_nCount;
399 const SfxPoolItem *pItemToClear = *ppFnd;
400 *ppFnd = 0;
402 if ( !IsInvalidItem(pItemToClear) )
404 if ( nWhich <= SFX_WHICH_MAX )
406 const SfxPoolItem& rNew = _pParent
407 ? _pParent->Get( nWhich, TRUE )
408 : _pPool->GetDefaultItem( nWhich );
410 Changed( *pItemToClear, rNew );
412 if ( pItemToClear->Which() )
413 _pPool->Remove( *pItemToClear );
415 ++nDel;
418 // gefunden => raus
419 break;
421 ppFnd += *(pPtr+1) - *pPtr + 1;
422 pPtr += 2;
425 else
427 nDel = _nCount;
429 USHORT* pPtr = _pWhichRanges;
430 while( *pPtr )
432 for( nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
433 if( *ppFnd )
435 // wegen der Assertions ins Sub-Calls mu\s das hier sein
436 --_nCount;
437 const SfxPoolItem *pItemToClear = *ppFnd;
438 *ppFnd = 0;
440 if ( !IsInvalidItem(pItemToClear) )
442 if ( nWhich <= SFX_WHICH_MAX )
444 const SfxPoolItem& rNew = _pParent
445 ? _pParent->Get( nWhich, TRUE )
446 : _pPool->GetDefaultItem( nWhich );
448 Changed( *pItemToClear, rNew );
451 // #i32448#
452 // Take care of disabled items, too.
453 if(!pItemToClear->nWhich)
455 // item is disabled, delete it
456 delete pItemToClear;
458 else
460 // remove item from pool
461 _pPool->Remove( *pItemToClear );
465 pPtr += 2;
468 return nDel;
471 // -----------------------------------------------------------------------
473 void SfxItemSet::ClearInvalidItems( BOOL bHardDefault )
475 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
476 USHORT* pPtr = _pWhichRanges;
477 SfxItemArray ppFnd = _aItems;
478 if ( bHardDefault )
479 while( *pPtr )
481 for ( USHORT nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
482 if ( IsInvalidItem(*ppFnd) )
483 *ppFnd = &_pPool->Put( _pPool->GetDefaultItem(nWhich) );
484 pPtr += 2;
486 else
487 while( *pPtr )
489 for( USHORT nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
490 if( IsInvalidItem(*ppFnd) )
492 *ppFnd = 0;
493 --_nCount;
495 pPtr += 2;
499 //------------------------------------------------------------------------
502 void SfxItemSet::InvalidateAllItems()
504 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
505 DBG_ASSERT( !_nCount, "Es sind noch Items gesetzt" );
507 memset( (void*)_aItems, -1, ( _nCount = TotalCount() ) * sizeof( SfxPoolItem*) );
510 // -----------------------------------------------------------------------
512 SfxItemState SfxItemSet::GetItemState( USHORT nWhich,
513 BOOL bSrchInParent,
514 const SfxPoolItem **ppItem ) const
516 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
517 // suche den Bereich in dem das Which steht:
518 const SfxItemSet* pAktSet = this;
519 SfxItemState eRet = SFX_ITEM_UNKNOWN;
522 SfxItemArray ppFnd = pAktSet->_aItems;
523 const USHORT* pPtr = pAktSet->_pWhichRanges;
524 if (pPtr)
526 while ( *pPtr )
528 if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
530 // in diesem Bereich
531 ppFnd += nWhich - *pPtr;
532 if ( !*ppFnd )
534 eRet = SFX_ITEM_DEFAULT;
535 if( !bSrchInParent )
536 return eRet; // nicht vorhanden
537 break; // JP: in den Parents weitersuchen !!!
540 if ( (SfxPoolItem*) -1 == *ppFnd )
541 // Unterschiedlich vorhanden
542 return SFX_ITEM_DONTCARE;
544 if ( (*ppFnd)->Type() == TYPE(SfxVoidItem) )
545 return SFX_ITEM_DISABLED;
547 if (ppItem)
549 #ifdef DBG_UTIL
550 const SfxPoolItem *pItem = *ppFnd;
551 DBG_ASSERT( !pItem->ISA(SfxSetItem) ||
552 0 != &((const SfxSetItem*)pItem)->GetItemSet(),
553 "SetItem without ItemSet" );
554 #endif
555 *ppItem = *ppFnd;
557 return SFX_ITEM_SET;
559 ppFnd += *(pPtr+1) - *pPtr + 1;
560 pPtr += 2;
563 } while( bSrchInParent && 0 != ( pAktSet = pAktSet->_pParent ));
564 return eRet;
567 // -----------------------------------------------------------------------
569 const SfxPoolItem* SfxItemSet::Put( const SfxPoolItem& rItem, USHORT nWhich )
571 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
572 DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
573 0 != &((const SfxSetItem&)rItem).GetItemSet(),
574 "SetItem without ItemSet" );
575 if ( !nWhich )
576 return 0; //! nur wegen Outliner-Bug
577 SfxItemArray ppFnd = _aItems;
578 const USHORT* pPtr = _pWhichRanges;
579 while( *pPtr )
581 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
583 // in diesem Bereich
584 ppFnd += nWhich - *pPtr;
585 if( *ppFnd ) // schon einer vorhanden
587 // selbes Item bereits vorhanden?
588 if ( *ppFnd == &rItem )
589 return 0;
591 // wird dontcare oder disabled mit was echtem ueberschrieben?
592 if ( rItem.Which() && ( IsInvalidItem(*ppFnd) || !(*ppFnd)->Which() ) )
594 *ppFnd = &_pPool->Put( rItem, nWhich );
595 return *ppFnd;
598 // wird disabled?
599 if( !rItem.Which() )
601 *ppFnd = rItem.Clone(_pPool);
602 return 0;
604 else
606 // selber Wert bereits vorhanden?
607 if ( rItem == **ppFnd )
608 return 0;
610 // den neuen eintragen, den alten austragen
611 const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich );
612 const SfxPoolItem* pOld = *ppFnd;
613 *ppFnd = &rNew;
614 if(nWhich <= SFX_WHICH_MAX)
615 Changed( *pOld, rNew );
616 _pPool->Remove( *pOld );
619 else
621 ++_nCount;
622 if( !rItem.Which() )
623 *ppFnd = rItem.Clone(_pPool);
624 else {
625 const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich );
626 *ppFnd = &rNew;
627 if (nWhich <= SFX_WHICH_MAX )
629 const SfxPoolItem& rOld = _pParent
630 ? _pParent->Get( nWhich, TRUE )
631 : _pPool->GetDefaultItem( nWhich );
632 Changed( rOld, rNew );
636 SFX_ASSERT( !_pPool->IsItemFlag(nWhich, SFX_ITEM_POOLABLE) ||
637 rItem.ISA(SfxSetItem) || **ppFnd == rItem,
638 nWhich, "putted Item unequal" );
639 return *ppFnd;
641 ppFnd += *(pPtr+1) - *pPtr + 1;
642 pPtr += 2;
644 return 0;
647 // -----------------------------------------------------------------------
649 int SfxItemSet::Put( const SfxItemSet& rSet, BOOL bInvalidAsDefault )
651 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
652 BOOL bRet = FALSE;
653 if( rSet.Count() )
655 SfxItemArray ppFnd = rSet._aItems;
656 const USHORT* pPtr = rSet._pWhichRanges;
657 while ( *pPtr )
659 for ( USHORT nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
660 if( *ppFnd )
662 if ( IsInvalidItem( *ppFnd ) )
664 if ( bInvalidAsDefault )
665 bRet |= 0 != ClearItem( nWhich );
666 // gab GPF bei non.WIDs:
667 // bRet |= 0 != Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
668 else
669 InvalidateItem( nWhich );
671 else
672 bRet |= 0 != Put( **ppFnd, nWhich );
674 pPtr += 2;
677 return bRet;
680 // -----------------------------------------------------------------------
682 void SfxItemSet::PutExtended
684 const SfxItemSet& rSet, // Quelle der zu puttenden Items
685 SfxItemState eDontCareAs, // was mit DontCare-Items passiert
686 SfxItemState eDefaultAs // was mit Default-Items passiert
689 /* [Beschreibung]
691 Diese Methode "ubernimmt die Items aus 'rSet' in '*this'. Die
692 Which-Bereiche in '*this', die in 'rSet' nicht vorkommen bleiben unver-
693 "andert. Der Which-Bereich von '*this' bleibt auch unver"andert.
695 In 'rSet' gesetzte Items werden auch in '*this*' gesetzt. Default-
696 (0 Pointer) und Invalid- (-1 Pointer) Items werden je nach Parameter
697 ('eDontCareAs' und 'eDefaultAs' behandelt:
699 SFX_ITEM_SET: hart auf Default des Pools gesetzt
700 SFX_ITEM_DEFAULT: gel"oscht (0 Pointer)
701 SFX_ITEM_DONTCARE: invalidiert (-1 Pointer)
703 Alle anderen Werte f"ur 'eDontCareAs' und 'eDefaultAs' sind ung"ultig.
707 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
709 // don't "optimize" with "if( rSet.Count()" because of dont-care + defaults
710 SfxItemArray ppFnd = rSet._aItems;
711 const USHORT* pPtr = rSet._pWhichRanges;
712 while ( *pPtr )
714 for ( USHORT nWhich = *pPtr; nWhich <= *(pPtr+1); ++nWhich, ++ppFnd )
715 if( *ppFnd )
717 if ( IsInvalidItem( *ppFnd ) )
719 // Item ist DontCare:
720 switch ( eDontCareAs )
722 case SFX_ITEM_SET:
723 Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
724 break;
726 case SFX_ITEM_DEFAULT:
727 ClearItem( nWhich );
728 break;
730 case SFX_ITEM_DONTCARE:
731 InvalidateItem( nWhich );
732 break;
734 default:
735 DBG_ERROR( "invalid Argument for eDontCareAs" );
738 else
739 // Item ist gesetzt:
740 Put( **ppFnd, nWhich );
742 else
744 // Item ist Default:
745 switch ( eDefaultAs )
747 case SFX_ITEM_SET:
748 Put( rSet.GetPool()->GetDefaultItem(nWhich), nWhich );
749 break;
751 case SFX_ITEM_DEFAULT:
752 ClearItem( nWhich );
753 break;
755 case SFX_ITEM_DONTCARE:
756 InvalidateItem( nWhich );
757 break;
759 default:
760 DBG_ERROR( "invalid Argument for eDefaultAs" );
763 pPtr += 2;
767 // -----------------------------------------------------------------------
769 void SfxItemSet::MergeRange( USHORT nFrom, USHORT nTo )
770 /** <H3>Description</H3>
772 Expands the ranges of settable items by 'nFrom' to 'nTo'. Keeps state of
773 items which are new ranges too.
777 // special case: exactly one USHORT which is already included?
778 if ( nFrom == nTo && SFX_ITEM_AVAILABLE <= GetItemState(nFrom, FALSE) )
779 return;
781 // merge new range
782 SfxUShortRanges aRanges( _pWhichRanges );
783 aRanges += SfxUShortRanges( nFrom, nTo );
784 SetRanges( aRanges );
787 // -----------------------------------------------------------------------
789 void SfxItemSet::SetRanges( const USHORT *pNewRanges )
791 /** <H3>Description</H3>
793 Modifies the ranges of settable items. Keeps state of items which
794 are new ranges too.
798 // identische Ranges?
799 if ( _pWhichRanges == pNewRanges )
800 return;
801 const USHORT* pOld = _pWhichRanges;
802 const USHORT* pNew = pNewRanges;
803 while ( *pOld == *pNew )
805 if ( !*pOld && !*pNew )
806 return;
807 ++pOld, ++pNew;
810 // create new item-array (by iterating through all new ranges)
811 ULONG nSize = Capacity_Impl(pNewRanges);
812 SfxItemArray aNewItems = new const SfxPoolItem* [ nSize ];
813 USHORT n = 0, nNewCount = 0;
814 if ( _nCount == 0 )
815 memset( aNewItems, 0, nSize * sizeof( SfxPoolItem* ) );
816 else
818 for ( const USHORT *pRange = pNewRanges; *pRange; pRange += 2 )
820 // iterate through all ids in the range
821 for ( USHORT nWID = *pRange; nWID <= pRange[1]; ++nWID, ++n )
823 // direct move of pointer (not via pool)
824 SfxItemState eState = GetItemState( nWID, FALSE, aNewItems+n );
825 if ( SFX_ITEM_SET == eState )
827 // increment new item count and possibly increment ref count
828 ++nNewCount;
829 aNewItems[n]->AddRef();
831 else if ( SFX_ITEM_DISABLED == eState )
833 // put "disabled" item
834 ++nNewCount;
835 aNewItems[n] = new SfxVoidItem(0);
837 else if ( SFX_ITEM_DONTCARE == eState )
839 ++nNewCount;
840 aNewItems[n] = (SfxPoolItem*)-1;
842 else
844 // default
845 aNewItems[n] = 0;
849 // free old items
850 USHORT nOldTotalCount = TotalCount();
851 for ( USHORT nItem = 0; nItem < nOldTotalCount; ++nItem )
853 const SfxPoolItem *pItem = _aItems[nItem];
854 if ( pItem && !IsInvalidItem(pItem) && pItem->Which() )
855 _pPool->Remove(*pItem);
859 // replace old items-array and ranges
860 delete[] _aItems;
861 _aItems = aNewItems;
862 _nCount = nNewCount;
864 if( pNewRanges == GetPool()->GetFrozenIdRanges() )
866 delete[] _pWhichRanges;
867 _pWhichRanges = ( USHORT* ) pNewRanges;
869 else
871 USHORT nCount = Count_Impl(pNewRanges) + 1;
872 if ( _pWhichRanges != _pPool->GetFrozenIdRanges() )
873 delete[] _pWhichRanges;
874 _pWhichRanges = new USHORT[ nCount ];
875 memcpy( _pWhichRanges, pNewRanges, sizeof( USHORT ) * nCount );
879 // -----------------------------------------------------------------------
881 int SfxItemSet::Set
883 const SfxItemSet& rSet, /* das SfxItemSet, dessen SfxPoolItems
884 "ubernommen werden sollen */
886 BOOL bDeep /* TRUE (default)
887 auch die SfxPoolItems aus den ggf. an
888 rSet vorhandenen Parents werden direkt
889 in das SfxItemSet "ubernommen
891 FALSE
892 die SfxPoolItems aus den Parents von
893 rSet werden nicht ber"ucksichtigt */
896 /* [Beschreibung]
898 Das SfxItemSet nimmt genau die SfxPoolItems an, die auch in
899 rSet gesetzt sind und im eigenen <Which-Bereich> liegen. Alle
900 anderen werden entfernt. Der SfxItemPool wird dabei beibehalten,
901 so da"s die "ubernommenen SfxPoolItems dabei ggf. vom SfxItemPool
902 von rSet in den SfxItemPool von *this "ubernommen werden.
904 SfxPoolItems, f"ur die in rSet IsInvalidItem() == TRUE gilt,
905 werden als Invalid-Item "ubernommen.
908 [R"uckgabewert]
910 int TRUE
911 es wurden SfxPoolItems "ubernommen
913 FALSE
914 es wurden keine SfxPoolItems "ubernommen,
915 da z.B. die Which-Bereiche der SfxItemSets
916 keine Schnittmenge haben oder in der
917 Schnittmenge keine SfxPoolItems in rSet
918 gesetzt sind
923 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
924 int bRet = FALSE;
925 if ( _nCount )
926 ClearItem();
927 if ( bDeep )
929 SfxWhichIter aIter(*this);
930 USHORT nWhich = aIter.FirstWhich();
931 while ( nWhich )
933 const SfxPoolItem* pItem;
934 if( SFX_ITEM_SET == rSet.GetItemState( nWhich, TRUE, &pItem ) )
935 bRet |= 0 != Put( *pItem, pItem->Which() );
936 nWhich = aIter.NextWhich();
939 else
940 bRet = Put(rSet, FALSE);
942 return bRet;
945 //------------------------------------------------------------------------
947 const SfxPoolItem* SfxItemSet::GetItem
949 USHORT nId, // Slot-Id oder Which-Id des Items
950 BOOL bSrchInParent, // TRUE: auch in Parent-ItemSets suchen
951 TypeId aItemType // != 0 => RTTI Pruefung mit Assertion
952 ) const
954 /* [Beschreibung]
956 Mit dieser Methode wird der Zugriff auf einzelne Items im
957 SfxItemSet wesentlich vereinfacht. Insbesondere wird die Typpr"ufung
958 (per Assertion) durchgef"uhrt, wodurch die Applikations-Sourcen
959 wesentlich "ubersichtlicher werden. In der PRODUCT-Version wird
960 eine 0 zur"uckgegeben, wenn das gefundene Item nicht von der
961 angegebenen Klasse ist. Ist kein Item mit der Id 'nWhich' in dem ItemSet,
962 so wird 0 zurueckgegeben.
966 // ggf. in Which-Id umrechnen
967 USHORT nWhich = GetPool()->GetWhich(nId);
969 // ist das Item gesetzt oder bei bDeep==TRUE verf"ugbar?
970 const SfxPoolItem *pItem = 0;
971 SfxItemState eState = GetItemState( nWhich, bSrchInParent, &pItem );
972 if ( bSrchInParent && SFX_ITEM_AVAILABLE == eState &&
973 nWhich <= SFX_WHICH_MAX )
974 pItem = &_pPool->GetDefaultItem(nWhich);
975 if ( pItem )
977 // stimmt der Typ "uberein?
978 if ( !aItemType || pItem->IsA(aItemType) )
979 return pItem;
981 // sonst Fehler melden
982 DBG_ERROR( "invalid argument type" );
985 // kein Item gefunden oder falschen Typ gefunden
986 return 0;
990 //------------------------------------------------------------------------
993 const SfxPoolItem& SfxItemSet::Get( USHORT nWhich, BOOL bSrchInParent) const
995 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
996 // suche den Bereich in dem das Which steht:
997 const SfxItemSet* pAktSet = this;
1000 if( pAktSet->Count() )
1002 SfxItemArray ppFnd = pAktSet->_aItems;
1003 const USHORT* pPtr = pAktSet->_pWhichRanges;
1004 while( *pPtr )
1006 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
1008 // in diesem Bereich
1009 ppFnd += nWhich - *pPtr;
1010 if( *ppFnd )
1012 if( (SfxPoolItem*)-1 == *ppFnd ) {
1013 //?MI: folgender code ist Doppelt (unten)
1014 SFX_ASSERT(_pPool, nWhich, "kein Pool, aber Status uneindeutig");
1015 //!((SfxAllItemSet *)this)->aDefault.SetWhich(nWhich);
1016 //!return aDefault;
1017 return _pPool->GetDefaultItem( nWhich );
1019 #ifdef DBG_UTIL
1020 const SfxPoolItem *pItem = *ppFnd;
1021 DBG_ASSERT( !pItem->ISA(SfxSetItem) ||
1022 0 != &((const SfxSetItem*)pItem)->GetItemSet(),
1023 "SetItem without ItemSet" );
1024 if ( pItem->ISA(SfxVoidItem) || !pItem->Which() )
1025 DBG_WARNING( "SFX_WARNING: Getting disabled Item" );
1026 #endif
1027 return **ppFnd;
1029 break; // dann beim Parent suchen
1031 ppFnd += *(pPtr+1) - *pPtr + 1;
1032 pPtr += 2;
1035 // bis zum Ende vom Such-Bereich: was nun ? zum Parent, oder Default ??
1036 // if( !*pPtr ) // bis zum Ende vom Such-Bereich ?
1037 // break;
1038 } while( bSrchInParent && 0 != ( pAktSet = pAktSet->_pParent ));
1040 // dann das Default vom Pool holen und returnen
1041 SFX_ASSERT(_pPool, nWhich, "kein Pool, aber Status uneindeutig");
1042 const SfxPoolItem *pItem = &_pPool->GetDefaultItem( nWhich );
1043 DBG_ASSERT( !pItem->ISA(SfxSetItem) ||
1044 0 != &((const SfxSetItem*)pItem)->GetItemSet(),
1045 "SetItem without ItemSet" );
1046 return *pItem;
1049 // Notification-Callback
1050 // -----------------------------------------------------------------------
1052 void SfxItemSet::Changed( const SfxPoolItem&, const SfxPoolItem& )
1054 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1057 // -----------------------------------------------------------------------
1059 USHORT SfxItemSet::TotalCount() const
1061 DBG_CHKTHIS(SfxItemSet, 0); // wird im Ctor benutzt bevor vollst. init.
1062 USHORT nRet = 0;
1063 USHORT* pPtr = _pWhichRanges;
1064 while( *pPtr )
1066 nRet += ( *(pPtr+1) - *pPtr ) + 1;
1067 pPtr += 2;
1069 return nRet;
1071 // -----------------------------------------------------------------------
1073 // behalte nur die Items, die auch in rSet enthalten sein (Wert egal)
1075 void SfxItemSet::Intersect( const SfxItemSet& rSet )
1077 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1078 DBG_ASSERT(_pPool, "nicht implementiert ohne Pool");
1079 if( !Count() ) // gar keine gesetzt ?
1080 return;
1082 // loesche alle Items, die im rSet nicht mehr vorhanden sind
1083 if( !rSet.Count() )
1085 ClearItem(); // alles loeschen
1086 return;
1089 // teste mal, ob sich die Which-Bereiche unterscheiden.
1090 BOOL bEqual = TRUE;
1091 USHORT* pWh1 = _pWhichRanges;
1092 USHORT* pWh2 = rSet._pWhichRanges;
1093 USHORT nSize = 0;
1095 for( USHORT n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
1097 if( *pWh1 != *pWh2 )
1099 bEqual = FALSE;
1100 break;
1102 if( n & 1 )
1103 nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
1105 bEqual = *pWh1 == *pWh2; // auch die 0 abpruefen
1107 // sind die Bereiche identisch, ist es einfacher zu handhaben !
1108 if( bEqual )
1110 SfxItemArray ppFnd1 = _aItems;
1111 SfxItemArray ppFnd2 = rSet._aItems;
1113 for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
1114 if( *ppFnd1 && !*ppFnd2 )
1116 // aus dem Pool loeschen
1117 if( !IsInvalidItem( *ppFnd1 ) )
1119 USHORT nWhich = (*ppFnd1)->Which();
1120 if(nWhich <= SFX_WHICH_MAX)
1122 const SfxPoolItem& rNew = _pParent
1123 ? _pParent->Get( nWhich, TRUE )
1124 : _pPool->GetDefaultItem( nWhich );
1126 Changed( **ppFnd1, rNew );
1128 _pPool->Remove( **ppFnd1 );
1130 *ppFnd1 = 0;
1131 --_nCount;
1134 else
1136 SfxItemIter aIter( *this );
1137 const SfxPoolItem* pItem = aIter.GetCurItem();
1138 while( TRUE )
1140 USHORT nWhich = IsInvalidItem( pItem )
1141 ? GetWhichByPos( aIter.GetCurPos() )
1142 : pItem->Which();
1143 if( 0 == rSet.GetItemState( nWhich, FALSE ) )
1144 ClearItem( nWhich ); // loeschen
1145 if( aIter.IsAtEnd() )
1146 break;
1147 pItem = aIter.NextItem();
1152 // -----------------------------------------------------------------------
1154 void SfxItemSet::Differentiate( const SfxItemSet& rSet )
1156 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1157 if( !Count() || !rSet.Count() ) // gar keine gesetzt ?
1158 return;
1160 // teste mal, ob sich die Which-Bereiche unterscheiden.
1161 BOOL bEqual = TRUE;
1162 USHORT* pWh1 = _pWhichRanges;
1163 USHORT* pWh2 = rSet._pWhichRanges;
1164 USHORT nSize = 0;
1166 for( USHORT n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
1168 if( *pWh1 != *pWh2 )
1170 bEqual = FALSE;
1171 break;
1173 if( n & 1 )
1174 nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
1176 bEqual = *pWh1 == *pWh2; // auch die 0 abpruefen
1178 // sind die Bereiche identisch, ist es einfacher zu handhaben !
1179 if( bEqual )
1181 SfxItemArray ppFnd1 = _aItems;
1182 SfxItemArray ppFnd2 = rSet._aItems;
1184 for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
1185 if( *ppFnd1 && *ppFnd2 )
1187 // aus dem Pool loeschen
1188 if( !IsInvalidItem( *ppFnd1 ) )
1190 USHORT nWhich = (*ppFnd1)->Which();
1191 if(nWhich <= SFX_WHICH_MAX)
1193 const SfxPoolItem& rNew = _pParent
1194 ? _pParent->Get( nWhich, TRUE )
1195 : _pPool->GetDefaultItem( nWhich );
1197 Changed( **ppFnd1, rNew );
1199 _pPool->Remove( **ppFnd1 );
1201 *ppFnd1 = 0;
1202 --_nCount;
1205 else
1207 SfxItemIter aIter( *this );
1208 const SfxPoolItem* pItem = aIter.GetCurItem();
1209 while( TRUE )
1211 USHORT nWhich = IsInvalidItem( pItem )
1212 ? GetWhichByPos( aIter.GetCurPos() )
1213 : pItem->Which();
1214 if( SFX_ITEM_SET == rSet.GetItemState( nWhich, FALSE ) )
1215 ClearItem( nWhich ); // loeschen
1216 if( aIter.IsAtEnd() )
1217 break;
1218 pItem = aIter.NextItem();
1224 // -----------------------------------------------------------------------
1225 /* Entscheidungstabelle fuer MergeValue[s]
1227 Grundsaetze:
1228 1. Ist der Which-Wert im 1.Set "unknown", dann folgt niemals eine Aktion.
1229 2. Ist der Which-Wert im 2.Set "unknown", dann gilt er als "default".
1230 3. Es gelten fuer Vergleiche die Werte der "default"-Items.
1232 1.-Item 2.-Item Values bIgnoreDefs Remove Assign Add
1234 set set == FALSE - - -
1235 default set == FALSE - - -
1236 dontcare set == FALSE - - -
1237 unknown set == FALSE - - -
1238 set default == FALSE - - -
1239 default default == FALSE - - -
1240 dontcare default == FALSE - - -
1241 unknown default == FALSE - - -
1242 set dontcare == FALSE 1.-Item -1 -
1243 default dontcare == FALSE - -1 -
1244 dontcare dontcare == FALSE - - -
1245 unknown dontcare == FALSE - - -
1246 set unknown == FALSE 1.-Item -1 -
1247 default unknown == FALSE - - -
1248 dontcare unknown == FALSE - - -
1249 unknown unknown == FALSE - - -
1251 set set != FALSE 1.-Item -1 -
1252 default set != FALSE - -1 -
1253 dontcare set != FALSE - - -
1254 unknown set != FALSE - - -
1255 set default != FALSE 1.-Item -1 -
1256 default default != FALSE - - -
1257 dontcare default != FALSE - - -
1258 unknown default != FALSE - - -
1259 set dontcare != FALSE 1.-Item -1 -
1260 default dontcare != FALSE - -1 -
1261 dontcare dontcare != FALSE - - -
1262 unknown dontcare != FALSE - - -
1263 set unknown != FALSE 1.-Item -1 -
1264 default unknown != FALSE - - -
1265 dontcare unknown != FALSE - - -
1266 unknown unknown != FALSE - - -
1268 set set == TRUE - - -
1269 default set == TRUE - 2.-Item 2.-Item
1270 dontcare set == TRUE - - -
1271 unknown set == TRUE - - -
1272 set default == TRUE - - -
1273 default default == TRUE - - -
1274 dontcare default == TRUE - - -
1275 unknown default == TRUE - - -
1276 set dontcare == TRUE - - -
1277 default dontcare == TRUE - -1 -
1278 dontcare dontcare == TRUE - - -
1279 unknown dontcare == TRUE - - -
1280 set unknown == TRUE - - -
1281 default unknown == TRUE - - -
1282 dontcare unknown == TRUE - - -
1283 unknown unknown == TRUE - - -
1285 set set != TRUE 1.-Item -1 -
1286 default set != TRUE - 2.-Item 2.-Item
1287 dontcare set != TRUE - - -
1288 unknown set != TRUE - - -
1289 set default != TRUE - - -
1290 default default != TRUE - - -
1291 dontcare default != TRUE - - -
1292 unknown default != TRUE - - -
1293 set dontcare != TRUE 1.-Item -1 -
1294 default dontcare != TRUE - -1 -
1295 dontcare dontcare != TRUE - - -
1296 unknown dontcare != TRUE - - -
1297 set unknown != TRUE - - -
1298 default unknown != TRUE - - -
1299 dontcare unknown != TRUE - - -
1300 unknown unknown != TRUE - - -
1304 static void MergeItem_Impl( SfxItemPool *_pPool, USHORT &rCount,
1305 const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2,
1306 BOOL bIgnoreDefaults )
1308 DBG_ASSERT( ppFnd1 != 0, "Merging to 0-Item" );
1310 // 1. Item ist default?
1311 if ( !*ppFnd1 )
1313 if ( IsInvalidItem(pFnd2) )
1314 // Entscheidungstabelle: default, dontcare, egal, egal
1315 *ppFnd1 = (SfxPoolItem*) -1;
1317 else if ( pFnd2 && !bIgnoreDefaults &&
1318 _pPool->GetDefaultItem(pFnd2->Which()) != *pFnd2 )
1319 // Entscheidungstabelle: default, set, !=, FALSE
1320 *ppFnd1 = (SfxPoolItem*) -1;
1322 else if ( pFnd2 && bIgnoreDefaults )
1323 // Entscheidungstabelle: default, set, egal, TRUE
1324 *ppFnd1 = &_pPool->Put( *pFnd2 );
1326 if ( *ppFnd1 )
1327 ++rCount;
1330 // 1. Item ist gesetzt?
1331 else if ( !IsInvalidItem(*ppFnd1) )
1333 if ( !pFnd2 )
1335 // 2. Item ist default
1336 if ( !bIgnoreDefaults &&
1337 **ppFnd1 != _pPool->GetDefaultItem((*ppFnd1)->Which()) )
1339 // Entscheidungstabelle: set, default, !=, FALSE
1340 _pPool->Remove( **ppFnd1 );
1341 *ppFnd1 = (SfxPoolItem*) -1;
1344 else if ( IsInvalidItem(pFnd2) )
1346 // 2. Item ist dontcare
1347 if ( !bIgnoreDefaults ||
1348 **ppFnd1 != _pPool->GetDefaultItem( (*ppFnd1)->Which()) )
1350 // Entscheidungstabelle: set, dontcare, egal, FALSE
1351 // oder: set, dontcare, !=, TRUE
1352 _pPool->Remove( **ppFnd1 );
1353 *ppFnd1 = (SfxPoolItem*) -1;
1356 else
1358 // 2. Item ist gesetzt
1359 if ( **ppFnd1 != *pFnd2 )
1361 // Entscheidungstabelle: set, set, !=, egal
1362 _pPool->Remove( **ppFnd1 );
1363 *ppFnd1 = (SfxPoolItem*) -1;
1369 // -----------------------------------------------------------------------
1371 void SfxItemSet::MergeValues( const SfxItemSet& rSet, BOOL bIgnoreDefaults )
1373 // Achtung!!! Bei Aenderungen/Bugfixes immer obenstehende Tabelle pflegen!
1374 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1375 DBG_ASSERT( GetPool() == rSet.GetPool(), "MergeValues mit verschiedenen Pools" );
1377 // teste mal, ob sich die Which-Bereiche unterscheiden.
1378 BOOL bEqual = TRUE;
1379 USHORT* pWh1 = _pWhichRanges;
1380 USHORT* pWh2 = rSet._pWhichRanges;
1381 USHORT nSize = 0;
1383 for( USHORT n = 0; *pWh1 && *pWh2; ++pWh1, ++pWh2, ++n )
1385 if( *pWh1 != *pWh2 )
1387 bEqual = FALSE;
1388 break;
1390 if( n & 1 )
1391 nSize += ( *(pWh1) - *(pWh1-1) ) + 1;
1393 bEqual = *pWh1 == *pWh2; // auch die 0 abpruefen
1395 // sind die Bereiche identisch, ist es effizieter zu handhaben !
1396 if( bEqual )
1398 SfxItemArray ppFnd1 = _aItems;
1399 SfxItemArray ppFnd2 = rSet._aItems;
1401 for( ; nSize; --nSize, ++ppFnd1, ++ppFnd2 )
1402 MergeItem_Impl( _pPool, _nCount, ppFnd1, *ppFnd2, bIgnoreDefaults );
1404 else
1406 SfxWhichIter aIter( rSet );
1407 register USHORT nWhich;
1408 while( 0 != ( nWhich = aIter.NextWhich() ) )
1410 const SfxPoolItem* pItem = 0;
1411 rSet.GetItemState( nWhich, TRUE, &pItem );
1412 if( !pItem )
1414 // nicht gesetzt, also default
1415 if ( !bIgnoreDefaults )
1416 MergeValue( rSet.GetPool()->GetDefaultItem( nWhich ), bIgnoreDefaults );
1418 else if( IsInvalidItem( pItem ) )
1419 // dont care
1420 InvalidateItem( nWhich );
1421 else
1422 MergeValue( *pItem, bIgnoreDefaults );
1427 // -----------------------------------------------------------------------
1429 void SfxItemSet::MergeValue( const SfxPoolItem& rAttr, BOOL bIgnoreDefaults )
1431 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1432 SfxItemArray ppFnd = _aItems;
1433 const USHORT* pPtr = _pWhichRanges;
1434 const USHORT nWhich = rAttr.Which();
1435 while( *pPtr )
1437 // in diesem Bereich?
1438 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
1440 ppFnd += nWhich - *pPtr;
1441 MergeItem_Impl( _pPool, _nCount, ppFnd, &rAttr, bIgnoreDefaults );
1442 break;
1444 ppFnd += *(pPtr+1) - *pPtr + 1;
1445 pPtr += 2;
1449 // -----------------------------------------------------------------------
1451 void SfxItemSet::InvalidateItem( USHORT nWhich )
1453 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1454 SfxItemArray ppFnd = _aItems;
1455 const USHORT* pPtr = _pWhichRanges;
1456 while( *pPtr )
1458 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
1460 // in diesem Bereich
1461 ppFnd += nWhich - *pPtr;
1463 if( *ppFnd ) // bei mir gesetzt
1465 if( (SfxPoolItem*)-1 != *ppFnd ) // noch nicht dontcare !
1467 _pPool->Remove( **ppFnd );
1468 *ppFnd = (SfxPoolItem*)-1;
1471 else
1473 *ppFnd = (SfxPoolItem*)-1;
1474 ++_nCount;
1476 break;
1478 ppFnd += *(pPtr+1) - *pPtr + 1;
1479 pPtr += 2;
1483 // -----------------------------------------------------------------------
1485 USHORT SfxItemSet::GetWhichByPos( USHORT nPos ) const
1487 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1488 USHORT n = 0;
1489 USHORT* pPtr = _pWhichRanges;
1490 while( *pPtr )
1492 n = ( *(pPtr+1) - *pPtr ) + 1;
1493 if( nPos < n )
1494 return *(pPtr)+nPos;
1495 nPos = nPos - n;
1496 pPtr += 2;
1498 DBG_ASSERT( FALSE, "Hier sind wir falsch" );
1499 return 0;
1502 // -----------------------------------------------------------------------
1504 SvStream &SfxItemSet::Store
1506 SvStream& rStream, // Zielstream f"ur normale Items
1507 FASTBOOL bDirect // TRUE: Items direkt speicher, FALSE: Surrogate
1508 ) const
1510 /* [Beschreibung]
1512 Speichert die <SfxItemSet>-Instanz in den angegebenen Stream. Dabei
1513 werden die Surrorage der gesetzten <SfxPoolItem>s bzw. ('bDirect==TRUE')
1514 die gesetzten Items selbst wie folgt im Stream abgelegt:
1516 USHORT (Count) Anzahl der gesetzten Items
1517 Count* _pPool->StoreItem() siehe <SfxItemPool::StoreItem()const>
1520 [Querverweise]
1522 <SfxItemSet::Load(SvStream&,BOOL,const SfxItemPool*)>
1526 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1527 DBG_ASSERT( _pPool, "Kein Pool" );
1528 DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "kein Master-Pool" );
1530 // Position des Counts merken, um ggf. zu korrigieren
1531 ULONG nCountPos = rStream.Tell();
1532 rStream << _nCount;
1534 // wenn nichts zu speichern ist, auch keinen ItemIter aufsetzen!
1535 if ( _nCount )
1537 // mitz"ahlen wieviel Items tats"achlich gespeichert werden
1538 USHORT nWrittenCount = 0; // Anzahl in 'rStream' gestreamter Items
1540 // "uber alle gesetzten Items iterieren
1541 SfxItemIter aIter(*this);
1542 for ( const SfxPoolItem *pItem = aIter.FirstItem();
1543 pItem;
1544 pItem = aIter.NextItem() )
1546 // Item (ggf. als Surrogat) via Pool speichern lassen
1547 DBG_ASSERT( !IsInvalidItem(pItem), "can't store invalid items" );
1548 if ( !IsInvalidItem(pItem) &&
1549 _pPool->StoreItem( rStream, *pItem, bDirect ) )
1550 // Item wurde in 'rStream' gestreamt
1551 ++nWrittenCount;
1554 // weniger geschrieben als enthalten (z.B. altes Format)
1555 if ( nWrittenCount != _nCount )
1557 // tats"achlichen Count im Stream ablegen
1558 ULONG nPos = rStream.Tell();
1559 rStream.Seek( nCountPos );
1560 rStream << nWrittenCount;
1561 rStream.Seek( nPos );
1565 return rStream;
1568 // -----------------------------------------------------------------------
1570 SvStream &SfxItemSet::Load
1572 SvStream& rStream, // Stream, aus dem geladen werden soll
1574 FASTBOOL bDirect, /* TRUE
1575 Items werden direkt aus dem Stream
1576 gelesen, nicht "uber Surrogate
1578 FALSE (default)
1579 Items werden "uber Surrogate gelesen */
1581 const SfxItemPool* pRefPool /* Pool, der die Surrogate aufl"osen kann
1582 (z.B. zum Einf"ugen von Dokumenten) */
1585 /* [Beschreibung]
1587 Diese Methode l"adt ein <SfxItemSet> aus einem Stream. Falls der
1588 <SfxItemPool> ohne Ref-Counts geladen wurde, werden die geladenen
1589 Item-Referenzen in den Items hochgez"ahlt, ansonsten wird vorausgesetzt,
1590 da\s sie schon beim Laden des SfxItemPools ber"ucksichtigt waren.
1592 [Querverweise]
1594 <SfxItemSet::Store(Stream&,BOOL)const>
1598 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1599 DBG_ASSERT( _pPool, "Kein Pool");
1600 DBG_ASSERTWARNING( _pPool == _pPool->GetMasterPool(), "Kein Master-Pool");
1602 // kein Ref-Pool => Surrogate mit Pool des ItemSets aufl"osen
1603 if ( !pRefPool )
1604 pRefPool = _pPool;
1606 // Anzahl der zu ladenden Items laden und dann ebensoviele Items
1607 USHORT nCount = 0;
1608 rStream >> nCount;
1609 for ( USHORT i = 0; i < nCount; ++i )
1611 // Surrogat/Item laden und (Surrogat) aufl"osen lassen
1612 const SfxPoolItem *pItem =
1613 _pPool->LoadItem( rStream, bDirect, pRefPool );
1615 // konnte ein Item geladen oder via Surrogat aufgel"ost werden?
1616 if ( pItem )
1618 // Position f"ur Item-Pointer im Set suchen
1619 USHORT nWhich = pItem->Which();
1620 SfxItemArray ppFnd = _aItems;
1621 const USHORT* pPtr = _pWhichRanges;
1622 while ( *pPtr )
1624 // in diesem Bereich?
1625 if ( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
1627 // Item-Pointer im Set merken
1628 ppFnd += nWhich - *pPtr;
1629 SFX_ASSERT( !*ppFnd, nWhich, "Item doppelt eingetragen");
1630 *ppFnd = pItem;
1631 ++_nCount;
1632 break;
1635 // im Range-Array und Item-Array zum n"achsten Which-Range
1636 ppFnd += *(pPtr+1) - *pPtr + 1;
1637 pPtr += 2;
1642 return rStream;
1645 // -----------------------------------------------------------------------
1647 int SfxItemSet::operator==(const SfxItemSet &rCmp) const
1649 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1650 DBG_CHKOBJ(&rCmp, SfxItemSet, DbgCheckItemSet);
1652 // besonders schnell zu ermittelnde Werte muessen gleich sein
1653 if ( _pParent != rCmp._pParent ||
1654 _pPool != rCmp._pPool ||
1655 Count() != rCmp.Count() )
1656 return FALSE;
1658 // Ranges durchzaehlen lassen dauert laenger, muss aber auch gleich sein
1659 USHORT nCount1 = TotalCount();
1660 USHORT nCount2 = rCmp.TotalCount();
1661 if ( nCount1 != nCount2 )
1662 return FALSE;
1664 // sind die Ranges selbst ungleich?
1665 for ( USHORT nRange = 0; _pWhichRanges[nRange]; nRange += 2 )
1666 if ( _pWhichRanges[nRange] != rCmp._pWhichRanges[nRange] ||
1667 _pWhichRanges[nRange+1] != rCmp._pWhichRanges[nRange+1] )
1669 // dann m"ussen wir die langsame Methode verwenden
1670 SfxWhichIter aIter( *this );
1671 for ( USHORT nWh = aIter.FirstWhich();
1672 nWh;
1673 nWh = aIter.NextWhich() )
1675 // wenn die Pointer von poolable Items ungleich sind,
1676 // muessen die Items gleich sein
1677 const SfxPoolItem *pItem1 = 0, *pItem2 = 0;
1678 if ( GetItemState( nWh, FALSE, &pItem1 ) !=
1679 rCmp.GetItemState( nWh, FALSE, &pItem2 ) ||
1680 ( pItem1 != pItem2 &&
1681 ( !pItem1 || IsInvalidItem(pItem1) ||
1682 ( _pPool->IsItemFlag(*pItem1, SFX_ITEM_POOLABLE) &&
1683 *pItem1 != *pItem2 ) ) ) )
1684 return FALSE;
1687 return TRUE;
1690 // Pointer alle gleich?
1691 if ( 0 == memcmp( _aItems, rCmp._aItems, nCount1 * sizeof(_aItems[0]) ) )
1692 return TRUE;
1694 // dann werden wir wohl alle einzeln vergleichen muessen
1695 const SfxPoolItem **ppItem1 = (const SfxPoolItem**) _aItems;
1696 const SfxPoolItem **ppItem2 = (const SfxPoolItem**) rCmp._aItems;
1697 for ( USHORT nPos = 0; nPos < nCount1; ++nPos )
1699 // wenn die Pointer von poolable Items ungleich sind,
1700 // muessen die Items gleich sein
1701 if ( *ppItem1 != *ppItem2 &&
1702 ( ( !*ppItem1 || !*ppItem2 ) ||
1703 ( IsInvalidItem(*ppItem1) || IsInvalidItem(*ppItem2) ) ||
1704 ( _pPool->IsItemFlag(**ppItem1, SFX_ITEM_POOLABLE) ) ||
1705 **ppItem1 != **ppItem2 ) )
1706 return FALSE;
1708 ++ppItem1;
1709 ++ppItem2;
1712 return TRUE;
1715 // -----------------------------------------------------------------------
1717 SfxItemSet *SfxItemSet::Clone(BOOL bItems, SfxItemPool *pToPool ) const
1719 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1720 if ( pToPool && pToPool != _pPool )
1722 SfxItemSet *pNewSet = new SfxItemSet( *pToPool, _pWhichRanges );
1723 if ( bItems )
1725 SfxWhichIter aIter(*pNewSet);
1726 USHORT nWhich = aIter.FirstWhich();
1727 while ( nWhich )
1729 const SfxPoolItem* pItem;
1730 if ( SFX_ITEM_SET == GetItemState( nWhich, FALSE, &pItem ) )
1731 pNewSet->Put( *pItem, pItem->Which() );
1732 nWhich = aIter.NextWhich();
1735 return pNewSet;
1737 else
1738 return bItems
1739 ? new SfxItemSet(*this)
1740 : new SfxItemSet(*_pPool, _pWhichRanges);
1743 // -----------------------------------------------------------------------
1745 int SfxItemSet::PutDirect(const SfxPoolItem &rItem)
1747 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
1748 SfxItemArray ppFnd = _aItems;
1749 const USHORT* pPtr = _pWhichRanges;
1750 const USHORT nWhich = rItem.Which();
1751 #ifdef DBG_UTIL
1752 IsPoolDefaultItem(&rItem) || _pPool->GetSurrogate(&rItem);
1753 // nur Assertion in den callees provozieren
1754 #endif
1755 while( *pPtr )
1757 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
1759 // in diesem Bereich
1760 ppFnd += nWhich - *pPtr;
1761 const SfxPoolItem* pOld = *ppFnd;
1762 if( pOld ) // schon einer vorhanden
1764 if( rItem == **ppFnd )
1765 return FALSE; // schon vorhanden !
1766 _pPool->Remove( *pOld );
1768 else
1769 ++_nCount;
1771 // den neuen eintragen
1772 if( IsPoolDefaultItem(&rItem) )
1773 *ppFnd = &_pPool->Put( rItem );
1774 else
1776 *ppFnd = &rItem;
1777 if( !IsStaticDefaultItem( &rItem ) )
1778 rItem.AddRef();
1781 return TRUE;
1783 ppFnd += *(pPtr+1) - *pPtr + 1;
1784 pPtr += 2;
1786 return FALSE;
1789 // -----------------------------------------------------------------------
1791 SfxAllItemSet::SfxAllItemSet( SfxItemPool &rPool )
1792 : SfxItemSet(rPool, (const USHORT*) 0),
1793 aDefault(0),
1794 nFree(nInitCount)
1796 // initial keine Items
1797 _aItems = 0;
1799 // nInitCount Paare an USHORTs fuer Ranges allozieren
1800 _pWhichRanges = new USHORT[ nInitCount + 1 ];
1801 memset( _pWhichRanges, 0, ( nInitCount + 1 ) * sizeof(USHORT) );
1805 // -----------------------------------------------------------------------
1808 SfxAllItemSet::SfxAllItemSet(const SfxItemSet &rCopy)
1809 : SfxItemSet(rCopy),
1810 aDefault(0),
1811 nFree(0)
1815 // -----------------------------------------------------------------------
1819 SfxAllItemSet::SfxAllItemSet(const SfxAllItemSet &rCopy)
1820 : SfxItemSet(rCopy),
1821 aDefault(0),
1822 nFree(0)
1823 /* [Anmerkung]
1825 Der mu\s sein, da sonst vom Compiler einer generiert wird, er nimmt
1826 nicht den Ctor mit der 'const SfxItemSet&'!
1831 // -----------------------------------------------------------------------
1833 static USHORT *AddRanges_Impl(
1834 USHORT *pUS, std::ptrdiff_t nOldSize, USHORT nIncr)
1836 /* Diese interne Funktion erzeugt ein neues Which-Range-Array, welches von
1837 dem 'nOldSize'-USHORTs langen 'pUS' kopiert wird und hinten an Platz
1838 f"ur 'nIncr' neue USHORTs hat. Das terminierende USHORT mit der '0'
1839 wird weder in 'nOldSize' noch in 'nIncr' mitgez"ahlt, sondern implizit
1840 hinzugerechnet.
1842 Das neue Which-Range-Array wird als Returnwert zur"uckgegeben, das alte
1843 'pUS' freigegeben.
1847 // neues Which-Range-Array anlegen
1848 USHORT *pNew = new USHORT[ nOldSize + nIncr + 1 ];
1850 // die alten Ranges "ubernehmen
1851 memcpy( pNew, pUS, nOldSize * sizeof(USHORT) );
1853 // die neuen auf 0 initialisieren
1854 memset( pNew + nOldSize, 0, ( nIncr + 1 ) * sizeof(USHORT) );
1856 // das alte Array freigeben
1857 delete[] pUS;
1859 return pNew;
1862 // -----------------------------------------------------------------------
1864 static SfxItemArray AddItem_Impl(SfxItemArray pItems, USHORT nOldSize, USHORT nPos)
1866 /* Diese interne Funktion erzeugt ein neues ItemArray, welches von 'pItems'
1867 kopiert wird, an der Position 'nPos' jedoch Platz f"ur einen neuen
1868 ItemPointer hat.
1870 Das neue ItemArray wird als Returnwert zur"uckgegeben, das alte 'pItems'
1871 wird freigegeben.
1875 // neues ItemArray anlegen
1876 SfxItemArray pNew = new const SfxPoolItem*[nOldSize+1];
1878 // war schon vorher eins da?
1879 if ( pItems )
1881 // alte Items vor nPos kopieren
1882 if ( nPos )
1883 memcpy( (void*) pNew, pItems, nPos * sizeof(SfxPoolItem **) );
1885 // alte Items hinter nPos kopieren
1886 if ( nPos < nOldSize )
1887 memcpy( (void*) (pNew + nPos + 1), pItems + nPos,
1888 (nOldSize-nPos) * sizeof(SfxPoolItem **) );
1891 // neues Item initialisieren
1892 *(pNew + nPos) = 0;
1894 // altes ItemArray freigeben
1895 delete[] pItems;
1897 return pNew;
1900 // -----------------------------------------------------------------------
1902 const SfxPoolItem* SfxAllItemSet::Put( const SfxPoolItem& rItem, USHORT nWhich )
1904 // Putten mit automatischer Erweiterung der Whichs-Ids um die ID
1905 // des Items.
1908 USHORT nPos = 0; // Position f"ur 'rItem' in '_aItems'
1909 const USHORT nItemCount = TotalCount();
1911 // erstmal sehen, ob es schon einen passenden Bereich gibt
1912 USHORT *pPtr = _pWhichRanges;
1913 while ( *pPtr )
1915 // Which-Id liegt in diesem Bereich?
1916 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
1918 // Einfuegen
1919 nPos += nWhich - *pPtr;
1920 break;
1923 // Position des Items in _aItems mitf"uhren
1924 nPos += *(pPtr+1) - *pPtr + 1;
1926 // zum n"achsten Bereich
1927 pPtr += 2;
1930 // Which-Id noch nicht vorhanden?
1931 if ( !*pPtr )
1933 // suchen, ob man sie irgendwo dranpacken kann
1934 pPtr = _pWhichRanges;
1935 nPos = 0;
1936 while ( *pPtr )
1938 // Which-Id liegt exakt vor diesem Bereich?
1939 if ( (nWhich+1) == *pPtr )
1941 // Bereich waechst nach unten
1942 (*pPtr)--;
1944 // vor erstem Item dieses Bereichs Platz schaffen
1945 _aItems = AddItem_Impl(_aItems, nItemCount, nPos);
1946 break;
1949 // Which-Id liegt exakt hinter diesem Bereich?
1950 else if ( (nWhich-1) == *(pPtr+1) )
1952 // Bereich waechst nach oben
1953 (*(pPtr+1))++;
1955 // hinter letztem Item dieses Bereichs Platz schaffen
1956 nPos += nWhich - *pPtr;
1957 _aItems = AddItem_Impl(_aItems, nItemCount, nPos);
1958 break;
1961 // Position des Items in _aItems mitf"uhren
1962 nPos += *(pPtr+1) - *pPtr + 1;
1964 // zum n"achsten Bereich
1965 pPtr += 2;
1969 // keinen erweiterbaren Bereich gefunden?
1970 if ( !*pPtr )
1972 // kein Platz mehr in _pWhichRanges => erweitern
1973 std::ptrdiff_t nSize = pPtr - _pWhichRanges;
1974 if( !nFree )
1976 _pWhichRanges = AddRanges_Impl(_pWhichRanges, nSize, nInitCount);
1977 nFree += nInitCount;
1980 // neuen Which-Range anh"angen
1981 pPtr = _pWhichRanges + nSize;
1982 *pPtr++ = nWhich;
1983 *pPtr = nWhich;
1984 nFree -= 2;
1986 // Itemarray vergroessern
1987 nPos = nItemCount;
1988 _aItems = AddItem_Impl(_aItems, nItemCount, nPos);
1991 // neues Item in Pool aufnehmen
1992 const SfxPoolItem& rNew = _pPool->Put( rItem, nWhich );
1994 // altes Item merken
1995 BOOL bIncrementCount = FALSE;
1996 const SfxPoolItem* pOld = *( _aItems + nPos );
1997 if ( reinterpret_cast< SfxPoolItem* >( -1 ) == pOld ) // state "dontcare"
1998 pOld = NULL;
1999 if ( !pOld )
2001 bIncrementCount = TRUE;
2002 pOld = _pParent ?
2003 &_pParent->Get( nWhich, TRUE )
2004 : nWhich <= SFX_WHICH_MAX ? &_pPool->GetDefaultItem( nWhich ) : 0;
2007 // neue Item in ItemSet aufnehmen
2008 *(_aItems + nPos) = &rNew;
2010 // Changed Notification versenden
2011 if ( pOld )
2013 Changed( *pOld, rNew );
2014 if ( !IsDefaultItem(pOld) )
2015 _pPool->Remove( *pOld );
2018 if ( bIncrementCount )
2019 ++_nCount;
2021 return &rNew;
2024 // -----------------------------------------------------------------------
2027 /* Diese Methode wird forwarded, damit sie nicht durch die anderen
2028 Put-Methoden dieser SubClass gehided wird.
2031 int SfxAllItemSet::Put( const SfxItemSet& rSet, BOOL bInvalidAsDefault )
2033 //? pruefen, ob Which-Ranges erweitert werden
2034 return SfxItemSet::Put( rSet, bInvalidAsDefault );
2037 // -----------------------------------------------------------------------
2038 // Item disablen, wenn durch ein VoidItem mit dem Which-Wert 0 ausgedrueckt
2040 void SfxItemSet::DisableItem(USHORT nWhich)
2042 DBG_CHKTHIS(SfxItemSet, 0);
2043 Put( SfxVoidItem(0), nWhich );
2046 // -----------------------------------------------------------------------
2048 #if 0
2049 BOOL SfxAllItemSet::Remove(USHORT nWhich)
2051 DBG_CHKTHIS(SfxAllItemSet, 0);
2052 USHORT *pPtr = _pWhichRanges;
2053 USHORT nPos = 0;
2054 while( *pPtr )
2056 if( *pPtr <= nWhich && nWhich <= *(pPtr+1) )
2058 USHORT *pTmp = pPtr;
2059 USHORT nLeft = 0;
2060 USHORT nRest = 0;
2061 while(*++pTmp){
2062 if( nLeft & 1 )
2063 nRest = *pTmp - *(pTmp-1) + 1;
2064 ++nLeft;
2067 // in diesem Bereich
2068 nPos += nWhich - *pPtr;
2069 nRest -= nWhich - *pPtr;
2070 // 3,3
2071 if(*pPtr == nWhich && *(pPtr+1) == nWhich) {
2072 memmove(pPtr, pPtr + 2, nLeft * sizeof(USHORT));
2073 nFree += 2;
2075 // Anfang
2076 else if(*pPtr == nWhich)
2077 (*pPtr)++;
2078 // Ende
2079 else if(*(pPtr+1) == nWhich)
2080 (*(pPtr+1))--;
2081 else {
2082 if(nPos + nRest + 2 > nFree) {
2083 USHORT nOf = pPtr - _pWhichRanges;
2084 _pWhichRanges = IncrSize(_pWhichRanges, nPos + nRest, nInitCount);
2085 nFree += nInitCount;
2086 pPtr = _pWhichRanges + nOf;
2088 memmove(pPtr +2, pPtr, (nLeft+2) * sizeof(USHORT));
2089 *++pPtr = nWhich-1;
2090 *++pPtr = nWhich+1;
2091 nFree -= 2;
2093 SfxPoolItem* pItem = *( _aItems + nPos );
2094 if( pItem )
2096 if(_pPool)
2097 _pPool->Remove(*pItem );
2098 else
2099 delete pItem;
2100 --_nCount;
2102 memmove(_aItems + nPos +1, _aItems + nPos,
2103 sizeof(SfxPoolItem *) * (nRest - 1));
2104 break; // dann beim Parent suchen
2106 nPos += *(pPtr+1) - *pPtr + 1;
2107 pPtr += 2;
2109 return *pPtr? TRUE: FALSE;
2111 #endif
2113 // -----------------------------------------------------------------------
2115 SfxItemSet *SfxAllItemSet::Clone(BOOL bItems, SfxItemPool *pToPool ) const
2117 DBG_CHKTHIS(SfxItemSet, DbgCheckItemSet);
2118 if ( pToPool && pToPool != _pPool )
2120 SfxAllItemSet *pNewSet = new SfxAllItemSet( *pToPool );
2121 if ( bItems )
2122 pNewSet->Set( *this );
2123 return pNewSet;
2125 else
2126 return bItems ? new SfxAllItemSet(*this) : new SfxAllItemSet(*_pPool);