xref: /aoo41x/main/svl/source/items/stylepool.cxx (revision 40df464e)
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