summaryrefslogtreecommitdiff
path: root/libs/gtkmm2/gtk/gtkmm/treeiter.h
diff options
context:
space:
mode:
Diffstat (limited to 'libs/gtkmm2/gtk/gtkmm/treeiter.h')
-rw-r--r--libs/gtkmm2/gtk/gtkmm/treeiter.h517
1 files changed, 517 insertions, 0 deletions
diff --git a/libs/gtkmm2/gtk/gtkmm/treeiter.h b/libs/gtkmm2/gtk/gtkmm/treeiter.h
new file mode 100644
index 0000000000..49a639d4cf
--- /dev/null
+++ b/libs/gtkmm2/gtk/gtkmm/treeiter.h
@@ -0,0 +1,517 @@
+// -*- c++ -*-
+// Generated by gtkmmproc -- DO NOT MODIFY!
+#ifndef _GTKMM_TREEITER_H
+#define _GTKMM_TREEITER_H
+
+#include <glibmm.h>
+
+/* $Id$ */
+
+/* Copyright(C) 1998-2002 The gtkmm Development Team
+ *
+ * This library is free software, ) you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation, ) either
+ * version 2 of the License, or(at your option) any later version.
+ *
+ * This library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library, ) if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+
+#include <gtkmm/treemodelcolumn.h>
+#include <gtkmmconfig.h>
+#include <iterator>
+#include <gtk/gtktreemodel.h> /* for GtkTreeIter */
+
+GLIBMM_USING_STD(forward_iterator_tag)
+
+
+namespace Gtk
+{
+
+class TreeModel;
+class TreeRow;
+class TreeNodeChildren;
+
+/**
+ * @ingroup TreeView
+ */
+class TreeIterBase
+{
+ public:
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ typedef TreeIterBase CppObjectType;
+ typedef GtkTreeIter BaseObjectType;
+
+ static GType get_type() G_GNUC_CONST;
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+ TreeIterBase();
+
+ explicit TreeIterBase(const GtkTreeIter* gobject); // always takes a copy
+
+ ///Provides access to the underlying C instance.
+ GtkTreeIter* gobj() { return &gobject_; }
+
+ ///Provides access to the underlying C instance.
+ const GtkTreeIter* gobj() const { return &gobject_; }
+
+protected:
+ GtkTreeIter gobject_;
+
+private:
+
+
+ //A wrap() for TreeIterBase* wouldn't be very helpful.
+
+
+};
+
+
+// In order to offer STL-like iterator functionality, we cannot wrap
+// GtkTreeIter directly. Most GTK+ functions that operate on GtkTreeIter
+// are virtual functions in GtkTreeModel. Therefore, the C++ TreeIter
+// must store a pointer to the Gtk::TreeModel to which it belongs.
+//
+// Another problem, which is much worse, is that the GTK+ tree iterator
+// doesn't support the STL-style half-open interval [begin,end). Instead,
+// it uses a [first,last] interval, and functions return FALSE to indicate
+// the end was reached. Also, some functions accept a NULL GtkTreeIter*,
+// which will be interpreted as the end() iterator.
+//
+// Most of the immense complexity in the Gtk::TreeIter implementation is
+// needed for proper emulation of [begin,end) intervals. Unfortunately,
+// it's not even possible to encapsulate everything in the TreeIter
+// class. Almost all wrapper methods dealing with GtkTreeIter must be
+// carefully implemented by hand. TODO: document implementation details
+
+//TODO: Implement a const_iterator too:
+//danielk says that this ConstTreeIter class should return a ConstTreeRow, which would not allow operator=.
+
+/** A Gtk::TreeModel::iterator is a reference to a specific node on a specific
+ * model.
+ *
+ * It is a generic structure with an integer and three generic pointers.
+ * These are filled in by the model in a model-specific way.
+ *
+ * One can convert a path to an iterator by calling Gtk::TreeModel::get_iter().
+ *
+ * These iterators are the primary way of accessing a model and are similar to the iterators
+ * used by Gtk::TextBuffer. The model interface defines a set of operations
+ * using them for navigating the model.
+ *
+ * The lifecycle of an iterator can be a little confusing at first. Iterators
+ * are expected to always be valid for as long as the model is unchanged (and
+ * doesn't emit a signal).
+ * Additionally, some models guarantee that an iterator is valid for as
+ * long as the node it refers to is valid (most notably the Gtk::TreeStore and
+ * Gtk::ListStore).
+ *
+ * Although generally uninteresting, as one always has to
+ * allow for the case where iterators do not persist beyond a signal, some very
+ * important performance enhancements were made in the sort model. As a result,
+ * the Gtk::TREE_MODEL_ITERS_PERSIST flag was added to indicate this behaviour -
+ * see Gtk::TreeModel::get_flags().
+ *
+ * Typedefed as Gtk::TreeModel::iterator.
+ * The Gtk::TreeModel iterator.
+ * @ingroup TreeView
+ */
+class TreeIter : public TreeIterBase
+{
+public:
+ typedef std::bidirectional_iterator_tag iterator_category;
+ typedef Gtk::TreeRow value_type;
+ typedef int difference_type;
+ typedef const Gtk::TreeRow& reference;
+ typedef const Gtk::TreeRow* pointer;
+
+ TreeIter();
+
+ TreeIter& operator++();
+ const TreeIter operator++(int);
+
+ /** Please note that this is very slow compared to operator++().
+ */
+ TreeIter& operator--();
+
+ /** Please note that this is very slow compared to operator++().
+ */
+ const TreeIter operator--(int);
+
+ inline reference operator*() const;
+ inline pointer operator->() const;
+
+ bool equal(const TreeIter& other) const;
+
+ /** Discover whether the iterator is valid, and not equal to end().
+ */
+ operator bool() const;
+
+ /** This is only useful when implementing a custom Gtk::TreeModel class.
+ * Compare the iterator's stamp with your model's stamp to discover whether it is valid.
+ * @see set_stamp().
+ * @result The iterator's stamp.
+ */
+ int get_stamp() const;
+
+ /** This is only useful when implementing a custom Gtk::TreeModel class.
+ * Set the stamp to be equal to your model's stamp, to mark the iterator as valid.
+ * When your model's structure changes, you should increment your model's stamp
+ * to mark all older iterators as invalid. They will be recognised as invalid because
+ * they will then have an incorrect stamp.
+ */
+ void set_stamp(int stamp);
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+ explicit TreeIter(TreeModel* model); // used in TreeModel methods
+ TreeIter(GtkTreeModel* model, const GtkTreeIter* iter); // used by signal proxies
+
+ void set_model_refptr(const Glib::RefPtr<TreeModel>& model);
+ void set_model_gobject(GtkTreeModel* model);
+ GtkTreeModel* get_model_gobject() const;
+
+ void setup_end_iterator(const TreeIter& last_valid);
+
+ const GtkTreeIter* get_gobject_if_not_end() const
+ { return (!is_end_) ? &gobject_ : 0; }
+
+ const GtkTreeIter* get_parent_gobject_if_end() const
+ { return (is_end_ && gobject_.stamp) ? &gobject_ : 0; }
+
+protected:
+
+ // Yes, using a simple TreeModel* rather than Glib::RefPtr<TreeModel>
+ // violates the general policy. But Gtk::TreeIter should have a trivial
+ // copy constructor and assignment operator, i.e. it must contain only
+ // POD (plain old data).
+ //
+ // Gtk::TreeIter is copied a lot, particularly often as return value from
+ // methods. Postfix ++ must return by value, and STL algorithms usually
+ // pass iterators by value, too. With a RefPtr<> as member data, copying
+ // would no longer be trivial, and even cause frequent calls to reference()
+ // and unreference(). That usually doesn't matter much for GUI stuff, but
+ // Gtk::TreeModel is used as a generic container. Imagine a for-loop that
+ // checks whether iter != children.end() on each iteration.
+
+ TreeModel* model_;
+ bool is_end_;
+
+ friend class Gtk::TreeRow;
+ friend class Gtk::TreeNodeChildren;
+ friend class Gtk::TreeModel;
+
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+};
+
+/** @relates Gtk::TreeIter */
+inline bool operator==(const TreeIter& lhs, const TreeIter& rhs)
+ { return lhs.equal(rhs); }
+
+/** @relates Gtk::TreeIter */
+inline bool operator!=(const TreeIter& lhs, const TreeIter& rhs)
+ { return !lhs.equal(rhs); }
+
+
+template <class ColumnType>
+class TreeValueProxy
+{
+public:
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ inline TreeValueProxy(const TreeRow& row, const TreeModelColumn<ColumnType>& column);
+#endif
+
+ inline TreeValueProxy<ColumnType>& operator=(const ColumnType& data);
+ inline operator ColumnType() const;
+
+private:
+ const TreeRow& row_;
+ const TreeModelColumn<ColumnType>& column_;
+
+ // no copy assignment
+ TreeValueProxy<ColumnType>& operator=(const TreeValueProxy<ColumnType>&);
+};
+
+
+/** Typedefed as TreeModel::Row.
+ *
+ * Dereference a TreeModel::iterator to get the Row. Use operator[] or set_value() and get_value() to access the
+ * values in the columns of this row.
+ *
+ * If the model contains a hierarchy of rows (such as Gtk::TreeStore), then you can access the child rows with
+ * children().
+ *
+ * You can use a const TreeModel::Row& for any parameter that takes a const TreeModel::iterator&.
+ * @ingroup TreeView
+ */
+class TreeRow : public TreeIter //We use public inheritance so that we can cast from a TreeRow to a TreeIter.
+{
+public:
+
+ /** Use this to set and get the value of this @a column of this row.
+ * This is a templated method, so the compiler will not allow you to provide an inappropriate type
+ * of data for the model column.
+ *
+ * This is just a more convient syntax that does the same thing as set_value() and get_value().
+ *
+ * @param column The model column..
+ */
+ template <class ColumnType> inline
+ TreeValueProxy<ColumnType> operator[](const TreeModelColumn<ColumnType>& column) const;
+
+ /** Sets the value of this @a column of this row.
+ * This is a templated method, so the compiler will not allow you to provide an inappropriate type
+ * of @a data for the model column.
+ *
+ * See also operator[].
+ *
+ * @param column The model column.
+ * @param data The new value to use for this column of this row.
+ */
+ template <class ColumnType>
+ void set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data) const;
+
+ /** Use set_value(const TreeModelColumn<>& column, const ColumnType& data) unless
+ * you do not know the column type at compile-time.
+ * If the @a data is of an inappropriate C++ type then this might fail at runtime.
+ * @param column The number of the column whose value you want to change.
+ * @param data The new value to use for this column of this row.
+ */
+ template <class ColumnType>
+ void set_value(int column, const ColumnType& data) const;
+
+ /** Gets the value of this @a column of this row.
+ * This is a templated method, so the compiler will not allow you to provide an inappropriate type
+ * of data for the model column.
+ *
+ * See also operator[].
+ *
+ * @param column The model column.
+ * @result The new value to use for this column of this row.
+ */
+ template <class ColumnType>
+ ColumnType get_value(const TreeModelColumn<ColumnType>& column) const;
+
+ /** Use get_value(const TreeModelColumn<>& column) unless
+ * you do not know the column type at compile-time.
+ * If the @a data output argument is of an inappropriate C++ type then this might fail at runtime.
+ * @param column The number of the column whose value you want to change.
+ * @retval data An output argument which will contain the value of this column of this row.
+ */
+ template <class ColumnType>
+ void get_value(int column, ColumnType& data) const;
+
+ /** This returns an STL-like container API, for iterating over the rows.
+ * See also Gtk::TreeModel::children() for the top-level children.
+ */
+ const TreeNodeChildren& children() const;
+
+ /** Gets an iterator to the parent row of this row.
+ * @result An iterator to the parent row.
+ */
+ TreeIter parent() const;
+
+ /** Discover whether this is a valid row.
+ */
+ operator bool() const;
+
+ /// Provides access to the underlying C GObject.
+ GtkTreeIter* gobj() { return TreeIter::gobj(); }
+
+ /// Provides access to the underlying C GObject.
+ const GtkTreeIter* gobj() const { return TreeIter::gobj(); }
+
+private:
+ // Forwarders to Gtk::TreeModel virtual methods.
+ void set_value_impl(int column, const Glib::ValueBase& value) const;
+ void get_value_impl(int column, Glib::ValueBase& value) const;
+};
+
+
+//TODO: Document begin(), end(), size(), etc, in an STL-style way. murrayc.
+
+/** typedefed as TreeModel::Children.
+ * Virtual container of TreeModel::Row items.
+ * @ingroup TreeView
+ */
+class TreeNodeChildren : public TreeIter
+{
+public:
+ typedef Gtk::TreeRow value_type;
+ typedef unsigned int size_type;
+ typedef int difference_type;
+ typedef Gtk::TreeIter iterator;
+
+ #ifndef GLIBMM_HAVE_SUN_REVERSE_ITERATOR
+ typedef std::reverse_iterator<iterator> reverse_iterator;
+ #else
+ typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
+ int, int&, int*, ptrdiff_t> reverse_iterator;
+ #endif
+
+ typedef Gtk::TreeIter const_iterator; //TODO: Make it a real const_iterator.
+
+ #ifndef GLIBMM_HAVE_SUN_REVERSE_ITERATOR
+ typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
+ #else
+ typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
+ int, const int&, const int*, ptrdiff_t> const_reverse_iterator;
+ #endif
+
+ iterator begin();
+ const_iterator begin() const;
+ iterator end();
+ const_iterator end() const;
+
+ // Note: there is no advantage in not inlining these methods.
+ // We can't change them without breaking ABI anyway.
+ reverse_iterator rbegin() { return reverse_iterator(end()); }
+ reverse_iterator rend() { return reverse_iterator(begin()); }
+ const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
+ const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
+
+ value_type operator[](size_type index) const;
+
+ size_type size() const;
+ bool empty() const;
+ operator bool() const { return !empty(); }
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+ explicit TreeNodeChildren(TreeModel* model)
+ : TreeIter(model) {}
+
+ const GtkTreeIter* get_parent_gobject() const
+ { return (gobject_.stamp != 0) ? &gobject_ : 0; }
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+};
+
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+/**** Gtk::TreeIter ********************************************************/
+
+inline
+TreeIter::reference TreeIter::operator*() const
+{
+ return static_cast<const TreeRow&>(*this);
+}
+
+inline
+TreeIter::pointer TreeIter::operator->() const
+{
+ return static_cast<const TreeRow*>(this);
+}
+
+
+/**** Gtk::TreeValueProxy<> ************************************************/
+
+template <class ColumnType> inline
+TreeValueProxy<ColumnType>::TreeValueProxy(const TreeRow& row, const TreeModelColumn<ColumnType>& column)
+:
+ row_ (row),
+ column_ (column)
+{}
+
+template <class ColumnType> inline
+TreeValueProxy<ColumnType>& TreeValueProxy<ColumnType>::operator=(const ColumnType& data)
+{
+ row_.set_value(column_, data);
+ return *this;
+}
+
+template <class ColumnType> inline
+TreeValueProxy<ColumnType>::operator ColumnType() const
+{
+ return row_.get_value(column_);
+}
+
+
+/**** Gtk::TreeRow *********************************************************/
+
+template <class ColumnType> inline
+TreeValueProxy<ColumnType> TreeRow::operator[](const TreeModelColumn<ColumnType>& column) const
+{
+ return TreeValueProxy<ColumnType>(*this, column);
+}
+
+template <class ColumnType>
+void TreeRow::set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data) const
+{
+ typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
+
+ ValueType value;
+ value.init(column.type());
+
+ value.set(data);
+ this->set_value_impl(column.index(), value);
+}
+
+template <class ColumnType>
+void TreeRow::set_value(int column, const ColumnType& data) const
+{
+ //This could fail at run-time, because the wrong ColumnType might be used.
+ //It's only for dynamically generated model columns.
+
+ typedef typename Gtk::TreeModelColumn<ColumnType> type_cppcolumn;
+ typedef typename type_cppcolumn::ValueType ValueType;
+
+ ValueType value;
+ value.init(ValueType::value_type());
+
+ value.set(data);
+ this->set_value_impl(column, value);
+}
+
+template <class ColumnType>
+ColumnType TreeRow::get_value(const TreeModelColumn<ColumnType>& column) const
+{
+ typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
+
+ ValueType value;
+ this->get_value_impl(column.index(), value);
+
+ return value.get();
+}
+
+template <class ColumnType>
+void TreeRow::get_value(int column, ColumnType& data) const
+{
+ //This could fail at run-time, because the wrong ColumnType might be used.
+ //It's only for dynamically generated model columns.
+
+ typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
+
+ ValueType value;
+ this->get_value_impl(column, value);
+
+ data = value.get();
+}
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} // namespace Gtk
+
+
+namespace Glib
+{
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+template <>
+class Value<Gtk::TreeIterBase> : public Glib::Value_Boxed<Gtk::TreeIterBase>
+{};
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+} // namespace Glib
+
+#endif /* _GTKMM_TREEITER_H */
+