1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_comphelper.hxx" 30 #include <com/sun/star/uno/XInterface.hpp> 31 #include <com/sun/star/container/XIndexAccess.hpp> 32 #include <com/sun/star/container/XChild.hpp> 33 #include <comphelper/container.hxx> 34 #include <osl/diagnose.h> 35 36 //......................................................................... 37 namespace comphelper 38 { 39 //......................................................................... 40 41 //============================================================================== 42 IndexAccessIterator::IndexAccessIterator(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xStartingPoint) 43 :m_xStartingPoint(xStartingPoint) 44 ,m_xCurrentObject(NULL) 45 { 46 OSL_ENSURE(m_xStartingPoint.is(), "IndexAccessIterator::IndexAccessIterator : no starting point !"); 47 } 48 49 IndexAccessIterator::~IndexAccessIterator() {} 50 51 //------------------------------------------------------------------------------ 52 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> IndexAccessIterator::Next() 53 { 54 sal_Bool bCheckingStartingPoint = !m_xCurrentObject.is(); 55 // ist die aktuelle Node der Anfangspunkt ? 56 sal_Bool bAlreadyCheckedCurrent = m_xCurrentObject.is(); 57 // habe ich die aktuelle Node schon mal mittels ShouldHandleElement testen ? 58 if (!m_xCurrentObject.is()) 59 m_xCurrentObject = m_xStartingPoint; 60 61 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xSearchLoop( m_xCurrentObject); 62 sal_Bool bHasMoreToSearch = sal_True; 63 sal_Bool bFoundSomething = sal_False; 64 while (!bFoundSomething && bHasMoreToSearch) 65 { 66 // pre-order-traversierung 67 if (!bAlreadyCheckedCurrent && ShouldHandleElement(xSearchLoop)) 68 { 69 m_xCurrentObject = xSearchLoop; 70 bFoundSomething = sal_True; 71 } 72 else 73 { 74 // zuerst absteigen, wenn moeglich 75 ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess> xContainerAccess(xSearchLoop, ::com::sun::star::uno::UNO_QUERY); 76 if (xContainerAccess.is() && xContainerAccess->getCount() && ShouldStepInto(xContainerAccess)) 77 { // zum ersten Child 78 ::com::sun::star::uno::Any aElement(xContainerAccess->getByIndex(0)); 79 xSearchLoop = *(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>*)aElement.getValue(); 80 bCheckingStartingPoint = sal_False; 81 82 m_arrChildIndizies.push_back((sal_Int32)0); 83 } 84 else 85 { 86 // dann nach oben und nach rechts, wenn moeglich 87 while (m_arrChildIndizies.size() > 0) 88 { // (mein Stack ist nich leer, also kann ich noch nach oben gehen) 89 ::com::sun::star::uno::Reference< ::com::sun::star::container::XChild> xChild(xSearchLoop, ::com::sun::star::uno::UNO_QUERY); 90 OSL_ENSURE(xChild.is(), "IndexAccessIterator::Next : a content has no approriate interface !"); 91 92 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xParent( xChild->getParent()); 93 xContainerAccess = ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>(xParent, ::com::sun::star::uno::UNO_QUERY); 94 OSL_ENSURE(xContainerAccess.is(), "IndexAccessIterator::Next : a content has an invalid parent !"); 95 96 // den Index, den SearchLoop in diesem Parent hatte, von meinem 'Stack' 97 sal_Int32 nOldSearchChildIndex = m_arrChildIndizies[m_arrChildIndizies.size() - 1]; 98 m_arrChildIndizies.pop_back(); 99 100 if (nOldSearchChildIndex < xContainerAccess->getCount() - 1) 101 { // auf dieser Ebene geht es noch nach rechts 102 ++nOldSearchChildIndex; 103 // also das naechste Child 104 ::com::sun::star::uno::Any aElement(xContainerAccess->getByIndex(nOldSearchChildIndex)); 105 xSearchLoop = *(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>*) aElement.getValue(); 106 bCheckingStartingPoint = sal_False; 107 // und dessen Position auf den 'Stack' 108 m_arrChildIndizies.push_back((sal_Int32)nOldSearchChildIndex); 109 110 break; 111 } 112 // hierher komme ich, wenn es auf der aktuellen Ebene nicht nach rechts geht, dann mache ich eine darueber weiter 113 xSearchLoop = xParent; 114 bCheckingStartingPoint = sal_False; 115 } 116 117 if ((m_arrChildIndizies.size() == 0) && !bCheckingStartingPoint) 118 { // das ist genau dann der Fall, wenn ich keinen rechten Nachbarn fuer irgendeinen der direkten Vorfahren des 119 // urspruenglichen xSearchLoop gefunden habe 120 bHasMoreToSearch = sal_False; 121 } 122 } 123 124 if (bHasMoreToSearch) 125 { // ich habe in xSearchLoop jetzt ein Interface eines 'Knotens' meines 'Baumes', den ich noch abtesten kann 126 if (ShouldHandleElement(xSearchLoop)) 127 { 128 m_xCurrentObject = xSearchLoop; 129 bFoundSomething = sal_True; 130 } 131 else 132 if (bCheckingStartingPoint) 133 // ich bin noch am Anfang, konnte nicht absteigen, und habe an diesem Anfang nix gefunden -> nix mehr zu tun 134 bHasMoreToSearch = sal_False; 135 bAlreadyCheckedCurrent = sal_True; 136 } 137 } 138 } 139 140 if (!bFoundSomething) 141 { 142 OSL_ENSURE(m_arrChildIndizies.size() == 0, "IndexAccessIterator::Next : items left on stack ! how this ?"); 143 Invalidate(); 144 } 145 146 return m_xCurrentObject; 147 } 148 149 //......................................................................... 150 } // namespace comphelper 151 //......................................................................... 152 153 154