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