[gtkmm] Gtk::TreeIter: Make a real const_iterator
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk::TreeIter: Make a real const_iterator
- Date: Thu, 5 Jan 2017 11:56:56 +0000 (UTC)
commit 5e420c96f1ce3517295eb15e5425c918174c6730
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Thu Jan 5 12:50:41 2017 +0100
Gtk::TreeIter: Make a real const_iterator
Rewrite the whole TreeIter class hierarchy, including TreeRow and
TreeNodeChildren. TreeRow and TreeNodeChildren (a TreeRow container) are no
longer subclasses of TreeIter. TreeIter is a template class, instantiated as
TreeIter<TreeRow> and TreeIter<const TreeRow> to get TreeNodeChildren::iterator
and TreeNodeChildren::const_iterator, a.k.a. TreeModel::iterator and
TreeModel::const_iterator. Bug #134520
demos/gtk-demo/demowindow.cc | 2 +-
demos/gtk-demo/demowindow.h | 2 +-
demos/gtk-demo/example_change_display.cc | 9 +-
demos/gtk-demo/example_iconview.cc | 8 +-
gtk/gtkmm/listviewtext.cc | 14 +-
gtk/gtkmm/treeview_private.cc | 6 +-
gtk/src/combobox.ccg | 2 +-
gtk/src/comboboxtext.ccg | 7 +-
gtk/src/entrycompletion.ccg | 2 +-
gtk/src/iconview.ccg | 2 +-
gtk/src/iconview.hg | 2 +-
gtk/src/liststore.hg | 2 +-
gtk/src/treeiter.ccg | 172 ++++++-----
gtk/src/treeiter.hg | 478 ++++++++++++++++++++----------
gtk/src/treemodel.ccg | 4 +-
gtk/src/treemodel.hg | 5 +-
gtk/src/treemodelfilter.ccg | 8 +-
gtk/src/treemodelsort.ccg | 6 +-
gtk/src/treemodelsort.hg | 2 +-
gtk/src/treepath.ccg | 4 +-
gtk/src/treesortable.ccg | 2 +-
gtk/src/treesortable.hg | 4 +-
gtk/src/treestore.hg | 2 +-
gtk/src/treeview.ccg | 4 +-
gtk/src/treeview.hg | 8 +-
tools/m4/convert_gtk.m4 | 2 +-
26 files changed, 480 insertions(+), 279 deletions(-)
---
diff --git a/demos/gtk-demo/demowindow.cc b/demos/gtk-demo/demowindow.cc
index 26e7e23..dbca1fa 100644
--- a/demos/gtk-demo/demowindow.cc
+++ b/demos/gtk-demo/demowindow.cc
@@ -185,7 +185,7 @@ void DemoWindow::on_treeview_row_activated(const Gtk::TreeModel::Path& path, Gtk
}
}
-void DemoWindow::run_example(const Gtk::TreeModel::Row& row)
+void DemoWindow::run_example(Gtk::TreeModel::Row& row)
{
const DemoColumns& columns = demo_columns();
diff --git a/demos/gtk-demo/demowindow.h b/demos/gtk-demo/demowindow.h
index 739ea8d..2cd53bd 100644
--- a/demos/gtk-demo/demowindow.h
+++ b/demos/gtk-demo/demowindow.h
@@ -37,7 +37,7 @@ public:
~DemoWindow() override;
protected:
- void run_example(const Gtk::TreeModel::Row& row);
+ void run_example(Gtk::TreeModel::Row& row);
void configure_header_bar();
void fill_tree();
diff --git a/demos/gtk-demo/example_change_display.cc b/demos/gtk-demo/example_change_display.cc
index be39f09..43ac50d 100644
--- a/demos/gtk-demo/example_change_display.cc
+++ b/demos/gtk-demo/example_change_display.cc
@@ -194,12 +194,13 @@ void Example_ChangeDisplay::initialize_displays()
void Example_ChangeDisplay::on_display_closed(bool /* is_error */, Glib::RefPtr<Gdk::Display> display)
{
- for(auto row : m_refListStore_Display->children())
+ auto children = m_refListStore_Display->children();
+ for (auto iter = children.begin(); iter != children.end(); ++iter)
{
- Glib::RefPtr<Gdk::Display> refDisplay = row[m_columns_display.m_display];
- if(refDisplay == display)
+ Glib::RefPtr<Gdk::Display> refDisplay = (*iter)[m_columns_display.m_display];
+ if (refDisplay == display)
{
- m_refListStore_Display->erase(row);
+ m_refListStore_Display->erase(iter);
}
}
}
diff --git a/demos/gtk-demo/example_iconview.cc b/demos/gtk-demo/example_iconview.cc
index 3023377..4a9b009 100644
--- a/demos/gtk-demo/example_iconview.cc
+++ b/demos/gtk-demo/example_iconview.cc
@@ -24,7 +24,7 @@ protected:
virtual void on_button_home();
virtual void on_iconview_item_activated(const Gtk::TreeModel::Path& path);
- virtual int on_model_sort(const Gtk::TreeModel::iterator& a, const Gtk::TreeModel::iterator& b);
+ virtual int on_model_sort(const Gtk::TreeModel::const_iterator& a, const Gtk::TreeModel::const_iterator&
b);
class ModelColumns : public Gtk::TreeModelColumnRecord
{
@@ -128,14 +128,14 @@ Example_IconView::Example_IconView()
show_all();
}
-int Example_IconView::on_model_sort(const Gtk::TreeModel::iterator& a, const Gtk::TreeModel::iterator& b)
+int Example_IconView::on_model_sort(const Gtk::TreeModel::const_iterator& a, const
Gtk::TreeModel::const_iterator& b)
{
/* We need this function because we want to sort
* folders before files.
*/
- Gtk::TreeModel::Row row_a = *a;
- Gtk::TreeModel::Row row_b = *b;
+ const Gtk::TreeModel::Row row_a = *a;
+ const Gtk::TreeModel::Row row_b = *b;
const bool a_is_dir = row_a[m_columns.is_directory];
const bool b_is_dir = row_b[m_columns.is_directory];
diff --git a/gtk/gtkmm/listviewtext.cc b/gtk/gtkmm/listviewtext.cc
index 9cd44b6..d8d2844 100644
--- a/gtk/gtkmm/listviewtext.cc
+++ b/gtk/gtkmm/listviewtext.cc
@@ -108,7 +108,7 @@ void ListViewText::insert(guint row, const Glib::ustring& column_one_value)
{
g_return_if_fail( row < size() );
- Gtk::ListStore::const_iterator iter = m_model->children()[row];
+ Gtk::ListStore::iterator iter = m_model->children()[row].get_iter();
Gtk::TreeModel::Row newRow = *(m_model->insert(iter));
if(!column_one_value.empty())
@@ -128,8 +128,8 @@ Glib::ustring ListViewText::get_text(guint row, guint column) const
g_return_val_if_fail( row < size(), result );
- Gtk::TreeModel::iterator iter = m_model->children()[row];
- iter->get_value(column, result);
+ const Gtk::TreeModel::Row childrow = m_model->children()[row];
+ childrow.get_value(column, result);
return result;
}
@@ -138,16 +138,16 @@ void ListViewText::set_text(guint row, guint column, const Glib::ustring& value)
{
g_return_if_fail( row < size() );
- Gtk::TreeModel::iterator iter = m_model->children()[row];
- (*iter)->set_value(column, value);
+ Gtk::TreeModel::Row childrow = m_model->children()[row];
+ childrow.set_value(column, value);
}
void ListViewText::set_text(guint row, const Glib::ustring& value)
{
g_return_if_fail( row < size() );
- Gtk::TreeModel::iterator iter = m_model->children()[ row ];
- (*iter)->set_value(0, value);
+ Gtk::TreeModel::Row childrow = m_model->children()[row];
+ childrow.set_value(0, value);
}
guint ListViewText::size() const
diff --git a/gtk/gtkmm/treeview_private.cc b/gtk/gtkmm/treeview_private.cc
index 2840a3d..04d73e0 100644
--- a/gtk/gtkmm/treeview_private.cc
+++ b/gtk/gtkmm/treeview_private.cc
@@ -36,8 +36,8 @@ void SignalProxy_CellData_gtk_callback(GtkTreeViewColumn*, GtkCellRenderer* cell
try
{
// use Slot::operator()
- Gtk::TreeModel::iterator cppiter = TreeIter(model, iter);
- if(!cppiter->get_model_gobject())
+ Gtk::TreeModel::iterator cppiter = Gtk::TreeModel::iterator(model, iter);
+ if(!cppiter.get_model_gobject())
{
g_warning("SignalProxy_CellData_gtk_callback() The cppiter has no model\n");
return;
@@ -63,7 +63,7 @@ gboolean SignalProxy_RowSeparator_gtk_callback(GtkTreeModel* model, GtkTreeIter*
try
{
- return (*the_slot)(Glib::wrap(model, true), Gtk::TreeIter(model, iter));
+ return (*the_slot)(Glib::wrap(model, true), Gtk::TreeModel::iterator(model, iter));
}
catch(...)
{
diff --git a/gtk/src/combobox.ccg b/gtk/src/combobox.ccg
index e8f296b..30ba714 100644
--- a/gtk/src/combobox.ccg
+++ b/gtk/src/combobox.ccg
@@ -62,7 +62,7 @@ TreeModel::iterator ComboBox::get_active()
TreeModel::const_iterator ComboBox::get_active() const
{
- Gtk::TreeModel::iterator iter;
+ Gtk::TreeModel::const_iterator iter;
const auto model = get_model();
if(model)
diff --git a/gtk/src/comboboxtext.ccg b/gtk/src/comboboxtext.ccg
index 3e6bead..b4bb86a 100644
--- a/gtk/src/comboboxtext.ccg
+++ b/gtk/src/comboboxtext.ccg
@@ -33,14 +33,15 @@ void ComboBoxText::set_active_text(const Glib::ustring& text)
auto model = get_model();
if(model)
{
- for(const auto& row : model->children())
+ auto enditer = model->children().end();
+ for(auto iter = model->children().begin(); iter != enditer; ++iter)
{
Glib::ustring this_text;
- row.get_value(0, this_text);
+ iter->get_value(0, this_text);
if(this_text == text)
{
- set_active(row);
+ set_active(iter);
return; //success
}
}
diff --git a/gtk/src/entrycompletion.ccg b/gtk/src/entrycompletion.ccg
index 7c7260e..21f5b43 100644
--- a/gtk/src/entrycompletion.ccg
+++ b/gtk/src/entrycompletion.ccg
@@ -240,7 +240,7 @@ bool Gtk::EntryCompletion::on_match_selected(const TreeModel::iterator& iter)
);
if(base && base->match_selected)
- return (*base->match_selected)(gobj(), iter.get_model_gobject(), const_cast<GtkTreeIter*>(iter.gobj()));
+ return (*base->match_selected)(gobj(), const_cast<GtkTreeModel*>(iter.get_model_gobject()),
const_cast<GtkTreeIter*>(iter.gobj()));
else
{
typedef bool RType;
diff --git a/gtk/src/iconview.ccg b/gtk/src/iconview.ccg
index 8566a0c..9f33975 100644
--- a/gtk/src/iconview.ccg
+++ b/gtk/src/iconview.ccg
@@ -222,7 +222,7 @@ IconView::get_tooltip_context_iter(int& x, int& y,
nullptr,
&src_iter);
- iter = TreeIter(gtk_icon_view_get_model(this->gobj()), &src_iter);
+ iter = Gtk::TreeModel::iterator(gtk_icon_view_get_model(this->gobj()), &src_iter);
return result;
}
diff --git a/gtk/src/iconview.hg b/gtk/src/iconview.hg
index 15fa51d..3274d6a 100644
--- a/gtk/src/iconview.hg
+++ b/gtk/src/iconview.hg
@@ -380,7 +380,7 @@ public:
* @param x: the x coordinate (relative to widget coordinates)
* @param y: the y coordinate (relative to widget coordinates)
* @param keyboard_tip: whether this is a keyboard tooltip or not
- * @param iter: a pointer to receive a Gtk::TreeIter
+ * @param iter: a pointer to receive a Gtk::TreeModel::iterator
*
* This function is supposed to be used in a Gtk::Widget::query-tooltip
* signal handler for Gtk::IconView. The x, y and keyboard_tip values
diff --git a/gtk/src/liststore.hg b/gtk/src/liststore.hg
index 3790fef..51929bf 100644
--- a/gtk/src/liststore.hg
+++ b/gtk/src/liststore.hg
@@ -143,7 +143,7 @@ public:
_WRAP_METHOD(void clear(), gtk_list_store_clear)
- _WRAP_METHOD(bool iter_is_valid(const iterator& iter) const, gtk_list_store_iter_is_valid)
+ _WRAP_METHOD(bool iter_is_valid(const const_iterator& iter) const, gtk_list_store_iter_is_valid)
protected:
void set_value_impl(const iterator& row, int column, const Glib::ValueBase& value) override;
diff --git a/gtk/src/treeiter.ccg b/gtk/src/treeiter.ccg
index d7d7e6a..db3dac4 100644
--- a/gtk/src/treeiter.ccg
+++ b/gtk/src/treeiter.ccg
@@ -22,60 +22,60 @@
namespace Gtk
{
-/**** Gtk::TreeIter ********************************************************/
+/**** Gtk::TreeIterBase2 ***************************************************/
-TreeIter::TreeIter()
+TreeIterBase2::TreeIterBase2()
:
TreeIterBase(),
model_ (nullptr),
is_end_ (false)
{}
-TreeIter::TreeIter(TreeModel* model)
+TreeIterBase2::TreeIterBase2(TreeModel* model)
:
TreeIterBase(),
model_ (model),
is_end_ (false)
{}
-TreeIter::TreeIter(GtkTreeModel* model, const GtkTreeIter* iter)
+TreeIterBase2::TreeIterBase2(GtkTreeModel* model, const GtkTreeIter* iter)
:
TreeIterBase(iter),
- model_ (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) model))),
+ model_ (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*)model))),
is_end_ (iter == nullptr)
{}
-TreeIter& TreeIter::operator++()
-{
- g_assert(!is_end_);
+/**** Gtk::TreeIterBase3 ***************************************************/
- auto previous = gobject_;
+TreeIterBase3::TreeIterBase3()
+:
+ TreeIterBase2()
+{}
- if(!gtk_tree_model_iter_next(model_->gobj(), &gobject_))
- {
- is_end_ = true;
- gtk_tree_model_iter_parent(Glib::unwrap(model_), &gobject_, &previous);
- }
+TreeIterBase3::TreeIterBase3(TreeModel* model)
+:
+ TreeIterBase2(model)
+{}
- return *this;
-}
+TreeIterBase3::TreeIterBase3(GtkTreeModel* model, const GtkTreeIter* iter)
+:
+ TreeIterBase2(model, iter)
+{}
-const TreeIter TreeIter::operator++(int)
+void TreeIterBase3::plus_plus()
{
g_assert(!is_end_);
- TreeIter previous (*this);
+ auto previous = gobject_;
if(!gtk_tree_model_iter_next(model_->gobj(), &gobject_))
{
is_end_ = true;
- gtk_tree_model_iter_parent(Glib::unwrap(model_), &gobject_, &previous.gobject_);
+ gtk_tree_model_iter_parent(Glib::unwrap(model_), &gobject_, &previous);
}
-
- return previous;
}
-TreeIter& TreeIter::operator--()
+void TreeIterBase3::minus_minus()
{
if(!is_end_)
{
@@ -91,34 +91,11 @@ TreeIter& TreeIter::operator--()
g_assert(!is_end_);
}
-
- return *this;
-}
-
-const TreeIter TreeIter::operator--(int)
-{
- TreeIter next (*this);
-
- if(!is_end_)
- {
- gtk_tree_model_iter_previous(Glib::unwrap(model_), &gobject_);
- }
- else // --end yields last
- {
- const auto parent = (next.gobject_.stamp != 0) ? &next.gobject_ : nullptr;
-
- 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
+bool TreeIterBase3::equal(const TreeIterBase3& other) const
{
g_assert(model_ == other.model_);
@@ -134,15 +111,7 @@ bool TreeIter::equal(const TreeIter& other) const
(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;
-}
-
-void TreeIter::setup_end_iterator(const TreeIter& last_valid)
+void TreeIterBase3::setup_end_iterator(const TreeIterBase3& last_valid)
{
g_assert(model_ == last_valid.model_);
@@ -154,28 +123,32 @@ void TreeIter::setup_end_iterator(const TreeIter& last_valid)
is_end_ = true;
}
-void TreeIter::set_model_refptr(const Glib::RefPtr<TreeModel>& model)
+void TreeIterBase3::set_model_refptr(const Glib::RefPtr<TreeModel>& model)
{
model_ = model.operator->();
}
-void TreeIter::set_model_gobject(GtkTreeModel* model)
+void TreeIterBase3::set_model_gobject(GtkTreeModel* model)
{
model_ = dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) model));
}
-GtkTreeModel* TreeIter::get_model_gobject() const
+GtkTreeModel* TreeIterBase3::get_model_gobject()
{
return (model_) ? model_->gobj() : nullptr;
}
+const GtkTreeModel* TreeIterBase3::get_model_gobject() const
+{
+ return (model_) ? model_->gobj() : nullptr;
+}
-int TreeIter::get_stamp() const
+int TreeIterBase3::get_stamp() const
{
return gobj()->stamp;
}
-void TreeIter::set_stamp(int stamp)
+void TreeIterBase3::set_stamp(int stamp)
{
gobj()->stamp = stamp;
}
@@ -183,16 +156,33 @@ void TreeIter::set_stamp(int stamp)
/**** Gtk::TreeRow *********************************************************/
-const TreeNodeChildren& TreeRow::children() const
+TreeNodeChildren& TreeRow::children()
{
g_assert(!is_end_);
- return static_cast<const TreeNodeChildren&>(static_cast<const TreeIter&>(*this));
+ return static_cast<TreeNodeChildren&>(static_cast<TreeIterBase2&>(*this));
}
-TreeIter TreeRow::parent() const
+const TreeNodeChildren& TreeRow::children() const
{
- TreeIter iter (model_);
+ return const_cast<TreeRow*>(this)->children();
+}
+
+TreeIter<TreeRow> TreeRow::parent()
+{
+ TreeIter<TreeRow> iter(model_);
+
+ if(is_end_)
+ iter.gobject_ = gobject_;
+ else
+ gtk_tree_model_iter_parent(model_->gobj(), iter.gobj(), &gobject_);
+
+ return iter;
+}
+
+TreeIter<const TreeRow> TreeRow::parent() const
+{
+ TreeIter<const TreeRow> iter(model_);
if(is_end_)
iter.gobject_ = gobject_;
@@ -202,26 +192,39 @@ TreeIter TreeRow::parent() const
return iter;
}
-void TreeRow::set_value_impl(int column, const Glib::ValueBase& value) const
+TreeIter<TreeRow> TreeRow::get_iter()
{
- model_->set_value_impl(*this, column, value);
+ return static_cast<TreeIter<TreeRow>&>(static_cast<TreeIterBase2&>(*this));
+}
+
+TreeIter<const TreeRow> TreeRow::get_iter() const
+{
+ return static_cast<const TreeIter<const TreeRow>&>(static_cast<const TreeIterBase2&>(*this));
+}
+
+void TreeRow::set_value_impl(int column, const Glib::ValueBase& value)
+{
+ model_->set_value_impl(static_cast<TreeIter<TreeRow>&>(static_cast<TreeIterBase2&>(*this)), column, value);
}
void TreeRow::get_value_impl(int column, Glib::ValueBase& value) const
{
- model_->get_value_impl(*this, column, value);
+ model_->get_value_impl(static_cast<const TreeIter<const TreeRow>&>(static_cast<const
TreeIterBase2&>(*this)), column, value);
}
TreeRow::operator bool() const
{
- return TreeIter::operator bool();
-
+ // 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;
}
+
/**** Gtk::TreeNodeChildren ************************************************/
TreeNodeChildren::iterator TreeNodeChildren::begin()
{
- iterator iter (model_);
+ iterator iter(model_);
// If the iterator is invalid (stamp == 0), assume a 'virtual' toplevel
// node. This behaviour is needed to implement Gtk::TreeModel::children().
@@ -251,7 +254,7 @@ TreeNodeChildren::const_iterator TreeNodeChildren::begin() const
{
//TODO: Reduce the copy/paste from the non-const begin()?
- const_iterator iter (model_);
+ 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().
@@ -280,7 +283,8 @@ TreeNodeChildren::const_iterator TreeNodeChildren::begin() const
TreeNodeChildren::iterator TreeNodeChildren::end()
{
// Just copy the parent, and turn it into an end iterator.
- iterator iter (*this);
+ iterator iter(model_);
+ iter.gobject_ = gobject_;
iter.is_end_ = true;
return iter;
}
@@ -288,14 +292,31 @@ TreeNodeChildren::iterator TreeNodeChildren::end()
TreeNodeChildren::const_iterator TreeNodeChildren::end() const
{
// Just copy the parent, and turn it into an end iterator.
- const_iterator iter (*this);
+ const_iterator iter(model_);
+ iter.gobject_ = gobject_;
iter.is_end_ = true;
return iter;
}
-TreeNodeChildren::value_type TreeNodeChildren::operator[](TreeNodeChildren::size_type index) const
+TreeNodeChildren::value_type TreeNodeChildren::operator[](TreeNodeChildren::size_type index)
+{
+ iterator iter(model_);
+
+ const auto 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;
+}
+
+const TreeNodeChildren::value_type TreeNodeChildren::operator[](TreeNodeChildren::size_type index) const
{
- iterator iter (model_);
+ const_iterator iter(model_);
const auto parent = const_cast<GtkTreeIter*>(get_parent_gobject());
@@ -331,4 +352,3 @@ bool TreeNodeChildren::empty() const
}
} // namespace Gtk
-
diff --git a/gtk/src/treeiter.hg b/gtk/src/treeiter.hg
index bb0c002..71065b2 100644
--- a/gtk/src/treeiter.hg
+++ b/gtk/src/treeiter.hg
@@ -1,17 +1,17 @@
/* Copyright(C) 1998-2002 The gtkmm Development Team
*
- * This library is free software, ) you can redistribute it and/or
+ * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation, ) either
- * version 2.1 of the License, or(at your option) any later version.
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library, ) if not, write to the Free Software
+ * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
@@ -20,6 +20,7 @@ _DEFS(gtkmm,gtk)
#include <gtkmm/treemodelcolumn.h>
#include <iterator>
+#include <type_traits>
#include <gtk/gtk.h> /* for GtkTreeIter */
#ifdef GLIBMM_HAVE_SUN_REVERSE_ITERATOR
#include <cstddef> /* for std::ptrdiff_t */
@@ -29,39 +30,140 @@ namespace Gtk
{
class TreeModel;
+template <typename T>
+class TreeIter;
class TreeRow;
class TreeNodeChildren;
-/**
+// Why all the base classes?
+//
+// TreeIterBase2 contains data members that can't be declared in TreeIterBase,
+// because a _CLASS_BOXEDTYPE_STATIC can't contain data members other than
+// the gmmproc-generated GtkTreeIter gobject_.
+//
+// TreeIterBase3 contains those parts of TreeIter<> that does not have to be in
+// the template class.
+
+/** Base of TreeIter, TreeRow and TreeNodeChildren.
+ *
* @ingroup TreeView
*/
class TreeIterBase
{
_CLASS_BOXEDTYPE_STATIC(TreeIterBase, GtkTreeIter)
_IGNORE(gtk_tree_iter_copy, gtk_tree_iter_free)
- _NO_WRAP_FUNCTION() //A wrap() for TreeIterBase* wouldn't be very helpful.
+ _NO_WRAP_FUNCTION() // A wrap() for TreeIterBase* wouldn't be very helpful.
};
+/** Base of TreeIter, TreeRow and TreeNodeChildren.
+ *
+ * @ingroup TreeView
+ */
+class TreeIterBase2 : public TreeIterBase
+{
+protected:
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ TreeIterBase2();
+ explicit TreeIterBase2(TreeModel* model); // used in TreeModel methods
+ TreeIterBase2(GtkTreeModel* model, const GtkTreeIter* iter); // used by signal proxies
+
+ // 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_;
+
+ // For the conversion and assignment from iterator to const_iterator
+ friend class Gtk::TreeIter<const Gtk::TreeRow>;
+ friend class Gtk::TreeRow;
+ friend class Gtk::TreeNodeChildren;
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+
+}; // class TreeIterBase2
+
+/** Base of TreeIter.
+ *
+ * Contains the common parts of TreeIter<TreeRow> and TreeIter<const TreeRow>.
+ *
+ * @ingroup TreeView
+ */
+class TreeIterBase3 : public TreeIterBase2
+{
+public:
+
+ bool equal(const TreeIterBase3& other) 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
+
+ void set_model_refptr(const Glib::RefPtr<TreeModel>& model);
+ void set_model_gobject(GtkTreeModel* model);
+ GtkTreeModel* get_model_gobject();
+ const GtkTreeModel* get_model_gobject() const;
+
+ void setup_end_iterator(const TreeIterBase3& last_valid);
+
+ const GtkTreeIter* get_gobject_if_not_end() const
+ { return (!is_end_) ? &gobject_ : nullptr; }
+
+ const GtkTreeIter* get_parent_gobject_if_end() const
+ { return (is_end_ && gobject_.stamp) ? &gobject_ : nullptr; }
+
+protected:
+ TreeIterBase3();
+ explicit TreeIterBase3(TreeModel* model); // used in TreeModel methods
+ TreeIterBase3(GtkTreeModel* model, const GtkTreeIter* iter); // used by signal proxies
+
+ // Common part of operator++() and operator++(int).
+ void plus_plus();
+ // Common part of operator--() and operator--(int).
+ void minus_minus();
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+
+}; // class TreeIterBase3
// 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
+// 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,
+// 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*,
+// 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,
+// 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=.
+// class. Almost all wrapper methods dealing with GtkTreeIter must be
+// carefully implemented by hand.
+//TODO: document implementation details.
/** A Gtk::TreeModel::iterator is a reference to a specific node on a specific
* model.
@@ -88,113 +190,78 @@ class TreeIterBase
* 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.
+ * Typedefed as Gtk::TreeModel::iterator and Gtk::TreeModel::const_iterator.
+ *
+ * @tparam T <TreeRow> for an iterator, or <const TreeRow> for a const_iterator.
+ *
* @ingroup TreeView
*/
-class TreeIter : public TreeIterBase
+template <typename T>
+class TreeIter : public TreeIterBase3
{
+ static_assert(std::is_same<T, TreeRow>::value || std::is_same<T, const TreeRow>::value,
+ "TreeIter can only iterate over TreeRow or const TreeRow");
+
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;
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = TreeRow;
+ using difference_type = int;
+ using reference = T&;
+ using pointer = T*;
TreeIter();
- TreeIter& operator++();
- const TreeIter operator++(int);
+ /// iterator to const_iterator conversion.
+ template <typename T2, typename = typename std::enable_if<!std::is_same<T, T2>::value &&
+ std::is_same<T, const T2>::value, T2>::type>
+ TreeIter(const TreeIter<T2>& src);
+
+ /// iterator to const_iterator assignment.
+ template <typename T2, typename = typename std::enable_if<!std::is_same<T, T2>::value &&
+ std::is_same<T, const T2>::value, T2>::type>
+ TreeIter& operator=(const TreeIter<T2>& src);
- /** Please note that this is very slow compared to operator++().
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+ explicit TreeIter(TreeModel* model); // used in TreeModel methods
+ TreeIter(GtkTreeModel* model, const GtkTreeIter* iter); // used by signal proxies
+#endif // DOXYGEN_SHOULD_SKIP_THIS
+
+ TreeIter& operator++();
+ TreeIter operator++(int);
+
+ /** Note that this is very slow compared to operator++().
*/
- TreeIter& operator--();
+ TreeIter& operator--();
- /** Please note that this is very slow compared to operator++().
+ /** Note that this is very slow compared to operator++(int).
*/
- const TreeIter operator--(int);
+ 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().
* For instance,
* @code
- * if(treeiter)
- * do_something()
+ * if (treeiter)
+ * do_something();
* @endcode
*
* @newin{3,22}
*/
- explicit 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_ : nullptr; }
-
- const GtkTreeIter* get_parent_gobject_if_end() const
- { return (is_end_ && gobject_.stamp) ? &gobject_ : nullptr; }
-
-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;
+ inline explicit operator bool() const;
-#endif // DOXYGEN_SHOULD_SKIP_THIS
-};
+}; // class TreeIter<>
/** @relates Gtk::TreeIter */
-inline bool operator==(const TreeIter& lhs, const TreeIter& rhs)
- { return lhs.equal(rhs); }
+template <typename T>
+inline bool operator==(const TreeIter<T>& lhs, const TreeIter<T>& rhs)
+{ return lhs.equal(rhs); }
/** @relates Gtk::TreeIter */
-inline bool operator!=(const TreeIter& lhs, const TreeIter& rhs)
- { return !lhs.equal(rhs); }
-
+template <typename T>
+inline bool operator!=(const TreeIter<T>& lhs, const TreeIter<T>& rhs)
+{ return !lhs.equal(rhs); }
template <class ColumnType>
class TreeValueProxy
@@ -208,26 +275,29 @@ public:
inline operator ColumnType() const;
private:
- const TreeRow& row_;
- const TreeModelColumn<ColumnType>& column_;
+ TreeRow& row_;
+ const TreeModelColumn<ColumnType>& column_;
// no copy assignment
- TreeValueProxy<ColumnType>& operator=(const TreeValueProxy<ColumnType>&);
+ TreeValueProxy<ColumnType>& operator=(const TreeValueProxy<ColumnType>&) = delete;
};
/** 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.
+ * 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().
*
- * If the model contains a hierarchy of rows (such as Gtk::TreeStore), then you can access the child rows
with
- * children().
+ * You can use get_iter() to get an iterator that points to the Row, e.g. for use
+ * in a parameter that takes a const TreeModel::iterator& or a
+ * const TreeModel::const_iterator&.
*
- * 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.
+class TreeRow : public TreeIterBase2
{
public:
@@ -237,10 +307,13 @@ public:
*
* This is just a more convenient syntax that does the same thing as set_value() and get_value().
*
- * @param column The model column..
+ * @param column The model column.
*/
template <class ColumnType> inline
- TreeValueProxy<ColumnType> operator[](const TreeModelColumn<ColumnType>& column) const;
+ TreeValueProxy<ColumnType> operator[](const TreeModelColumn<ColumnType>& column);
+
+ template <class ColumnType> inline
+ const 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
@@ -252,7 +325,7 @@ public:
* @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;
+ void set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data);
/** Use set_value(const TreeModelColumn<>& column, const ColumnType& data) unless
* you do not know the column type at compile-time.
@@ -261,7 +334,7 @@ public:
* @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;
+ void set_value(int column, const ColumnType& data);
/** 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
@@ -287,18 +360,38 @@ public:
/** This returns an STL-like container API, for iterating over the rows.
* See also Gtk::TreeModel::children() for the top-level children.
*/
+ TreeNodeChildren& children();
+
+ /** 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;
+ TreeIter<TreeRow> parent();
+
+ /** Gets a const_iterator to the parent row of this row.
+ * @result A const_iterator to the parent row.
+ */
+ TreeIter<const TreeRow> parent() const;
+
+ /** Gets an iterator to this row.
+ * @result An iterator to this row.
+ */
+ TreeIter<TreeRow> get_iter();
+
+ /** Gets a const_iterator to this row.
+ * @result A const_iterator to this row.
+ */
+ TreeIter<const TreeRow> get_iter() const;
/** Discover whether this is a valid row.
* For instance,
* @code
- * if(treerow)
- * do_something()
+ * if (treerow)
+ * do_something();
* @endcode
*
* @newin{3,22}
@@ -306,39 +399,43 @@ public:
explicit operator bool() const;
/// Provides access to the underlying C GObject.
- GtkTreeIter* gobj() { return TreeIter::gobj(); }
+ GtkTreeIter* gobj() { return TreeIterBase::gobj(); }
/// Provides access to the underlying C GObject.
- const GtkTreeIter* gobj() const { return TreeIter::gobj(); }
+ const GtkTreeIter* gobj() const { return TreeIterBase::gobj(); }
private:
// Forwarders to Gtk::TreeModel virtual methods.
- void set_value_impl(int column, const Glib::ValueBase& value) const;
+ void set_value_impl(int column, const Glib::ValueBase& value);
void get_value_impl(int column, Glib::ValueBase& value) const;
-};
+
+}; // class TreeRow
//TODO: Document begin(), end(), size(), etc, in an STL-style way. murrayc.
-/** typedefed as TreeModel::Children.
- * Virtual container of TreeModel::Row items.
+/** Virtual container of TreeModel::Row items.
+ *
+ * typedefed as TreeModel::Children.
+ *
* @ingroup TreeView
*/
-class TreeNodeChildren : public TreeIter
+class TreeNodeChildren : public TreeIterBase2
{
public:
- typedef Gtk::TreeRow value_type;
- typedef unsigned int size_type;
- typedef int difference_type;
- typedef Gtk::TreeIter iterator;
- typedef Gtk::TreeIter const_iterator; //TODO: Make it a real const_iterator.
+ using value_type = Gtk::TreeRow;
+ using size_type = unsigned int;
+ using difference_type = int;
+ using iterator = Gtk::TreeIter<Gtk::TreeRow>;
+ using const_iterator = Gtk::TreeIter<const Gtk::TreeRow>;
iterator begin();
const_iterator begin() const;
iterator end();
const_iterator end() const;
- value_type operator[](size_type index) const;
+ value_type operator[](size_type index);
+ const value_type operator[](size_type index) const;
size_type size() const;
bool empty() const;
@@ -346,8 +443,8 @@ public:
/** Discover whether this is a valid TreeNodeChildren.
* For instance,
* @code
- * if(children)
- * do_something()
+ * if (children)
+ * do_something();
* @endcode
*
* @newin{3,22}
@@ -360,38 +457,115 @@ public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
explicit TreeNodeChildren(TreeModel* model)
- : TreeIter(model) {}
+ : TreeIterBase2(model) {}
const GtkTreeIter* get_parent_gobject() const
{ return (gobject_.stamp != 0) ? &gobject_ : nullptr; }
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
-};
+
+}; // class TreeNodeChildren
#ifndef DOXYGEN_SHOULD_SKIP_THIS
/**** Gtk::TreeIter ********************************************************/
-inline
-TreeIter::reference TreeIter::operator*() const
+template <typename T>
+TreeIter<T>::TreeIter()
+:
+ TreeIterBase3()
+{}
+
+template <typename T>
+template <typename T2, typename>
+TreeIter<T>::TreeIter(const TreeIter<T2>& src)
+:
+ TreeIterBase3()
{
- return static_cast<const TreeRow&>(*this);
+ gobject_ = src.gobject_;
+ model_ = src.model_;
+ is_end_ = src.is_end_;
}
-inline
-TreeIter::pointer TreeIter::operator->() const
+template <typename T>
+template <typename T2, typename>
+TreeIter<T>& TreeIter<T>::operator=(const TreeIter<T2>& src)
{
- return static_cast<const TreeRow*>(this);
+ gobject_ = src.gobject_;
+ model_ = src.model_;
+ is_end_ = src.is_end_;
}
+template <typename T>
+TreeIter<T>::TreeIter(TreeModel* model)
+:
+ TreeIterBase3(model)
+{}
+
+template <typename T>
+TreeIter<T>::TreeIter(GtkTreeModel* model, const GtkTreeIter* iter)
+:
+ TreeIterBase3(model, iter)
+{}
+
+template <typename T> inline
+TreeIter<T>& TreeIter<T>::operator++()
+{
+ plus_plus();
+ return *this;
+}
+
+template <typename T> inline
+TreeIter<T> TreeIter<T>::operator++(int)
+{
+ TreeIter previous(*this);
+ plus_plus();
+ return previous;
+}
+
+template <typename T> inline
+TreeIter<T>& TreeIter<T>::operator--()
+{
+ minus_minus();
+ return *this;
+}
+
+template <typename T> inline
+TreeIter<T> TreeIter<T>::operator--(int)
+{
+ TreeIter next(*this);
+ minus_minus();
+ return next;
+}
+
+template <typename T> inline
+typename TreeIter<T>::reference TreeIter<T>::operator*() const
+{
+ return static_cast<reference>(static_cast<TreeIterBase2&>(const_cast<TreeIter&>(*this)));
+}
+
+template <typename T> inline
+typename TreeIter<T>::pointer TreeIter<T>::operator->() const
+{
+ return static_cast<pointer>(static_cast<TreeIterBase2*>(const_cast<TreeIter*>(this)));
+}
+
+template <typename T> inline
+TreeIter<T>::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;
+}
/**** Gtk::TreeValueProxy<> ************************************************/
template <class ColumnType> inline
TreeValueProxy<ColumnType>::TreeValueProxy(const TreeRow& row, const TreeModelColumn<ColumnType>& column)
:
- row_ (row),
+ row_ (const_cast<TreeRow&>(row)),
column_ (column)
{}
@@ -412,15 +586,21 @@ TreeValueProxy<ColumnType>::operator ColumnType() const
/**** Gtk::TreeRow *********************************************************/
template <class ColumnType> inline
-TreeValueProxy<ColumnType> TreeRow::operator[](const TreeModelColumn<ColumnType>& column) const
+const TreeValueProxy<ColumnType> TreeRow::operator[](const TreeModelColumn<ColumnType>& column) const
+{
+ return TreeValueProxy<ColumnType>(*this, column);
+}
+
+template <class ColumnType> inline
+TreeValueProxy<ColumnType> TreeRow::operator[](const TreeModelColumn<ColumnType>& column)
{
return TreeValueProxy<ColumnType>(*this, column);
}
template <class ColumnType>
-void TreeRow::set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data) const
+void TreeRow::set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data)
{
- typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
+ using ValueType = typename Gtk::TreeModelColumn<ColumnType>::ValueType;
ValueType value;
value.init(column.type());
@@ -430,13 +610,12 @@ void TreeRow::set_value(const TreeModelColumn<ColumnType>& column, const ColumnT
}
template <class ColumnType>
-void TreeRow::set_value(int column, const ColumnType& data) const
+void TreeRow::set_value(int column, const ColumnType& data)
{
- //This could fail at run-time, because the wrong ColumnType might be used.
- //It's only for dynamically generated model columns.
+ // 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;
+ using ValueType = typename Gtk::TreeModelColumn<ColumnType>::ValueType;
ValueType value;
value.init(ValueType::value_type());
@@ -448,7 +627,7 @@ void TreeRow::set_value(int column, const ColumnType& data) const
template <class ColumnType>
ColumnType TreeRow::get_value(const TreeModelColumn<ColumnType>& column) const
{
- typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
+ using ValueType = typename Gtk::TreeModelColumn<ColumnType>::ValueType;
ValueType value;
this->get_value_impl(column.index(), value);
@@ -459,10 +638,10 @@ ColumnType TreeRow::get_value(const TreeModelColumn<ColumnType>& column) const
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.
+ // 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;
+ using ValueType = typename Gtk::TreeModelColumn<ColumnType>::ValueType;
ValueType value;
this->get_value_impl(column, value);
@@ -473,4 +652,3 @@ void TreeRow::get_value(int column, ColumnType& data) const
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
} // namespace Gtk
-
diff --git a/gtk/src/treemodel.ccg b/gtk/src/treemodel.ccg
index e52ebc5..5766464 100644
--- a/gtk/src/treemodel.ccg
+++ b/gtk/src/treemodel.ccg
@@ -116,11 +116,11 @@ void TreeModel::set_value_impl(const iterator&, int, const Glib::ValueBase&)
g_assert_not_reached();
}
-void TreeModel::get_value_impl(const iterator& row, int column, Glib::ValueBase& value) const
+void TreeModel::get_value_impl(const const_iterator& iter, int column, Glib::ValueBase& value) const
{
gtk_tree_model_get_value(
const_cast<GtkTreeModel*>(gobj()),
- const_cast<GtkTreeIter*>(row.gobj()),
+ const_cast<GtkTreeIter*>(iter.gobj()),
column, value.gobj());
}
diff --git a/gtk/src/treemodel.hg b/gtk/src/treemodel.hg
index 28684f7..f63b849 100644
--- a/gtk/src/treemodel.hg
+++ b/gtk/src/treemodel.hg
@@ -396,15 +396,14 @@ dnl
* Row::set_value() work.
* Your implementation of set_value_impl() should call row_changed() after changing the value.
*/
- virtual void set_value_impl(const iterator& row, int column, const Glib::ValueBase& value);
+ virtual void set_value_impl(const iterator& iter, int column, const Glib::ValueBase& value);
//This might not need to be virtual, but it's not a big deal. murrayc.
- virtual void get_value_impl(const iterator& row, int column, Glib::ValueBase& value) const;
+ virtual void get_value_impl(const const_iterator& iter, int column, Glib::ValueBase& value) const;
friend class Gtk::TreeModelFilter;
friend class Gtk::TreeModelSort;
friend class Gtk::TreeRow;
- friend class Gtk::TreeIter;
};
} // namespace Gtk
diff --git a/gtk/src/treemodelfilter.ccg b/gtk/src/treemodelfilter.ccg
index a229d7f..3c7a073 100644
--- a/gtk/src/treemodelfilter.ccg
+++ b/gtk/src/treemodelfilter.ccg
@@ -53,7 +53,7 @@ static void SignalProxy_Modify_gtk_callback(GtkTreeModel* model, GtkTreeIter* it
auto column_type = gtk_tree_model_get_column_type(model, column);
cppValue.init(column_type);
- (*the_slot)( Gtk::TreeModel::const_iterator(model, iter), cppValue, column );
+ (*the_slot)( Gtk::TreeModel::iterator(model, iter), cppValue, column );
//GTK+ has already done this for us: g_value_init(value, column_type);
@@ -105,7 +105,7 @@ void TreeModelFilter::set_visible_func(const SlotVisible& slot)
TreeModel::iterator TreeModelFilter::convert_child_iter_to_iter(const iterator& child_iter) const
{
- TreeIter filter_iter (const_cast<TreeModelFilter*>(this));
+ iterator filter_iter(const_cast<TreeModelFilter*>(this));
gtk_tree_model_filter_convert_child_iter_to_iter(
const_cast<GtkTreeModelFilter*>(gobj()), filter_iter.gobj(),
@@ -118,7 +118,7 @@ TreeModel::iterator TreeModelFilter::convert_iter_to_child_iter(const iterator&
{
const auto child_model = gtk_tree_model_filter_get_model(const_cast<GtkTreeModelFilter*>(gobj()));
- TreeIter child_iter (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) child_model, false)));
+ iterator child_iter(dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*)child_model, false)));
gtk_tree_model_filter_convert_iter_to_child_iter(
const_cast<GtkTreeModelFilter*>(gobj()), child_iter.gobj(),
@@ -148,7 +148,7 @@ void TreeModelFilter::set_value_impl(const iterator& row, int column, const Glib
const auto child_model = dynamic_cast<TreeModel*>(
Glib::wrap_auto((GObject*) gtk_tree_model_filter_get_model(gobj()), false));
- TreeIter child_iter (child_model);
+ iterator child_iter(child_model);
gtk_tree_model_filter_convert_iter_to_child_iter(
gobj(), child_iter.gobj(), const_cast<GtkTreeIter*>(row.gobj()));
diff --git a/gtk/src/treemodelsort.ccg b/gtk/src/treemodelsort.ccg
index 4e508c5..e892c7c 100644
--- a/gtk/src/treemodelsort.ccg
+++ b/gtk/src/treemodelsort.ccg
@@ -25,7 +25,7 @@ namespace Gtk
TreeModel::iterator TreeModelSort::convert_child_iter_to_iter(const iterator& child_iter) const
{
- TreeIter sorted_iter (const_cast<TreeModelSort*>(this));
+ iterator sorted_iter(const_cast<TreeModelSort*>(this));
gtk_tree_model_sort_convert_child_iter_to_iter(
const_cast<GtkTreeModelSort*>(gobj()), sorted_iter.gobj(),
@@ -38,7 +38,7 @@ TreeModel::iterator TreeModelSort::convert_iter_to_child_iter(const iterator& so
{
const auto child_model = gtk_tree_model_sort_get_model(const_cast<GtkTreeModelSort*>(gobj()));
- TreeIter child_iter (dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) child_model, false)));
+ iterator child_iter(dynamic_cast<TreeModel*>(Glib::wrap_auto((GObject*) child_model, false)));
gtk_tree_model_sort_convert_iter_to_child_iter(
const_cast<GtkTreeModelSort*>(gobj()), child_iter.gobj(),
@@ -55,7 +55,7 @@ void TreeModelSort::set_value_impl(const iterator& row, int column, const Glib::
const auto child_model = dynamic_cast<TreeModel*>(
Glib::wrap_auto((GObject*) gtk_tree_model_sort_get_model(gobj()), false));
- TreeIter child_iter (child_model);
+ iterator child_iter(child_model);
gtk_tree_model_sort_convert_iter_to_child_iter(
gobj(), child_iter.gobj(), const_cast<GtkTreeIter*>(row.gobj()));
diff --git a/gtk/src/treemodelsort.hg b/gtk/src/treemodelsort.hg
index 4eb9ec5..87042d5 100644
--- a/gtk/src/treemodelsort.hg
+++ b/gtk/src/treemodelsort.hg
@@ -86,7 +86,7 @@ public:
_WRAP_METHOD(void reset_default_sort_func(), gtk_tree_model_sort_reset_default_sort_func)
_WRAP_METHOD(void clear_cache(), gtk_tree_model_sort_clear_cache)
- _WRAP_METHOD(bool iter_is_valid(const iterator& iter) const, gtk_tree_model_sort_iter_is_valid)
+ _WRAP_METHOD(bool iter_is_valid(const const_iterator& iter) const, gtk_tree_model_sort_iter_is_valid)
_WRAP_PROPERTY("model", Glib::RefPtr<TreeModel>)
diff --git a/gtk/src/treepath.ccg b/gtk/src/treepath.ccg
index 57b7c25..4951df3 100644
--- a/gtk/src/treepath.ccg
+++ b/gtk/src/treepath.ccg
@@ -51,7 +51,9 @@ TreePath::TreePath(const Glib::ustring& path)
TreePath::TreePath(const TreeModel::iterator& iter)
:
// The GtkTreePath* is always newly created.
- gobject_ (gtk_tree_model_get_path(iter.get_model_gobject(), const_cast<GtkTreeIter*>(iter.gobj())))
+ gobject_(gtk_tree_model_get_path(
+ const_cast<GtkTreeModel*>(iter.get_model_gobject()),
+ const_cast<GtkTreeIter*>(iter.gobj())))
{
if (!gobject_)
gobject_ = gtk_tree_path_new();
diff --git a/gtk/src/treesortable.ccg b/gtk/src/treesortable.ccg
index 31645aa..077f360 100644
--- a/gtk/src/treesortable.ccg
+++ b/gtk/src/treesortable.ccg
@@ -22,7 +22,7 @@ static int SignalProxy_Compare_gtk_callback(GtkTreeModel* model, GtkTreeIter* lh
try
{
// use Slot::operator()
- return (*the_slot)(Gtk::TreeIter(model, lhs), Gtk::TreeIter(model, rhs));
+ return (*the_slot)(Gtk::TreeModel::const_iterator(model, lhs), Gtk::TreeModel::const_iterator(model,
rhs));
}
catch(...)
{
diff --git a/gtk/src/treesortable.hg b/gtk/src/treesortable.hg
index 0d21fa8..b8a478c 100644
--- a/gtk/src/treesortable.hg
+++ b/gtk/src/treesortable.hg
@@ -66,9 +66,9 @@ public:
gtk_tree_sortable_set_sort_column_id)
/** This callback should return -1 if a compares before b, 0 if they compare equal, 1 if a compares after
b.
- * For instance, int on_sort_compare(const Gtk::TreeModel::iterator& a, const Gtk::TreeModel::iterator& b);
+ * For instance, int on_sort_compare(const Gtk::TreeModel::const_iterator& a, const
Gtk::TreeModel::const_iterator& b);
*/
- typedef sigc::slot<int(const Gtk::TreeModel::iterator&, const Gtk::TreeModel::iterator&)> SlotCompare;
+ typedef sigc::slot<int(const Gtk::TreeModel::const_iterator&, const Gtk::TreeModel::const_iterator&)>
SlotCompare;
_IGNORE(gtk_tree_sortable_set_sort_func, gtk_tree_sortable_set_default_sort_func)
diff --git a/gtk/src/treestore.hg b/gtk/src/treestore.hg
index 1e2adba..303de87 100644
--- a/gtk/src/treestore.hg
+++ b/gtk/src/treestore.hg
@@ -158,7 +158,7 @@ public:
_WRAP_METHOD(bool is_ancestor(const iterator& iter, const iterator& descendant) const,
gtk_tree_store_is_ancestor)
_WRAP_METHOD(int iter_depth(const iterator& iter) const, gtk_tree_store_iter_depth)
- _WRAP_METHOD(bool iter_is_valid(const iterator& iter) const, gtk_tree_store_iter_is_valid)
+ _WRAP_METHOD(bool iter_is_valid(const const_iterator& iter) const, gtk_tree_store_iter_is_valid)
protected:
void set_value_impl(const iterator& row, int column, const Glib::ValueBase& value) override;
diff --git a/gtk/src/treeview.ccg b/gtk/src/treeview.ccg
index d31eed8..d270f79 100644
--- a/gtk/src/treeview.ccg
+++ b/gtk/src/treeview.ccg
@@ -55,7 +55,7 @@ static gboolean SignalProxy_SearchEqual_gtk_callback(GtkTreeModel* model, int co
try
{
- return (*the_slot)(Glib::wrap(model, true), column, key, Gtk::TreeIter(model, iter));
+ return (*the_slot)(Glib::wrap(model, true), column, key, Gtk::TreeModel::const_iterator(model, iter));
}
catch(...)
{
@@ -438,7 +438,7 @@ TreeView::get_tooltip_context_iter(int& x, int& y,
nullptr,
&src_iter);
- iter = TreeIter(gtk_tree_view_get_model(this->gobj()), &src_iter);
+ iter = TreeModel::iterator(gtk_tree_view_get_model(this->gobj()), &src_iter);
return result;
}
diff --git a/gtk/src/treeview.hg b/gtk/src/treeview.hg
index bbd0d47..d6c23d0 100644
--- a/gtk/src/treeview.hg
+++ b/gtk/src/treeview.hg
@@ -647,8 +647,8 @@ public:
_WRAP_METHOD(void set_search_column(const TreeModelColumnBase& column), gtk_tree_view_set_search_column)
_WRAP_METHOD(void set_search_column(int column), gtk_tree_view_set_search_column)
- ///void on_search_equal(const Glib::RefPtr<TreeModel>& model, int column, const Glib::ustring& key, const
TreeModel::iterator& iter)
- typedef sigc::slot<bool(const Glib::RefPtr<TreeModel>&, int, const Glib::ustring&, const
TreeModel::iterator&)> SlotSearchEqual;
+ /// void on_search_equal(const Glib::RefPtr<TreeModel>& model, int column, const Glib::ustring& key, const
TreeModel::const_iterator& iter)
+ typedef sigc::slot<bool(const Glib::RefPtr<TreeModel>&, int, const Glib::ustring&, const
TreeModel::const_iterator&)> SlotSearchEqual;
//SlotSearchEqual get_search_equal_func();
_IGNORE(gtk_tree_view_get_search_equal_func)
@@ -758,7 +758,7 @@ public:
* @param x: the x coordinate (relative to widget coordinates)
* @param y: the y coordinate (relative to widget coordinates)
* @param keyboard_tip: whether this is a keyboard tooltip or not
- * @param iter: a pointer to receive a Gtk::TreeIter
+ * @param iter: a pointer to receive a Gtk::TreeModel::iterator
*
* This function is supposed to be used in a Gtk::Widget::query-tooltip
* signal handler for Gtk::TreeView. The x, y and keyboard_tip values
@@ -770,7 +770,7 @@ public:
* tooltips the row returned will be the cursor item. When true, then the
* iter which has been provided will be set to point to
* that row and the corresponding model. x and y will always be converted
- * to be relative to Gtk::TreeView's bin_window if keyboard_tooltip is false.
+ * to be relative to Gtk::TreeView's bin_window if keyboard_tip is false.
*
* Return value: whether or not the given tooltip context points to a row.
*
diff --git a/tools/m4/convert_gtk.m4 b/tools/m4/convert_gtk.m4
index 40e2a39..88b110b 100644
--- a/tools/m4/convert_gtk.m4
+++ b/tools/m4/convert_gtk.m4
@@ -436,10 +436,10 @@ _CONVERSION(`const Glib::RefPtr<EntryBuffer>&',`GtkEntryBuffer*',__CONVERT_REFPT
_CONVERSION(`const iterator&',`const GtkTreeIter*',__FR2P)
#_CONVERSION(`const TreeIter&',`GtkTreeIter*',__FCR2P)
_CONVERSION(`const iterator&',`GtkTreeIter*',__FCR2P)
+_CONVERSION(`const const_iterator&',`GtkTreeIter*',__FCR2P)
_CONVERSION(`const TreeModel::Row&',`GtkTreeIter*',__FCR2P)
_CONVERSION(`iterator&',`GtkTreeIter*',__FR2P)
_CONVERSION(`const TreeModel::iterator&',`GtkTreeIter*',__FCR2P)
-_CONVERSION(`const iterator&',`GtkTreeIter*',__FCR2P)
_CONVERSION(`TreeViewColumn&',`GtkTreeViewColumn*',__FR2P)
_CONVERSION(`GtkTreeViewColumn*',`TreeViewColumn*',`Glib::wrap($3)')
_CONVERSION(`GtkTreeViewColumn*',`const TreeViewColumn*',`Glib::wrap($3)')
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]