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 <limits.h>
28
29 #ifndef GCC
30 #endif
31
32 #include <svl/itempool.hxx>
33 #include <svl/itemset.hxx>
34 #include <svl/poolcach.hxx>
35
36 // STATIC DATA -----------------------------------------------------------
37
DBG_NAME(SfxItemPoolCache)38 DBG_NAME(SfxItemPoolCache)
39
40 //------------------------------------------------------------------------
41
42 SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool,
43 const SfxPoolItem *pPutItem ):
44 pPool(pItemPool),
45 pCache(new SfxItemModifyArr_Impl),
46 pSetToPut( 0 ),
47 pItemToPut( &pItemPool->Put(*pPutItem) )
48 {
49 DBG_CTOR(SfxItemPoolCache, 0);
50 DBG_ASSERT(pItemPool, "kein Pool angegeben");
51 }
52
53 //------------------------------------------------------------------------
54
SfxItemPoolCache(SfxItemPool * pItemPool,const SfxItemSet * pPutSet)55 SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool,
56 const SfxItemSet *pPutSet ):
57 pPool(pItemPool),
58 pCache(new SfxItemModifyArr_Impl),
59 pSetToPut( pPutSet ),
60 pItemToPut( 0 )
61 {
62 DBG_CTOR(SfxItemPoolCache, 0);
63 DBG_ASSERT(pItemPool, "kein Pool angegeben");
64 }
65
66 //------------------------------------------------------------------------
67
~SfxItemPoolCache()68 SfxItemPoolCache::~SfxItemPoolCache()
69 {
70 DBG_DTOR(SfxItemPoolCache, 0);
71 for ( size_t nPos = 0; nPos < pCache->size(); ++nPos ) {
72 pPool->Remove( *(*pCache)[nPos].pPoolItem );
73 pPool->Remove( *(*pCache)[nPos].pOrigItem );
74 }
75 delete pCache; pCache = 0;
76
77 if ( pItemToPut )
78 pPool->Remove( *pItemToPut );
79 }
80
81 //------------------------------------------------------------------------
82
ApplyTo(const SfxSetItem & rOrigItem,sal_Bool bNew)83 const SfxSetItem& SfxItemPoolCache::ApplyTo( const SfxSetItem &rOrigItem, sal_Bool bNew )
84 {
85 DBG_CHKTHIS(SfxItemPoolCache, 0);
86 DBG_ASSERT( pPool == rOrigItem.GetItemSet().GetPool(), "invalid Pool" );
87 DBG_ASSERT( IsDefaultItem( &rOrigItem ) || IsPooledItem( &rOrigItem ),
88 "original not in pool" );
89
90 // Find whether this Transformations ever occurred
91 for ( size_t nPos = 0; nPos < pCache->size(); ++nPos )
92 {
93 SfxItemModifyImpl &rMapEntry = (*pCache)[nPos];
94 if ( rMapEntry.pOrigItem == &rOrigItem )
95 {
96 // aendert sich ueberhaupt etwas?
97 if ( rMapEntry.pPoolItem != &rOrigItem )
98 {
99 rMapEntry.pPoolItem->AddRef(2); // einen davon fuer den Cache
100 if ( bNew )
101 pPool->Put( rOrigItem ); //! AddRef??
102 }
103 return *rMapEntry.pPoolItem;
104 }
105 }
106
107 // die neue Attributierung in einem neuen Set eintragen
108 SfxSetItem *pNewItem = (SfxSetItem *)rOrigItem.Clone();
109 if ( pItemToPut )
110 {
111 pNewItem->GetItemSet().PutDirect( *pItemToPut );
112 DBG_ASSERT( &pNewItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut,
113 "wrong item in temporary set" );
114 }
115 else
116 pNewItem->GetItemSet().Put( *pSetToPut );
117 const SfxSetItem* pNewPoolItem = (const SfxSetItem*) &pPool->Put( *pNewItem );
118 DBG_ASSERT( pNewPoolItem != pNewItem, "Pool: rein == raus?" );
119 delete pNewItem;
120
121 // Refernzzaehler anpassen, je einen davon fuer den Cache
122 pNewPoolItem->AddRef( pNewPoolItem != &rOrigItem ? 2 : 1 );
123 if ( bNew )
124 pPool->Put( rOrigItem ); //! AddRef??
125
126 // die Transformation im Cache eintragen
127 SfxItemModifyImpl aModify;
128 aModify.pOrigItem = &rOrigItem;
129 aModify.pPoolItem = (SfxSetItem*) pNewPoolItem;
130 pCache->push_back( aModify );
131
132 DBG_ASSERT( !pItemToPut ||
133 &pNewPoolItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut,
134 "wrong item in resulting set" );
135
136 return *pNewPoolItem;
137 }
138
139
140
141