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