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 18656 : void SfxItemPool::AddSfxItemPoolUser(SfxItemPoolUser& rNewUser)
34 : {
35 18656 : pImp->maSfxItemPoolUsers.push_back(&rNewUser);
36 18656 : }
37 :
38 18616 : void SfxItemPool::RemoveSfxItemPoolUser(SfxItemPoolUser& rOldUser)
39 : {
40 : const std::vector<SfxItemPoolUser*>::iterator aFindResult = ::std::find(
41 18616 : pImp->maSfxItemPoolUsers.begin(), pImp->maSfxItemPoolUsers.end(), &rOldUser);
42 18616 : if(aFindResult != pImp->maSfxItemPoolUsers.end())
43 : {
44 18616 : pImp->maSfxItemPoolUsers.erase(aFindResult);
45 : }
46 18616 : }
47 :
48 23062 : const SfxPoolItem* SfxItemPool::GetPoolDefaultItem( sal_uInt16 nWhich ) const
49 : {
50 : DBG_CHKTHIS(SfxItemPool, 0);
51 : const SfxPoolItem* pRet;
52 23062 : if( IsInRange( nWhich ) )
53 22320 : pRet = *(pImp->ppPoolDefaults + GetIndex_Impl( nWhich ));
54 742 : else if( pImp->mpSecondary )
55 742 : 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 23062 : return pRet;
62 : }
63 :
64 : // -----------------------------------------------------------------------
65 :
66 4192482 : bool SfxItemPool::IsItemFlag_Impl( sal_uInt16 nPos, sal_uInt16 nFlag ) const
67 : {
68 4192482 : sal_uInt16 nItemFlag = pItemInfos[nPos]._nFlags;
69 4192482 : return nFlag == (nItemFlag & nFlag);
70 : }
71 :
72 : // -----------------------------------------------------------------------
73 :
74 828674 : bool SfxItemPool::IsItemFlag( sal_uInt16 nWhich, sal_uInt16 nFlag ) const
75 : {
76 1097548 : for ( const SfxItemPool *pPool = this; pPool; pPool = pPool->pImp->mpSecondary )
77 : {
78 1074004 : if ( pPool->IsInRange(nWhich) )
79 805130 : return pPool->IsItemFlag_Impl( pPool->GetIndex_Impl(nWhich), nFlag);
80 : }
81 : DBG_ASSERT( !IsWhich(nWhich), "unknown which-id" );
82 23544 : return sal_False;
83 : }
84 :
85 : // -----------------------------------------------------------------------
86 :
87 12 : SfxBroadcaster& SfxItemPool::BC()
88 : {
89 12 : return pImp->aBC;
90 : }
91 :
92 : // -----------------------------------------------------------------------
93 :
94 :
95 7218 : SfxItemPool::SfxItemPool
96 : (
97 : const rtl::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 7218 : pImp( new SfxItemPool_Impl( this, rName, nStartWhich, nEndWhich ) )
141 : {
142 : DBG_CTOR(SfxItemPool, 0);
143 :
144 7218 : pImp->eDefMetric = SFX_MAPUNIT_TWIP;
145 7218 : pImp->nVersion = 0;
146 7218 : pImp->bStreaming = false;
147 7218 : pImp->nLoadingVersion = 0;
148 7218 : pImp->nInitRefCount = 1;
149 7218 : pImp->nVerStart = pImp->mnStart;
150 7218 : pImp->nVerEnd = pImp->mnEnd;
151 7218 : pImp->bInSetItem = false;
152 7218 : pImp->nStoringStart = nStartWhich;
153 7218 : pImp->nStoringEnd = nEndWhich;
154 7218 : pImp->mbPersistentRefCounts = bLoadRefCounts;
155 :
156 7218 : if ( pDefaults )
157 286 : SetDefaults(pDefaults);
158 7218 : }
159 :
160 : // -----------------------------------------------------------------------
161 :
162 :
163 0 : 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 0 : pImp( new SfxItemPool_Impl( this, rPool.pImp->aName, rPool.pImp->mnStart, rPool.pImp->mnEnd ) )
186 : {
187 : DBG_CTOR(SfxItemPool, 0);
188 0 : pImp->eDefMetric = rPool.pImp->eDefMetric;
189 0 : pImp->nVersion = rPool.pImp->nVersion;
190 0 : pImp->bStreaming = sal_False;
191 0 : pImp->nLoadingVersion = 0;
192 0 : pImp->nInitRefCount = 1;
193 0 : pImp->nVerStart = rPool.pImp->nVerStart;
194 0 : pImp->nVerEnd = rPool.pImp->nVerEnd;
195 0 : pImp->bInSetItem = false;
196 0 : pImp->nStoringStart = pImp->mnStart;
197 0 : pImp->nStoringEnd = pImp->mnEnd;
198 0 : pImp->mbPersistentRefCounts = rPool.pImp->mbPersistentRefCounts;
199 :
200 : // Static Defaults "ubernehmen
201 0 : 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 0 : SetDefaults( rPool.pImp->ppStaticDefaults );
214 :
215 : // Pool Defaults kopieren
216 0 : for ( sal_uInt16 n = 0; n <= pImp->mnEnd - pImp->mnStart; ++n )
217 0 : 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 0 : for ( size_t nVer = 0; nVer < rPool.pImp->aVersions.size(); ++nVer )
225 : {
226 0 : const SfxPoolVersion_ImplPtr pOld = rPool.pImp->aVersions[nVer];
227 0 : SfxPoolVersion_ImplPtr pNew = SfxPoolVersion_ImplPtr( new SfxPoolVersion_Impl( *pOld ) );
228 0 : pImp->aVersions.push_back( pNew );
229 0 : }
230 :
231 : // Verkettung wiederherstellen
232 0 : if ( rPool.pImp->mpSecondary )
233 0 : SetSecondaryPool( rPool.pImp->mpSecondary->Clone() );
234 0 : }
235 :
236 : // -----------------------------------------------------------------------
237 :
238 7218 : 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 7218 : 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 489143 : 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 481925 : (*( pImp->ppStaticDefaults + n ))->SetKind( SFX_ITEMS_STATICDEFAULT );
256 : DBG_ASSERT( !(pImp->maPoolItems[n]), "defaults with setitems with items?!" );
257 : }
258 : }
259 7218 : }
260 :
261 : // -----------------------------------------------------------------------
262 :
263 0 : 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 0 : 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 0 : if ( bDelete )
290 0 : pImp->ppStaticDefaults = 0;
291 0 : }
292 :
293 : // -----------------------------------------------------------------------
294 :
295 18 : 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 954 : for ( sal_uInt16 n = 0; n < nCount; ++n )
324 : {
325 : SFX_ASSERT( IsStaticDefaultItem( *(pDefaults+n) ),
326 : n, "das ist kein static-default" );
327 936 : (*( pDefaults + n ))->SetRefCount( 0 );
328 936 : if ( bDelete )
329 936 : { delete *( pDefaults + n ); *(pDefaults + n) = 0; }
330 : }
331 :
332 18 : if ( bDelete )
333 18 : { delete[] pDefaults; pDefaults = 0; }
334 18 : }
335 :
336 : // -----------------------------------------------------------------------
337 :
338 5767 : SfxItemPool::~SfxItemPool()
339 : {
340 : DBG_DTOR(SfxItemPool, 0);
341 : DBG_ASSERT( pImp->mpMaster == this, "destroying active Secondary-Pool" );
342 :
343 5767 : if ( !pImp->maPoolItems.empty() && pImp->ppPoolDefaults )
344 5419 : Delete();
345 5767 : delete pImp;
346 5767 : }
347 :
348 6173 : void SfxItemPool::Free(SfxItemPool* pPool)
349 : {
350 6173 : if(pPool)
351 : {
352 : // tell all the registered SfxItemPoolUsers that the pool is in destruction
353 5767 : std::vector<SfxItemPoolUser*> aListCopy(pPool->pImp->maSfxItemPoolUsers.begin(), pPool->pImp->maSfxItemPoolUsers.end());
354 5767 : for(std::vector<SfxItemPoolUser*>::iterator aIterator = aListCopy.begin(); aIterator != aListCopy.end(); ++aIterator)
355 : {
356 0 : SfxItemPoolUser* pSfxItemPoolUser = *aIterator;
357 : DBG_ASSERT(pSfxItemPoolUser, "corrupt SfxItemPoolUser list (!)");
358 0 : pSfxItemPoolUser->ObjectInDestruction(*pPool);
359 : }
360 :
361 : // Clear the vector. This means that user do not need to call RemoveSfxItemPoolUser()
362 : // when they get called from ObjectInDestruction().
363 5767 : pPool->pImp->maSfxItemPoolUsers.clear();
364 :
365 : // delete pool
366 5767 : delete pPool;
367 : }
368 6173 : }
369 :
370 : // -----------------------------------------------------------------------
371 :
372 :
373 1117 : void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool )
374 : {
375 : // ggf. an abgeh"angten Pools den Master zur"ucksetzen
376 1117 : if ( pImp->mpSecondary )
377 : {
378 : #ifdef DBG_UTIL
379 : SAL_INFO( "svl.items", "fuer Image, dort gibt es derzeit keine Statics - Bug" );
380 : if ( pImp->ppStaticDefaults )
381 : {
382 : // Delete() ist noch nicht gelaufen?
383 : if ( !pImp->maPoolItems.empty() && !pImp->mpSecondary->pImp->maPoolItems.empty() )
384 : {
385 : // hat der master SetItems?
386 : sal_Bool bHasSetItems = sal_False;
387 : for ( sal_uInt16 i = 0; !bHasSetItems && i < pImp->mnEnd - pImp->mnStart; ++i )
388 : bHasSetItems = pImp->ppStaticDefaults[i]->ISA(SfxSetItem);
389 :
390 : // abgehaengte Pools muessen leer sein
391 : bool bOK = bHasSetItems;
392 : for ( sal_uInt16 n = 0;
393 : bOK && n <= pImp->mpSecondary->pImp->mnEnd - pImp->mpSecondary->pImp->mnStart;
394 : ++n )
395 : {
396 : SfxPoolItemArray_Impl* pItemArr = pImp->mpSecondary->pImp->maPoolItems[n];
397 : if ( pItemArr )
398 : {
399 : SfxPoolItemArrayBase_Impl::iterator ppHtArr = pItemArr->begin();
400 : for( size_t i = pItemArr->size(); i; ++ppHtArr, --i )
401 : if ( !(*ppHtArr) )
402 : {
403 : OSL_FAIL( "old secondary pool must be empty" );
404 : bOK = false;
405 : break;
406 : }
407 : }
408 : }
409 : }
410 : }
411 : #endif
412 :
413 326 : pImp->mpSecondary->pImp->mpMaster = pImp->mpSecondary;
414 414 : for ( SfxItemPool *p = pImp->mpSecondary->pImp->mpSecondary; p; p = p->pImp->mpSecondary )
415 88 : p->pImp->mpMaster = pImp->mpSecondary;
416 : }
417 :
418 : // ggf. den Master der neuen Secondary-Pools setzen
419 : DBG_ASSERT( !pPool || pPool->pImp->mpMaster == pPool, "Secondary tanzt auf zwei Hochzeiten " );
420 1117 : SfxItemPool *pNewMaster = pImp->mpMaster ? pImp->mpMaster : this;
421 1820 : for ( SfxItemPool *p = pPool; p; p = p->pImp->mpSecondary )
422 703 : p->pImp->mpMaster = pNewMaster;
423 :
424 : // neuen Secondary-Pool merken
425 1117 : pImp->mpSecondary = pPool;
426 1117 : }
427 :
428 : // -----------------------------------------------------------------------
429 :
430 185235 : SfxMapUnit SfxItemPool::GetMetric( sal_uInt16 ) const
431 : {
432 : DBG_CHKTHIS(SfxItemPool, 0);
433 :
434 185235 : return pImp->eDefMetric;
435 : }
436 :
437 : // -----------------------------------------------------------------------
438 :
439 5568 : void SfxItemPool::SetDefaultMetric( SfxMapUnit eNewMetric )
440 : {
441 : DBG_CHKTHIS(SfxItemPool, 0);
442 :
443 5568 : pImp->eDefMetric = eNewMetric;
444 5568 : }
445 :
446 484 : const rtl::OUString& SfxItemPool::GetName() const
447 : {
448 484 : return pImp->aName;
449 : }
450 :
451 : // -----------------------------------------------------------------------
452 :
453 0 : SfxItemPresentation SfxItemPool::GetPresentation
454 : (
455 : const SfxPoolItem& rItem, /* IN: <SfxPoolItem>, dessen textuelle
456 : Wert-Darstellung geliefert werden
457 : soll */
458 : SfxItemPresentation ePresent, /* IN: gew"unschte Art der Darstellung;
459 : siehe <SfxItemPresentation> */
460 : SfxMapUnit eMetric, /* IN: gew"unschte Ma\seinheit der Darstellung */
461 : XubString& rText, /* OUT: textuelle Darstellung von 'rItem' */
462 : const IntlWrapper * pIntlWrapper
463 : ) const
464 :
465 : /* [Beschreibung]
466 :
467 : "Uber diese virtuelle Methode k"onnen textuelle Darstellungen der
468 : von der jeweilige SfxItemPool-Subklasse verwalteten SfxPoolItems
469 : angefordert werden.
470 :
471 : In Ableitungen sollte diese Methode "uberladen werden und auf
472 : SfxPoolItems reagiert werden, die bei <SfxPoolItem::GetPresentation()const>
473 : keine vollst"andige Information liefern k"onnen.
474 :
475 : Die Basisklasse liefert die unver"anderte Presentation von 'rItem'.
476 : */
477 :
478 : {
479 : DBG_CHKTHIS(SfxItemPool, 0);
480 : return rItem.GetPresentation(
481 0 : ePresent, GetMetric(rItem.Which()), eMetric, rText, pIntlWrapper );
482 : }
483 :
484 :
485 : // -----------------------------------------------------------------------
486 :
487 0 : SfxItemPool* SfxItemPool::Clone() const
488 : {
489 : DBG_CHKTHIS(SfxItemPool, 0);
490 :
491 0 : SfxItemPool *pPool = new SfxItemPool( *this );
492 0 : return pPool;
493 : }
494 :
495 : // ----------------------------------------------------------------------
496 :
497 6051 : void SfxItemPool::Delete()
498 : {
499 : DBG_CHKTHIS(SfxItemPool, 0);
500 :
501 : // schon deleted?
502 6051 : if ( pImp->maPoolItems.empty() || !pImp->ppPoolDefaults )
503 6051 : return;
504 :
505 : // z.B. laufenden Requests bescheidsagen
506 5767 : pImp->aBC.Broadcast( SfxSimpleHint( SFX_HINT_DYING ) );
507 :
508 : //MA 16. Apr. 97: Zweimal durchlaufen, in der ersten Runde fuer die SetItems.
509 : //Der Klarheit halber wird das jetzt in zwei besser lesbare Schleifen aufgeteilt.
510 :
511 5767 : std::vector<SfxPoolItemArray_Impl*>::iterator itrItemArr = pImp->maPoolItems.begin();
512 5767 : SfxPoolItem** ppDefaultItem = pImp->ppPoolDefaults;
513 5767 : SfxPoolItem** ppStaticDefaultItem = pImp->ppStaticDefaults;
514 : sal_uInt16 nArrCnt;
515 :
516 : //Erst die SetItems abraeumen
517 : SAL_INFO( "svl.items", "fuer Image, dort gibt es derzeit keine Statics - Bug" );
518 5767 : if ( pImp->ppStaticDefaults )
519 : {
520 357737 : for ( nArrCnt = GetSize_Impl();
521 : nArrCnt;
522 : --nArrCnt, ++itrItemArr, ++ppDefaultItem, ++ppStaticDefaultItem )
523 : {
524 : // KSO (22.10.98): *ppStaticDefaultItem kann im dtor einer
525 : // von SfxItemPool abgeleiteten Klasse bereits geloescht worden
526 : // sein! -> CHAOS Itempool
527 351970 : if ( *ppStaticDefaultItem && (*ppStaticDefaultItem)->ISA(SfxSetItem) )
528 : {
529 723 : if ( *itrItemArr )
530 : {
531 165 : SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*itrItemArr)->begin();
532 1223 : for ( size_t n = (*itrItemArr)->size(); n; --n, ++ppHtArr )
533 1058 : if (*ppHtArr)
534 : {
535 : #ifdef DBG_UTIL
536 : ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() );
537 : #endif
538 132 : delete *ppHtArr;
539 : }
540 165 : DELETEZ( *itrItemArr );
541 : }
542 723 : if ( *ppDefaultItem )
543 : {
544 : #ifdef DBG_UTIL
545 : SetRefCount( **ppDefaultItem, 0 );
546 : #endif
547 0 : DELETEZ( *ppDefaultItem );
548 : }
549 : }
550 : }
551 : }
552 :
553 5767 : itrItemArr = pImp->maPoolItems.begin();
554 5767 : ppDefaultItem = pImp->ppPoolDefaults;
555 :
556 : //Jetzt die 'einfachen' Items
557 357737 : for ( nArrCnt = GetSize_Impl();
558 : nArrCnt;
559 : --nArrCnt, ++itrItemArr, ++ppDefaultItem )
560 : {
561 351970 : if ( *itrItemArr )
562 : {
563 51396 : SfxPoolItemArrayBase_Impl::iterator ppHtArr = (*itrItemArr)->begin();
564 119147 : for ( size_t n = (*itrItemArr)->size(); n; --n, ++ppHtArr )
565 67751 : if (*ppHtArr)
566 : {
567 : #ifdef DBG_UTIL
568 : ReleaseRef( **ppHtArr, (*ppHtArr)->GetRefCount() );
569 : #endif
570 42004 : delete *ppHtArr;
571 : }
572 51396 : DELETEZ( *itrItemArr );
573 : }
574 351970 : if ( *ppDefaultItem )
575 : {
576 : #ifdef DBG_UTIL
577 : SetRefCount( **ppDefaultItem, 0 );
578 : #endif
579 6014 : delete *ppDefaultItem;
580 : }
581 : }
582 :
583 5767 : pImp->DeleteItems();
584 : }
585 :
586 : // ----------------------------------------------------------------------
587 :
588 30589 : void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem &rItem)
589 : {
590 : DBG_CHKTHIS(SfxItemPool, 0);
591 30589 : if ( IsInRange(rItem.Which()) )
592 : {
593 : SfxPoolItem **ppOldDefault =
594 19340 : pImp->ppPoolDefaults + GetIndex_Impl(rItem.Which());
595 19340 : SfxPoolItem *pNewDefault = rItem.Clone(this);
596 19340 : pNewDefault->SetKind(SFX_ITEMS_POOLDEFAULT);
597 19340 : if ( *ppOldDefault )
598 : {
599 6202 : (*ppOldDefault)->SetRefCount(0);
600 6202 : DELETEZ( *ppOldDefault );
601 : }
602 19340 : *ppOldDefault = pNewDefault;
603 : }
604 11249 : else if ( pImp->mpSecondary )
605 11249 : pImp->mpSecondary->SetPoolDefaultItem(rItem);
606 : else
607 : {
608 : SFX_ASSERT( 0, rItem.Which(), "unknown Which-Id - cannot set pool default" );
609 : }
610 30589 : }
611 :
612 : /*
613 : * Resets the default of the given <Which-Id> back to the static default.
614 : * If a pool default exists it is removed.
615 : */
616 111 : void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 nWhichId )
617 : {
618 : DBG_CHKTHIS(SfxItemPool, 0);
619 111 : if ( IsInRange(nWhichId) )
620 : {
621 : SfxPoolItem **ppOldDefault =
622 111 : pImp->ppPoolDefaults + GetIndex_Impl( nWhichId );
623 111 : if ( *ppOldDefault )
624 : {
625 74 : (*ppOldDefault)->SetRefCount(0);
626 74 : DELETEZ( *ppOldDefault );
627 : }
628 : }
629 0 : else if ( pImp->mpSecondary )
630 0 : pImp->mpSecondary->ResetPoolDefaultItem(nWhichId);
631 : else
632 : {
633 : SFX_ASSERT( 0, nWhichId, "unknown Which-Id - cannot set pool default" );
634 : }
635 111 : }
636 :
637 : // -----------------------------------------------------------------------
638 :
639 1802097 : const SfxPoolItem& SfxItemPool::Put( const SfxPoolItem& rItem, sal_uInt16 nWhich )
640 : {
641 : DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
642 : 0 != &((const SfxSetItem&)rItem).GetItemSet(),
643 : "SetItem without ItemSet" );
644 :
645 : DBG_CHKTHIS(SfxItemPool, 0);
646 1802097 : if ( 0 == nWhich )
647 321610 : nWhich = rItem.Which();
648 :
649 : // richtigen Secondary-Pool finden
650 1802097 : bool bSID = nWhich > SFX_WHICH_MAX;
651 1802097 : if ( !bSID && !IsInRange(nWhich) )
652 : {
653 439817 : if ( pImp->mpSecondary )
654 439817 : return pImp->mpSecondary->Put( rItem, nWhich );
655 : OSL_FAIL( "unknown Which-Id - cannot put item" );
656 : }
657 :
658 : // SID oder nicht poolable (neue Definition)?
659 1362280 : sal_uInt16 nIndex = bSID ? USHRT_MAX : GetIndex_Impl(nWhich);
660 2667655 : if ( USHRT_MAX == nIndex ||
661 1305375 : IsItemFlag_Impl( nIndex, SFX_ITEM_NOT_POOLABLE ) )
662 : {
663 : SFX_ASSERT( USHRT_MAX != nIndex || rItem.Which() != nWhich ||
664 : !IsDefaultItem(&rItem) || rItem.GetKind() == SFX_ITEMS_DELETEONIDLE,
665 : nWhich, "ein nicht Pool-Item ist Default?!" );
666 56905 : SfxPoolItem *pPoolItem = rItem.Clone(pImp->mpMaster);
667 56905 : pPoolItem->SetWhich(nWhich);
668 56905 : AddRef( *pPoolItem );
669 56905 : return *pPoolItem;
670 : }
671 :
672 : SFX_ASSERT( rItem.IsA(GetDefaultItem(nWhich).Type()), nWhich,
673 : "SFxItemPool: wrong item type in Put" );
674 :
675 1305375 : SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[nIndex];
676 1305375 : if (!pItemArr)
677 : {
678 64643 : pImp->maPoolItems[nIndex] = new SfxPoolItemArray_Impl;
679 64643 : pItemArr = pImp->maPoolItems[nIndex];
680 : }
681 :
682 1305375 : SfxPoolItemArrayBase_Impl::iterator ppFree;
683 1305375 : bool ppFreeIsSet = false;
684 1305375 : if ( IsItemFlag_Impl( nIndex, SFX_ITEM_POOLABLE ) )
685 : {
686 : // wenn es ueberhaupt gepoolt ist, koennte es schon drin sein
687 1286952 : if ( IsPooledItem(&rItem) )
688 : {
689 : // 1. Schleife: teste ob der Pointer vorhanden ist.
690 : SfxPoolItemArrayBase_Impl::iterator itr =
691 827264 : std::find(pItemArr->begin(), pItemArr->end(), &rItem);
692 827264 : if (itr != pItemArr->end())
693 : {
694 770886 : AddRef(**itr);
695 770886 : return **itr;
696 : }
697 : }
698 :
699 : // 2. Schleife: dann muessen eben die Attribute verglichen werden
700 516066 : SfxPoolItemArrayBase_Impl::iterator itr = pItemArr->begin();
701 8159201 : for (; itr != pItemArr->end(); ++itr)
702 : {
703 8029807 : if (*itr)
704 : {
705 7955801 : if (**itr == rItem)
706 : {
707 386672 : AddRef(**itr);
708 386672 : return **itr;
709 : }
710 : }
711 : else
712 : {
713 74006 : if (!ppFreeIsSet)
714 : {
715 50386 : ppFree = itr;
716 50386 : ppFreeIsSet = true;
717 : }
718 : }
719 : }
720 : }
721 : else
722 : {
723 : // freien Platz suchen
724 18423 : SfxPoolItemArrayBase_Impl::iterator itr = pItemArr->begin();
725 18423 : std::advance(itr, pItemArr->nFirstFree);
726 147012 : for (; itr != pItemArr->end(); ++itr)
727 : {
728 140871 : if (!*itr)
729 : {
730 12282 : ppFree = itr;
731 12282 : ppFreeIsSet = true;
732 12282 : break;
733 : }
734 : }
735 : // naechstmoeglichen freien Platz merken
736 18423 : pItemArr->nFirstFree = std::distance(pItemArr->begin(), itr);
737 : }
738 :
739 : // nicht vorhanden, also im PtrArray eintragen
740 147817 : SfxPoolItem* pNewItem = rItem.Clone(pImp->mpMaster);
741 147817 : pNewItem->SetWhich(nWhich);
742 : #ifdef DBG_UTIL
743 : SFX_ASSERT( rItem.Type() == pNewItem->Type(), nWhich, "unequal types in Put(): no Clone()?" )
744 : if ( !rItem.ISA(SfxSetItem) )
745 : {
746 : SFX_ASSERT( !IsItemFlag(nWhich, SFX_ITEM_POOLABLE) ||
747 : rItem == *pNewItem,
748 : nWhich, "unequal items in Put(): no operator==?" );
749 : SFX_ASSERT( !IsItemFlag(*pNewItem, SFX_ITEM_POOLABLE) ||
750 : *pNewItem == rItem,
751 : nWhich, "unequal items in Put(): no operator==?" );
752 : }
753 : #endif
754 147817 : AddRef( *pNewItem, pImp->nInitRefCount );
755 :
756 147817 : if ( ppFreeIsSet == false )
757 91357 : pItemArr->push_back( pNewItem );
758 : else
759 : {
760 : DBG_ASSERT( *ppFree == 0, "using surrogate in use" );
761 56460 : *ppFree = pNewItem;
762 : }
763 147817 : return *pNewItem;
764 : }
765 :
766 : // -----------------------------------------------------------------------
767 :
768 946423 : void SfxItemPool::Remove( const SfxPoolItem& rItem )
769 : {
770 : DBG_CHKTHIS(SfxItemPool, 0);
771 :
772 : DBG_ASSERT( !rItem.ISA(SfxSetItem) ||
773 : 0 != &((const SfxSetItem&)rItem).GetItemSet(),
774 : "SetItem without ItemSet" );
775 :
776 : SFX_ASSERT( !IsPoolDefaultItem(&rItem), rItem.Which(),
777 : "wo kommt denn hier ein Pool-Default her" );
778 :
779 : // richtigen Secondary-Pool finden
780 946423 : const sal_uInt16 nWhich = rItem.Which();
781 946423 : bool bSID = nWhich > SFX_WHICH_MAX;
782 946423 : if ( !bSID && !IsInRange(nWhich) )
783 : {
784 114798 : if ( pImp->mpSecondary )
785 : {
786 114798 : pImp->mpSecondary->Remove( rItem );
787 : return;
788 : }
789 : OSL_FAIL( "unknown Which-Id - cannot remove item" );
790 : }
791 :
792 : // SID oder nicht poolable (neue Definition)?
793 831625 : sal_uInt16 nIndex = bSID ? USHRT_MAX : GetIndex_Impl(nWhich);
794 831625 : if ( bSID || IsItemFlag_Impl( nIndex, SFX_ITEM_NOT_POOLABLE ) )
795 : {
796 : SFX_ASSERT( USHRT_MAX != nIndex ||
797 : !IsDefaultItem(&rItem), rItem.Which(),
798 : "ein nicht Pool-Item ist Default?!" );
799 55023 : if ( 0 == ReleaseRef(rItem) )
800 : {
801 55023 : SfxPoolItem *pItem = &(SfxPoolItem &)rItem;
802 55023 : delete pItem;
803 : }
804 : return;
805 : }
806 :
807 : SFX_ASSERT( rItem.GetRefCount(), rItem.Which(), "RefCount == 0, Remove unmoeglich" );
808 :
809 : // statische Defaults sind eben einfach da
810 1032187 : if ( rItem.GetKind() == SFX_ITEMS_STATICDEFAULT &&
811 255585 : &rItem == *( pImp->ppStaticDefaults + GetIndex_Impl(nWhich) ) )
812 : return;
813 :
814 : // Item im eigenen Pool suchen
815 521017 : SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[nIndex];
816 : SFX_ASSERT( pItemArr, rItem.Which(), "removing Item not in Pool" );
817 521017 : SfxPoolItemArrayBase_Impl::iterator ppHtArrBeg = pItemArr->begin(), ppHtArrEnd = pItemArr->end();
818 8540372 : for (SfxPoolItemArrayBase_Impl::iterator ppHtArr = ppHtArrBeg; ppHtArr != ppHtArrEnd; ++ppHtArr)
819 : {
820 8540372 : SfxPoolItem*& p = *ppHtArr;
821 8540372 : if (p == &rItem)
822 : {
823 521017 : if ( p->GetRefCount() ) //!
824 521017 : ReleaseRef( *p );
825 : else
826 : {
827 : SFX_ASSERT( 0, rItem.Which(), "removing Item without ref" );
828 : }
829 :
830 : // ggf. kleinstmoegliche freie Position merken
831 521017 : size_t nPos = std::distance(ppHtArrBeg, ppHtArr);
832 521017 : if ( pItemArr->nFirstFree > nPos )
833 10038 : pItemArr->nFirstFree = nPos;
834 :
835 : //! MI: Hack, solange wir das Problem mit dem Outliner haben
836 : //! siehe anderes MI-REF
837 521017 : if ( 0 == p->GetRefCount() && nWhich < 4000 )
838 89135 : DELETEZ(p);
839 : return;
840 : }
841 : }
842 :
843 : // nicht vorhanden
844 : SFX_ASSERT( 0, rItem.Which(), "removing Item not in Pool" );
845 : }
846 :
847 : // -----------------------------------------------------------------------
848 :
849 7428042 : const SfxPoolItem& SfxItemPool::GetDefaultItem( sal_uInt16 nWhich ) const
850 : {
851 : DBG_CHKTHIS(SfxItemPool, 0);
852 :
853 7428042 : if ( !IsInRange(nWhich) )
854 : {
855 1481827 : if ( pImp->mpSecondary )
856 1481827 : return pImp->mpSecondary->GetDefaultItem( nWhich );
857 : SFX_ASSERT( 0, nWhich, "unknown which - dont ask me for defaults" );
858 : }
859 :
860 : DBG_ASSERT( pImp->ppStaticDefaults, "no defaults known - dont ask me for defaults" );
861 5946215 : sal_uInt16 nPos = GetIndex_Impl(nWhich);
862 5946215 : SfxPoolItem *pDefault = *(pImp->ppPoolDefaults + nPos);
863 5946215 : if ( pDefault )
864 459517 : return *pDefault;
865 5486698 : return **(pImp->ppStaticDefaults + nPos);
866 : }
867 :
868 23949 : SfxItemPool* SfxItemPool::GetSecondaryPool() const
869 : {
870 23949 : return pImp->mpSecondary;
871 : }
872 :
873 0 : SfxItemPool* SfxItemPool::GetMasterPool() const
874 : {
875 0 : return pImp->mpMaster;
876 : }
877 :
878 911 : void SfxItemPool::FreezeIdRanges()
879 :
880 : /* [Beschreibung]
881 :
882 : This method should be called at the master pool, when all secondary
883 : pools are appended to it.
884 :
885 : It calculates the ranges of 'which-ids' for fast construction of
886 : item-sets, which contains all 'which-ids'.
887 : */
888 :
889 : {
890 911 : FillItemIdRanges_Impl( pImp->mpPoolRanges );
891 911 : }
892 :
893 :
894 : // -----------------------------------------------------------------------
895 :
896 911 : void SfxItemPool::FillItemIdRanges_Impl( sal_uInt16*& pWhichRanges ) const
897 : {
898 : DBG_CHKTHIS(SfxItemPool, 0);
899 : DBG_ASSERT( !pImp->mpPoolRanges, "GetFrozenRanges() would be faster!" );
900 :
901 : const SfxItemPool *pPool;
902 911 : sal_uInt16 nLevel = 0;
903 2525 : for( pPool = this; pPool; pPool = pPool->pImp->mpSecondary )
904 1614 : ++nLevel;
905 :
906 911 : pWhichRanges = new sal_uInt16[ 2*nLevel + 1 ];
907 :
908 911 : nLevel = 0;
909 2525 : for( pPool = this; pPool; pPool = pPool->pImp->mpSecondary )
910 : {
911 1614 : *(pWhichRanges+(nLevel++)) = pPool->pImp->mnStart;
912 1614 : *(pWhichRanges+(nLevel++)) = pPool->pImp->mnEnd;
913 1614 : *(pWhichRanges+nLevel) = 0;
914 : }
915 911 : }
916 :
917 636011 : const sal_uInt16* SfxItemPool::GetFrozenIdRanges() const
918 : {
919 636011 : return pImp->mpPoolRanges;
920 : }
921 :
922 3453 : const SfxPoolItem *SfxItemPool::GetItem2(sal_uInt16 nWhich, sal_uInt32 nOfst) const
923 : {
924 : DBG_CHKTHIS(SfxItemPool, 0);
925 :
926 3453 : if ( !IsInRange(nWhich) )
927 : {
928 397 : if ( pImp->mpSecondary )
929 397 : return pImp->mpSecondary->GetItem2( nWhich, nOfst );
930 : SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot resolve surrogate" );
931 0 : return 0;
932 : }
933 :
934 : // dflt-Attribut?
935 3056 : if ( nOfst == SFX_ITEMS_DEFAULT )
936 0 : return *(pImp->ppStaticDefaults + GetIndex_Impl(nWhich));
937 :
938 3056 : SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[GetIndex_Impl(nWhich)];
939 3056 : if( pItemArr && nOfst < pItemArr->size() )
940 3056 : return (*pItemArr)[nOfst];
941 :
942 0 : return 0;
943 : }
944 :
945 : // -----------------------------------------------------------------------
946 :
947 2250 : sal_uInt32 SfxItemPool::GetItemCount2(sal_uInt16 nWhich) const
948 : {
949 : DBG_CHKTHIS(SfxItemPool, 0);
950 :
951 2250 : if ( !IsInRange(nWhich) )
952 : {
953 204 : if ( pImp->mpSecondary )
954 204 : return pImp->mpSecondary->GetItemCount2( nWhich );
955 : SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot resolve surrogate" );
956 0 : return 0;
957 : }
958 :
959 2046 : SfxPoolItemArray_Impl* pItemArr = pImp->maPoolItems[GetIndex_Impl(nWhich)];
960 2046 : if ( pItemArr )
961 1152 : return pItemArr->size();
962 894 : return 0;
963 : }
964 :
965 : // -----------------------------------------------------------------------
966 :
967 304367 : sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, sal_Bool bDeep ) const
968 : {
969 304367 : if ( !IsSlot(nSlotId) )
970 10039 : return nSlotId;
971 :
972 294328 : sal_uInt16 nCount = pImp->mnEnd - pImp->mnStart + 1;
973 18961164 : for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
974 18672392 : if ( pItemInfos[nOfs]._nSID == nSlotId )
975 5556 : return nOfs + pImp->mnStart;
976 288772 : if ( pImp->mpSecondary && bDeep )
977 89028 : return pImp->mpSecondary->GetWhich(nSlotId);
978 199744 : return nSlotId;
979 : }
980 :
981 : // -----------------------------------------------------------------------
982 :
983 17074 : sal_uInt16 SfxItemPool::GetSlotId( sal_uInt16 nWhich, sal_Bool bDeep ) const
984 : {
985 17074 : if ( !IsWhich(nWhich) )
986 0 : return nWhich;
987 :
988 17074 : if ( !IsInRange( nWhich ) )
989 : {
990 0 : if ( pImp->mpSecondary && bDeep )
991 0 : return pImp->mpSecondary->GetSlotId(nWhich);
992 : SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get slot-id" );
993 0 : return 0;
994 : }
995 :
996 17074 : sal_uInt16 nSID = pItemInfos[nWhich - pImp->mnStart]._nSID;
997 17074 : return nSID ? nSID : nWhich;
998 : }
999 :
1000 : // -----------------------------------------------------------------------
1001 :
1002 0 : sal_uInt16 SfxItemPool::GetTrueWhich( sal_uInt16 nSlotId, sal_Bool bDeep ) const
1003 : {
1004 0 : if ( !IsSlot(nSlotId) )
1005 0 : return 0;
1006 :
1007 0 : sal_uInt16 nCount = pImp->mnEnd - pImp->mnStart + 1;
1008 0 : for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
1009 0 : if ( pItemInfos[nOfs]._nSID == nSlotId )
1010 0 : return nOfs + pImp->mnStart;
1011 0 : if ( pImp->mpSecondary && bDeep )
1012 0 : return pImp->mpSecondary->GetTrueWhich(nSlotId);
1013 0 : return 0;
1014 : }
1015 :
1016 : // -----------------------------------------------------------------------
1017 :
1018 0 : sal_uInt16 SfxItemPool::GetTrueSlotId( sal_uInt16 nWhich, sal_Bool bDeep ) const
1019 : {
1020 0 : if ( !IsWhich(nWhich) )
1021 0 : return 0;
1022 :
1023 0 : if ( !IsInRange( nWhich ) )
1024 : {
1025 0 : if ( pImp->mpSecondary && bDeep )
1026 0 : return pImp->mpSecondary->GetTrueSlotId(nWhich);
1027 : SFX_ASSERT( 0, nWhich, "unknown Which-Id - cannot get slot-id" );
1028 0 : return 0;
1029 : }
1030 0 : return pItemInfos[nWhich - pImp->mnStart]._nSID;
1031 : }
1032 :
1033 919 : void SfxItemPool::SetFileFormatVersion( sal_uInt16 nFileFormatVersion )
1034 :
1035 : /* [Description]
1036 :
1037 : You must call this function to set the file format version after
1038 : concatenating your secondary-pools but before you store any
1039 : pool, itemset or item. Only set the version at the master pool,
1040 : never at any secondary pool.
1041 : */
1042 :
1043 : {
1044 : DBG_ASSERT( this == pImp->mpMaster,
1045 : "SfxItemPool::SetFileFormatVersion() but not a master pool" );
1046 1838 : for ( SfxItemPool *pPool = this; pPool; pPool = pPool->pImp->mpSecondary )
1047 919 : pPool->pImp->mnFileFormatVersion = nFileFormatVersion;
1048 919 : }
1049 :
1050 : const SfxItemPool* SfxItemPool::pStoringPool_ = 0;
1051 :
1052 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|