summaryrefslogtreecommitdiff
path: root/comphelper/source/container/container.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'comphelper/source/container/container.cxx')
-rw-r--r--comphelper/source/container/container.cxx153
1 files changed, 153 insertions, 0 deletions
diff --git a/comphelper/source/container/container.cxx b/comphelper/source/container/container.cxx
new file mode 100644
index 000000000000..9f834de85b66
--- /dev/null
+++ b/comphelper/source/container/container.cxx
@@ -0,0 +1,153 @@
+/*************************************************************************
+ *
+ * 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
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_comphelper.hxx"
+#include <com/sun/star/uno/XInterface.hpp>
+#include <com/sun/star/container/XIndexAccess.hpp>
+#include <com/sun/star/container/XChild.hpp>
+#include <comphelper/container.hxx>
+#include <osl/diagnose.h>
+
+//.........................................................................
+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
+//.........................................................................
+
+