xref: /aoo41x/main/svx/source/inc/treevisitor.hxx (revision cdf0e10c)
1 /*************************************************************************
2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
3  *
4  * Copyright 2000, 2010 Oracle and/or its affiliates.
5  *
6  * OpenOffice.org - a multi-platform office productivity suite
7  *
8  * This file is part of OpenOffice.org.
9  *
10  * OpenOffice.org is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License version 3
12  * only, as published by the Free Software Foundation.
13  *
14  * OpenOffice.org is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU Lesser General Public License version 3 for more details
18  * (a copy is included in the LICENSE file that accompanied this code).
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * version 3 along with OpenOffice.org.  If not, see
22  * <http://www.openoffice.org/license.html>
23  * for a copy of the LGPLv3 License.
24  *
25 ************************************************************************/
26 
27 #ifndef SVX_TREE_VISITOR_HXX
28 #define SVX_TREE_VISITOR_HXX
29 
30 #include <stack>
31 
32 template< class ELEMENT, class NODEINFO, class PROCESSOR >
33 class TreeVisitor
34 {
35 public:
36     TreeVisitor( NODEINFO _nodeInfo )
37         :m_visitedRoot( false )
38         ,m_root()
39         ,m_current()
40         ,m_nodeInfo( _nodeInfo )
41     {
42     }
43 
44     void    process( const ELEMENT& _root, PROCESSOR& _processor )
45     {
46         m_root = _root;
47         m_visitedRoot = false;
48 
49         while ( do_step() )
50             _processor.process( m_current );
51     }
52 
53 private:
54     bool    do_step();
55 
56 private:
57     bool            m_visitedRoot;
58     ELEMENT         m_root;
59     ELEMENT         m_current;
60     const NODEINFO  m_nodeInfo;
61 
62     ::std::stack< size_t >  m_pathToCurrent;
63     ::std::stack< ELEMENT > m_currentAncestors;
64 };
65 
66 template< class ELEMENT, class NODEINFO, class PROCESSOR >
67 bool TreeVisitor< ELEMENT, NODEINFO, PROCESSOR >::do_step()
68 {
69     if ( !m_visitedRoot )
70     {
71         m_current = m_root;
72         m_visitedRoot = true;
73         return true;
74     }
75 
76     // can we step down from the current node?
77     size_t childCount = m_nodeInfo.childCount( m_current );
78     if ( childCount )
79     {
80         m_currentAncestors.push( m_current );
81         m_current = m_nodeInfo.getChild( m_current, 0 );
82         m_pathToCurrent.push( 0 );
83         return true;
84     }
85 
86     // is there a right sibling of the current node?
87     while ( !m_pathToCurrent.empty() )
88     {
89         const ELEMENT& currentParent = m_currentAncestors.top();
90         childCount = m_nodeInfo.childCount( currentParent );
91 
92         size_t currentChildPos = m_pathToCurrent.top();
93         if ( ++currentChildPos < childCount )
94         {
95             // yes there is
96             m_pathToCurrent.top() = currentChildPos;
97             m_current = m_nodeInfo.getChild( currentParent, currentChildPos );
98             return true;
99         }
100 
101         // no there isn't => step up
102         m_currentAncestors.pop();
103         m_pathToCurrent.pop();
104     }
105 
106     return false;
107 }
108 
109 #endif // SVX_TREE_VISITOR_HXX
110