1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 .
24 #include <svl/itempool.hxx>
25 #include "whassert.hxx"
26 #include <svl/brdcst.hxx>
27 #include <svl/smplhint.hxx>
31 #if OSL_DEBUG_LEVEL > 0
35 lcl_CheckSlots2(std::map
<sal_uInt16
, sal_uInt16
> & rSlotMap
,
36 SfxItemPool
const& rPool
, SfxItemInfo
const* 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
);
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
);
60 rSlotMap
.insert(std::make_pair(nSlotId
, nWhich
));
65 #define CHECK_SLOTS() \
67 std::map<sal_uInt16, sal_uInt16> slotmap; \
68 for (SfxItemPool * p = pImp->mpMaster; p; p = p->pImp->mpSecondary) \
70 lcl_CheckSlots2(slotmap, *p, p->pItemInfos); \
75 #define CHECK_SLOTS() do {} while (false)
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
);
104 SFX_ASSERT( 0, nWhich
, "unknown Which-Id - cannot get pool default" );
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" );
131 // -----------------------------------------------------------------------
133 SfxBroadcaster
& SfxItemPool::BC()
138 // -----------------------------------------------------------------------
141 SfxItemPool::SfxItemPool
143 const OUString
& rName
, /* Name des Pools zur Idetifikation
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 */
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.
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.
180 <SfxItemPool::SetDefaults(SfxItemPool**)>
181 <SfxItemPool::ReleaseDefaults(SfxPoolItem**,sal_uInt16,sal_Bool)>
182 <SfxItemPool::ReldaseDefaults(sal_Bool)>
186 pImp( new SfxItemPool_Impl( this, rName
, nStartWhich
, nEndWhich
) )
188 DBG_CTOR(SfxItemPool
, 0);
190 pImp
->eDefMetric
= SFX_MAPUNIT_TWIP
;
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
;
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
222 Copy-Konstruktor der Klasse SfxItemPool.
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
);
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
);
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
316 l"oscht weder das Array noch die einzelnen
317 statischen Defaults */
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.
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
352 l"oscht weder das Array noch die
353 einzelnen statischen Defaults */
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,
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 );
375 { delete *( pDefaults
+ n
); *(pDefaults
+ n
) = 0; }
379 { delete[] pDefaults
; pDefaults
= 0; }
382 // -----------------------------------------------------------------------
384 SfxItemPool::~SfxItemPool()
386 DBG_DTOR(SfxItemPool
, 0);
388 if ( !pImp
->maPoolItems
.empty() && pImp
->ppPoolDefaults
)
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
;
405 void SfxItemPool::Free(SfxItemPool
* 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();
427 // -----------------------------------------------------------------------
430 void SfxItemPool::SetSecondaryPool( SfxItemPool
*pPool
)
432 // ggf. an abgeh"angten Pools den Master zur"ucksetzen
433 if ( pImp
->mpSecondary
)
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
;
453 SfxPoolItemArray_Impl
* pItemArr
= pImp
->mpSecondary
->pImp
->maPoolItems
[n
];
456 SfxPoolItemArrayBase_Impl::iterator ppHtArr
= pItemArr
->begin();
457 for( size_t i
= pItemArr
->size(); i
; ++ppHtArr
, --i
)
460 OSL_FAIL( "old secondary pool must be empty" );
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
;
487 void SfxItemPool::SetItemInfos(SfxItemInfo
const*const pInfos
)
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
516 // -----------------------------------------------------------------------
518 SfxItemPresentation
SfxItemPool::GetPresentation
520 const SfxPoolItem
& rItem
,
521 SfxItemPresentation ePresent
,
524 const IntlWrapper
* pIntlWrapper
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 );
543 // ----------------------------------------------------------------------
545 void SfxItemPool::Delete()
547 DBG_CHKTHIS(SfxItemPool
, 0);
550 if ( pImp
->maPoolItems
.empty() || !pImp
->ppPoolDefaults
)
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
;
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();
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
) )
579 SfxPoolItemArrayBase_Impl::iterator ppHtArr
= (*itrItemArr
)->begin();
580 for ( size_t n
= (*itrItemArr
)->size(); n
; --n
, ++ppHtArr
)
584 ReleaseRef( **ppHtArr
, (*ppHtArr
)->GetRefCount() );
588 DELETEZ( *itrItemArr
);
590 if ( *ppDefaultItem
)
593 SetRefCount( **ppDefaultItem
, 0 );
595 DELETEZ( *ppDefaultItem
);
601 itrItemArr
= pImp
->maPoolItems
.begin();
602 ppDefaultItem
= pImp
->ppPoolDefaults
;
604 //Jetzt die 'einfachen' Items
605 for ( nArrCnt
= GetSize_Impl();
607 --nArrCnt
, ++itrItemArr
, ++ppDefaultItem
)
611 SfxPoolItemArrayBase_Impl::iterator ppHtArr
= (*itrItemArr
)->begin();
612 for ( size_t n
= (*itrItemArr
)->size(); n
; --n
, ++ppHtArr
)
616 ReleaseRef( **ppHtArr
, (*ppHtArr
)->GetRefCount() );
620 DELETEZ( *itrItemArr
);
622 if ( *ppDefaultItem
)
625 SetRefCount( **ppDefaultItem
, 0 );
627 delete *ppDefaultItem
;
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
);
647 (*ppOldDefault
)->SetRefCount(0);
648 DELETEZ( *ppOldDefault
);
650 *ppOldDefault
= pNewDefault
;
652 else if ( pImp
->mpSecondary
)
653 pImp
->mpSecondary
->SetPoolDefaultItem(rItem
);
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
);
673 (*ppOldDefault
)->SetRefCount(0);
674 DELETEZ( *ppOldDefault
);
677 else if ( pImp
->mpSecondary
)
678 pImp
->mpSecondary
->ResetPoolDefaultItem(nWhichId
);
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);
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
);
720 SFX_ASSERT( rItem
.IsA(GetDefaultItem(nWhich
).Type()), nWhich
,
721 "SFxItemPool: wrong item type in Put" );
723 SfxPoolItemArray_Impl
* pItemArr
= pImp
->maPoolItems
[nIndex
];
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())
747 // 2. Schleife: dann muessen eben die Attribute verglichen werden
748 SfxPoolItemArrayBase_Impl::iterator itr
= pItemArr
->begin();
749 for (; itr
!= pItemArr
->end(); ++itr
)
771 // freien Platz suchen
772 SfxPoolItemArrayBase_Impl::iterator itr
= pItemArr
->begin();
773 std::advance(itr
, pItemArr
->nFirstFree
);
774 for (; itr
!= pItemArr
->end(); ++itr
)
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
);
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
) ||
796 nWhich
, "unequal items in Put(): no operator==?" );
797 SFX_ASSERT( !IsItemFlag(*pNewItem
, SFX_ITEM_POOLABLE
) ||
799 nWhich
, "unequal items in Put(): no operator==?" );
802 AddRef( *pNewItem
, pImp
->nInitRefCount
);
804 if ( ppFreeIsSet
== false )
805 pItemArr
->push_back( pNewItem
);
808 DBG_ASSERT( *ppFree
== 0, "using surrogate in use" );
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
);
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
;
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
) ) )
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
;
871 if ( p
->GetRefCount() ) //!
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 )
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
);
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()
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
)
954 pWhichRanges
= new sal_uInt16
[ 2*nLevel
+ 1 ];
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" );
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
];
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" );
1007 SfxPoolItemArray_Impl
* pItemArr
= pImp
->maPoolItems
[GetIndex_Impl(nWhich
)];
1009 return pItemArr
->size();
1013 // -----------------------------------------------------------------------
1015 sal_uInt16
SfxItemPool::GetWhich( sal_uInt16 nSlotId
, sal_Bool bDeep
) const
1017 if ( !IsSlot(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
);
1029 // -----------------------------------------------------------------------
1031 sal_uInt16
SfxItemPool::GetSlotId( sal_uInt16 nWhich
, sal_Bool bDeep
) const
1033 if ( !IsWhich(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" );
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
) )
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
);
1064 // -----------------------------------------------------------------------
1066 sal_uInt16
SfxItemPool::GetTrueSlotId( sal_uInt16 nWhich
, sal_Bool bDeep
) const
1068 if ( !IsWhich(nWhich
) )
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" );
1078 return pItemInfos
[nWhich
- pImp
->mnStart
]._nSID
;
1081 void SfxItemPool::SetFileFormatVersion( sal_uInt16 nFileFormatVersion
)
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: */