/************************************************************** * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * *************************************************************/ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_comphelper.hxx" #include #include #include #include #include //......................................................................... namespace comphelper { //......................................................................... //============================================================================== IndexAccessIterator::IndexAccessIterator(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xStartingPoint) :m_xStartingPoint(xStartingPoint) ,m_xCurrentObject(NULL) { OSL_ENSURE(m_xStartingPoint.is(), "IndexAccessIterator::IndexAccessIterator : no starting point !"); } IndexAccessIterator::~IndexAccessIterator() {} //------------------------------------------------------------------------------ ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> IndexAccessIterator::Next() { sal_Bool bCheckingStartingPoint = !m_xCurrentObject.is(); // ist die aktuelle Node der Anfangspunkt ? sal_Bool bAlreadyCheckedCurrent = m_xCurrentObject.is(); // habe ich die aktuelle Node schon mal mittels ShouldHandleElement testen ? if (!m_xCurrentObject.is()) m_xCurrentObject = m_xStartingPoint; ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xSearchLoop( m_xCurrentObject); sal_Bool bHasMoreToSearch = sal_True; sal_Bool bFoundSomething = sal_False; while (!bFoundSomething && bHasMoreToSearch) { // pre-order-traversierung if (!bAlreadyCheckedCurrent && ShouldHandleElement(xSearchLoop)) { m_xCurrentObject = xSearchLoop; bFoundSomething = sal_True; } else { // zuerst absteigen, wenn moeglich ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess> xContainerAccess(xSearchLoop, ::com::sun::star::uno::UNO_QUERY); if (xContainerAccess.is() && xContainerAccess->getCount() && ShouldStepInto(xContainerAccess)) { // zum ersten Child ::com::sun::star::uno::Any aElement(xContainerAccess->getByIndex(0)); xSearchLoop = *(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>*)aElement.getValue(); bCheckingStartingPoint = sal_False; m_arrChildIndizies.push_back((sal_Int32)0); } else { // dann nach oben und nach rechts, wenn moeglich while (m_arrChildIndizies.size() > 0) { // (mein Stack ist nich leer, also kann ich noch nach oben gehen) ::com::sun::star::uno::Reference< ::com::sun::star::container::XChild> xChild(xSearchLoop, ::com::sun::star::uno::UNO_QUERY); OSL_ENSURE(xChild.is(), "IndexAccessIterator::Next : a content has no approriate interface !"); ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface> xParent( xChild->getParent()); xContainerAccess = ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess>(xParent, ::com::sun::star::uno::UNO_QUERY); OSL_ENSURE(xContainerAccess.is(), "IndexAccessIterator::Next : a content has an invalid parent !"); // den Index, den SearchLoop in diesem Parent hatte, von meinem 'Stack' sal_Int32 nOldSearchChildIndex = m_arrChildIndizies[m_arrChildIndizies.size() - 1]; m_arrChildIndizies.pop_back(); if (nOldSearchChildIndex < xContainerAccess->getCount() - 1) { // auf dieser Ebene geht es noch nach rechts ++nOldSearchChildIndex; // also das naechste Child ::com::sun::star::uno::Any aElement(xContainerAccess->getByIndex(nOldSearchChildIndex)); xSearchLoop = *(::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>*) aElement.getValue(); bCheckingStartingPoint = sal_False; // und dessen Position auf den 'Stack' m_arrChildIndizies.push_back((sal_Int32)nOldSearchChildIndex); break; } // hierher komme ich, wenn es auf der aktuellen Ebene nicht nach rechts geht, dann mache ich eine darueber weiter xSearchLoop = xParent; bCheckingStartingPoint = sal_False; } if ((m_arrChildIndizies.size() == 0) && !bCheckingStartingPoint) { // das ist genau dann der Fall, wenn ich keinen rechten Nachbarn fuer irgendeinen der direkten Vorfahren des // urspruenglichen xSearchLoop gefunden habe bHasMoreToSearch = sal_False; } } if (bHasMoreToSearch) { // ich habe in xSearchLoop jetzt ein Interface eines 'Knotens' meines 'Baumes', den ich noch abtesten kann if (ShouldHandleElement(xSearchLoop)) { m_xCurrentObject = xSearchLoop; bFoundSomething = sal_True; } else if (bCheckingStartingPoint) // ich bin noch am Anfang, konnte nicht absteigen, und habe an diesem Anfang nix gefunden -> nix mehr zu tun bHasMoreToSearch = sal_False; bAlreadyCheckedCurrent = sal_True; } } } if (!bFoundSomething) { OSL_ENSURE(m_arrChildIndizies.size() == 0, "IndexAccessIterator::Next : items left on stack ! how this ?"); Invalidate(); } return m_xCurrentObject; } //......................................................................... } // namespace comphelper //.........................................................................