1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: drawshapesubsetting.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_slideshow.hxx"
35 #include <canvas/debug.hxx>
36 #include <tools/diagnose_ex.h>
37 #include <canvas/verbosetrace.hxx>
39 #include <rtl/math.hxx>
40 #include <rtl/logfile.hxx>
42 #include <vcl/metaact.hxx>
43 #include <vcl/gdimtf.hxx>
44 #include <basegfx/numeric/ftools.hxx>
46 #include "drawshapesubsetting.hxx"
47 #include "drawshape.hxx"
49 #include <boost/bind.hpp>
55 using namespace ::com::sun::star
;
63 //////////////////////////////////////////////////////////////////////
67 //////////////////////////////////////////////////////////////////////
69 void DrawShapeSubsetting::ensureInitializedNodeTree() const
71 ENSURE_OR_THROW( mpMtf
,
72 "DrawShapeSubsetting::ensureInitializedNodeTree(): Invalid mtf" );
74 if( mbNodeTreeInitialized
)
75 return; // done, already initialized.
77 // init doctree vector
78 maActionClassVector
.clear();
79 maActionClassVector
.reserve( mpMtf
->GetActionCount() );
81 // search metafile for text output
84 sal_Int32
nActionIndex(0);
85 sal_Int32
nLastTextActionIndex(0);
86 for( pCurrAct
= mpMtf
->FirstAction(); pCurrAct
; pCurrAct
= mpMtf
->NextAction() )
88 // check for one of our special text doctree comments
89 switch( pCurrAct
->GetType() )
91 case META_COMMENT_ACTION
:
93 MetaCommentAction
* pAct
= static_cast<MetaCommentAction
*>(pCurrAct
);
95 // skip comment if not a special XTEXT comment
96 if( pAct
->GetComment().CompareIgnoreCaseToAscii( "XTEXT", 5 ) == COMPARE_EQUAL
)
98 // fill classification vector with NOOPs,
99 // then insert corresponding classes at
101 maActionClassVector
.resize( nActionIndex
+1, CLASS_NOOP
);
103 if( pAct
->GetComment().CompareIgnoreCaseToAscii( "XTEXT_EOC" ) == COMPARE_EQUAL
)
105 // special, because can happen
106 // in-between of portions - set
107 // character-end classificator at
108 // given index (relative to last text
110 const sal_Int32
nIndex( nLastTextActionIndex
+ pAct
->GetValue() );
112 ENSURE_OR_THROW( static_cast< ::std::size_t >(nIndex
) < maActionClassVector
.size(),
113 "DrawShapeSubsetting::ensureInitializedNodeTree(): sentence index out of range" );
115 maActionClassVector
[ nIndex
] = CLASS_CHARACTER_CELL_END
;
117 else if( pAct
->GetComment().CompareIgnoreCaseToAscii( "XTEXT_EOW" ) == COMPARE_EQUAL
)
119 // special, because can happen
120 // in-between of portions - set
121 // word-end classificator at given
122 // index (relative to last text
124 const sal_Int32
nIndex( nLastTextActionIndex
+ pAct
->GetValue() );
126 ENSURE_OR_THROW( static_cast< ::std::size_t >(nIndex
) < maActionClassVector
.size(),
127 "DrawShapeSubsetting::ensureInitializedNodeTree(): sentence index out of range" );
129 maActionClassVector
[ nIndex
] = CLASS_WORD_END
;
131 else if( pAct
->GetComment().CompareIgnoreCaseToAscii( "XTEXT_EOS" ) == COMPARE_EQUAL
)
133 // special, because can happen
134 // in-between of portions - set
135 // sentence-end classificator at given
136 // index (relative to last text
138 const sal_Int32
nIndex( nLastTextActionIndex
+ pAct
->GetValue() );
140 ENSURE_OR_THROW( static_cast< ::std::size_t >(nIndex
) < maActionClassVector
.size(),
141 "DrawShapeSubsetting::ensureInitializedNodeTree(): sentence index out of range" );
143 maActionClassVector
[ nIndex
] = CLASS_SENTENCE_END
;
145 else if( pAct
->GetComment().CompareIgnoreCaseToAscii( "XTEXT_EOL" ) == COMPARE_EQUAL
)
147 maActionClassVector
[ nActionIndex
] = CLASS_LINE_END
;
149 else if( pAct
->GetComment().CompareIgnoreCaseToAscii( "XTEXT_EOP" ) == COMPARE_EQUAL
)
151 maActionClassVector
[ nActionIndex
] = CLASS_PARAGRAPH_END
;
153 else if( pAct
->GetComment().CompareIgnoreCaseToAscii( "XTEXT_PAINTSHAPE_END" ) == COMPARE_EQUAL
)
155 maActionClassVector
[ nActionIndex
] = CLASS_SHAPE_END
;
157 else if( pAct
->GetComment().CompareIgnoreCaseToAscii( "XTEXT_PAINTSHAPE_BEGIN" ) == COMPARE_EQUAL
)
159 maActionClassVector
[ nActionIndex
] = CLASS_SHAPE_START
;
165 case META_TEXT_ACTION
:
166 case META_TEXTARRAY_ACTION
:
167 case META_STRETCHTEXT_ACTION
:
168 nLastTextActionIndex
= nActionIndex
;
169 // fallthrough intended
171 // comment action and all actions not
172 // explicitely handled here:
173 nActionIndex
+= getNextActionOffset(pCurrAct
);
178 mbNodeTreeInitialized
= true;
181 void DrawShapeSubsetting::updateSubsetBounds( const SubsetEntry
& rSubsetEntry
)
183 // TODO(F1): This removes too much from non-contiguous subsets
184 mnMinSubsetActionIndex
= ::std::min(
185 mnMinSubsetActionIndex
,
186 rSubsetEntry
.mnStartActionIndex
);
187 mnMaxSubsetActionIndex
= ::std::max(
188 mnMaxSubsetActionIndex
,
189 rSubsetEntry
.mnEndActionIndex
);
192 void DrawShapeSubsetting::updateSubsets()
194 maCurrentSubsets
.clear();
196 if( !maSubsetShapes
.empty() )
198 if( maSubset
.isEmpty() )
200 // non-subsetted node, with some child subsets
201 // that subtract from it
202 maCurrentSubsets
.push_back( DocTreeNode( 0,
203 mnMinSubsetActionIndex
,
204 DocTreeNode::NODETYPE_INVALID
) );
205 maCurrentSubsets
.push_back( DocTreeNode( mnMaxSubsetActionIndex
,
206 maActionClassVector
.size(),
207 DocTreeNode::NODETYPE_INVALID
) );
211 // subsetted node, from which some further child
212 // subsets subtract content
213 maCurrentSubsets
.push_back( DocTreeNode( maSubset
.getStartIndex(),
214 mnMinSubsetActionIndex
,
215 DocTreeNode::NODETYPE_INVALID
) );
216 maCurrentSubsets
.push_back( DocTreeNode( mnMaxSubsetActionIndex
,
217 maSubset
.getEndIndex(),
218 DocTreeNode::NODETYPE_INVALID
) );
223 // no further child subsets, simply add our subset (if any)
224 if( !maSubset
.isEmpty() )
226 // subsetted node, without any subset children
227 maCurrentSubsets
.push_back( maSubset
);
232 //////////////////////////////////////////////////////////////////////
236 //////////////////////////////////////////////////////////////////////
238 DrawShapeSubsetting::DrawShapeSubsetting() :
239 maActionClassVector(),
243 mnMinSubsetActionIndex( SAL_MAX_INT32
),
244 mnMaxSubsetActionIndex(0),
246 mbNodeTreeInitialized( false )
250 DrawShapeSubsetting::DrawShapeSubsetting( const GDIMetaFileSharedPtr
& rMtf
) :
251 maActionClassVector(),
255 mnMinSubsetActionIndex( SAL_MAX_INT32
),
256 mnMaxSubsetActionIndex(0),
258 mbNodeTreeInitialized( false )
260 ENSURE_OR_THROW( mpMtf
,
261 "DrawShapeSubsetting::DrawShapeSubsetting(): Invalid metafile" );
263 initCurrentSubsets();
266 DrawShapeSubsetting::DrawShapeSubsetting( const DocTreeNode
& rShapeSubset
,
267 const GDIMetaFileSharedPtr
& rMtf
) :
268 maActionClassVector(),
270 maSubset( rShapeSubset
),
272 mnMinSubsetActionIndex( SAL_MAX_INT32
),
273 mnMaxSubsetActionIndex(0),
275 mbNodeTreeInitialized( false )
277 ENSURE_OR_THROW( mpMtf
,
278 "DrawShapeSubsetting::DrawShapeSubsetting(): Invalid metafile" );
280 initCurrentSubsets();
283 void DrawShapeSubsetting::reset()
285 maActionClassVector
.clear();
288 maSubsetShapes
.clear();
289 mnMinSubsetActionIndex
= SAL_MAX_INT32
;
290 mnMaxSubsetActionIndex
= 0;
291 maCurrentSubsets
.clear();
292 mbNodeTreeInitialized
= false;
295 void DrawShapeSubsetting::reset( const ::boost::shared_ptr
< GDIMetaFile
>& rMtf
)
300 initCurrentSubsets();
303 void DrawShapeSubsetting::reset( const DocTreeNode
& rShapeSubset
,
304 const ::boost::shared_ptr
< GDIMetaFile
>& rMtf
)
308 maSubset
= rShapeSubset
;
310 initCurrentSubsets();
313 void DrawShapeSubsetting::initCurrentSubsets()
315 // only add subset to vector, if it's not empty - that's
316 // because the vector's content is later literally used
317 // for e.g. painting.
318 if( !maSubset
.isEmpty() )
319 maCurrentSubsets
.push_back( maSubset
);
322 DocTreeNode
DrawShapeSubsetting::getSubsetNode() const
327 bool DrawShapeSubsetting::hasSubsetShapes() const
329 return !maSubsetShapes
.empty();
332 AttributableShapeSharedPtr
DrawShapeSubsetting::getSubsetShape( const DocTreeNode
& rTreeNode
) const
334 RTL_LOGFILE_CONTEXT( aLog
, "::presentation::internal::DrawShapeSubsetting::getSubsetShape()" );
336 // subset shape already created for this DocTreeNode?
339 aEntry
.mnStartActionIndex
= rTreeNode
.getStartIndex();
340 aEntry
.mnEndActionIndex
= rTreeNode
.getEndIndex();
342 ShapeSet::const_iterator aIter
;
343 if( (aIter
=maSubsetShapes
.find( aEntry
)) != maSubsetShapes
.end() )
345 // already created, return found entry
346 return aIter
->mpShape
;
349 return AttributableShapeSharedPtr();
352 void DrawShapeSubsetting::addSubsetShape( const AttributableShapeSharedPtr
& rShape
)
354 RTL_LOGFILE_CONTEXT( aLog
, "::presentation::internal::DrawShapeSubsetting::addSubsetShape()" );
356 // subset shape already created for this DocTreeNode?
358 const DocTreeNode
& rEffectiveSubset( rShape
->getSubsetNode() );
360 aEntry
.mnStartActionIndex
= rEffectiveSubset
.getStartIndex();
361 aEntry
.mnEndActionIndex
= rEffectiveSubset
.getEndIndex();
363 ShapeSet::const_iterator aIter
;
364 if( (aIter
=maSubsetShapes
.find( aEntry
)) != maSubsetShapes
.end() )
366 // already created, increment use count and return
368 // safe cast, since set order does not depend on
369 // mnSubsetQueriedCount
370 const_cast<SubsetEntry
&>(*aIter
).mnSubsetQueriedCount
++;
374 // not yet created, init entry
375 aEntry
.mnSubsetQueriedCount
= 1;
376 aEntry
.mpShape
= rShape
;
378 maSubsetShapes
.insert( aEntry
);
380 // update cached subset borders
381 updateSubsetBounds( aEntry
);
386 bool DrawShapeSubsetting::revokeSubsetShape( const AttributableShapeSharedPtr
& rShape
)
388 RTL_LOGFILE_CONTEXT( aLog
, "::presentation::internal::DrawShapeSubsetting::revokeSubsetShape()" );
390 // lookup subset shape
392 const DocTreeNode
& rEffectiveSubset( rShape
->getSubsetNode() );
394 aEntry
.mnStartActionIndex
= rEffectiveSubset
.getStartIndex();
395 aEntry
.mnEndActionIndex
= rEffectiveSubset
.getEndIndex();
397 ShapeSet::iterator aIter
;
398 if( (aIter
=maSubsetShapes
.find( aEntry
)) == maSubsetShapes
.end() )
399 return false; // not found, subset was never queried
401 // last client of the subset revoking?
402 if( aIter
->mnSubsetQueriedCount
> 1 )
404 // no, still clients out there. Just decrement use count
405 // safe cast, since order does not depend on mnSubsetQueriedCount
406 const_cast<SubsetEntry
&>(*aIter
).mnSubsetQueriedCount
--;
408 VERBOSE_TRACE( "Subset summary: shape 0x%X, %d open subsets, revoked subset has refcount %d",
410 maSubsetShapes
.size(),
411 aIter
->mnSubsetQueriedCount
);
413 return false; // not the last client
416 VERBOSE_TRACE( "Subset summary: shape 0x%X, %d open subsets, cleared subset has range [%d,%d]",
418 maSubsetShapes
.size(),
419 aEntry
.mnStartActionIndex
,
420 aEntry
.mnEndActionIndex
);
422 // yes, remove from set
423 maSubsetShapes
.erase( aIter
);
426 // update currently active subset for _our_ shape (the
427 // part of this shape that is visible, i.e. not displayed
429 // ======================================================
432 mnMinSubsetActionIndex
= SAL_MAX_INT32
;
433 mnMaxSubsetActionIndex
= 0;
435 // TODO(P2): This is quite expensive, when
436 // after every subset effect end, we have to scan
437 // the whole shape set
439 // determine new subset range
440 ::std::for_each( maSubsetShapes
.begin(),
441 maSubsetShapes
.end(),
442 ::boost::bind(&DrawShapeSubsetting::updateSubsetBounds
,
453 /** Iterate over all action classification entries in the
454 given range, pass each element range found to the
457 This method extracts, for each of the different action
458 classifications, the count and the ranges for each of
459 them, and calls the provided functor with that
463 This is the functor's operator() calling signature,
464 with eCurrElemClassification denoting the current
465 classification type the functor is called for,
466 nCurrElemCount the running total of elements visited
467 for the given class (starting from 0), and
468 rCurrElemBegin/rCurrElemEnd the range of the current
469 element (i.e. the iterators from the start to the end
472 bool operator()( IndexClassificator eCurrElemClassification
473 sal_Int32 nCurrElemCount,
474 const IndexClassificatorVector::const_iterator& rCurrElemBegin,
475 const IndexClassificatorVector::const_iterator& rCurrElemEnd );
477 If the functor returns false, iteration over the
478 shapes is immediately stopped.
481 This functor is called for every shape found.
484 Start of range to iterate over
487 End of range to iterate over
489 @return the number of shapes found in the metafile
491 template< typename FunctorT
> void iterateActionClassifications(
492 FunctorT
& io_rFunctor
,
493 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& rBegin
,
494 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& rEnd
)
496 sal_Int32
nCurrShapeCount( 0 );
497 sal_Int32
nCurrParaCount( 0 );
498 sal_Int32
nCurrLineCount( 0 );
499 sal_Int32
nCurrSentenceCount( 0 );
500 sal_Int32
nCurrWordCount( 0 );
501 sal_Int32
nCurrCharCount( 0 );
503 DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aLastShapeStart(rBegin
);
504 DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aLastParaStart(rBegin
);
505 DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aLastLineStart(rBegin
);
506 DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aLastSentenceStart(rBegin
);
507 DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aLastWordStart(rBegin
);
508 DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aLastCharStart(rBegin
);
510 DrawShapeSubsetting::IndexClassificatorVector::const_iterator aNext
;
511 DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aCurr( rBegin
);
512 while( aCurr
!= rEnd
)
514 // aNext will hold an iterator to the next element
515 // (or the past-the-end iterator, if aCurr
516 // references the last element). Used to pass a
517 // valid half-open range to the functors.
524 ENSURE_OR_THROW( false,
525 "Unexpected type in iterateDocShapes()" );
526 case DrawShapeSubsetting::CLASS_NOOP
:
527 // ignore NOOP actions
530 case DrawShapeSubsetting::CLASS_SHAPE_START
:
531 // regardless of ending action
532 // classifications before: a new shape
533 // always also starts contained elements
540 aLastCharStart
= aCurr
;
543 case DrawShapeSubsetting::CLASS_SHAPE_END
:
544 if( !io_rFunctor( DrawShapeSubsetting::CLASS_SHAPE_END
,
553 // FALLTHROUGH intended: shape end also
555 case DrawShapeSubsetting::CLASS_PARAGRAPH_END
:
556 if( !io_rFunctor( DrawShapeSubsetting::CLASS_PARAGRAPH_END
,
565 aLastParaStart
= aNext
;
566 // FALLTHROUGH intended: para end also
568 case DrawShapeSubsetting::CLASS_LINE_END
:
569 if( !io_rFunctor( DrawShapeSubsetting::CLASS_LINE_END
,
578 aLastLineStart
= aNext
;
580 if( *aCurr
== DrawShapeSubsetting::CLASS_LINE_END
)
582 // DON'T fall through here, as a line
583 // does NOT end neither a sentence,
584 // nor a word. OTOH, all parent
585 // structures (paragraph and shape),
586 // which itself fall through to this
587 // code, DO end word, sentence and
590 // TODO(F1): Maybe a line should end a
591 // character cell, OTOH?
594 // FALLTHROUGH intended
595 case DrawShapeSubsetting::CLASS_SENTENCE_END
:
596 if( !io_rFunctor( DrawShapeSubsetting::CLASS_SENTENCE_END
,
604 ++nCurrSentenceCount
;
605 aLastSentenceStart
= aNext
;
606 // FALLTHROUGH intended
607 case DrawShapeSubsetting::CLASS_WORD_END
:
608 if( !io_rFunctor( DrawShapeSubsetting::CLASS_WORD_END
,
617 aLastWordStart
= aNext
;
618 // FALLTHROUGH intended
619 case DrawShapeSubsetting::CLASS_CHARACTER_CELL_END
:
620 if( !io_rFunctor( DrawShapeSubsetting::CLASS_CHARACTER_CELL_END
,
629 aLastCharStart
= aNext
;
637 DrawShapeSubsetting::IndexClassificator
mapDocTreeNode( DocTreeNode::NodeType eNodeType
)
641 case DocTreeNode::NODETYPE_INVALID
:
642 // FALLTHROUGH intended
645 "DrawShapeSubsetting::mapDocTreeNode(): unexpected node type");
646 return DrawShapeSubsetting::CLASS_NOOP
;
648 case DocTreeNode::NODETYPE_LOGICAL_SHAPE
:
649 // FALLTHROUGH intended
650 case DocTreeNode::NODETYPE_FORMATTING_SHAPE
:
651 return DrawShapeSubsetting::CLASS_SHAPE_END
;
653 case DocTreeNode::NODETYPE_FORMATTING_LINE
:
654 return DrawShapeSubsetting::CLASS_LINE_END
;
656 case DocTreeNode::NODETYPE_LOGICAL_PARAGRAPH
:
657 return DrawShapeSubsetting::CLASS_PARAGRAPH_END
;
659 case DocTreeNode::NODETYPE_LOGICAL_SENTENCE
:
660 return DrawShapeSubsetting::CLASS_SENTENCE_END
;
662 case DocTreeNode::NODETYPE_LOGICAL_WORD
:
663 return DrawShapeSubsetting::CLASS_WORD_END
;
665 case DocTreeNode::NODETYPE_LOGICAL_CHARACTER_CELL
:
666 return DrawShapeSubsetting::CLASS_CHARACTER_CELL_END
;
670 /// Counts number of class occurences
671 class CountClassFunctor
674 CountClassFunctor( DrawShapeSubsetting::IndexClassificator eClass
) :
680 bool operator()( DrawShapeSubsetting::IndexClassificator eCurrElemClassification
,
681 sal_Int32
/*nCurrElemCount*/,
682 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& /*rCurrElemBegin*/,
683 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& /*rCurrElemEnd*/ )
685 if( eCurrElemClassification
== meClass
)
688 return true; // never stop, count all occurences
691 sal_Int32
getCount() const
697 DrawShapeSubsetting::IndexClassificator meClass
;
698 sal_Int32 mnCurrCount
;
702 sal_Int32
DrawShapeSubsetting::implGetNumberOfTreeNodes( const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& rBegin
,
703 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& rEnd
,
704 DocTreeNode::NodeType eNodeType
) const
706 const IndexClassificator
eRequestedClass(
707 mapDocTreeNode( eNodeType
) );
709 // create a counting functor for the requested class of
711 CountClassFunctor
aFunctor( eRequestedClass
);
713 // count all occurences in the given range
714 iterateActionClassifications( aFunctor
, rBegin
, rEnd
);
716 return aFunctor
.getCount();
719 sal_Int32
DrawShapeSubsetting::getNumberOfTreeNodes( DocTreeNode::NodeType eNodeType
) const
721 ensureInitializedNodeTree();
723 return implGetNumberOfTreeNodes( maActionClassVector
.begin(),
724 maActionClassVector
.end(),
730 /** This functor finds the nth occurrence of a given
733 The operator() compares the given index value with the
734 requested index, as given on the functor's
735 constructor. Then, the operator() returns false,
736 denoting that the requested action is found.
738 class FindNthElementFunctor
741 FindNthElementFunctor( sal_Int32 nNodeIndex
,
742 DrawShapeSubsetting::IndexClassificator eClass
) :
743 mnNodeIndex( nNodeIndex
),
748 bool operator()( DrawShapeSubsetting::IndexClassificator eCurrElemClassification
,
749 sal_Int32 nCurrElemCount
,
750 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& rCurrElemBegin
,
751 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& rCurrElemEnd
)
753 if( eCurrElemClassification
== meClass
&&
754 nCurrElemCount
== mnNodeIndex
)
756 maLastBegin
= rCurrElemBegin
;
757 maLastEnd
= rCurrElemEnd
;
759 return false; // abort iteration, we've
760 // already found what we've been
764 return true; // keep on truckin'
767 DrawShapeSubsetting::IndexClassificatorVector::const_iterator
getBeginElement() const
772 DrawShapeSubsetting::IndexClassificatorVector::const_iterator
getEndElement() const
778 sal_Int32 mnNodeIndex
;
779 DrawShapeSubsetting::IndexClassificatorVector::const_iterator maLastBegin
;
780 DrawShapeSubsetting::IndexClassificatorVector::const_iterator maLastEnd
;
781 DrawShapeSubsetting::IndexClassificator meClass
;
784 DocTreeNode
makeTreeNode( const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& rBegin
,
785 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& rStart
,
786 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
& rEnd
,
787 DocTreeNode::NodeType eNodeType
)
789 return DocTreeNode( ::std::distance(rBegin
,
791 ::std::distance(rBegin
,
797 DocTreeNode
DrawShapeSubsetting::implGetTreeNode( const IndexClassificatorVector::const_iterator
& rBegin
,
798 const IndexClassificatorVector::const_iterator
& rEnd
,
799 sal_Int32 nNodeIndex
,
800 DocTreeNode::NodeType eNodeType
) const
802 const IndexClassificator
eRequestedClass(
803 mapDocTreeNode( eNodeType
) );
805 // create a nth element functor for the requested class of
806 // actions, and nNodeIndex as the target index
807 FindNthElementFunctor
aFunctor( nNodeIndex
,
810 // find given index in the given range
811 iterateActionClassifications( aFunctor
, rBegin
, rEnd
);
813 return makeTreeNode( maActionClassVector
.begin(),
814 aFunctor
.getBeginElement(),
815 aFunctor
.getEndElement(),
819 DocTreeNode
DrawShapeSubsetting::getTreeNode( sal_Int32 nNodeIndex
,
820 DocTreeNode::NodeType eNodeType
) const
822 ensureInitializedNodeTree();
824 return implGetTreeNode( maActionClassVector
.begin(),
825 maActionClassVector
.end(),
830 sal_Int32
DrawShapeSubsetting::getNumberOfSubsetTreeNodes( const DocTreeNode
& rParentNode
,
831 DocTreeNode::NodeType eNodeType
) const
833 ensureInitializedNodeTree();
835 // convert from vector indices to vector iterators
836 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aBegin( maActionClassVector
.begin() );
837 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aParentBegin( aBegin
+ rParentNode
.getStartIndex() );
838 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aParentEnd( aBegin
+ rParentNode
.getEndIndex() );
840 return implGetNumberOfTreeNodes( aParentBegin
,
845 DocTreeNode
DrawShapeSubsetting::getSubsetTreeNode( const DocTreeNode
& rParentNode
,
846 sal_Int32 nNodeIndex
,
847 DocTreeNode::NodeType eNodeType
) const
849 ensureInitializedNodeTree();
851 // convert from vector indices to vector iterators
852 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aBegin( maActionClassVector
.begin() );
853 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aParentBegin( aBegin
+ rParentNode
.getStartIndex() );
854 const DrawShapeSubsetting::IndexClassificatorVector::const_iterator
aParentEnd( aBegin
+ rParentNode
.getEndIndex() );
856 return implGetTreeNode( aParentBegin
,
862 const VectorOfDocTreeNodes
& DrawShapeSubsetting::getActiveSubsets() const
864 return maCurrentSubsets
;