xref: /AOO41X/main/svl/source/items/itempool.cxx (revision b2e8c96c9849fe374756981616f8432053febcd7)
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