1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2000, 2010 Oracle and/or its affiliates.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * This file is part of OpenOffice.org.
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.
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).
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.
26 ************************************************************************/
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>
36 //.........................................................................
39 //.........................................................................
41 //==============================================================================
42 IndexAccessIterator::IndexAccessIterator(::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
> xStartingPoint
)
43 :m_xStartingPoint(xStartingPoint
)
44 ,m_xCurrentObject(NULL
)
46 OSL_ENSURE(m_xStartingPoint
.is(), "IndexAccessIterator::IndexAccessIterator : no starting point !");
49 IndexAccessIterator::~IndexAccessIterator() {}
51 //------------------------------------------------------------------------------
52 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
> IndexAccessIterator::Next()
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
;
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
)
66 // pre-order-traversierung
67 if (!bAlreadyCheckedCurrent
&& ShouldHandleElement(xSearchLoop
))
69 m_xCurrentObject
= xSearchLoop
;
70 bFoundSomething
= sal_True
;
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
))
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
;
82 m_arrChildIndizies
.push_back((sal_Int32
)0);
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 !");
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 !");
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();
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
);
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
;
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
;
124 if (bHasMoreToSearch
)
125 { // ich habe in xSearchLoop jetzt ein Interface eines 'Knotens' meines 'Baumes', den ich noch abtesten kann
126 if (ShouldHandleElement(xSearchLoop
))
128 m_xCurrentObject
= xSearchLoop
;
129 bFoundSomething
= sal_True
;
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
;
140 if (!bFoundSomething
)
142 OSL_ENSURE(m_arrChildIndizies
.size() == 0, "IndexAccessIterator::Next : items left on stack ! how this ?");
146 return m_xCurrentObject
;
149 //.........................................................................
150 } // namespace comphelper
151 //.........................................................................