summaryrefslogtreecommitdiff
path: root/libs/gtkmm2/gtk/gtkmm/treeiter.cc
diff options
context:
space:
mode:
Diffstat (limited to 'libs/gtkmm2/gtk/gtkmm/treeiter.cc')
-rw-r--r--libs/gtkmm2/gtk/gtkmm/treeiter.cc395
1 files changed, 395 insertions, 0 deletions
diff --git a/libs/gtkmm2/gtk/gtkmm/treeiter.cc b/libs/gtkmm2/gtk/gtkmm/treeiter.cc
new file mode 100644
index 0000000000..8c355c353d
--- /dev/null
+++ b/libs/gtkmm2/gtk/gtkmm/treeiter.cc
@@ -0,0 +1,395 @@
+// Generated by gtkmmproc -- DO NOT MODIFY!
+
+#include <gtkmm/treeiter.h>
+#include <gtkmm/private/treeiter_p.h>
+
+// -*- c++ -*-
+/* $Id$ */
+
+/* Copyright 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/treemodel.h>
+
+namespace
+{
+
+// This is copied from Totem. In future there might be a version in GTK+ itself - see bug #
+void gtkmm_gtk_tree_model_iter_previous(GtkTreeModel* tree_model, GtkTreeIter* iter)
+{
+ GtkTreePath *const path = gtk_tree_model_get_path(tree_model, iter);
+
+ if(gtk_tree_path_prev(path))
+ gtk_tree_model_get_iter(tree_model, iter, path);
+ else
+ g_assert_not_reached();
+
+ gtk_tree_path_free(path);
+}
+
+} // anonymous namespace
+
+
+namespace Gtk
+{
+
+/**** Gtk::TreeIter ********************************************************/
+
+TreeIter::TreeIter()
+:
+ TreeIterBase(),
+ model_ (0),
+ is_end_ (false)
+{}
+
+TreeIter::TreeIter(TreeModel* model)
+:
+ TreeIterBase(),
+ model_ (model),
+ is_end_ (false)
+{}
+
+TreeIter::TreeIter(GtkTreeModel* model, const GtkTreeIter* iter)
+:
+ TreeIterBase(iter),
+ model_ (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) model))),
+ is_end_ (iter == 0)
+{}
+
+TreeIter& TreeIter::operator++()
+{
+ g_assert(!is_end_);
+
+ GtkTreeIter previous = gobject_;
+
+ if(!gtk_tree_model_iter_next(model_->gobj(), &gobject_))
+ {
+ is_end_ = true;
+ gtk_tree_model_iter_parent(model_->gobj(), &gobject_, &previous);
+ }
+
+ return *this;
+}
+
+const TreeIter TreeIter::operator++(int)
+{
+ g_assert(!is_end_);
+
+ TreeIter previous (*this);
+
+ if(!gtk_tree_model_iter_next(model_->gobj(), &gobject_))
+ {
+ is_end_ = true;
+ gtk_tree_model_iter_parent(model_->gobj(), &gobject_, &previous.gobject_);
+ }
+
+ return previous;
+}
+
+TreeIter& TreeIter::operator--()
+{
+ if(!is_end_)
+ {
+ gtkmm_gtk_tree_model_iter_previous(model_->gobj(), &gobject_);
+ }
+ else // --end yields last
+ {
+ GtkTreeIter next = gobject_;
+ GtkTreeIter *const parent = (next.stamp != 0) ? &next : 0;
+
+ const int index = gtk_tree_model_iter_n_children(model_->gobj(), parent) - 1;
+ is_end_ = !gtk_tree_model_iter_nth_child(model_->gobj(), &gobject_, parent, index);
+
+ g_assert(!is_end_);
+ }
+
+ return *this;
+}
+
+const TreeIter TreeIter::operator--(int)
+{
+ TreeIter next (*this);
+
+ if(!is_end_)
+ {
+ gtkmm_gtk_tree_model_iter_previous(model_->gobj(), &gobject_);
+ }
+ else // --end yields last
+ {
+ GtkTreeIter *const parent = (next.gobject_.stamp != 0) ? &next.gobject_ : 0;
+
+ const int index = gtk_tree_model_iter_n_children(model_->gobj(), parent) - 1;
+ is_end_ = !gtk_tree_model_iter_nth_child(model_->gobj(), &gobject_, parent, index);
+
+ g_assert(!is_end_);
+ }
+
+ return next;
+}
+
+/* There is no public gtk_tree_iter_equal(), so we must write our own.
+ */
+bool TreeIter::equal(const TreeIter& other) const
+{
+ g_assert(model_ == other.model_);
+
+ // A GtkTreeIter has the same stamp value as its model.
+ g_assert(gobject_.stamp == other.gobject_.stamp || is_end_ || other.is_end_);
+
+ //TODO: Allow custom treemodels to provide a different implementation.
+
+ // If all user_data pointers are equal we can assume the iterators to be
+ // equal. This should be safe since GtkTreeIter lacks destroy notification,
+ // thus there is no way to attach more data fields to the iterator.
+ return (is_end_ == other.is_end_) &&
+ (gobject_.user_data == other.gobject_.user_data) &&
+ (gobject_.user_data2 == other.gobject_.user_data2) &&
+ (gobject_.user_data3 == other.gobject_.user_data3);
+}
+
+TreeIter::operator bool() const
+{
+ // Test whether the GtkTreeIter is valid and not an end iterator. This check
+ // is almost the same as the private VALID_ITER() macro in gtkliststore.c and
+ // gtktreestore.c.
+ return (!is_end_ && gobject_.stamp != 0);
+}
+
+void TreeIter::setup_end_iterator(const TreeIter& last_valid)
+{
+ g_assert(model_ == last_valid.model_);
+
+ if(last_valid.is_end_)
+ gobject_ = last_valid.gobject_;
+ else
+ gtk_tree_model_iter_parent(model_->gobj(), &gobject_, const_cast<GtkTreeIter*>(&last_valid.gobject_));
+
+ is_end_ = true;
+}
+
+void TreeIter::set_model_refptr(const Glib::RefPtr<TreeModel>& model)
+{
+ model_ = model.operator->();
+}
+
+void TreeIter::set_model_gobject(GtkTreeModel* model)
+{
+ model_ = dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) model));
+}
+
+GtkTreeModel* TreeIter::get_model_gobject() const
+{
+ return (model_) ? model_->gobj() : 0;
+}
+
+
+int TreeIter::get_stamp() const
+{
+ return gobj()->stamp;
+}
+
+void TreeIter::set_stamp(int stamp)
+{
+ gobj()->stamp = stamp;
+}
+
+
+/**** Gtk::TreeRow *********************************************************/
+
+const TreeNodeChildren& TreeRow::children() const
+{
+ g_assert(!is_end_);
+
+ return static_cast<const TreeNodeChildren&>(static_cast<const TreeIter&>(*this));
+}
+
+TreeIter TreeRow::parent() const
+{
+ TreeIter iter (model_);
+
+ if(is_end_)
+ iter.gobject_ = gobject_;
+ else
+ gtk_tree_model_iter_parent(model_->gobj(), iter.gobj(), const_cast<GtkTreeIter*>(&gobject_));
+
+ return iter;
+}
+
+void TreeRow::set_value_impl(int column, const Glib::ValueBase& value) const
+{
+ model_->set_value_impl(*this, column, value);
+}
+
+void TreeRow::get_value_impl(int column, Glib::ValueBase& value) const
+{
+ model_->get_value_impl(*this, column, value);
+}
+
+TreeRow::operator bool() const
+{
+ return TreeIter::operator bool();
+}
+
+
+/**** Gtk::TreeNodeChildren ************************************************/
+
+TreeNodeChildren::iterator TreeNodeChildren::begin()
+{
+ iterator iter (model_);
+
+ // If the iterator is invalid (stamp == 0), assume a 'virtual' toplevel
+ // node. This behaviour is needed to implement Gtk::TreeModel::children().
+
+ if(gobject_.stamp != 0)
+ {
+ if(!gtk_tree_model_iter_children(model_->gobj(), iter.gobj(), const_cast<GtkTreeIter*>(&gobject_)))
+ {
+ // Assign the already known parent, in order to create an end iterator.
+ iter.gobject_ = gobject_;
+ iter.is_end_ = true;
+ }
+ }
+ else
+ {
+ if(!gtk_tree_model_get_iter_first(model_->gobj(), iter.gobj()))
+ {
+ // No need to copy the GtkTreeIter, since iter.gobject_ is already empty.
+ iter.is_end_ = true;
+ }
+ }
+
+ return iter;
+}
+
+TreeNodeChildren::const_iterator TreeNodeChildren::begin() const
+{
+ //TODO: Reduce the copy/paste from the non-const begin()?
+
+ const_iterator iter (model_);
+
+ // If the iterator is invalid (stamp == 0), assume a 'virtual' toplevel
+ // node. This behaviour is needed to implement Gtk::TreeModel::children().
+
+ if(gobject_.stamp != 0)
+ {
+ if(!gtk_tree_model_iter_children(model_->gobj(), iter.gobj(), const_cast<GtkTreeIter*>(&gobject_)))
+ {
+ // Assign the already known parent, in order to create an end iterator.
+ iter.gobject_ = gobject_;
+ iter.is_end_ = true;
+ }
+ }
+ else
+ {
+ if(!gtk_tree_model_get_iter_first(model_->gobj(), iter.gobj()))
+ {
+ // No need to copy the GtkTreeIter, since iter.gobject_ is already empty.
+ iter.is_end_ = true;
+ }
+ }
+
+ return iter;
+}
+
+TreeNodeChildren::iterator TreeNodeChildren::end()
+{
+ // Just copy the parent, and turn it into an end iterator.
+ iterator iter (*this);
+ iter.is_end_ = true;
+ return iter;
+}
+
+TreeNodeChildren::const_iterator TreeNodeChildren::end() const
+{
+ // Just copy the parent, and turn it into an end iterator.
+ const_iterator iter (*this);
+ iter.is_end_ = true;
+ return iter;
+}
+
+TreeNodeChildren::value_type TreeNodeChildren::operator[](TreeNodeChildren::size_type index) const
+{
+ iterator iter (model_);
+
+ GtkTreeIter *const parent = const_cast<GtkTreeIter*>(get_parent_gobject());
+
+ if(!gtk_tree_model_iter_nth_child(model_->gobj(), iter.gobj(), parent, index))
+ {
+ // Assign the already known parent, in order to create an end iterator.
+ iter.gobject_ = gobject_;
+ iter.is_end_ = true;
+ }
+
+ return *iter;
+}
+
+TreeNodeChildren::size_type TreeNodeChildren::size() const
+{
+ GtkTreeIter *const parent = const_cast<GtkTreeIter*>(get_parent_gobject());
+
+ return gtk_tree_model_iter_n_children(model_->gobj(), parent);
+}
+
+bool TreeNodeChildren::empty() const
+{
+ // If the iterator is invalid (stamp == 0), assume a 'virtual' toplevel
+ // node. This behaviour is needed to implement Gtk::TreeModel::children().
+
+ if(gobject_.stamp == 0)
+ {
+ GtkTreeIter dummy;
+ return !gtk_tree_model_get_iter_first(model_->gobj(), &dummy);
+ }
+
+ return !gtk_tree_model_iter_has_child(model_->gobj(), const_cast<GtkTreeIter*>(&gobject_));
+}
+
+} // namespace Gtk
+
+
+namespace
+{
+} // anonymous namespace
+
+
+namespace Gtk
+{
+
+
+// static
+GType TreeIterBase::get_type()
+{
+ return gtk_tree_iter_get_type();
+}
+
+TreeIterBase::TreeIterBase()
+{
+ GLIBMM_INITIALIZE_STRUCT(gobject_, GtkTreeIter);
+}
+
+TreeIterBase::TreeIterBase(const GtkTreeIter* gobject)
+{
+ if(gobject)
+ gobject_ = *gobject;
+ else
+ GLIBMM_INITIALIZE_STRUCT(gobject_, GtkTreeIter);
+}
+
+
+} // namespace Gtk
+
+