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