1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 28*cdf0e10cSrcweir #include "precompiled_svl.hxx" 29*cdf0e10cSrcweir 30*cdf0e10cSrcweir #ifdef _MSC_VER 31*cdf0e10cSrcweir #pragma hdrstop 32*cdf0e10cSrcweir #endif 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include <vector> 35*cdf0e10cSrcweir #include <map> 36*cdf0e10cSrcweir 37*cdf0e10cSrcweir #include <svl/stylepool.hxx> 38*cdf0e10cSrcweir #include <svl/itemiter.hxx> 39*cdf0e10cSrcweir #include <svl/itempool.hxx> 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir using namespace boost; 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir namespace { 45*cdf0e10cSrcweir // A "Node" represents a subset of inserted SfxItemSets 46*cdf0e10cSrcweir // The root node represents the empty set 47*cdf0e10cSrcweir // The other nodes contain a SfxPoolItem and represents an item set which contains their 48*cdf0e10cSrcweir // pool item and the pool items of their parents. 49*cdf0e10cSrcweir class Node 50*cdf0e10cSrcweir { 51*cdf0e10cSrcweir std::vector<Node*> mChildren; // child nodes, create by findChildNode(..) 52*cdf0e10cSrcweir // container of shared pointers of inserted item sets; for non-poolable 53*cdf0e10cSrcweir // items more than one item set is needed 54*cdf0e10cSrcweir std::vector< StylePool::SfxItemSet_Pointer_t > maItemSet; 55*cdf0e10cSrcweir const SfxPoolItem *mpItem; // my pool item 56*cdf0e10cSrcweir Node *mpUpper; // if I'm a child node that's my parent node 57*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 58*cdf0e10cSrcweir const bool mbIsItemIgnorable; 59*cdf0e10cSrcweir // <-- 60*cdf0e10cSrcweir public: 61*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 62*cdf0e10cSrcweir Node() // root node Ctor 63*cdf0e10cSrcweir : mChildren(), 64*cdf0e10cSrcweir maItemSet(), 65*cdf0e10cSrcweir mpItem( 0 ), 66*cdf0e10cSrcweir mpUpper( 0 ), 67*cdf0e10cSrcweir mbIsItemIgnorable( false ) 68*cdf0e10cSrcweir {} 69*cdf0e10cSrcweir Node( const SfxPoolItem& rItem, Node* pParent, const bool bIgnorable ) // child node Ctor 70*cdf0e10cSrcweir : mChildren(), 71*cdf0e10cSrcweir maItemSet(), 72*cdf0e10cSrcweir mpItem( rItem.Clone() ), 73*cdf0e10cSrcweir mpUpper( pParent ), 74*cdf0e10cSrcweir mbIsItemIgnorable( bIgnorable ) 75*cdf0e10cSrcweir {} 76*cdf0e10cSrcweir // <-- 77*cdf0e10cSrcweir ~Node(); 78*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 79*cdf0e10cSrcweir bool hasItemSet( const bool bCheckUsage ) const; 80*cdf0e10cSrcweir // <-- 81*cdf0e10cSrcweir // --> OD 2008-04-29 #i87808# 82*cdf0e10cSrcweir // const StylePool::SfxItemSet_Pointer_t getItemSet() const { return aItemSet[aItemSet.size()-1]; } 83*cdf0e10cSrcweir const StylePool::SfxItemSet_Pointer_t getItemSet() const 84*cdf0e10cSrcweir { 85*cdf0e10cSrcweir return maItemSet.back(); 86*cdf0e10cSrcweir } 87*cdf0e10cSrcweir const StylePool::SfxItemSet_Pointer_t getUsedOrLastAddedItemSet() const; 88*cdf0e10cSrcweir // <-- 89*cdf0e10cSrcweir void setItemSet( const SfxItemSet& rSet ){ maItemSet.push_back( StylePool::SfxItemSet_Pointer_t( rSet.Clone() ) ); } 90*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 91*cdf0e10cSrcweir Node* findChildNode( const SfxPoolItem& rItem, 92*cdf0e10cSrcweir const bool bIsItemIgnorable = false ); 93*cdf0e10cSrcweir Node* nextItemSet( Node* pLast, 94*cdf0e10cSrcweir const bool bSkipUnusedItemSet, 95*cdf0e10cSrcweir const bool bSkipIgnorable ); 96*cdf0e10cSrcweir // <-- 97*cdf0e10cSrcweir const SfxPoolItem& getPoolItem() const { return *mpItem; } 98*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 99*cdf0e10cSrcweir bool hasIgnorableChildren( const bool bCheckUsage ) const; 100*cdf0e10cSrcweir const StylePool::SfxItemSet_Pointer_t getItemSetOfIgnorableChild( 101*cdf0e10cSrcweir const bool bSkipUnusedItemSets ) const; 102*cdf0e10cSrcweir // <-- 103*cdf0e10cSrcweir }; 104*cdf0e10cSrcweir 105*cdf0e10cSrcweir // --> OD 2008-04-29 #i87808# 106*cdf0e10cSrcweir const StylePool::SfxItemSet_Pointer_t Node::getUsedOrLastAddedItemSet() const 107*cdf0e10cSrcweir { 108*cdf0e10cSrcweir std::vector< StylePool::SfxItemSet_Pointer_t >::const_reverse_iterator aIter; 109*cdf0e10cSrcweir 110*cdf0e10cSrcweir for ( aIter = maItemSet.rbegin(); aIter != maItemSet.rend(); ++aIter ) 111*cdf0e10cSrcweir { 112*cdf0e10cSrcweir if ( (*aIter).use_count() > 1 ) 113*cdf0e10cSrcweir { 114*cdf0e10cSrcweir return *aIter; 115*cdf0e10cSrcweir } 116*cdf0e10cSrcweir } 117*cdf0e10cSrcweir 118*cdf0e10cSrcweir return maItemSet.back(); 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir // <-- 121*cdf0e10cSrcweir 122*cdf0e10cSrcweir // --> OD 2008-05-06 #i86923# 123*cdf0e10cSrcweir bool Node::hasItemSet( const bool bCheckUsage ) const 124*cdf0e10cSrcweir { 125*cdf0e10cSrcweir bool bHasItemSet = false; 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir if ( maItemSet.size() > 0 ) 128*cdf0e10cSrcweir { 129*cdf0e10cSrcweir if ( bCheckUsage ) 130*cdf0e10cSrcweir { 131*cdf0e10cSrcweir std::vector< StylePool::SfxItemSet_Pointer_t >::const_reverse_iterator aIter; 132*cdf0e10cSrcweir 133*cdf0e10cSrcweir for ( aIter = maItemSet.rbegin(); aIter != maItemSet.rend(); ++aIter ) 134*cdf0e10cSrcweir { 135*cdf0e10cSrcweir if ( (*aIter).use_count() > 1 ) 136*cdf0e10cSrcweir { 137*cdf0e10cSrcweir bHasItemSet = true; 138*cdf0e10cSrcweir break; 139*cdf0e10cSrcweir } 140*cdf0e10cSrcweir } 141*cdf0e10cSrcweir } 142*cdf0e10cSrcweir else 143*cdf0e10cSrcweir { 144*cdf0e10cSrcweir bHasItemSet = true; 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir return bHasItemSet; 148*cdf0e10cSrcweir } 149*cdf0e10cSrcweir // <-- 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 152*cdf0e10cSrcweir Node* Node::findChildNode( const SfxPoolItem& rItem, 153*cdf0e10cSrcweir const bool bIsItemIgnorable ) 154*cdf0e10cSrcweir // <-- 155*cdf0e10cSrcweir { 156*cdf0e10cSrcweir Node* pNextNode = this; 157*cdf0e10cSrcweir std::vector<Node*>::iterator aIter = mChildren.begin(); 158*cdf0e10cSrcweir while( aIter != mChildren.end() ) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir if( rItem.Which() == (*aIter)->getPoolItem().Which() && 161*cdf0e10cSrcweir rItem == (*aIter)->getPoolItem() ) 162*cdf0e10cSrcweir return *aIter; 163*cdf0e10cSrcweir ++aIter; 164*cdf0e10cSrcweir } 165*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 166*cdf0e10cSrcweir pNextNode = new Node( rItem, pNextNode, bIsItemIgnorable ); 167*cdf0e10cSrcweir // <-- 168*cdf0e10cSrcweir mChildren.push_back( pNextNode ); 169*cdf0e10cSrcweir return pNextNode; 170*cdf0e10cSrcweir } 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir /* Find the next node which has a SfxItemSet. 173*cdf0e10cSrcweir The input parameter pLast has a sophisticated meaning: 174*cdf0e10cSrcweir downstairs only: 175*cdf0e10cSrcweir pLast == 0 => scan your children and their children 176*cdf0e10cSrcweir but neither your parents neither your siblings 177*cdf0e10cSrcweir downstairs and upstairs: 178*cdf0e10cSrcweir pLast == this => scan your children, their children, 179*cdf0e10cSrcweir the children of your parent behind you, and so on 180*cdf0e10cSrcweir partial downstairs and upstairs 181*cdf0e10cSrcweir pLast != 0 && pLast != this => scan your children behind the given children, 182*cdf0e10cSrcweir the children of your parent behind you and so on. 183*cdf0e10cSrcweir 184*cdf0e10cSrcweir OD 2008-03-11 #i86923# 185*cdf0e10cSrcweir introduce parameters <bSkipUnusedItemSets> and <bSkipIgnorable> 186*cdf0e10cSrcweir and its handling. 187*cdf0e10cSrcweir */ 188*cdf0e10cSrcweir Node* Node::nextItemSet( Node* pLast, 189*cdf0e10cSrcweir const bool bSkipUnusedItemSets, 190*cdf0e10cSrcweir const bool bSkipIgnorable ) 191*cdf0e10cSrcweir { 192*cdf0e10cSrcweir // Searching downstairs 193*cdf0e10cSrcweir std::vector<Node*>::iterator aIter = mChildren.begin(); 194*cdf0e10cSrcweir // For pLast == 0 and pLast == this all children are of interest 195*cdf0e10cSrcweir // for another pLast the search starts behind pLast... 196*cdf0e10cSrcweir if( pLast && pLast != this ) 197*cdf0e10cSrcweir { 198*cdf0e10cSrcweir aIter = std::find( mChildren.begin(), mChildren.end(), pLast ); 199*cdf0e10cSrcweir if( aIter != mChildren.end() ) 200*cdf0e10cSrcweir ++aIter; 201*cdf0e10cSrcweir } 202*cdf0e10cSrcweir Node *pNext = 0; 203*cdf0e10cSrcweir while( aIter != mChildren.end() ) 204*cdf0e10cSrcweir { 205*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 206*cdf0e10cSrcweir if ( bSkipIgnorable && (*aIter)->mbIsItemIgnorable ) 207*cdf0e10cSrcweir { 208*cdf0e10cSrcweir ++aIter; 209*cdf0e10cSrcweir continue; 210*cdf0e10cSrcweir } 211*cdf0e10cSrcweir // <-- 212*cdf0e10cSrcweir pNext = *aIter; 213*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 214*cdf0e10cSrcweir if ( pNext->hasItemSet( bSkipUnusedItemSets ) ) 215*cdf0e10cSrcweir { 216*cdf0e10cSrcweir return pNext; 217*cdf0e10cSrcweir } 218*cdf0e10cSrcweir if ( bSkipIgnorable && 219*cdf0e10cSrcweir pNext->hasIgnorableChildren( bSkipUnusedItemSets ) ) 220*cdf0e10cSrcweir { 221*cdf0e10cSrcweir return pNext; 222*cdf0e10cSrcweir } 223*cdf0e10cSrcweir pNext = pNext->nextItemSet( 0, bSkipUnusedItemSets, bSkipIgnorable ); // 0 => downstairs only 224*cdf0e10cSrcweir // <-- 225*cdf0e10cSrcweir if( pNext ) 226*cdf0e10cSrcweir return pNext; 227*cdf0e10cSrcweir ++aIter; 228*cdf0e10cSrcweir } 229*cdf0e10cSrcweir // Searching upstairs 230*cdf0e10cSrcweir if( pLast && mpUpper ) 231*cdf0e10cSrcweir { 232*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 233*cdf0e10cSrcweir pNext = mpUpper->nextItemSet( this, bSkipUnusedItemSets, bSkipIgnorable ); 234*cdf0e10cSrcweir // <-- 235*cdf0e10cSrcweir } 236*cdf0e10cSrcweir return pNext; 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 240*cdf0e10cSrcweir bool Node::hasIgnorableChildren( const bool bCheckUsage ) const 241*cdf0e10cSrcweir { 242*cdf0e10cSrcweir bool bHasIgnorableChildren( false ); 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir std::vector<Node*>::const_iterator aIter = mChildren.begin(); 245*cdf0e10cSrcweir while( aIter != mChildren.end() && !bHasIgnorableChildren ) 246*cdf0e10cSrcweir { 247*cdf0e10cSrcweir Node* pChild = *aIter; 248*cdf0e10cSrcweir if ( pChild->mbIsItemIgnorable ) 249*cdf0e10cSrcweir { 250*cdf0e10cSrcweir bHasIgnorableChildren = 251*cdf0e10cSrcweir !bCheckUsage || 252*cdf0e10cSrcweir ( pChild->hasItemSet( bCheckUsage /* == true */ ) || 253*cdf0e10cSrcweir pChild->hasIgnorableChildren( bCheckUsage /* == true */ ) ); 254*cdf0e10cSrcweir } 255*cdf0e10cSrcweir ++aIter; 256*cdf0e10cSrcweir } 257*cdf0e10cSrcweir 258*cdf0e10cSrcweir return bHasIgnorableChildren; 259*cdf0e10cSrcweir } 260*cdf0e10cSrcweir 261*cdf0e10cSrcweir const StylePool::SfxItemSet_Pointer_t Node::getItemSetOfIgnorableChild( 262*cdf0e10cSrcweir const bool bSkipUnusedItemSets ) const 263*cdf0e10cSrcweir { 264*cdf0e10cSrcweir DBG_ASSERT( hasIgnorableChildren( bSkipUnusedItemSets ), 265*cdf0e10cSrcweir "<Node::getItemSetOfIgnorableChild> - node has no ignorable children" ); 266*cdf0e10cSrcweir 267*cdf0e10cSrcweir std::vector<Node*>::const_iterator aIter = mChildren.begin(); 268*cdf0e10cSrcweir while( aIter != mChildren.end() ) 269*cdf0e10cSrcweir { 270*cdf0e10cSrcweir Node* pChild = *aIter; 271*cdf0e10cSrcweir if ( pChild->mbIsItemIgnorable ) 272*cdf0e10cSrcweir { 273*cdf0e10cSrcweir if ( pChild->hasItemSet( bSkipUnusedItemSets ) ) 274*cdf0e10cSrcweir { 275*cdf0e10cSrcweir return pChild->getUsedOrLastAddedItemSet(); 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir else 278*cdf0e10cSrcweir { 279*cdf0e10cSrcweir pChild = pChild->nextItemSet( 0, bSkipUnusedItemSets, false ); 280*cdf0e10cSrcweir if ( pChild ) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir return pChild->getUsedOrLastAddedItemSet(); 283*cdf0e10cSrcweir } 284*cdf0e10cSrcweir } 285*cdf0e10cSrcweir } 286*cdf0e10cSrcweir ++aIter; 287*cdf0e10cSrcweir } 288*cdf0e10cSrcweir 289*cdf0e10cSrcweir StylePool::SfxItemSet_Pointer_t pReturn; 290*cdf0e10cSrcweir return pReturn; 291*cdf0e10cSrcweir } 292*cdf0e10cSrcweir // <-- 293*cdf0e10cSrcweir 294*cdf0e10cSrcweir Node::~Node() 295*cdf0e10cSrcweir { 296*cdf0e10cSrcweir std::vector<Node*>::iterator aIter = mChildren.begin(); 297*cdf0e10cSrcweir while( aIter != mChildren.end() ) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir delete *aIter; 300*cdf0e10cSrcweir ++aIter; 301*cdf0e10cSrcweir } 302*cdf0e10cSrcweir delete mpItem; 303*cdf0e10cSrcweir } 304*cdf0e10cSrcweir 305*cdf0e10cSrcweir class Iterator : public IStylePoolIteratorAccess 306*cdf0e10cSrcweir { 307*cdf0e10cSrcweir std::map< const SfxItemSet*, Node >& mrRoot; 308*cdf0e10cSrcweir std::map< const SfxItemSet*, Node >::iterator mpCurrNode; 309*cdf0e10cSrcweir Node* mpNode; 310*cdf0e10cSrcweir const bool mbSkipUnusedItemSets; 311*cdf0e10cSrcweir const bool mbSkipIgnorable; 312*cdf0e10cSrcweir public: 313*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 314*cdf0e10cSrcweir Iterator( std::map< const SfxItemSet*, Node >& rR, 315*cdf0e10cSrcweir const bool bSkipUnusedItemSets, 316*cdf0e10cSrcweir const bool bSkipIgnorable ) 317*cdf0e10cSrcweir : mrRoot( rR ), 318*cdf0e10cSrcweir mpCurrNode( rR.begin() ), 319*cdf0e10cSrcweir mpNode(0), 320*cdf0e10cSrcweir mbSkipUnusedItemSets( bSkipUnusedItemSets ), 321*cdf0e10cSrcweir mbSkipIgnorable( bSkipIgnorable ) 322*cdf0e10cSrcweir {} 323*cdf0e10cSrcweir // <-- 324*cdf0e10cSrcweir virtual StylePool::SfxItemSet_Pointer_t getNext(); 325*cdf0e10cSrcweir virtual ::rtl::OUString getName(); 326*cdf0e10cSrcweir }; 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir StylePool::SfxItemSet_Pointer_t Iterator::getNext() 329*cdf0e10cSrcweir { 330*cdf0e10cSrcweir StylePool::SfxItemSet_Pointer_t pReturn; 331*cdf0e10cSrcweir while( mpNode || mpCurrNode != mrRoot.end() ) 332*cdf0e10cSrcweir { 333*cdf0e10cSrcweir if( !mpNode ) 334*cdf0e10cSrcweir { 335*cdf0e10cSrcweir mpNode = &mpCurrNode->second; 336*cdf0e10cSrcweir ++mpCurrNode; 337*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 338*cdf0e10cSrcweir if ( mpNode->hasItemSet( mbSkipUnusedItemSets ) ) 339*cdf0e10cSrcweir { 340*cdf0e10cSrcweir // --> OD 2008-04-30 #i87808# 341*cdf0e10cSrcweir // return pNode->getItemSet(); 342*cdf0e10cSrcweir return mpNode->getUsedOrLastAddedItemSet(); 343*cdf0e10cSrcweir // <-- 344*cdf0e10cSrcweir } 345*cdf0e10cSrcweir // <-- 346*cdf0e10cSrcweir } 347*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 348*cdf0e10cSrcweir mpNode = mpNode->nextItemSet( mpNode, mbSkipUnusedItemSets, mbSkipIgnorable ); 349*cdf0e10cSrcweir if ( mpNode && mpNode->hasItemSet( mbSkipUnusedItemSets ) ) 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir // --> OD 2008-04-30 #i87808# 352*cdf0e10cSrcweir // return pNode->getItemSet(); 353*cdf0e10cSrcweir return mpNode->getUsedOrLastAddedItemSet(); 354*cdf0e10cSrcweir // <-- 355*cdf0e10cSrcweir } 356*cdf0e10cSrcweir if ( mbSkipIgnorable && 357*cdf0e10cSrcweir mpNode && mpNode->hasIgnorableChildren( mbSkipUnusedItemSets ) ) 358*cdf0e10cSrcweir { 359*cdf0e10cSrcweir return mpNode->getItemSetOfIgnorableChild( mbSkipUnusedItemSets ); 360*cdf0e10cSrcweir } 361*cdf0e10cSrcweir // <-- 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir return pReturn; 364*cdf0e10cSrcweir } 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir ::rtl::OUString Iterator::getName() 367*cdf0e10cSrcweir { 368*cdf0e10cSrcweir ::rtl::OUString aString; 369*cdf0e10cSrcweir if( mpNode && mpNode->hasItemSet( false ) ) 370*cdf0e10cSrcweir { 371*cdf0e10cSrcweir // --> OD 2008-04-30 #i87808# 372*cdf0e10cSrcweir // aString = StylePool::nameOf( pNode->getItemSet() ); 373*cdf0e10cSrcweir aString = StylePool::nameOf( mpNode->getUsedOrLastAddedItemSet() ); 374*cdf0e10cSrcweir // <-- 375*cdf0e10cSrcweir } 376*cdf0e10cSrcweir return aString; 377*cdf0e10cSrcweir } 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir } 380*cdf0e10cSrcweir 381*cdf0e10cSrcweir /* This static method creates a unique name from a shared pointer to a SfxItemSet 382*cdf0e10cSrcweir The name is the memory address of the SfxItemSet itself. */ 383*cdf0e10cSrcweir 384*cdf0e10cSrcweir ::rtl::OUString StylePool::nameOf( SfxItemSet_Pointer_t pSet ) 385*cdf0e10cSrcweir { 386*cdf0e10cSrcweir return ::rtl::OUString::valueOf( reinterpret_cast<sal_IntPtr>( pSet.get() ), 16 ); 387*cdf0e10cSrcweir } 388*cdf0e10cSrcweir 389*cdf0e10cSrcweir // class StylePoolImpl organized a tree-structure where every node represents a SfxItemSet. 390*cdf0e10cSrcweir // The insertItemSet method adds a SfxItemSet into the tree if necessary and returns a shared_ptr 391*cdf0e10cSrcweir // to a copy of the SfxItemSet. 392*cdf0e10cSrcweir // The aRoot-Node represents an empty SfxItemSet. 393*cdf0e10cSrcweir 394*cdf0e10cSrcweir class StylePoolImpl 395*cdf0e10cSrcweir { 396*cdf0e10cSrcweir private: 397*cdf0e10cSrcweir std::map< const SfxItemSet*, Node > maRoot; 398*cdf0e10cSrcweir sal_Int32 mnCount; 399*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 400*cdf0e10cSrcweir SfxItemSet* mpIgnorableItems; 401*cdf0e10cSrcweir // <-- 402*cdf0e10cSrcweir public: 403*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 404*cdf0e10cSrcweir explicit StylePoolImpl( SfxItemSet* pIgnorableItems = 0 ) 405*cdf0e10cSrcweir : maRoot(), 406*cdf0e10cSrcweir mnCount(0), 407*cdf0e10cSrcweir mpIgnorableItems( pIgnorableItems != 0 408*cdf0e10cSrcweir ? pIgnorableItems->Clone( sal_False ) 409*cdf0e10cSrcweir : 0 ) 410*cdf0e10cSrcweir { 411*cdf0e10cSrcweir DBG_ASSERT( !pIgnorableItems || !pIgnorableItems->Count(), 412*cdf0e10cSrcweir "<StylePoolImpl::StylePoolImpl(..)> - misusage: item set for ignorable item should be empty. Please correct usage." ); 413*cdf0e10cSrcweir DBG_ASSERT( !mpIgnorableItems || !mpIgnorableItems->Count(), 414*cdf0e10cSrcweir "<StylePoolImpl::StylePoolImpl(..)> - <SfxItemSet::Clone( sal_False )> does not work as excepted - <mpIgnorableItems> is not empty. Please inform OD." ); 415*cdf0e10cSrcweir } 416*cdf0e10cSrcweir 417*cdf0e10cSrcweir ~StylePoolImpl() 418*cdf0e10cSrcweir { 419*cdf0e10cSrcweir delete mpIgnorableItems; 420*cdf0e10cSrcweir } 421*cdf0e10cSrcweir // <-- 422*cdf0e10cSrcweir 423*cdf0e10cSrcweir StylePool::SfxItemSet_Pointer_t insertItemSet( const SfxItemSet& rSet ); 424*cdf0e10cSrcweir 425*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 426*cdf0e10cSrcweir IStylePoolIteratorAccess* createIterator( bool bSkipUnusedItemSets = false, 427*cdf0e10cSrcweir bool bSkipIgnorableItems = false ); 428*cdf0e10cSrcweir // <-- 429*cdf0e10cSrcweir sal_Int32 getCount() const { return mnCount; } 430*cdf0e10cSrcweir }; 431*cdf0e10cSrcweir 432*cdf0e10cSrcweir StylePool::SfxItemSet_Pointer_t StylePoolImpl::insertItemSet( const SfxItemSet& rSet ) 433*cdf0e10cSrcweir { 434*cdf0e10cSrcweir bool bNonPoolable = false; 435*cdf0e10cSrcweir Node* pCurNode = &maRoot[ rSet.GetParent() ]; 436*cdf0e10cSrcweir SfxItemIter aIter( rSet ); 437*cdf0e10cSrcweir const SfxPoolItem* pItem = aIter.GetCurItem(); 438*cdf0e10cSrcweir // Every SfxPoolItem in the SfxItemSet causes a step deeper into the tree, 439*cdf0e10cSrcweir // a complete empty SfxItemSet would stay at the root node. 440*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 441*cdf0e10cSrcweir // insert ignorable items to the tree leaves. 442*cdf0e10cSrcweir std::auto_ptr<SfxItemSet> pFoundIgnorableItems; 443*cdf0e10cSrcweir if ( mpIgnorableItems ) 444*cdf0e10cSrcweir { 445*cdf0e10cSrcweir pFoundIgnorableItems.reset( new SfxItemSet( *mpIgnorableItems ) ); 446*cdf0e10cSrcweir } 447*cdf0e10cSrcweir while( pItem ) 448*cdf0e10cSrcweir { 449*cdf0e10cSrcweir if( !rSet.GetPool()->IsItemFlag(pItem->Which(), SFX_ITEM_POOLABLE ) ) 450*cdf0e10cSrcweir bNonPoolable = true; 451*cdf0e10cSrcweir if ( !pFoundIgnorableItems.get() || 452*cdf0e10cSrcweir ( pFoundIgnorableItems.get() && 453*cdf0e10cSrcweir pFoundIgnorableItems->Put( *pItem ) == 0 ) ) 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir pCurNode = pCurNode->findChildNode( *pItem ); 456*cdf0e10cSrcweir } 457*cdf0e10cSrcweir pItem = aIter.NextItem(); 458*cdf0e10cSrcweir } 459*cdf0e10cSrcweir if ( pFoundIgnorableItems.get() && 460*cdf0e10cSrcweir pFoundIgnorableItems->Count() > 0 ) 461*cdf0e10cSrcweir { 462*cdf0e10cSrcweir SfxItemIter aIgnorableItemsIter( *pFoundIgnorableItems ); 463*cdf0e10cSrcweir pItem = aIgnorableItemsIter.GetCurItem(); 464*cdf0e10cSrcweir while( pItem ) 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir if( !rSet.GetPool()->IsItemFlag(pItem->Which(), SFX_ITEM_POOLABLE ) ) 467*cdf0e10cSrcweir bNonPoolable = true; 468*cdf0e10cSrcweir pCurNode = pCurNode->findChildNode( *pItem, true ); 469*cdf0e10cSrcweir pItem = aIgnorableItemsIter.NextItem(); 470*cdf0e10cSrcweir } 471*cdf0e10cSrcweir } 472*cdf0e10cSrcweir // <-- 473*cdf0e10cSrcweir // Every leaf node represents an inserted item set, but "non-leaf" nodes represents subsets 474*cdf0e10cSrcweir // of inserted itemsets. 475*cdf0e10cSrcweir // These nodes could have but does not need to have a shared_ptr to a item set. 476*cdf0e10cSrcweir if( !pCurNode->hasItemSet( false ) ) 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir pCurNode->setItemSet( rSet ); 479*cdf0e10cSrcweir bNonPoolable = false; // to avoid a double insertion 480*cdf0e10cSrcweir ++mnCount; 481*cdf0e10cSrcweir } 482*cdf0e10cSrcweir // If rSet contains at least one non poolable item, a new itemset has to be inserted 483*cdf0e10cSrcweir if( bNonPoolable ) 484*cdf0e10cSrcweir pCurNode->setItemSet( rSet ); 485*cdf0e10cSrcweir #ifdef DEBUG 486*cdf0e10cSrcweir { 487*cdf0e10cSrcweir sal_Int32 nCheck = -1; 488*cdf0e10cSrcweir sal_Int32 nNo = -1; 489*cdf0e10cSrcweir IStylePoolIteratorAccess* pIter = createIterator(); 490*cdf0e10cSrcweir StylePool::SfxItemSet_Pointer_t pTemp; 491*cdf0e10cSrcweir do 492*cdf0e10cSrcweir { 493*cdf0e10cSrcweir ++nCheck; 494*cdf0e10cSrcweir pTemp = pIter->getNext(); 495*cdf0e10cSrcweir if( pCurNode->hasItemSet( false ) && pTemp.get() == pCurNode->getItemSet().get() ) 496*cdf0e10cSrcweir { 497*cdf0e10cSrcweir ::rtl::OUString aStr = StylePool::nameOf( pTemp ); 498*cdf0e10cSrcweir nNo = nCheck; 499*cdf0e10cSrcweir } 500*cdf0e10cSrcweir } while( pTemp.get() ); 501*cdf0e10cSrcweir DBG_ASSERT( mnCount == nCheck, "Wrong counting"); 502*cdf0e10cSrcweir delete pIter; 503*cdf0e10cSrcweir } 504*cdf0e10cSrcweir #endif 505*cdf0e10cSrcweir return pCurNode->getItemSet(); 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 509*cdf0e10cSrcweir IStylePoolIteratorAccess* StylePoolImpl::createIterator( bool bSkipUnusedItemSets, 510*cdf0e10cSrcweir bool bSkipIgnorableItems ) 511*cdf0e10cSrcweir { 512*cdf0e10cSrcweir return new Iterator( maRoot, bSkipUnusedItemSets, bSkipIgnorableItems ); 513*cdf0e10cSrcweir } 514*cdf0e10cSrcweir // <-- 515*cdf0e10cSrcweir 516*cdf0e10cSrcweir // Ctor, Dtor and redirected methods of class StylePool, nearly inline ;-) 517*cdf0e10cSrcweir 518*cdf0e10cSrcweir // --> OD 2008-03-07 #i86923# 519*cdf0e10cSrcweir StylePool::StylePool( SfxItemSet* pIgnorableItems ) 520*cdf0e10cSrcweir : pImpl( new StylePoolImpl( pIgnorableItems ) ) 521*cdf0e10cSrcweir {} 522*cdf0e10cSrcweir // <-- 523*cdf0e10cSrcweir 524*cdf0e10cSrcweir StylePool::SfxItemSet_Pointer_t StylePool::insertItemSet( const SfxItemSet& rSet ) 525*cdf0e10cSrcweir { return pImpl->insertItemSet( rSet ); } 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir // --> OD 2008-03-11 #i86923# 528*cdf0e10cSrcweir IStylePoolIteratorAccess* StylePool::createIterator( const bool bSkipUnusedItemSets, 529*cdf0e10cSrcweir const bool bSkipIgnorableItems ) 530*cdf0e10cSrcweir { 531*cdf0e10cSrcweir return pImpl->createIterator( bSkipUnusedItemSets, bSkipIgnorableItems ); 532*cdf0e10cSrcweir } 533*cdf0e10cSrcweir // <-- 534*cdf0e10cSrcweir 535*cdf0e10cSrcweir sal_Int32 StylePool::getCount() const 536*cdf0e10cSrcweir { return pImpl->getCount(); } 537*cdf0e10cSrcweir 538*cdf0e10cSrcweir StylePool::~StylePool() { delete pImpl; } 539*cdf0e10cSrcweir 540*cdf0e10cSrcweir // End of class StylePool 541*cdf0e10cSrcweir 542