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 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 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 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 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