xref: /trunk/main/svl/source/items/itempool.cxx (revision b2e8c96c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svl.hxx"
26 
27 #include <string.h>
28 #include <stdio.h>
29 #ifndef GCC
30 #endif
31 
32 #include <svl/itempool.hxx>
33 #include "whassert.hxx"
34 #include <svl/brdcst.hxx>
35 #include <svl/smplhint.hxx>
36 #include "poolio.hxx"
37 
38 //========================================================================
39 
40 
AddSfxItemPoolUser(SfxItemPoolUser & rNewUser)41 void SfxItemPool::AddSfxItemPoolUser(SfxItemPoolUser& rNewUser)
42 {
43 	maSfxItemPoolUsers.push_back(&rNewUser);
44 }
45 
RemoveSfxItemPoolUser(SfxItemPoolUser & rOldUser)46 void SfxItemPool::RemoveSfxItemPoolUser(SfxItemPoolUser& rOldUser)
47 {
48 	const SfxItemPoolUserVector::iterator aFindResult = ::std::find(maSfxItemPoolUsers.begin(), maSfxItemPoolUsers.end(), &rOldUser);
49 	if(aFindResult != maSfxItemPoolUsers.end())
50 	{
51 		maSfxItemPoolUsers.erase(aFindResult);
52 	}
53 }
54 
GetPoolDefaultItem(sal_uInt16 nWhich) const55 const SfxPoolItem* SfxItemPool::GetPoolDefaultItem( sal_uInt16 nWhich ) const
56 {
57 	DBG_CHKTHIS(SfxItemPool, 0);
58 	const SfxPoolItem* pRet;
59 	if( IsInRange( nWhich ) )
60 		pRet = *(ppPoolDefaults + GetIndex_Impl( nWhich ));
61 	else if( pSecondary )
62 		pRet = pSecondary->GetPoolDefaultItem( nWhich );
63 	else
64 	{
65 		SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get pool default" );
66 		pRet = 0;
67 	}
68 	return pRet;
69 }
70 
71 // -----------------------------------------------------------------------
72 
IsItemFlag_Impl(sal_uInt16 nPos,sal_uInt16 nFlag) const73 inline FASTBOOL SfxItemPool::IsItemFlag_Impl( sal_uInt16 nPos, sal_uInt16 nFlag ) const
74 {
75 	sal_uInt16 nItemFlag = pItemInfos[nPos]._nFlags;
76 	return nFlag == (nItemFlag & nFlag);
77 }
78 
79 // -----------------------------------------------------------------------
80 
IsItemFlag(sal_uInt16 nWhich,sal_uInt16 nFlag) const81 FASTBOOL SfxItemPool::IsItemFlag( sal_uInt16 nWhich, sal_uInt16 nFlag ) const
82 {
83 	for ( const SfxItemPool *pPool = this; pPool; pPool = pPool->pSecondary )
84 	{
85 		if ( pPool->IsInRange(nWhich) )
86 			return pPool->IsItemFlag_Impl( pPool->GetIndex_Impl(nWhich), nFlag);
87 	}
88 	DBG_ASSERT( !IsWhich(nWhich), "unknown which-id" );
89 	return sal_False;
90 }
91 
92 // -----------------------------------------------------------------------
93 
BC()94 SfxBroadcaster& SfxItemPool::BC()
95 {
96 	return pImp->aBC;
97 }
98 
99 // -----------------------------------------------------------------------
100 
101 
SfxItemPool(UniString const & rName,sal_uInt16 nStartWhich,sal_uInt16 nEndWhich,const SfxItemInfo * pInfos,SfxPoolItem ** pDefaults,sal_uInt16 * pSlotIdArray,FASTBOOL bLoadRefCounts)102 SfxItemPool::SfxItemPool
103 (
104 	UniString const &	rName,          /* Name des Pools zur Idetifikation
105 										   im File-Format */
106 	sal_uInt16              nStartWhich,    /* erste Which-Id des Pools */
107 	sal_uInt16              nEndWhich,      /* letzte Which-Id des Pools */
108 #ifdef TF_POOLABLE
109 	const SfxItemInfo*  pInfos,         /* SID-Map und Item-Flags */
110 #endif
111 	SfxPoolItem**       pDefaults,      /* Pointer auf statische Defaults,
112 										   wird direkt vom Pool referenziert,
113 										   jedoch kein Eigent"umer"ubergang */
114 #ifndef TF_POOLABLE
115 	sal_uInt16*             pSlotIdArray,   /* Zuordnung von Slot-Ids zu Which-Ids */
116 #endif
117 	FASTBOOL            bLoadRefCounts  /* Ref-Counts mitladen oder auf 1 setzen */
118 )
119 
120 /*  [Beschreibung]
121 
122 	Der im Normalfall verwendete Konstruktor der Klasse SfxItemPool. Es
123 	wird eine SfxItemPool-Instanz initialisiert, die Items im b"undigen
124 	Which-Bereich von 'nStartWhich' bis 'nEndWhich' verwalten kann.
125 
126 	F"ur jede dieser Which-Ids mu\s ein statischer Default im Array 'pDefaults'
127 	vorhanden sein, die dort beginnend mit einem <SfxPoolItem> mit der
128 	Which-Id 'nStartWhich' nach Which-Ids sortiert aufeinanderfolgend
129 	eingetragen sein m"ussen.
130 
131 	'pItemInfos' ist ein identisch angeordnetes Array von USHORTs, die
132 	Slot-Ids darstellen und Flags. Die Slot-Ids k"onnen 0 sein, wenn die
133 	betreffenden Items ausschlie\slich in der Core verwendet werden.
134 	"Uber die Flags kann z.B. bestimmt werden, ob Value-Sharing
135 	(SFX_ITEM_POOLABLE) stattfinden soll.
136 
137 	[Anmerkung]
138 
139 	Wenn der Pool <SfxSetItem>s enthalten soll, k"onnen im Konstruktor noch
140 	keine static-Defaults angegeben werden. Dies mu\s dann nachtr"aglich
141 	mit <SfxItemPool::SetDefaults(SfxItemPool**)> geschehen.
142 
143 
144 	[Querverweise]
145 
146 	<SfxItemPool::SetDefaults(SfxItemPool**)>
147 	<SfxItemPool::ReleaseDefaults(SfxPoolItem**,sal_uInt16,sal_Bool)>
148 	<SfxItemPool::ReldaseDefaults(sal_Bool)>
149 */
150 
151 :   aName(rName),
152 	nStart(nStartWhich),
153 	nEnd(nEndWhich),
154 #ifdef TF_POOLABLE
155 	pItemInfos(pInfos),
156 #else
157 	pSlotIds(pSlotIdArray),
158 #endif
159 	pImp( new SfxItemPool_Impl( nStart, nEnd ) ),
160 	ppStaticDefaults(0),
161 	ppPoolDefaults(new SfxPoolItem* [ nEndWhich - nStartWhich + 1]),
162 	pSecondary(0),
163 	pMaster(this),
164 	_pPoolRanges( 0 ),
165 	bPersistentRefCounts(bLoadRefCounts),
166     maSfxItemPoolUsers()
167 {
168 	DBG_CTOR(SfxItemPool, 0);
169 	DBG_ASSERT(nStart, "Start-Which-Id must be greater 0" );
170 
171 	pImp->eDefMetric = SFX_MAPUNIT_TWIP;
172 	pImp->nVersion = 0;
173 	pImp->bStreaming = sal_False;
174 	pImp->nLoadingVersion = 0;
175 	pImp->nInitRefCount = 1;
176 	pImp->nVerStart = nStart;
177 	pImp->nVerEnd = nEnd;
178 	pImp->bInSetItem = sal_False;
179 	pImp->nStoringStart = nStartWhich;
180 	pImp->nStoringEnd = nEndWhich;
181 
182 	memset( ppPoolDefaults, 0, sizeof( SfxPoolItem* ) * (nEnd - nStart + 1));
183 
184 	if ( pDefaults )
185 		SetDefaults(pDefaults);
186 }
187 
188 // -----------------------------------------------------------------------
189 
190 
SfxItemPool(const SfxItemPool & rPool,sal_Bool bCloneStaticDefaults)191 SfxItemPool::SfxItemPool
192 (
193 	const SfxItemPool&  rPool,                  //  von dieser Instanz kopieren
194 	sal_Bool                bCloneStaticDefaults    /*  sal_True
195 													statische Defaults kopieren
196 
197 													sal_False
198 													statische Defaults
199 													"ubernehehmen */
200 )
201 
202 /*  [Beschreibung]
203 
204 	Copy-Konstruktor der Klasse SfxItemPool.
205 
206 
207 	[Querverweise]
208 
209 	<SfxItemPool::Clone()const>
210 */
211 
212 :   aName(rPool.aName),
213 	nStart(rPool.nStart),
214 	nEnd(rPool.nEnd),
215 #ifdef TF_POOLABLE
216 	pItemInfos(rPool.pItemInfos),
217 #else
218 	pSlotIds(rPool.pSlotIds),
219 #endif
220 	pImp( new SfxItemPool_Impl( nStart, nEnd ) ),
221 	ppStaticDefaults(0),
222 	ppPoolDefaults(new SfxPoolItem* [ nEnd - nStart + 1]),
223 	pSecondary(0),
224 	pMaster(this),
225 	_pPoolRanges( 0 ),
226 	bPersistentRefCounts(rPool.bPersistentRefCounts ),
227     maSfxItemPoolUsers()
228 {
229 	DBG_CTOR(SfxItemPool, 0);
230 	pImp->eDefMetric = rPool.pImp->eDefMetric;
231 	pImp->nVersion = rPool.pImp->nVersion;
232 	pImp->bStreaming = sal_False;
233 	pImp->nLoadingVersion = 0;
234 	pImp->nInitRefCount = 1;
235 	pImp->nVerStart = rPool.pImp->nVerStart;
236 	pImp->nVerEnd = rPool.pImp->nVerEnd;
237 	pImp->bInSetItem = sal_False;
238 	pImp->nStoringStart = nStart;
239 	pImp->nStoringEnd = nEnd;
240 
241 	memset( ppPoolDefaults, 0, sizeof( SfxPoolItem* ) * (nEnd - nStart + 1));
242 
243 	// Static Defaults "ubernehmen
244 	if ( bCloneStaticDefaults )
245 	{
246 		SfxPoolItem **ppDefaults = new SfxPoolItem*[nEnd-nStart+1];
247 		for ( sal_uInt16 n = 0; n <= nEnd - nStart; ++n )
248 		{
249 			(*( ppDefaults + n )) = (*( rPool.ppStaticDefaults + n ))->Clone(this);
250 			(*( ppDefaults + n ))->SetKind( SFX_ITEMS_STATICDEFAULT );
251 		}
252 
253 		SetDefaults( ppDefaults );
254 	}
255 	else
256 		SetDefaults( rPool.ppStaticDefaults );
257 
258 	// Pool Defaults kopieren
259 	for ( sal_uInt16 n = 0; n <= nEnd - nStart; ++n )
260 		if ( (*( rPool.ppPoolDefaults + n )) )
261 		{
262 			(*( ppPoolDefaults + n )) = (*( rPool.ppPoolDefaults + n ))->Clone(this);
263 			(*( ppPoolDefaults + n ))->SetKind( SFX_ITEMS_POOLDEFAULT );
264 		}
265 
266 	// Copy Version-Map
267 	for ( size_t nVer = 0; nVer < rPool.pImp->aVersions.size(); ++nVer )
268 	{
269 		const SfxPoolVersion_ImplPtr pOld = rPool.pImp->aVersions[nVer];
270 		SfxPoolVersion_ImplPtr pNew = SfxPoolVersion_ImplPtr( new SfxPoolVersion_Impl( *pOld ) );
271 		pImp->aVersions.push_back( pNew );
272 	}
273 
274 	// Verkettung wiederherstellen
275 	if ( rPool.pSecondary )
276 		SetSecondaryPool( rPool.pSecondary->Clone() );
277 }
278 
279 // -----------------------------------------------------------------------
280 
SetDefaults(SfxPoolItem ** pDefaults)281 void SfxItemPool::SetDefaults( SfxPoolItem **pDefaults )
282 {
283 	DBG_CHKTHIS(SfxItemPool, 0);
284 	DBG_ASSERT( pDefaults, "erst wollen, dann nichts geben..." );
285 	DBG_ASSERT( !ppStaticDefaults, "habe schon defaults" );
286 
287 	ppStaticDefaults = pDefaults;
288 	//! if ( (*ppStaticDefaults)->GetKind() != SFX_ITEMS_STATICDEFAULT )
289 	//! geht wohl nicht im Zshg mit SetItems, die hinten stehen
290 	{
291 		DBG_ASSERT( (*ppStaticDefaults)->GetRefCount() == 0 ||
292 					IsDefaultItem( (*ppStaticDefaults) ),
293 					"das sind keine statics" );
294 		for ( sal_uInt16 n = 0; n <= nEnd - nStart; ++n )
295 		{
296 			SFX_ASSERT( (*( ppStaticDefaults + n ))->Which() == n + nStart,
297 						n + nStart, "static defaults not sorted" );
298 			(*( ppStaticDefaults + n ))->SetKind( SFX_ITEMS_STATICDEFAULT );
299 			DBG_ASSERT( !(pImp->ppPoolItems[n]), "defaults with setitems with items?!" );
300 		}
301 	}
302 }
303 
304 // -----------------------------------------------------------------------
305 
ReleaseDefaults(sal_Bool bDelete)306 void SfxItemPool::ReleaseDefaults
307 (
308 	sal_Bool    bDelete     /*  sal_True
309 							l"oscht sowohl das Array als auch die einzelnen
310 							statischen Defaults
311 
312 							sal_False
313 							l"oscht weder das Array noch die einzelnen
314 							statischen Defaults */
315 )
316 
317 /*  [Beschreibung]
318 
319 	Gibt die statischen Defaults der betreffenden SfxItemPool-Instanz frei
320 	und l"oscht ggf. die statischen Defaults.
321 
322 	Nach Aufruf dieser Methode darf die SfxItemPool-Instanz nicht mehr
323 	verwendet werden, einzig ist der Aufruf des Destruktors zu"lassig.
324 */
325 
326 {
327 	DBG_ASSERT( ppStaticDefaults, "keine Arme keine Kekse" );
328 	ReleaseDefaults( ppStaticDefaults, nEnd - nStart + 1, bDelete );
329 
330 	// KSO (22.10.98): ppStaticDefaults zeigt auf geloeschten Speicher,
331 	// wenn bDelete == sal_True.
332 	if ( bDelete )
333 		ppStaticDefaults = 0;
334 }
335 
336 // -----------------------------------------------------------------------
337 
ReleaseDefaults(SfxPoolItem ** pDefaults,sal_uInt16 nCount,sal_Bool bDelete)338 void SfxItemPool::ReleaseDefaults
339 (
340 	SfxPoolItem**   pDefaults,  /*  freizugebende statische Defaults */
341 
342 	sal_uInt16          nCount,     /*  Anzahl der statischen Defaults */
343 
344 	sal_Bool            bDelete     /*  sal_True
345 									l"oscht sowohl das Array als auch die
346 									einzelnen statischen Defaults
347 
348 									sal_False
349 									l"oscht weder das Array noch die
350 									einzelnen statischen Defaults */
351 )
352 
353 /*  [Beschreibung]
354 
355 	Gibt die angegebenen statischen Defaults frei und l"oscht ggf.
356 	die statischen Defaults.
357 
358 	Diese Methode darf erst nach Zerst"orung aller SfxItemPool-Instanzen,
359 	welche die angegebenen statischen Defaults 'pDefault' verwenden,
360 	aufgerufen werden.
361 */
362 
363 {
364 	DBG_ASSERT( pDefaults, "erst wollen, dann nichts geben..." );
365 
366 	for ( sal_uInt16 n = 0; n < nCount; ++n )
367 	{
368 		SFX_ASSERT( IsStaticDefaultItem( *(pDefaults+n) ),
369 					n, "das ist kein static-default" );
370 		(*( pDefaults + n ))->SetRefCount( 0 );
371 		if ( bDelete )
372 			{ delete *( pDefaults + n ); *(pDefaults + n) = 0; }
373 	}
374 
375 	if ( bDelete )
376 		{ delete[] pDefaults; pDefaults = 0; }
377 }
378 
379 // -----------------------------------------------------------------------
380 
~SfxItemPool()381 SfxItemPool::~SfxItemPool()
382 {
383 	DBG_DTOR(SfxItemPool, 0);
384 
385     if ( pImp->ppPoolItems && ppPoolDefaults )
386 		Delete();
387 	delete[] _pPoolRanges;
388 	delete pImp;
389 
390     if (pMaster != NULL && pMaster != this)
391     {
392         // This condition indicates an error.  A
393         // pMaster->SetSecondaryPool(...) call should have been made
394         // earlier to prevent this.  At this point we can only try to
395         // prevent a crash later on.
396         DBG_ASSERT( pMaster == this, "destroying active Secondary-Pool" );
397         if (pMaster->pSecondary == this)
398             pMaster->pSecondary = NULL;
399     }
400 }
401 
Free(SfxItemPool * pPool)402 void SfxItemPool::Free(SfxItemPool* pPool)
403 {
404     if(pPool)
405     {
406 	    // tell all the registered SfxItemPoolUsers that the pool is in destruction
407 	    SfxItemPoolUserVector aListCopy(pPool->maSfxItemPoolUsers.begin(), pPool->maSfxItemPoolUsers.end());
408 	    for(SfxItemPoolUserVector::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); aIterator++)
409 	    {
410 		    SfxItemPoolUser* pSfxItemPoolUser = *aIterator;
411 		    DBG_ASSERT(pSfxItemPoolUser, "corrupt SfxItemPoolUser list (!)");
412 		    pSfxItemPoolUser->ObjectInDestruction(*pPool);
413 	    }
414 
415 	    // Clear the vector. This means that user do not need to call RemoveSfxItemPoolUser()
416 	    // when they get called from ObjectInDestruction().
417 	    pPool->maSfxItemPoolUsers.clear();
418 
419         // delete pool
420         delete pPool;
421     }
422 }
423 
424 // -----------------------------------------------------------------------
425 
426 
SetSecondaryPool(SfxItemPool * pPool)427 void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool )
428 {
429 	// ggf. an abgeh"angten Pools den Master zur"ucksetzen
430 	if ( pSecondary )
431 	{
432 #ifdef DBG_UTIL
433 		HACK( "fuer Image, dort gibt es derzeit keine Statics - Bug" )
434 		if ( ppStaticDefaults )
435 		{
436 			// Delete() ist noch nicht gelaufen?
437 			if ( pImp->ppPoolItems && pSecondary->pImp->ppPoolItems )
438 			{
439 				// hat der master SetItems?
440 				sal_Bool bHasSetItems = sal_False;
441 				for ( sal_uInt16 i = 0; !bHasSetItems && i < nEnd-nStart; ++i )
442 					bHasSetItems = ppStaticDefaults[i]->ISA(SfxSetItem);
443 
444 				// abgehaengte Pools muessen leer sein
445 				sal_Bool bOK = bHasSetItems;
446 				for ( sal_uInt16 n = 0;
447 					  bOK && n <= pSecondary->nEnd - pSecondary->nStart;
448 					  ++n )
449 				{
450 					SfxPoolItemArray_Impl** ppItemArr =
451 												pSecondary->pImp->ppPoolItems + n;
452 					if ( *ppItemArr )
453 					{
454 						SfxPoolItemArrayBase_Impl::iterator ppHtArr =	(*ppItemArr)->begin();
455 						for( size_t i = (*ppItemArr)->size(); i; ++ppHtArr, --i )
456 							if ( !(*ppHtArr) )
457 							{
458 								DBG_ERROR( "old secondary pool must be empty" );
459 								bOK = sal_False;
460 								break;
461 							}
462 					}
463 				}
464 			}
465 		}
466 #endif
467 
468 		pSecondary->pMaster = pSecondary;
469 		for ( SfxItemPool *p = pSecondary->pSecondary; p; p = p->pSecondary )
470 			p->pMaster = pSecondary;
471 	}
472 
473 	// ggf. den Master der neuen Secondary-Pools setzen
474 	DBG_ASSERT( !pPool || pPool->pMaster == pPool, "Secondary tanzt auf zwei Hochzeiten " );
475 	SfxItemPool *pNewMaster = pMaster ? pMaster : this;
476 	for ( SfxItemPool *p = pPool; p; p = p->pSecondary )
477 		p->pMaster = pNewMaster;
478 
479 	// neuen Secondary-Pool merken
480 	pSecondary = pPool;
481 }
482 
483 // -----------------------------------------------------------------------
484 
GetMetric(sal_uInt16) const485 SfxMapUnit SfxItemPool::GetMetric( sal_uInt16 ) const
486 {
487 	DBG_CHKTHIS(SfxItemPool, 0);
488 
489 	return pImp->eDefMetric;
490 }
491 
492 // -----------------------------------------------------------------------
493 
SetDefaultMetric(SfxMapUnit eNewMetric)494 void SfxItemPool::SetDefaultMetric( SfxMapUnit eNewMetric )
495 {
496 	DBG_CHKTHIS(SfxItemPool, 0);
497 
498 	pImp->eDefMetric = eNewMetric;
499 }
500 
501 // -----------------------------------------------------------------------
502 
GetPresentation(const SfxPoolItem & rItem,SfxItemPresentation ePresent,SfxMapUnit eMetric,XubString & rText,const IntlWrapper * pIntlWrapper) const503 SfxItemPresentation SfxItemPool::GetPresentation
504 (
505 	const SfxPoolItem&  rItem,      /*  IN: <SfxPoolItem>, dessen textuelle
506 											Wert-Darstellung geliefert werden
507 											soll */
508 	SfxItemPresentation ePresent,   /*  IN: gew"unschte Art der Darstellung;
509 											siehe <SfxItemPresentation> */
510 	SfxMapUnit          eMetric,    /*  IN: gew"unschte Ma\seinheit der Darstellung */
511 	XubString&           rText,      /*  OUT: textuelle Darstellung von 'rItem' */
512     const IntlWrapper * pIntlWrapper
513 )   const
514 
515 /*  [Beschreibung]
516 
517 	"Uber diese virtuelle Methode k"onnen textuelle Darstellungen der
518 	von der jeweilige SfxItemPool-Subklasse verwalteten SfxPoolItems
519 	angefordert werden.
520 
521 	In Ableitungen sollte diese Methode "uberladen werden und auf
522 	SfxPoolItems reagiert werden, die bei <SfxPoolItem::GetPresentation()const>
523 	keine vollst"andige Information liefern k"onnen.
524 
525 	Die Basisklasse liefert die unver"anderte Presentation von 'rItem'.
526 */
527 
528 {
529 	DBG_CHKTHIS(SfxItemPool, 0);
530 	return rItem.GetPresentation(
531         ePresent, GetMetric(rItem.Which()), eMetric, rText, pIntlWrapper );
532 }
533 
534 
535 // -----------------------------------------------------------------------
536 
Clone() const537 SfxItemPool* SfxItemPool::Clone() const
538 {
539 	DBG_CHKTHIS(SfxItemPool, 0);
540 
541 	SfxItemPool *pPool = new SfxItemPool( *this );
542 	return pPool;
543 }
544 
545 // ----------------------------------------------------------------------
546 
Delete()547 void SfxItemPool::Delete()
548 {
549 	DBG_CHKTHIS(SfxItemPool, 0);
550 
551 	// schon deleted?
552 	if ( !pImp->ppPoolItems || !ppPoolDefaults )
553 		return;
554 
555 	// z.B. laufenden Requests bescheidsagen
556 	pImp->aBC.Broadcast( SfxSimpleHint( SFX_HINT_DYING ) );
557 
558 	//MA 16. Apr. 97: Zweimal durchlaufen, in der ersten Runde fuer die SetItems.
559 	//Der Klarheit halber wird das jetzt in zwei besser lesbare Schleifen aufgeteilt.
560 
561 	SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems;
562 	SfxPoolItem** ppDefaultItem = ppPoolDefaults;
563 	SfxPoolItem** ppStaticDefaultItem = ppStaticDefaults;
564 	sal_uInt16 nArrCnt;
565 
566 	//Erst die SetItems abraeumen
567 	HACK( "fuer Image, dort gibt es derzeit keine Statics - Bug" )
568 	if ( ppStaticDefaults )
569 	{
570 		for ( nArrCnt = GetSize_Impl();
571 				nArrCnt;
572 				--nArrCnt, ++ppItemArr, ++ppDefaultItem, ++ppStaticDefaultItem )
573 		{
574 			// KSO (22.10.98): *ppStaticDefaultItem kann im dtor einer
575 			// von SfxItemPool abgeleiteten Klasse bereits geloescht worden
576 			// sein! -> CHAOS Itempool
577 			if ( *ppStaticDefaultItem && (*ppStaticDefaultItem)->ISA(SfxSetItem) )
578 			{
579 				if ( *ppItemArr )
580 				{
581 					SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*ppItemArr)->begin();
582 					for ( size_t n = (*ppItemArr)->size(); n; --n, ++ppHtArr )
583 						if (*ppHtArr)
584 						{
585 #ifdef DBG_UTIL
586 							ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() );
587 #endif
588 							delete *ppHtArr;
589 						}
590 					DELETEZ( *ppItemArr );
591 				}
592 				if ( *ppDefaultItem )
593 				{
594 #ifdef DBG_UTIL
595 					SetRefCount( **ppDefaultItem, 0 );
596 #endif
597 					DELETEZ( *ppDefaultItem );
598 				}
599 			}
600 		}
601 	}
602 
603 	ppItemArr = pImp->ppPoolItems;
604 	ppDefaultItem = ppPoolDefaults;
605 
606 	//Jetzt die 'einfachen' Items
607 	for ( nArrCnt = GetSize_Impl();
608 			nArrCnt;
609 			--nArrCnt, ++ppItemArr, ++ppDefaultItem )
610 	{
611 		if ( *ppItemArr )
612 		{
613 			SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*ppItemArr)->begin();
614 			for ( size_t n = (*ppItemArr)->size(); n; --n, ++ppHtArr )
615 				if (*ppHtArr)
616 				{
617 #ifdef DBG_UTIL
618 					ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() );
619 #endif
620 					delete *ppHtArr;
621 				}
622 			delete *ppItemArr;
623 		}
624 		if ( *ppDefaultItem )
625 		{
626 #ifdef DBG_UTIL
627 			SetRefCount( **ppDefaultItem, 0 );
628 #endif
629 			delete *ppDefaultItem;
630 		}
631 	}
632 
633 	pImp->DeleteItems();
634 	delete[] ppPoolDefaults; ppPoolDefaults = 0;
635 }
636 
637 // ----------------------------------------------------------------------
638 
Cleanup()639 void SfxItemPool::Cleanup()
640 {
641 	DBG_CHKTHIS(SfxItemPool, 0);
642 
643 	//MA 16. Apr. 97: siehe ::Delete()
644 
645 	SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems;
646 	SfxPoolItem** ppDefaultItem = ppPoolDefaults;
647 	SfxPoolItem** ppStaticDefaultItem = ppStaticDefaults;
648 	sal_uInt16 nArrCnt;
649 
650 	HACK( "fuer Image, dort gibt es derzeit keine Statics - Bug" )
651 	if ( ppStaticDefaults ) //HACK fuer Image, dort gibt es keine Statics!!
652 	{
653 		for ( nArrCnt = GetSize_Impl();
654 				nArrCnt;
655 				--nArrCnt, ++ppItemArr, ++ppDefaultItem, ++ppStaticDefaultItem )
656 		{
657 			//Fuer jedes Item gibt es entweder ein Default oder ein static Default!
658 			if ( *ppItemArr &&
659 				 ((*ppDefaultItem && (*ppDefaultItem)->ISA(SfxSetItem)) ||
660 				  (*ppStaticDefaultItem)->ISA(SfxSetItem)) )
661 			{
662 				SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*ppItemArr)->begin();
663 				for ( size_t n = (*ppItemArr)->size(); n; --n, ++ppHtArr )
664 					if ( *ppHtArr && !(*ppHtArr)->GetRefCount() )
665 					{
666 						 DELETEZ(*ppHtArr);
667 					}
668 			}
669 		}
670 	}
671 
672 	ppItemArr = pImp->ppPoolItems;
673 
674 	for ( nArrCnt = GetSize_Impl();
675 		  nArrCnt;
676 		  --nArrCnt, ++ppItemArr )
677 	{
678 		if ( *ppItemArr )
679 		{
680 			SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*ppItemArr)->begin();
681 			for ( size_t n = (*ppItemArr)->size(); n; --n, ++ppHtArr )
682 				if ( *ppHtArr && !(*ppHtArr)->GetRefCount() )
683 					DELETEZ( *ppHtArr );
684 		}
685 	}
686 }
687 
688 // ----------------------------------------------------------------------
689 
SetPoolDefaultItem(const SfxPoolItem & rItem)690 void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem &rItem)
691 {
692 	DBG_CHKTHIS(SfxItemPool, 0);
693 	if ( IsInRange(rItem.Which()) )
694 	{
695 		SfxPoolItem **ppOldDefault =
696 			ppPoolDefaults + GetIndex_Impl(rItem.Which());
697 		SfxPoolItem *pNewDefault = rItem.Clone(this);
698 		pNewDefault->SetKind(SFX_ITEMS_POOLDEFAULT);
699 		if ( *ppOldDefault )
700 		{
701 			(*ppOldDefault)->SetRefCount(0);
702 			DELETEZ( *ppOldDefault );
703 		}
704 		*ppOldDefault = pNewDefault;
705 	}
706 	else if ( pSecondary )
707 		pSecondary->SetPoolDefaultItem(rItem);
708 	else
709 	{
710 		SFX_ASSERT( 0, rItem.Which(), "unknown Which-Id - cannot set pool default" );
711 	}
712 }
713 
714 /*
715  * Resets the default of the given <Which-Id> back to the static default.
716  * If a pool default exists it is removed.
717  */
ResetPoolDefaultItem(sal_uInt16 nWhichId)718 void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 nWhichId )
719 {
720 	DBG_CHKTHIS(SfxItemPool, 0);
721 	if ( IsInRange(nWhichId) )
722 	{
723 		SfxPoolItem **ppOldDefault =
724 			ppPoolDefaults + GetIndex_Impl( nWhichId );
725 		if ( *ppOldDefault )
726 		{
727 			(*ppOldDefault)->SetRefCount(0);
728 			DELETEZ( *ppOldDefault );
729 		}
730 	}
731 	else if ( pSecondary )
732 		pSecondary->ResetPoolDefaultItem(nWhichId);
733 	else
734 	{
735 		SFX_ASSERT( 0, nWhichId, "unknown Which-Id - cannot set pool default" );
736 	}
737 }
738 
739 // -----------------------------------------------------------------------
740 
Put(const SfxPoolItem & rItem,sal_uInt16 nWhich)741 const SfxPoolItem& SfxItemPool::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
742 {
743 	DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
744 				0 != &((const SfxSetItem&)rItem).GetItemSet(),
745 				"SetItem without ItemSet" );
746 
747 	DBG_CHKTHIS(SfxItemPool, 0);
748 	if ( 0 == nWhich )
749 		nWhich = rItem.Which();
750 
751 	// richtigen Secondary-Pool finden
752 	sal_Bool bSID = nWhich > SFX_WHICH_MAX;
753 	if ( !bSID && !IsInRange(nWhich) )
754 	{
755 		if ( pSecondary )
756 			return pSecondary->Put( rItem, nWhich );
757 		DBG_ERROR( "unknown Which-Id - cannot put item" );
758 	}
759 
760 	// SID oder nicht poolable (neue Definition)?
761 	sal_uInt16 nIndex = bSID ? USHRT_MAX : GetIndex_Impl(nWhich);
762 	if ( USHRT_MAX == nIndex ||
763 		 IsItemFlag_Impl( nIndex, SFX_ITEM_NOT_POOLABLE ) )
764 	{
765 		SFX_ASSERT( USHRT_MAX != nIndex || rItem.Which() != nWhich ||
766 					!IsDefaultItem(&rItem) || rItem.GetKind() == SFX_ITEMS_DELETEONIDLE,
767 					nWhich, "ein nicht Pool-Item ist Default?!" );
768 		SfxPoolItem *pPoolItem = rItem.Clone(pMaster);
769 		pPoolItem->SetWhich(nWhich);
770 		AddRef( *pPoolItem );
771 		return *pPoolItem;
772 	}
773 
774 	SFX_ASSERT( rItem.IsA(GetDefaultItem(nWhich).Type()), nWhich,
775 				"SFxItemPool: wrong item type in Put" );
776 
777 	SfxPoolItemArray_Impl** ppItemArr = pImp->ppPoolItems + nIndex;
778 	if( !*ppItemArr )
779 		*ppItemArr = new SfxPoolItemArray_Impl;
780 
781 	SfxPoolItemArrayBase_Impl::iterator ppFree;
782 	sal_Bool ppFreeIsSet = sal_False;
783 	SfxPoolItemArrayBase_Impl::iterator ppHtArray = (*ppItemArr)->begin();
784 	if ( IsItemFlag_Impl( nIndex, SFX_ITEM_POOLABLE ) )
785 	{
786 		// wenn es ueberhaupt gepoolt ist, koennte es schon drin sein
787 		if ( IsPooledItem(&rItem) )
788 		{
789 			// 1. Schleife: teste ob der Pointer vorhanden ist.
790 			for( size_t n = (*ppItemArr)->size(); n; ++ppHtArray, --n )
791 				if( &rItem == (*ppHtArray) )
792 				{
793 					AddRef( **ppHtArray );
794 					return **ppHtArray;
795 				}
796 		}
797 
798 		// 2. Schleife: dann muessen eben die Attribute verglichen werden
799 		size_t n;
800 		for ( n = (*ppItemArr)->size(), ppHtArray = (*ppItemArr)->begin();
801 			  n; ++ppHtArray, --n )
802 		{
803 			if ( *ppHtArray )
804 			{
805 				if( **ppHtArray == rItem )
806 				{
807 					AddRef( **ppHtArray );
808 					return **ppHtArray;
809 				}
810 			}
811 			else
812 				if ( ppFreeIsSet == sal_False )
813 				{
814 					ppFree = ppHtArray;
815 					ppFreeIsSet = sal_True;
816 				}
817 		}
818 	}
819 	else
820 	{
821 		// freien Platz suchen
822 		SfxPoolItemArrayBase_Impl::iterator ppHtArr;
823 		size_t n, nCount = (*ppItemArr)->size();
824 		for ( n = (*ppItemArr)->nFirstFree,
825 				  ppHtArr = (*ppItemArr)->begin() + n;
826 			  n < nCount;
827 			  ++ppHtArr, ++n )
828 			if ( !*ppHtArr )
829 			{
830 				ppFree = ppHtArr;
831 				ppFreeIsSet = sal_True;
832 				break;
833 			}
834 
835 		// naechstmoeglichen freien Platz merken
836 		(*ppItemArr)->nFirstFree = n;
837 	}
838 
839 	// nicht vorhanden, also im PtrArray eintragen
840 	SfxPoolItem* pNewItem = rItem.Clone(pMaster);
841 	pNewItem->SetWhich(nWhich);
842 #ifdef DBG_UTIL
843 	SFX_ASSERT( rItem.Type() == pNewItem->Type(), nWhich, "unequal types in Put(): no Clone()?" )
844 #ifdef TF_POOLABLE
845 	if ( !rItem.ISA(SfxSetItem) )
846 	{
847 		SFX_ASSERT( !IsItemFlag(nWhich, SFX_ITEM_POOLABLE) ||
848 					rItem == *pNewItem,
849 					nWhich, "unequal items in Put(): no operator==?" );
850 		SFX_ASSERT( !IsItemFlag(*pNewItem, SFX_ITEM_POOLABLE) ||
851 					*pNewItem == rItem,
852 					nWhich, "unequal items in Put(): no operator==?" );
853 	}
854 #endif
855 #endif
856 	AddRef( *pNewItem, pImp->nInitRefCount );
857 	SfxPoolItem* pTemp = pNewItem;
858 	if ( ppFreeIsSet == sal_False )
859 		(*ppItemArr)->push_back( pTemp );
860 	else
861 	{
862 		DBG_ASSERT( *ppFree == 0, "using surrogate in use" );
863 		*ppFree = pNewItem;
864 	}
865 	return *pNewItem;
866 }
867 
868 // -----------------------------------------------------------------------
869 
Remove(const SfxPoolItem & rItem)870 void SfxItemPool::Remove( const SfxPoolItem& rItem )
871 {
872 	DBG_CHKTHIS(SfxItemPool, 0);
873 
874 	DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
875 				0 != &((const SfxSetItem&)rItem).GetItemSet(),
876 				"SetItem without ItemSet" );
877 
878 	SFX_ASSERT( !IsPoolDefaultItem(&rItem), rItem.Which(),
879 				"wo kommt denn hier ein Pool-Default her" );
880 
881 	// richtigen Secondary-Pool finden
882 	const sal_uInt16 nWhich = rItem.Which();
883 	sal_Bool bSID = nWhich > SFX_WHICH_MAX;
884 	if ( !bSID && !IsInRange(nWhich) )
885 	{
886 		if ( pSecondary )
887 		{
888 			pSecondary->Remove( rItem );
889 			return;
890 		}
891 		DBG_ERROR( "unknown Which-Id - cannot remove item" );
892 	}
893 
894 	// SID oder nicht poolable (neue Definition)?
895 	sal_uInt16 nIndex = bSID ? USHRT_MAX : GetIndex_Impl(nWhich);
896 	if ( bSID || IsItemFlag_Impl( nIndex, SFX_ITEM_NOT_POOLABLE ) )
897 	{
898 		SFX_ASSERT( USHRT_MAX != nIndex ||
899 					!IsDefaultItem(&rItem), rItem.Which(),
900 					"ein nicht Pool-Item ist Default?!" );
901 		if ( 0 == ReleaseRef(rItem) )
902 		{
903 			SfxPoolItem *pItem = &(SfxPoolItem &)rItem;
904 			delete pItem;
905 		}
906 		return;
907 	}
908 
909 	SFX_ASSERT( rItem.GetRefCount(), rItem.Which(), "RefCount == 0, Remove unmoeglich" );
910 
911 	// statische Defaults sind eben einfach da
912 	if ( rItem.GetKind() == SFX_ITEMS_STATICDEFAULT &&
913 		 &rItem == *( ppStaticDefaults + GetIndex_Impl(nWhich) ) )
914 		return;
915 
916 	// Item im eigenen Pool suchen
917 	SfxPoolItemArray_Impl** ppItemArr = (pImp->ppPoolItems + nIndex);
918 	SFX_ASSERT( *ppItemArr, rItem.Which(), "removing Item not in Pool" );
919 	SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*ppItemArr)->begin();
920 	for( size_t n = (*ppItemArr)->size(); n; ++ppHtArr, --n )
921 		if( *ppHtArr == &rItem )
922 		{
923 			if ( (*ppHtArr)->GetRefCount() ) //!
924 				ReleaseRef( **ppHtArr );
925 			else
926 			{
927 				SFX_ASSERT( 0, rItem.Which(), "removing Item without ref" );
928 				SFX_TRACE( "to be removed, but not no refs: ", *ppHtArr );
929 			}
930 
931 			// ggf. kleinstmoegliche freie Position merken
932 			size_t nPos = (*ppItemArr)->size() - n;
933 			if ( (*ppItemArr)->nFirstFree > nPos )
934 				(*ppItemArr)->nFirstFree = nPos;
935 
936 			//! MI: Hack, solange wir das Problem mit dem Outliner haben
937 			//! siehe anderes MI-REF
938 			if ( 0 == (*ppHtArr)->GetRefCount() && nWhich < 4000 )
939 				DELETEZ(*ppHtArr);
940 			return;
941 		}
942 
943 	// nicht vorhanden
944 	SFX_ASSERT( 0, rItem.Which(), "removing Item not in Pool" );
945 	SFX_TRACE( "to be removed, but not in pool: ", &rItem );
946 }
947 
948 // -----------------------------------------------------------------------
949 
GetDefaultItem(sal_uInt16 nWhich) const950 const SfxPoolItem& SfxItemPool::GetDefaultItem( sal_uInt16 nWhich ) const
951 {
952 	DBG_CHKTHIS(SfxItemPool, 0);
953 
954 	if ( !IsInRange(nWhich) )
955 	{
956 		if ( pSecondary )
957 			return pSecondary->GetDefaultItem( nWhich );
958 		SFX_ASSERT( 0, nWhich, "unknown which - dont ask me for defaults" );
959 	}
960 
961 	DBG_ASSERT( ppStaticDefaults, "no defaults known - dont ask me for defaults" );
962 	sal_uInt16 nPos = GetIndex_Impl(nWhich);
963 	SfxPoolItem *pDefault = *(ppPoolDefaults + nPos);
964 	if ( pDefault )
965 		return *pDefault;
966 	return **(ppStaticDefaults + nPos);
967 }
968 
969 // -----------------------------------------------------------------------
970 
971 
FreezeIdRanges()972 void SfxItemPool::FreezeIdRanges()
973 
974 /*	[Beschreibung]
975 
976 	This method should be called at the master pool, when all secondary
977 	pools are appended to it.
978 
979 	It calculates the ranges of 'which-ids' for fast construction of
980 	item-sets, which contains all 'which-ids'.
981 */
982 
983 {
984 	FillItemIdRanges_Impl( _pPoolRanges );
985 }
986 
987 
988 // -----------------------------------------------------------------------
989 
FillItemIdRanges_Impl(sal_uInt16 * & pWhichRanges) const990 void SfxItemPool::FillItemIdRanges_Impl( sal_uInt16*& pWhichRanges ) const
991 {
992 	DBG_CHKTHIS(SfxItemPool, 0);
993 	DBG_ASSERT( !_pPoolRanges, "GetFrozenRanges() would be faster!" );
994 
995 	const SfxItemPool *pPool;
996 	sal_uInt16 nLevel = 0;
997 	for( pPool = this; pPool; pPool = pPool->pSecondary )
998 		++nLevel;
999 
1000 	pWhichRanges = new sal_uInt16[ 2*nLevel + 1 ];
1001 
1002 	nLevel = 0;
1003 	for( pPool = this; pPool; pPool = pPool->pSecondary )
1004 	{
1005 		*(pWhichRanges+(nLevel++)) = pPool->nStart;
1006 		*(pWhichRanges+(nLevel++)) = pPool->nEnd;
1007 		*(pWhichRanges+nLevel) = 0;
1008 	}
1009 }
1010 
1011 // -----------------------------------------------------------------------
1012 
GetItem2(sal_uInt16 nWhich,sal_uInt32 nOfst) const1013 const SfxPoolItem *SfxItemPool::GetItem2(sal_uInt16 nWhich, sal_uInt32 nOfst) const
1014 {
1015 	DBG_CHKTHIS(SfxItemPool, 0);
1016 
1017 	if ( !IsInRange(nWhich) )
1018 	{
1019 		if ( pSecondary )
1020 			return pSecondary->GetItem2( nWhich, nOfst );
1021 		SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot resolve surrogate" );
1022 		return 0;
1023 	}
1024 
1025 	// dflt-Attribut?
1026 	if ( nOfst == SFX_ITEMS_DEFAULT )
1027 		return *(ppStaticDefaults + GetIndex_Impl(nWhich));
1028 
1029 	SfxPoolItemArray_Impl* pItemArr = *(pImp->ppPoolItems + GetIndex_Impl(nWhich));
1030 	if( pItemArr && nOfst < pItemArr->size() )
1031 		return (*pItemArr)[nOfst];
1032 
1033 	return 0;
1034 }
1035 
1036 // -----------------------------------------------------------------------
1037 
GetItemCount2(sal_uInt16 nWhich) const1038 sal_uInt32 SfxItemPool::GetItemCount2(sal_uInt16 nWhich) const
1039 {
1040 	DBG_CHKTHIS(SfxItemPool, 0);
1041 
1042 	if ( !IsInRange(nWhich) )
1043 	{
1044 		if ( pSecondary )
1045 			return pSecondary->GetItemCount2( nWhich );
1046 		SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot resolve surrogate" );
1047 		return 0;
1048 	}
1049 
1050 	SfxPoolItemArray_Impl* pItemArr = *(pImp->ppPoolItems + GetIndex_Impl(nWhich));
1051 	if  ( pItemArr )
1052 		return pItemArr->size();
1053 	return 0;
1054 }
1055 
1056 // -----------------------------------------------------------------------
1057 
GetWhich(sal_uInt16 nSlotId,sal_Bool bDeep) const1058 sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, sal_Bool bDeep ) const
1059 {
1060 	if ( !IsSlot(nSlotId) )
1061 		return nSlotId;
1062 
1063 #ifdef TF_POOLABLE
1064 	sal_uInt16 nCount = nEnd - nStart + 1;
1065 	for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
1066 		if ( pItemInfos[nOfs]._nSID == nSlotId )
1067 			return nOfs + nStart;
1068 #else
1069 	if ( pSlotIds )
1070 	{
1071 		sal_uInt16 nCount = nEnd - nStart + 1;
1072 		for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
1073 			if ( pSlotIds[nOfs] == nSlotId )
1074 				return nOfs + nStart;
1075 	}
1076 #endif
1077 	if ( pSecondary && bDeep )
1078 		return pSecondary->GetWhich(nSlotId);
1079 	return nSlotId;
1080 }
1081 
1082 // -----------------------------------------------------------------------
1083 
GetSlotId(sal_uInt16 nWhich,sal_Bool bDeep) const1084 sal_uInt16 SfxItemPool::GetSlotId( sal_uInt16 nWhich, sal_Bool bDeep ) const
1085 {
1086 	if ( !IsWhich(nWhich) )
1087 		return nWhich;
1088 
1089 	if ( !IsInRange( nWhich ) )
1090 	{
1091 		if ( pSecondary && bDeep )
1092 			return pSecondary->GetSlotId(nWhich);
1093 		SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get slot-id" );
1094 		return 0;
1095 	}
1096 #ifdef TF_POOLABLE
1097 
1098 	sal_uInt16 nSID = pItemInfos[nWhich - nStart]._nSID;
1099 	return nSID ? nSID : nWhich;
1100 #else
1101 	else if ( pSlotIds )
1102 		return pSlotIds[nWhich - nStart];
1103 	return nWhich;
1104 #endif
1105 }
1106 
1107 // -----------------------------------------------------------------------
1108 
GetTrueWhich(sal_uInt16 nSlotId,sal_Bool bDeep) const1109 sal_uInt16 SfxItemPool::GetTrueWhich( sal_uInt16 nSlotId, sal_Bool bDeep ) const
1110 {
1111 	if ( !IsSlot(nSlotId) )
1112 		return 0;
1113 
1114 #ifdef TF_POOLABLE
1115 	sal_uInt16 nCount = nEnd - nStart + 1;
1116 	for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
1117 		if ( pItemInfos[nOfs]._nSID == nSlotId )
1118 			return nOfs + nStart;
1119 #else
1120 	if ( pSlotIds )
1121 	{
1122 		sal_uInt16 nCount = nEnd - nStart + 1;
1123 		for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
1124 			if ( pSlotIds[nOfs] == nSlotId )
1125 				return nOfs + nStart;
1126 	}
1127 #endif
1128 	if ( pSecondary && bDeep )
1129 		return pSecondary->GetTrueWhich(nSlotId);
1130 	return 0;
1131 }
1132 
1133 // -----------------------------------------------------------------------
1134 
GetTrueSlotId(sal_uInt16 nWhich,sal_Bool bDeep) const1135 sal_uInt16 SfxItemPool::GetTrueSlotId( sal_uInt16 nWhich, sal_Bool bDeep ) const
1136 {
1137 	if ( !IsWhich(nWhich) )
1138 		return 0;
1139 
1140 	if ( !IsInRange( nWhich ) )
1141 	{
1142 		if ( pSecondary && bDeep )
1143 			return pSecondary->GetTrueSlotId(nWhich);
1144 		SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get slot-id" );
1145 		return 0;
1146 	}
1147 #ifdef TF_POOLABLE
1148 	return pItemInfos[nWhich - nStart]._nSID;
1149 #else
1150 	else if ( pSlotIds )
1151 		return pSlotIds[nWhich - nStart];
1152 	else
1153 		return 0;
1154 #endif
1155 }
1156 // -----------------------------------------------------------------------
SetFileFormatVersion(sal_uInt16 nFileFormatVersion)1157 void SfxItemPool::SetFileFormatVersion( sal_uInt16 nFileFormatVersion )
1158 
1159 /*  [Description]
1160 
1161 	You must call this function to set the file format version after
1162 	concatenating your secondary-pools but before you store any
1163 	pool, itemset or item. Only set the version at the master pool,
1164 	never at any secondary pool.
1165 */
1166 
1167 {
1168 	DBG_ASSERT( this == pMaster,
1169 				"SfxItemPool::SetFileFormatVersion() but not a master pool" );
1170 	for ( SfxItemPool *pPool = this; pPool; pPool = pPool->pSecondary )
1171 		pPool->_nFileFormatVersion = nFileFormatVersion;
1172 }
1173 
1174 
1175