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
10*40df464eSAndrew Rist *
11*40df464eSAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12*40df464eSAndrew Rist *
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.
19*40df464eSAndrew Rist *
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#
Node()58cdf0e10cSrcweir Node() // root node Ctor
59cdf0e10cSrcweir : mChildren(),
60cdf0e10cSrcweir maItemSet(),
61cdf0e10cSrcweir mpItem( 0 ),
62cdf0e10cSrcweir mpUpper( 0 ),
63cdf0e10cSrcweir mbIsItemIgnorable( false )
64cdf0e10cSrcweir {}
Node(const SfxPoolItem & rItem,Node * pParent,const bool bIgnorable)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]; }
getItemSet() const79cdf0e10cSrcweir const StylePool::SfxItemSet_Pointer_t getItemSet() const
80cdf0e10cSrcweir {
81cdf0e10cSrcweir return maItemSet.back();
82cdf0e10cSrcweir }
83cdf0e10cSrcweir const StylePool::SfxItemSet_Pointer_t getUsedOrLastAddedItemSet() const;
84cdf0e10cSrcweir // <--
setItemSet(const SfxItemSet & rSet)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 // <--
getPoolItem() const93cdf0e10cSrcweir 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#
getUsedOrLastAddedItemSet() const102cdf0e10cSrcweir 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#
hasItemSet(const bool bCheckUsage) const119cdf0e10cSrcweir 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#
findChildNode(const SfxPoolItem & rItem,const bool bIsItemIgnorable)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 */
nextItemSet(Node * pLast,const bool bSkipUnusedItemSets,const bool bSkipIgnorable)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#
hasIgnorableChildren(const bool bCheckUsage) const236cdf0e10cSrcweir 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
getItemSetOfIgnorableChild(const bool bSkipUnusedItemSets) const257cdf0e10cSrcweir 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
~Node()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#
Iterator(std::map<const SfxItemSet *,Node> & rR,const bool bSkipUnusedItemSets,const bool bSkipIgnorable)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
getNext()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
getName()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
nameOf(SfxItemSet_Pointer_t pSet)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#
StylePoolImpl(SfxItemSet * pIgnorableItems=0)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
~StylePoolImpl()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 // <--
getCount() const425cdf0e10cSrcweir sal_Int32 getCount() const { return mnCount; }
426cdf0e10cSrcweir };
427cdf0e10cSrcweir
insertItemSet(const SfxItemSet & rSet)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#
createIterator(bool bSkipUnusedItemSets,bool bSkipIgnorableItems)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#
StylePool(SfxItemSet * pIgnorableItems)515cdf0e10cSrcweir StylePool::StylePool( SfxItemSet* pIgnorableItems )
516cdf0e10cSrcweir : pImpl( new StylePoolImpl( pIgnorableItems ) )
517cdf0e10cSrcweir {}
518cdf0e10cSrcweir // <--
519cdf0e10cSrcweir
insertItemSet(const SfxItemSet & rSet)520cdf0e10cSrcweir StylePool::SfxItemSet_Pointer_t StylePool::insertItemSet( const SfxItemSet& rSet )
521cdf0e10cSrcweir { return pImpl->insertItemSet( rSet ); }
522cdf0e10cSrcweir
523cdf0e10cSrcweir // --> OD 2008-03-11 #i86923#
createIterator(const bool bSkipUnusedItemSets,const bool bSkipIgnorableItems)524cdf0e10cSrcweir IStylePoolIteratorAccess* StylePool::createIterator( const bool bSkipUnusedItemSets,
525cdf0e10cSrcweir const bool bSkipIgnorableItems )
526cdf0e10cSrcweir {
527cdf0e10cSrcweir return pImpl->createIterator( bSkipUnusedItemSets, bSkipIgnorableItems );
528cdf0e10cSrcweir }
529cdf0e10cSrcweir // <--
530cdf0e10cSrcweir
getCount() const531cdf0e10cSrcweir sal_Int32 StylePool::getCount() const
532cdf0e10cSrcweir { return pImpl->getCount(); }
533cdf0e10cSrcweir
~StylePool()534cdf0e10cSrcweir StylePool::~StylePool() { delete pImpl; }
535cdf0e10cSrcweir
536cdf0e10cSrcweir // End of class StylePool
537cdf0e10cSrcweir
538