/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /************************************************************************* * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * Copyright 2000, 2010 Oracle and/or its affiliates. * * OpenOffice.org - a multi-platform office productivity suite * * This file is part of OpenOffice.org. * * OpenOffice.org is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License version 3 * only, as published by the Free Software Foundation. * * OpenOffice.org is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License version 3 for more details * (a copy is included in the LICENSE file that accompanied this code). * * You should have received a copy of the GNU Lesser General Public License * version 3 along with OpenOffice.org. If not, see * * for a copy of the LGPLv3 License. * ************************************************************************/ #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(); // Is the current node the starting point? sal_Bool bAlreadyCheckedCurrent = m_xCurrentObject.is(); // Have I already tested the current node through ShouldHandleElement? 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) { // Priming loop if (!bAlreadyCheckedCurrent && ShouldHandleElement(xSearchLoop)) { m_xCurrentObject = xSearchLoop; bFoundSomething = sal_True; } else { // First, check to see if there's a match below ::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)) { ::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 { // otherwise, look above and to the right, if possible while (m_arrChildIndizies.size() > 0) { // If the list isn't empty and there's nothing above ::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 !"); // Remove the index that SearchLoop had within this parent from my stack sal_Int32 nOldSearchChildIndex = m_arrChildIndizies[m_arrChildIndizies.size() - 1]; m_arrChildIndizies.pop_back(); if (nOldSearchChildIndex < xContainerAccess->getCount() - 1) { // Move to the right in this row ++nOldSearchChildIndex; // and check the next 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; // and update its position in the list. m_arrChildIndizies.push_back((sal_Int32)nOldSearchChildIndex); break; } // Finally, if there's nothing more to do in this row (to the right), we'll move on to the next row. xSearchLoop = xParent; bCheckingStartingPoint = sal_False; } if (m_arrChildIndizies.empty() && !bCheckingStartingPoint) { //This is the case if there is nothing to the right in the original search loop bHasMoreToSearch = sal_False; } } if (bHasMoreToSearch) { // If there is still a node in the tree which can be tested if (ShouldHandleElement(xSearchLoop)) { m_xCurrentObject = xSearchLoop; bFoundSomething = sal_True; } else if (bCheckingStartingPoint) bHasMoreToSearch = sal_False; bAlreadyCheckedCurrent = sal_True; } } } if (!bFoundSomething) { OSL_ENSURE(m_arrChildIndizies.empty(), "IndexAccessIterator::Next : items left on stack ! how this ?"); Invalidate(); } return m_xCurrentObject; } //......................................................................... } // namespace comphelper //......................................................................... /* vim:set shiftwidth=4 softtabstop=4 expandtab: */