GPU-Calc: remove Alloc_Host_Ptr for clmem of NAN vector
[LibreOffice.git] / svl / source / items / itempool.cxx
blob83e2e12655abf09c86026ea6155e04d564e58db9
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <string.h>
22 #include <stdio.h>
24 #include <svl/itempool.hxx>
25 #include "whassert.hxx"
26 #include <svl/brdcst.hxx>
27 #include <svl/smplhint.hxx>
28 #include "poolio.hxx"
31 #if OSL_DEBUG_LEVEL > 0
32 #include <map>
34 static void
35 lcl_CheckSlots2(std::map<sal_uInt16, sal_uInt16> & rSlotMap,
36 SfxItemPool const& rPool, SfxItemInfo const* pInfos)
38 if (!pInfos)
39 return; // may not be initialized yet
40 if (rPool.GetName() == "EditEngineItemPool")
41 return; // HACK: this one has loads of duplicates already, ignore it :(
42 sal_uInt16 const nFirst(rPool.GetFirstWhich());
43 sal_uInt16 const nCount(rPool.GetLastWhich() - rPool.GetFirstWhich() + 1);
44 for (sal_uInt16 n = 0; n < nCount; ++n)
46 sal_uInt16 const nSlotId(pInfos[n]._nSID);
47 if (nSlotId != 0
48 && nSlotId != 10883 // preexisting duplicate SID_ATTR_GRAF_CROP
49 && nSlotId != 10024) // preexisting duplicate SID_ATTR_BORDER_OUTER
50 { // check for duplicate slot-id mapping
51 std::map<sal_uInt16, sal_uInt16>::const_iterator const iter(
52 rSlotMap.find(nSlotId));
53 sal_uInt16 const nWhich(nFirst + n);
54 if (iter != rSlotMap.end())
56 SAL_WARN("svl", "SfxItemPool: duplicate SlotId " << nSlotId
57 << " mapped to " << iter->second << " and " << nWhich);
58 assert(false);
60 rSlotMap.insert(std::make_pair(nSlotId, nWhich));
65 #define CHECK_SLOTS() \
66 do { \
67 std::map<sal_uInt16, sal_uInt16> slotmap; \
68 for (SfxItemPool * p = pImp->mpMaster; p; p = p->pImp->mpSecondary) \
69 { \
70 lcl_CheckSlots2(slotmap, *p, p->pItemInfos); \
71 } \
72 } while (false)
74 #else
75 #define CHECK_SLOTS() do {} while (false)
76 #endif
79 void SfxItemPool::AddSfxItemPoolUser(SfxItemPoolUser& rNewUser)
81 pImp->maSfxItemPoolUsers.push_back(&rNewUser);
84 void SfxItemPool::RemoveSfxItemPoolUser(SfxItemPoolUser& rOldUser)
86 const std::vector<SfxItemPoolUser*>::iterator aFindResult = ::std::find(
87 pImp->maSfxItemPoolUsers.begin(), pImp->maSfxItemPoolUsers.end(), &rOldUser);
88 if(aFindResult != pImp->maSfxItemPoolUsers.end())
90 pImp->maSfxItemPoolUsers.erase(aFindResult);
94 const SfxPoolItem* SfxItemPool::GetPoolDefaultItem( sal_uInt16 nWhich ) const
96 DBG_CHKTHIS(SfxItemPool, 0);
97 const SfxPoolItem* pRet;
98 if( IsInRange( nWhich ) )
99 pRet = *(pImp->ppPoolDefaults + GetIndex_Impl( nWhich ));
100 else if( pImp->mpSecondary )
101 pRet = pImp->mpSecondary->GetPoolDefaultItem( nWhich );
102 else
104 SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get pool default" );
105 pRet = 0;
107 return pRet;
110 // -----------------------------------------------------------------------
112 bool SfxItemPool::IsItemFlag_Impl( sal_uInt16 nPos, sal_uInt16 nFlag ) const
114 sal_uInt16 nItemFlag = pItemInfos[nPos]._nFlags;
115 return nFlag == (nItemFlag & nFlag);
118 // -----------------------------------------------------------------------
120 bool SfxItemPool::IsItemFlag( sal_uInt16 nWhich, sal_uInt16 nFlag ) const
122 for ( const SfxItemPool *pPool = this; pPool; pPool = pPool->pImp->mpSecondary )
124 if ( pPool->IsInRange(nWhich) )
125 return pPool->IsItemFlag_Impl( pPool->GetIndex_Impl(nWhich), nFlag);
127 DBG_ASSERT( !IsWhich(nWhich), "unknown which-id" );
128 return sal_False;
131 // -----------------------------------------------------------------------
133 SfxBroadcaster& SfxItemPool::BC()
135 return pImp->aBC;
138 // -----------------------------------------------------------------------
141 SfxItemPool::SfxItemPool
143 const OUString& rName, /* Name des Pools zur Idetifikation
144 im File-Format */
145 sal_uInt16 nStartWhich, /* erste Which-Id des Pools */
146 sal_uInt16 nEndWhich, /* letzte Which-Id des Pools */
147 const SfxItemInfo* pInfos, /* SID-Map und Item-Flags */
148 SfxPoolItem** pDefaults, /* Pointer auf statische Defaults,
149 wird direkt vom Pool referenziert,
150 jedoch kein Eigent"umer"ubergang */
151 bool bLoadRefCounts /* Ref-Counts mitladen oder auf 1 setzen */
154 /* [Beschreibung]
156 Der im Normalfall verwendete Konstruktor der Klasse SfxItemPool. Es
157 wird eine SfxItemPool-Instanz initialisiert, die Items im b"undigen
158 Which-Bereich von 'nStartWhich' bis 'nEndWhich' verwalten kann.
160 F"ur jede dieser Which-Ids mu\s ein statischer Default im Array 'pDefaults'
161 vorhanden sein, die dort beginnend mit einem <SfxPoolItem> mit der
162 Which-Id 'nStartWhich' nach Which-Ids sortiert aufeinanderfolgend
163 eingetragen sein m"ussen.
165 'pItemInfos' ist ein identisch angeordnetes Array von USHORTs, die
166 Slot-Ids darstellen und Flags. Die Slot-Ids k"onnen 0 sein, wenn die
167 betreffenden Items ausschlie\slich in der Core verwendet werden.
168 "Uber die Flags kann z.B. bestimmt werden, ob Value-Sharing
169 (SFX_ITEM_POOLABLE) stattfinden soll.
171 [Anmerkung]
173 Wenn der Pool <SfxSetItem>s enthalten soll, k"onnen im Konstruktor noch
174 keine static-Defaults angegeben werden. Dies mu\s dann nachtr"aglich
175 mit <SfxItemPool::SetDefaults(SfxItemPool**)> geschehen.
178 [Querverweise]
180 <SfxItemPool::SetDefaults(SfxItemPool**)>
181 <SfxItemPool::ReleaseDefaults(SfxPoolItem**,sal_uInt16,sal_Bool)>
182 <SfxItemPool::ReldaseDefaults(sal_Bool)>
185 pItemInfos(pInfos),
186 pImp( new SfxItemPool_Impl( this, rName, nStartWhich, nEndWhich ) )
188 DBG_CTOR(SfxItemPool, 0);
190 pImp->eDefMetric = SFX_MAPUNIT_TWIP;
191 pImp->nVersion = 0;
192 pImp->bStreaming = false;
193 pImp->nLoadingVersion = 0;
194 pImp->nInitRefCount = 1;
195 pImp->nVerStart = pImp->mnStart;
196 pImp->nVerEnd = pImp->mnEnd;
197 pImp->bInSetItem = false;
198 pImp->nStoringStart = nStartWhich;
199 pImp->nStoringEnd = nEndWhich;
200 pImp->mbPersistentRefCounts = bLoadRefCounts;
202 if ( pDefaults )
203 SetDefaults(pDefaults);
206 // -----------------------------------------------------------------------
209 SfxItemPool::SfxItemPool
211 const SfxItemPool& rPool, // von dieser Instanz kopieren
212 sal_Bool bCloneStaticDefaults /* sal_True
213 statische Defaults kopieren
215 sal_False
216 statische Defaults
217 "ubernehehmen */
220 /* [Beschreibung]
222 Copy-Konstruktor der Klasse SfxItemPool.
225 [Querverweise]
227 <SfxItemPool::Clone()const>
230 pItemInfos(rPool.pItemInfos),
231 pImp( new SfxItemPool_Impl( this, rPool.pImp->aName, rPool.pImp->mnStart, rPool.pImp->mnEnd ) )
233 DBG_CTOR(SfxItemPool, 0);
234 pImp->eDefMetric = rPool.pImp->eDefMetric;
235 pImp->nVersion = rPool.pImp->nVersion;
236 pImp->bStreaming = sal_False;
237 pImp->nLoadingVersion = 0;
238 pImp->nInitRefCount = 1;
239 pImp->nVerStart = rPool.pImp->nVerStart;
240 pImp->nVerEnd = rPool.pImp->nVerEnd;
241 pImp->bInSetItem = false;
242 pImp->nStoringStart = pImp->mnStart;
243 pImp->nStoringEnd = pImp->mnEnd;
244 pImp->mbPersistentRefCounts = rPool.pImp->mbPersistentRefCounts;
246 // Static Defaults "ubernehmen
247 if ( bCloneStaticDefaults )
249 SfxPoolItem **ppDefaults = new SfxPoolItem*[pImp->mnEnd-pImp->mnStart+1];
250 for ( sal_uInt16 n = 0; n <= pImp->mnEnd - pImp->mnStart; ++n )
252 (*( ppDefaults + n )) = (*( rPool.pImp->ppStaticDefaults + n ))->Clone(this);
253 (*( ppDefaults + n ))->SetKind( SFX_ITEMS_STATICDEFAULT );
256 SetDefaults( ppDefaults );
258 else
259 SetDefaults( rPool.pImp->ppStaticDefaults );
261 // Pool Defaults kopieren
262 for ( sal_uInt16 n = 0; n <= pImp->mnEnd - pImp->mnStart; ++n )
263 if ( (*( rPool.pImp->ppPoolDefaults + n )) )
265 (*( pImp->ppPoolDefaults + n )) = (*( rPool.pImp->ppPoolDefaults + n ))->Clone(this);
266 (*( pImp->ppPoolDefaults + n ))->SetKind( SFX_ITEMS_POOLDEFAULT );
269 // Copy Version-Map
270 for ( size_t nVer = 0; nVer < rPool.pImp->aVersions.size(); ++nVer )
272 const SfxPoolVersion_ImplPtr pOld = rPool.pImp->aVersions[nVer];
273 SfxPoolVersion_ImplPtr pNew = SfxPoolVersion_ImplPtr( new SfxPoolVersion_Impl( *pOld ) );
274 pImp->aVersions.push_back( pNew );
277 // Verkettung wiederherstellen
278 if ( rPool.pImp->mpSecondary )
279 SetSecondaryPool( rPool.pImp->mpSecondary->Clone() );
282 // -----------------------------------------------------------------------
284 void SfxItemPool::SetDefaults( SfxPoolItem **pDefaults )
286 DBG_CHKTHIS(SfxItemPool, 0);
287 DBG_ASSERT( pDefaults, "erst wollen, dann nichts geben..." );
288 DBG_ASSERT( !pImp->ppStaticDefaults, "habe schon defaults" );
290 pImp->ppStaticDefaults = pDefaults;
291 //! if ( (*ppStaticDefaults)->GetKind() != SFX_ITEMS_STATICDEFAULT )
292 //! geht wohl nicht im Zshg mit SetItems, die hinten stehen
294 DBG_ASSERT( (*pImp->ppStaticDefaults)->GetRefCount() == 0 ||
295 IsDefaultItem( (*pImp->ppStaticDefaults) ),
296 "das sind keine statics" );
297 for ( sal_uInt16 n = 0; n <= pImp->mnEnd - pImp->mnStart; ++n )
299 SFX_ASSERT( (*( pImp->ppStaticDefaults + n ))->Which() == n + pImp->mnStart,
300 n + pImp->mnStart, "static defaults not sorted" );
301 (*( pImp->ppStaticDefaults + n ))->SetKind( SFX_ITEMS_STATICDEFAULT );
302 DBG_ASSERT( !(pImp->maPoolItems[n]), "defaults with setitems with items?!" );
307 // -----------------------------------------------------------------------
309 void SfxItemPool::ReleaseDefaults
311 sal_Bool bDelete /* sal_True
312 l"oscht sowohl das Array als auch die einzelnen
313 statischen Defaults
315 sal_False
316 l"oscht weder das Array noch die einzelnen
317 statischen Defaults */
320 /* [Beschreibung]
322 Gibt die statischen Defaults der betreffenden SfxItemPool-Instanz frei
323 und l"oscht ggf. die statischen Defaults.
325 Nach Aufruf dieser Methode darf die SfxItemPool-Instanz nicht mehr
326 verwendet werden, einzig ist der Aufruf des Destruktors zu"lassig.
330 DBG_ASSERT( pImp->ppStaticDefaults, "keine Arme keine Kekse" );
331 ReleaseDefaults( pImp->ppStaticDefaults, pImp->mnEnd - pImp->mnStart + 1, bDelete );
333 // KSO (22.10.98): ppStaticDefaults zeigt auf geloeschten Speicher,
334 // wenn bDelete == sal_True.
335 if ( bDelete )
336 pImp->ppStaticDefaults = 0;
339 // -----------------------------------------------------------------------
341 void SfxItemPool::ReleaseDefaults
343 SfxPoolItem** pDefaults, /* freizugebende statische Defaults */
345 sal_uInt16 nCount, /* Anzahl der statischen Defaults */
347 sal_Bool bDelete /* sal_True
348 l"oscht sowohl das Array als auch die
349 einzelnen statischen Defaults
351 sal_False
352 l"oscht weder das Array noch die
353 einzelnen statischen Defaults */
356 /* [Beschreibung]
358 Gibt die angegebenen statischen Defaults frei und l"oscht ggf.
359 die statischen Defaults.
361 Diese Methode darf erst nach Zerst"orung aller SfxItemPool-Instanzen,
362 welche die angegebenen statischen Defaults 'pDefault' verwenden,
363 aufgerufen werden.
367 DBG_ASSERT( pDefaults, "erst wollen, dann nichts geben..." );
369 for ( sal_uInt16 n = 0; n < nCount; ++n )
371 SFX_ASSERT( IsStaticDefaultItem( *(pDefaults+n) ),
372 n, "das ist kein static-default" );
373 (*( pDefaults + n ))->SetRefCount( 0 );
374 if ( bDelete )
375 { delete *( pDefaults + n ); *(pDefaults + n) = 0; }
378 if ( bDelete )
379 { delete[] pDefaults; pDefaults = 0; }
382 // -----------------------------------------------------------------------
384 SfxItemPool::~SfxItemPool()
386 DBG_DTOR(SfxItemPool, 0);
388 if ( !pImp->maPoolItems.empty() && pImp->ppPoolDefaults )
389 Delete();
391 if (pImp->mpMaster != NULL && pImp->mpMaster != this)
393 // This condition indicates an error. A
394 // pImp->mpMaster->SetSecondaryPool(...) call should have been made
395 // earlier to prevent this. At this point we can only try to
396 // prevent a crash later on.
397 DBG_ASSERT( pImp->mpMaster == this, "destroying active Secondary-Pool" );
398 if (pImp->mpMaster->pImp->mpSecondary == this)
399 pImp->mpMaster->pImp->mpSecondary = NULL;
402 delete pImp;
405 void SfxItemPool::Free(SfxItemPool* pPool)
407 if(pPool)
409 // tell all the registered SfxItemPoolUsers that the pool is in destruction
410 std::vector<SfxItemPoolUser*> aListCopy(pPool->pImp->maSfxItemPoolUsers.begin(), pPool->pImp->maSfxItemPoolUsers.end());
411 for(std::vector<SfxItemPoolUser*>::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); ++aIterator)
413 SfxItemPoolUser* pSfxItemPoolUser = *aIterator;
414 DBG_ASSERT(pSfxItemPoolUser, "corrupt SfxItemPoolUser list (!)");
415 pSfxItemPoolUser->ObjectInDestruction(*pPool);
418 // Clear the vector. This means that user do not need to call RemoveSfxItemPoolUser()
419 // when they get called from ObjectInDestruction().
420 pPool->pImp->maSfxItemPoolUsers.clear();
422 // delete pool
423 delete pPool;
427 // -----------------------------------------------------------------------
430 void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool )
432 // ggf. an abgeh"angten Pools den Master zur"ucksetzen
433 if ( pImp->mpSecondary )
435 #ifdef DBG_UTIL
436 SAL_INFO( "svl.items", "fuer Image, dort gibt es derzeit keine Statics - Bug" );
437 if ( pImp->ppStaticDefaults )
439 // Delete() ist noch nicht gelaufen?
440 if ( !pImp->maPoolItems.empty() && !pImp->mpSecondary->pImp->maPoolItems.empty() )
442 // hat der master SetItems?
443 bool bHasSetItems = false;
444 for ( sal_uInt16 i = 0; !bHasSetItems && i < pImp->mnEnd - pImp->mnStart; ++i )
445 bHasSetItems = pImp->ppStaticDefaults[i]->ISA(SfxSetItem);
447 // abgehaengte Pools muessen leer sein
448 bool bOK = bHasSetItems;
449 for ( sal_uInt16 n = 0;
450 bOK && n <= pImp->mpSecondary->pImp->mnEnd - pImp->mpSecondary->pImp->mnStart;
451 ++n )
453 SfxPoolItemArray_Impl* pItemArr = pImp->mpSecondary->pImp->maPoolItems[n];
454 if ( pItemArr )
456 SfxPoolItemArrayBase_Impl::iterator ppHtArr = pItemArr->begin();
457 for( size_t i = pItemArr->size(); i; ++ppHtArr, --i )
458 if ( !(*ppHtArr) )
460 OSL_FAIL( "old secondary pool must be empty" );
461 bOK = false;
462 break;
468 #endif
470 pImp->mpSecondary->pImp->mpMaster = pImp->mpSecondary;
471 for ( SfxItemPool *p = pImp->mpSecondary->pImp->mpSecondary; p; p = p->pImp->mpSecondary )
472 p->pImp->mpMaster = pImp->mpSecondary;
475 // ggf. den Master der neuen Secondary-Pools setzen
476 DBG_ASSERT( !pPool || pPool->pImp->mpMaster == pPool, "Secondary tanzt auf zwei Hochzeiten " );
477 SfxItemPool *pNewMaster = pImp->mpMaster ? pImp->mpMaster : this;
478 for ( SfxItemPool *p = pPool; p; p = p->pImp->mpSecondary )
479 p->pImp->mpMaster = pNewMaster;
481 // neuen Secondary-Pool merken
482 pImp->mpSecondary = pPool;
484 CHECK_SLOTS();
487 void SfxItemPool::SetItemInfos(SfxItemInfo const*const pInfos)
489 pItemInfos = pInfos;
490 CHECK_SLOTS();
493 // -----------------------------------------------------------------------
495 SfxMapUnit SfxItemPool::GetMetric( sal_uInt16 ) const
497 DBG_CHKTHIS(SfxItemPool, 0);
499 return pImp->eDefMetric;
502 // -----------------------------------------------------------------------
504 void SfxItemPool::SetDefaultMetric( SfxMapUnit eNewMetric )
506 DBG_CHKTHIS(SfxItemPool, 0);
508 pImp->eDefMetric = eNewMetric;
511 const OUString& SfxItemPool::GetName() const
513 return pImp->aName;
516 // -----------------------------------------------------------------------
518 SfxItemPresentation SfxItemPool::GetPresentation
520 const SfxPoolItem& rItem,
521 SfxItemPresentation ePresent,
522 SfxMapUnit eMetric,
523 OUString& rText,
524 const IntlWrapper * pIntlWrapper
525 ) const
527 DBG_CHKTHIS(SfxItemPool, 0);
528 return rItem.GetPresentation(
529 ePresent, GetMetric(rItem.Which()), eMetric, rText, pIntlWrapper );
533 // -----------------------------------------------------------------------
535 SfxItemPool* SfxItemPool::Clone() const
537 DBG_CHKTHIS(SfxItemPool, 0);
539 SfxItemPool *pPool = new SfxItemPool( *this );
540 return pPool;
543 // ----------------------------------------------------------------------
545 void SfxItemPool::Delete()
547 DBG_CHKTHIS(SfxItemPool, 0);
549 // schon deleted?
550 if ( pImp->maPoolItems.empty() || !pImp->ppPoolDefaults )
551 return;
553 // z.B. laufenden Requests bescheidsagen
554 pImp->aBC.Broadcast( SfxSimpleHint( SFX_HINT_DYING ) );
556 //MA 16. Apr. 97: Zweimal durchlaufen, in der ersten Runde fuer die SetItems.
557 //Der Klarheit halber wird das jetzt in zwei besser lesbare Schleifen aufgeteilt.
559 std::vector<SfxPoolItemArray_Impl*>::iterator itrItemArr = pImp->maPoolItems.begin();
560 SfxPoolItem** ppDefaultItem = pImp->ppPoolDefaults;
561 SfxPoolItem** ppStaticDefaultItem = pImp->ppStaticDefaults;
562 sal_uInt16 nArrCnt;
564 //Erst die SetItems abraeumen
565 SAL_INFO( "svl.items", "fuer Image, dort gibt es derzeit keine Statics - Bug" );
566 if ( pImp->ppStaticDefaults )
568 for ( nArrCnt = GetSize_Impl();
569 nArrCnt;
570 --nArrCnt, ++itrItemArr, ++ppDefaultItem, ++ppStaticDefaultItem )
572 // KSO (22.10.98): *ppStaticDefaultItem kann im dtor einer
573 // von SfxItemPool abgeleiteten Klasse bereits geloescht worden
574 // sein! -> CHAOS Itempool
575 if ( *ppStaticDefaultItem && (*ppStaticDefaultItem)->ISA(SfxSetItem) )
577 if ( *itrItemArr )
579 SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*itrItemArr)->begin();
580 for ( size_t n = (*itrItemArr)->size(); n; --n, ++ppHtArr )
581 if (*ppHtArr)
583 #ifdef DBG_UTIL
584 ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() );
585 #endif
586 delete *ppHtArr;
588 DELETEZ( *itrItemArr );
590 if ( *ppDefaultItem )
592 #ifdef DBG_UTIL
593 SetRefCount( **ppDefaultItem, 0 );
594 #endif
595 DELETEZ( *ppDefaultItem );
601 itrItemArr = pImp->maPoolItems.begin();
602 ppDefaultItem = pImp->ppPoolDefaults;
604 //Jetzt die 'einfachen' Items
605 for ( nArrCnt = GetSize_Impl();
606 nArrCnt;
607 --nArrCnt, ++itrItemArr, ++ppDefaultItem )
609 if ( *itrItemArr )
611 SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*itrItemArr)->begin();
612 for ( size_t n = (*itrItemArr)->size(); n; --n, ++ppHtArr )
613 if (*ppHtArr)
615 #ifdef DBG_UTIL
616 ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() );
617 #endif
618 delete *ppHtArr;
620 DELETEZ( *itrItemArr );
622 if ( *ppDefaultItem )
624 #ifdef DBG_UTIL
625 SetRefCount( **ppDefaultItem, 0 );
626 #endif
627 delete *ppDefaultItem;
631 pImp->DeleteItems();
634 // ----------------------------------------------------------------------
636 void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem &rItem)
638 DBG_CHKTHIS(SfxItemPool, 0);
639 if ( IsInRange(rItem.Which()) )
641 SfxPoolItem **ppOldDefault =
642 pImp->ppPoolDefaults + GetIndex_Impl(rItem.Which());
643 SfxPoolItem *pNewDefault = rItem.Clone(this);
644 pNewDefault->SetKind(SFX_ITEMS_POOLDEFAULT);
645 if ( *ppOldDefault )
647 (*ppOldDefault)->SetRefCount(0);
648 DELETEZ( *ppOldDefault );
650 *ppOldDefault = pNewDefault;
652 else if ( pImp->mpSecondary )
653 pImp->mpSecondary->SetPoolDefaultItem(rItem);
654 else
656 SFX_ASSERT( 0, rItem.Which(), "unknown Which-Id - cannot set pool default" );
661 * Resets the default of the given <Which-Id> back to the static default.
662 * If a pool default exists it is removed.
664 void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 nWhichId )
666 DBG_CHKTHIS(SfxItemPool, 0);
667 if ( IsInRange(nWhichId) )
669 SfxPoolItem **ppOldDefault =
670 pImp->ppPoolDefaults + GetIndex_Impl( nWhichId );
671 if ( *ppOldDefault )
673 (*ppOldDefault)->SetRefCount(0);
674 DELETEZ( *ppOldDefault );
677 else if ( pImp->mpSecondary )
678 pImp->mpSecondary->ResetPoolDefaultItem(nWhichId);
679 else
681 SFX_ASSERT( 0, nWhichId, "unknown Which-Id - cannot set pool default" );
685 // -----------------------------------------------------------------------
687 const SfxPoolItem& SfxItemPool::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
689 DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
690 0 != &((const SfxSetItem&)rItem).GetItemSet(),
691 "SetItem without ItemSet" );
693 DBG_CHKTHIS(SfxItemPool, 0);
694 if ( 0 == nWhich )
695 nWhich = rItem.Which();
697 // richtigen Secondary-Pool finden
698 bool bSID = nWhich > SFX_WHICH_MAX;
699 if ( !bSID && !IsInRange(nWhich) )
701 if ( pImp->mpSecondary )
702 return pImp->mpSecondary->Put( rItem, nWhich );
703 OSL_FAIL( "unknown Which-Id - cannot put item" );
706 // SID oder nicht poolable (neue Definition)?
707 sal_uInt16 nIndex = bSID ? USHRT_MAX : GetIndex_Impl(nWhich);
708 if ( USHRT_MAX == nIndex ||
709 IsItemFlag_Impl( nIndex, SFX_ITEM_NOT_POOLABLE ) )
711 SFX_ASSERT( USHRT_MAX != nIndex || rItem.Which() != nWhich ||
712 !IsDefaultItem(&rItem) || rItem.GetKind() == SFX_ITEMS_DELETEONIDLE,
713 nWhich, "ein nicht Pool-Item ist Default?!" );
714 SfxPoolItem *pPoolItem = rItem.Clone(pImp->mpMaster);
715 pPoolItem->SetWhich(nWhich);
716 AddRef( *pPoolItem );
717 return *pPoolItem;
720 SFX_ASSERT( rItem.IsA(GetDefaultItem(nWhich).Type()), nWhich,
721 "SFxItemPool: wrong item type in Put" );
723 SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[nIndex];
724 if (!pItemArr)
726 pImp->maPoolItems[nIndex] = new SfxPoolItemArray_Impl;
727 pItemArr = pImp->maPoolItems[nIndex];
730 SfxPoolItemArrayBase_Impl::iterator ppFree;
731 bool ppFreeIsSet = false;
732 if ( IsItemFlag_Impl( nIndex, SFX_ITEM_POOLABLE ) )
734 // wenn es ueberhaupt gepoolt ist, koennte es schon drin sein
735 if ( IsPooledItem(&rItem) )
737 // 1. Schleife: teste ob der Pointer vorhanden ist.
738 SfxPoolItemArrayBase_Impl::iterator itr =
739 std::find(pItemArr->begin(), pItemArr->end(), &rItem);
740 if (itr != pItemArr->end())
742 AddRef(**itr);
743 return **itr;
747 // 2. Schleife: dann muessen eben die Attribute verglichen werden
748 SfxPoolItemArrayBase_Impl::iterator itr = pItemArr->begin();
749 for (; itr != pItemArr->end(); ++itr)
751 if (*itr)
753 if (**itr == rItem)
755 AddRef(**itr);
756 return **itr;
759 else
761 if (!ppFreeIsSet)
763 ppFree = itr;
764 ppFreeIsSet = true;
769 else
771 // freien Platz suchen
772 SfxPoolItemArrayBase_Impl::iterator itr = pItemArr->begin();
773 std::advance(itr, pItemArr->nFirstFree);
774 for (; itr != pItemArr->end(); ++itr)
776 if (!*itr)
778 ppFree = itr;
779 ppFreeIsSet = true;
780 break;
783 // naechstmoeglichen freien Platz merken
784 pItemArr->nFirstFree = std::distance(pItemArr->begin(), itr);
787 // nicht vorhanden, also im PtrArray eintragen
788 SfxPoolItem* pNewItem = rItem.Clone(pImp->mpMaster);
789 pNewItem->SetWhich(nWhich);
790 #ifdef DBG_UTIL
791 SFX_ASSERT( rItem.Type() == pNewItem->Type(), nWhich, "unequal types in Put(): no Clone()?" )
792 if ( !rItem.ISA(SfxSetItem) )
794 SFX_ASSERT( !IsItemFlag(nWhich, SFX_ITEM_POOLABLE) ||
795 rItem == *pNewItem,
796 nWhich, "unequal items in Put(): no operator==?" );
797 SFX_ASSERT( !IsItemFlag(*pNewItem, SFX_ITEM_POOLABLE) ||
798 *pNewItem == rItem,
799 nWhich, "unequal items in Put(): no operator==?" );
801 #endif
802 AddRef( *pNewItem, pImp->nInitRefCount );
804 if ( ppFreeIsSet == false )
805 pItemArr->push_back( pNewItem );
806 else
808 DBG_ASSERT( *ppFree == 0, "using surrogate in use" );
809 *ppFree = pNewItem;
811 return *pNewItem;
814 // -----------------------------------------------------------------------
816 void SfxItemPool::Remove( const SfxPoolItem& rItem )
818 DBG_CHKTHIS(SfxItemPool, 0);
820 DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
821 0 != &((const SfxSetItem&)rItem).GetItemSet(),
822 "SetItem without ItemSet" );
824 SFX_ASSERT( !IsPoolDefaultItem(&rItem), rItem.Which(),
825 "wo kommt denn hier ein Pool-Default her" );
827 // richtigen Secondary-Pool finden
828 const sal_uInt16 nWhich = rItem.Which();
829 bool bSID = nWhich > SFX_WHICH_MAX;
830 if ( !bSID && !IsInRange(nWhich) )
832 if ( pImp->mpSecondary )
834 pImp->mpSecondary->Remove( rItem );
835 return;
837 OSL_FAIL( "unknown Which-Id - cannot remove item" );
840 // SID oder nicht poolable (neue Definition)?
841 sal_uInt16 nIndex = bSID ? USHRT_MAX : GetIndex_Impl(nWhich);
842 if ( bSID || IsItemFlag_Impl( nIndex, SFX_ITEM_NOT_POOLABLE ) )
844 SFX_ASSERT( USHRT_MAX != nIndex ||
845 !IsDefaultItem(&rItem), rItem.Which(),
846 "ein nicht Pool-Item ist Default?!" );
847 if ( 0 == ReleaseRef(rItem) )
849 SfxPoolItem *pItem = &(SfxPoolItem &)rItem;
850 delete pItem;
852 return;
855 SFX_ASSERT( rItem.GetRefCount(), rItem.Which(), "RefCount == 0, Remove unmoeglich" );
857 // statische Defaults sind eben einfach da
858 if ( rItem.GetKind() == SFX_ITEMS_STATICDEFAULT &&
859 &rItem == *( pImp->ppStaticDefaults + GetIndex_Impl(nWhich) ) )
860 return;
862 // Item im eigenen Pool suchen
863 SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[nIndex];
864 SFX_ASSERT( pItemArr, rItem.Which(), "removing Item not in Pool" );
865 SfxPoolItemArrayBase_Impl::iterator ppHtArrBeg = pItemArr->begin(), ppHtArrEnd = pItemArr->end();
866 for (SfxPoolItemArrayBase_Impl::iterator ppHtArr = ppHtArrBeg; ppHtArr != ppHtArrEnd; ++ppHtArr)
868 SfxPoolItem*& p = *ppHtArr;
869 if (p == &rItem)
871 if ( p->GetRefCount() ) //!
872 ReleaseRef( *p );
873 else
875 SFX_ASSERT( 0, rItem.Which(), "removing Item without ref" );
878 // ggf. kleinstmoegliche freie Position merken
879 size_t nPos = std::distance(ppHtArrBeg, ppHtArr);
880 if ( pItemArr->nFirstFree > nPos )
881 pItemArr->nFirstFree = nPos;
883 //! MI: Hack, solange wir das Problem mit dem Outliner haben
884 //! siehe anderes MI-REF
885 if ( 0 == p->GetRefCount() && nWhich < 4000 )
886 DELETEZ(p);
887 return;
891 // nicht vorhanden
892 SFX_ASSERT( 0, rItem.Which(), "removing Item not in Pool" );
895 // -----------------------------------------------------------------------
897 const SfxPoolItem& SfxItemPool::GetDefaultItem( sal_uInt16 nWhich ) const
899 DBG_CHKTHIS(SfxItemPool, 0);
901 if ( !IsInRange(nWhich) )
903 if ( pImp->mpSecondary )
904 return pImp->mpSecondary->GetDefaultItem( nWhich );
905 SFX_ASSERT( 0, nWhich, "unknown which - dont ask me for defaults" );
908 DBG_ASSERT( pImp->ppStaticDefaults, "no defaults known - dont ask me for defaults" );
909 sal_uInt16 nPos = GetIndex_Impl(nWhich);
910 SfxPoolItem *pDefault = *(pImp->ppPoolDefaults + nPos);
911 if ( pDefault )
912 return *pDefault;
913 return **(pImp->ppStaticDefaults + nPos);
916 SfxItemPool* SfxItemPool::GetSecondaryPool() const
918 return pImp->mpSecondary;
921 SfxItemPool* SfxItemPool::GetMasterPool() const
923 return pImp->mpMaster;
926 void SfxItemPool::FreezeIdRanges()
928 /* [Beschreibung]
930 This method should be called at the master pool, when all secondary
931 pools are appended to it.
933 It calculates the ranges of 'which-ids' for fast construction of
934 item-sets, which contains all 'which-ids'.
938 FillItemIdRanges_Impl( pImp->mpPoolRanges );
942 // -----------------------------------------------------------------------
944 void SfxItemPool::FillItemIdRanges_Impl( sal_uInt16*& pWhichRanges ) const
946 DBG_CHKTHIS(SfxItemPool, 0);
947 DBG_ASSERT( !pImp->mpPoolRanges, "GetFrozenRanges() would be faster!" );
949 const SfxItemPool *pPool;
950 sal_uInt16 nLevel = 0;
951 for( pPool = this; pPool; pPool = pPool->pImp->mpSecondary )
952 ++nLevel;
954 pWhichRanges = new sal_uInt16[ 2*nLevel + 1 ];
956 nLevel = 0;
957 for( pPool = this; pPool; pPool = pPool->pImp->mpSecondary )
959 *(pWhichRanges+(nLevel++)) = pPool->pImp->mnStart;
960 *(pWhichRanges+(nLevel++)) = pPool->pImp->mnEnd;
961 *(pWhichRanges+nLevel) = 0;
965 const sal_uInt16* SfxItemPool::GetFrozenIdRanges() const
967 return pImp->mpPoolRanges;
970 const SfxPoolItem *SfxItemPool::GetItem2(sal_uInt16 nWhich, sal_uInt32 nOfst) const
972 DBG_CHKTHIS(SfxItemPool, 0);
974 if ( !IsInRange(nWhich) )
976 if ( pImp->mpSecondary )
977 return pImp->mpSecondary->GetItem2( nWhich, nOfst );
978 SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot resolve surrogate" );
979 return 0;
982 // dflt-Attribut?
983 if ( nOfst == SFX_ITEMS_DEFAULT )
984 return *(pImp->ppStaticDefaults + GetIndex_Impl(nWhich));
986 SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[GetIndex_Impl(nWhich)];
987 if( pItemArr && nOfst < pItemArr->size() )
988 return (*pItemArr)[nOfst];
990 return 0;
993 // -----------------------------------------------------------------------
995 sal_uInt32 SfxItemPool::GetItemCount2(sal_uInt16 nWhich) const
997 DBG_CHKTHIS(SfxItemPool, 0);
999 if ( !IsInRange(nWhich) )
1001 if ( pImp->mpSecondary )
1002 return pImp->mpSecondary->GetItemCount2( nWhich );
1003 SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot resolve surrogate" );
1004 return 0;
1007 SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[GetIndex_Impl(nWhich)];
1008 if ( pItemArr )
1009 return pItemArr->size();
1010 return 0;
1013 // -----------------------------------------------------------------------
1015 sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, sal_Bool bDeep ) const
1017 if ( !IsSlot(nSlotId) )
1018 return nSlotId;
1020 sal_uInt16 nCount = pImp->mnEnd - pImp->mnStart + 1;
1021 for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
1022 if ( pItemInfos[nOfs]._nSID == nSlotId )
1023 return nOfs + pImp->mnStart;
1024 if ( pImp->mpSecondary && bDeep )
1025 return pImp->mpSecondary->GetWhich(nSlotId);
1026 return nSlotId;
1029 // -----------------------------------------------------------------------
1031 sal_uInt16 SfxItemPool::GetSlotId( sal_uInt16 nWhich, sal_Bool bDeep ) const
1033 if ( !IsWhich(nWhich) )
1034 return nWhich;
1036 if ( !IsInRange( nWhich ) )
1038 if ( pImp->mpSecondary && bDeep )
1039 return pImp->mpSecondary->GetSlotId(nWhich);
1040 SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get slot-id" );
1041 return 0;
1044 sal_uInt16 nSID = pItemInfos[nWhich - pImp->mnStart]._nSID;
1045 return nSID ? nSID : nWhich;
1048 // -----------------------------------------------------------------------
1050 sal_uInt16 SfxItemPool::GetTrueWhich( sal_uInt16 nSlotId, sal_Bool bDeep ) const
1052 if ( !IsSlot(nSlotId) )
1053 return 0;
1055 sal_uInt16 nCount = pImp->mnEnd - pImp->mnStart + 1;
1056 for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
1057 if ( pItemInfos[nOfs]._nSID == nSlotId )
1058 return nOfs + pImp->mnStart;
1059 if ( pImp->mpSecondary && bDeep )
1060 return pImp->mpSecondary->GetTrueWhich(nSlotId);
1061 return 0;
1064 // -----------------------------------------------------------------------
1066 sal_uInt16 SfxItemPool::GetTrueSlotId( sal_uInt16 nWhich, sal_Bool bDeep ) const
1068 if ( !IsWhich(nWhich) )
1069 return 0;
1071 if ( !IsInRange( nWhich ) )
1073 if ( pImp->mpSecondary && bDeep )
1074 return pImp->mpSecondary->GetTrueSlotId(nWhich);
1075 SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get slot-id" );
1076 return 0;
1078 return pItemInfos[nWhich - pImp->mnStart]._nSID;
1081 void SfxItemPool::SetFileFormatVersion( sal_uInt16 nFileFormatVersion )
1083 /* [Description]
1085 You must call this function to set the file format version after
1086 concatenating your secondary-pools but before you store any
1087 pool, itemset or item. Only set the version at the master pool,
1088 never at any secondary pool.
1092 DBG_ASSERT( this == pImp->mpMaster,
1093 "SfxItemPool::SetFileFormatVersion() but not a master pool" );
1094 for ( SfxItemPool *pPool = this; pPool; pPool = pPool->pImp->mpSecondary )
1095 pPool->pImp->mnFileFormatVersion = nFileFormatVersion;
1098 const SfxItemPool* SfxItemPool::pStoringPool_ = 0;
1100 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */