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