1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_svl.hxx" 30 31 #include <limits.h> 32 33 #ifndef GCC 34 #endif 35 36 #include <svl/itempool.hxx> 37 #include <svl/itemset.hxx> 38 #include <svl/poolcach.hxx> 39 40 // STATIC DATA ----------------------------------------------------------- 41 42 DBG_NAME(SfxItemPoolCache) 43 44 //------------------------------------------------------------------------ 45 46 SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool, 47 const SfxPoolItem *pPutItem ): 48 pPool(pItemPool), 49 pCache(new SfxItemModifyArr_Impl), 50 pSetToPut( 0 ), 51 pItemToPut( &pItemPool->Put(*pPutItem) ) 52 { 53 DBG_CTOR(SfxItemPoolCache, 0); 54 DBG_ASSERT(pItemPool, "kein Pool angegeben"); 55 } 56 57 //------------------------------------------------------------------------ 58 59 SfxItemPoolCache::SfxItemPoolCache( SfxItemPool *pItemPool, 60 const SfxItemSet *pPutSet ): 61 pPool(pItemPool), 62 pCache(new SfxItemModifyArr_Impl), 63 pSetToPut( pPutSet ), 64 pItemToPut( 0 ) 65 { 66 DBG_CTOR(SfxItemPoolCache, 0); 67 DBG_ASSERT(pItemPool, "kein Pool angegeben"); 68 } 69 70 //------------------------------------------------------------------------ 71 72 SfxItemPoolCache::~SfxItemPoolCache() 73 { 74 DBG_DTOR(SfxItemPoolCache, 0); 75 for ( size_t nPos = 0; nPos < pCache->size(); ++nPos ) { 76 pPool->Remove( *(*pCache)[nPos].pPoolItem ); 77 pPool->Remove( *(*pCache)[nPos].pOrigItem ); 78 } 79 delete pCache; pCache = 0; 80 81 if ( pItemToPut ) 82 pPool->Remove( *pItemToPut ); 83 } 84 85 //------------------------------------------------------------------------ 86 87 const SfxSetItem& SfxItemPoolCache::ApplyTo( const SfxSetItem &rOrigItem, sal_Bool bNew ) 88 { 89 DBG_CHKTHIS(SfxItemPoolCache, 0); 90 DBG_ASSERT( pPool == rOrigItem.GetItemSet().GetPool(), "invalid Pool" ); 91 DBG_ASSERT( IsDefaultItem( &rOrigItem ) || IsPooledItem( &rOrigItem ), 92 "original not in pool" ); 93 94 // Find whether this Transformations ever occurred 95 for ( size_t nPos = 0; nPos < pCache->size(); ++nPos ) 96 { 97 SfxItemModifyImpl &rMapEntry = (*pCache)[nPos]; 98 if ( rMapEntry.pOrigItem == &rOrigItem ) 99 { 100 // aendert sich ueberhaupt etwas? 101 if ( rMapEntry.pPoolItem != &rOrigItem ) 102 { 103 rMapEntry.pPoolItem->AddRef(2); // einen davon fuer den Cache 104 if ( bNew ) 105 pPool->Put( rOrigItem ); //! AddRef?? 106 } 107 return *rMapEntry.pPoolItem; 108 } 109 } 110 111 // die neue Attributierung in einem neuen Set eintragen 112 SfxSetItem *pNewItem = (SfxSetItem *)rOrigItem.Clone(); 113 if ( pItemToPut ) 114 { 115 pNewItem->GetItemSet().PutDirect( *pItemToPut ); 116 DBG_ASSERT( &pNewItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut, 117 "wrong item in temporary set" ); 118 } 119 else 120 pNewItem->GetItemSet().Put( *pSetToPut ); 121 const SfxSetItem* pNewPoolItem = (const SfxSetItem*) &pPool->Put( *pNewItem ); 122 DBG_ASSERT( pNewPoolItem != pNewItem, "Pool: rein == raus?" ); 123 delete pNewItem; 124 125 // Refernzzaehler anpassen, je einen davon fuer den Cache 126 pNewPoolItem->AddRef( pNewPoolItem != &rOrigItem ? 2 : 1 ); 127 if ( bNew ) 128 pPool->Put( rOrigItem ); //! AddRef?? 129 130 // die Transformation im Cache eintragen 131 SfxItemModifyImpl aModify; 132 aModify.pOrigItem = &rOrigItem; 133 aModify.pPoolItem = (SfxSetItem*) pNewPoolItem; 134 pCache->push_back( aModify ); 135 136 DBG_ASSERT( !pItemToPut || 137 &pNewPoolItem->GetItemSet().Get( pItemToPut->Which() ) == pItemToPut, 138 "wrong item in resulting set" ); 139 140 return *pNewPoolItem; 141 } 142 143 144 145