[gtkmm] Gtk::TreeRow and TreeNodeChildren: Make real const versions
- From: Kjell Ahlstedt <kjellahl src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtkmm] Gtk::TreeRow and TreeNodeChildren: Make real const versions
- Date: Sun, 8 Jan 2017 14:53:11 +0000 (UTC)
commit acd6dcfb65c61e8517ed84a51721cdd2bcdeeeb5
Author: Kjell Ahlstedt <kjell ahlstedt bredband net>
Date: Sun Jan 8 15:46:53 2017 +0100
Gtk::TreeRow and TreeNodeChildren: Make real const versions
Split TreeRow and TreeNodeChildren into TreeRow+TreeConstRow and
TreeNodeChildren+TreeNodeConstChildren. Since TreeRow and TreeNodeChildren
are just disguised iterators, they too shall have const versions that can't
be implicitly copied to non-const versions that can be used for changing the
underlying TreeModel.
Add const versions of TreeModel::get_iter(). Bug #134520
demos/gtk-demo/example_iconbrowser.cc | 7 +-
demos/gtk-demo/example_iconview.cc | 4 +-
gtk/src/treeiter.ccg | 72 +++------
gtk/src/treeiter.hg | 292 ++++++++++++++++++++-------------
gtk/src/treemodel.ccg | 15 ++-
gtk/src/treemodel.hg | 35 +++--
6 files changed, 241 insertions(+), 184 deletions(-)
---
diff --git a/demos/gtk-demo/example_iconbrowser.cc b/demos/gtk-demo/example_iconbrowser.cc
index 47b660f..fa14ba9 100644
--- a/demos/gtk-demo/example_iconbrowser.cc
+++ b/demos/gtk-demo/example_iconbrowser.cc
@@ -865,7 +865,7 @@ void Example_IconBrowser::add_icon(const Glib::ustring& name,
bool Example_IconBrowser::is_icon_visible(const Gtk::TreeModel::const_iterator& iter) const
{
- const Gtk::TreeModel::Row row = *iter;
+ const auto row = *iter;
const Glib::ustring name = row[m_store->get_text_column()];
if (name.empty())
return false;
@@ -1005,12 +1005,11 @@ Glib::RefPtr<IconInfoStore> IconInfoStore::create()
bool IconInfoStore::drag_data_get_vfunc(const Gtk::TreeModel::Path& path,
Gtk::SelectionData& selection_data) const
{
- // There is no const version of Gtk::TreeModel::get_iter().
- Gtk::TreeModel::const_iterator iter = const_cast<IconInfoStore*>(this)->get_iter(path);
+ const auto iter = get_iter(path);
if (!iter)
return false;
- const Gtk::TreeModel::Row row = *iter;
+ const auto row = *iter;
const Glib::ustring name = row[m_text_column];
selection_data.set_text(name);
return true;
diff --git a/demos/gtk-demo/example_iconview.cc b/demos/gtk-demo/example_iconview.cc
index 4a9b009..6a14bce 100644
--- a/demos/gtk-demo/example_iconview.cc
+++ b/demos/gtk-demo/example_iconview.cc
@@ -134,8 +134,8 @@ int Example_IconView::on_model_sort(const Gtk::TreeModel::const_iterator& a, con
* folders before files.
*/
- const Gtk::TreeModel::Row row_a = *a;
- const Gtk::TreeModel::Row row_b = *b;
+ const auto row_a = *a;
+ const auto 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/src/treeiter.ccg b/gtk/src/treeiter.ccg
index db3dac4..8335770 100644
--- a/gtk/src/treeiter.ccg
+++ b/gtk/src/treeiter.ccg
@@ -154,7 +154,7 @@ void TreeIterBase3::set_stamp(int stamp)
}
-/**** Gtk::TreeRow *********************************************************/
+/**** Gtk::TreeConstRow and Gtk::TreeRow **************************************/
TreeNodeChildren& TreeRow::children()
{
@@ -163,9 +163,11 @@ TreeNodeChildren& TreeRow::children()
return static_cast<TreeNodeChildren&>(static_cast<TreeIterBase2&>(*this));
}
-const TreeNodeChildren& TreeRow::children() const
+const TreeNodeConstChildren& TreeConstRow::children() const
{
- return const_cast<TreeRow*>(this)->children();
+ g_assert(!is_end_);
+
+ return static_cast<const TreeNodeConstChildren&>(static_cast<const TreeIterBase2&>(*this));
}
TreeIter<TreeRow> TreeRow::parent()
@@ -180,9 +182,9 @@ TreeIter<TreeRow> TreeRow::parent()
return iter;
}
-TreeIter<const TreeRow> TreeRow::parent() const
+TreeIter<TreeConstRow> TreeConstRow::parent() const
{
- TreeIter<const TreeRow> iter(model_);
+ TreeIter<TreeConstRow> iter(model_);
if(is_end_)
iter.gobject_ = gobject_;
@@ -197,9 +199,9 @@ TreeIter<TreeRow> TreeRow::get_iter()
return static_cast<TreeIter<TreeRow>&>(static_cast<TreeIterBase2&>(*this));
}
-TreeIter<const TreeRow> TreeRow::get_iter() const
+TreeIter<TreeConstRow> TreeConstRow::get_iter() const
{
- return static_cast<const TreeIter<const TreeRow>&>(static_cast<const TreeIterBase2&>(*this));
+ return static_cast<const TreeIter<TreeConstRow>&>(static_cast<const TreeIterBase2&>(*this));
}
void TreeRow::set_value_impl(int column, const Glib::ValueBase& value)
@@ -209,10 +211,15 @@ void TreeRow::set_value_impl(int column, const Glib::ValueBase& value)
void TreeRow::get_value_impl(int column, Glib::ValueBase& value) const
{
- model_->get_value_impl(static_cast<const TreeIter<const TreeRow>&>(static_cast<const
TreeIterBase2&>(*this)), column, value);
+ model_->get_value_impl(static_cast<const TreeIter<TreeConstRow>&>(static_cast<const
TreeIterBase2&>(*this)), column, value);
+}
+
+void TreeConstRow::get_value_impl(int column, Glib::ValueBase& value) const
+{
+ model_->get_value_impl(static_cast<const TreeIter<TreeConstRow>&>(static_cast<const
TreeIterBase2&>(*this)), column, value);
}
-TreeRow::operator bool() const
+TreeConstRow::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
@@ -220,7 +227,7 @@ TreeRow::operator bool() const
return !is_end_ && gobject_.stamp;
}
-/**** Gtk::TreeNodeChildren ************************************************/
+/**** Gtk::TreeNodeConstChildren and Gtk::TreeNodeChildren ********************/
TreeNodeChildren::iterator TreeNodeChildren::begin()
{
@@ -231,7 +238,7 @@ TreeNodeChildren::iterator TreeNodeChildren::begin()
if(gobject_.stamp != 0)
{
- if(!gtk_tree_model_iter_children(model_->gobj(), iter.gobj(), const_cast<GtkTreeIter*>(&gobject_)))
+ if(!gtk_tree_model_iter_children(model_->gobj(), iter.gobj(), &gobject_))
{
// Assign the already known parent, in order to create an end iterator.
iter.gobject_ = gobject_;
@@ -250,34 +257,9 @@ TreeNodeChildren::iterator TreeNodeChildren::begin()
return iter;
}
-TreeNodeChildren::const_iterator TreeNodeChildren::begin() const
+TreeNodeConstChildren::const_iterator TreeNodeConstChildren::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;
+ return const_cast<TreeNodeChildren*>(static_cast<const TreeNodeChildren*>(this))->begin();
}
TreeNodeChildren::iterator TreeNodeChildren::end()
@@ -289,13 +271,9 @@ TreeNodeChildren::iterator TreeNodeChildren::end()
return iter;
}
-TreeNodeChildren::const_iterator TreeNodeChildren::end() const
+TreeNodeConstChildren::const_iterator TreeNodeConstChildren::end() const
{
- // Just copy the parent, and turn it into an end iterator.
- const_iterator iter(model_);
- iter.gobject_ = gobject_;
- iter.is_end_ = true;
- return iter;
+ return const_cast<TreeNodeChildren*>(static_cast<const TreeNodeChildren*>(this))->end();
}
TreeNodeChildren::value_type TreeNodeChildren::operator[](TreeNodeChildren::size_type index)
@@ -314,7 +292,7 @@ TreeNodeChildren::value_type TreeNodeChildren::operator[](TreeNodeChildren::size
return *iter;
}
-const TreeNodeChildren::value_type TreeNodeChildren::operator[](TreeNodeChildren::size_type index) const
+const TreeNodeConstChildren::value_type TreeNodeConstChildren::operator[](TreeNodeChildren::size_type index)
const
{
const_iterator iter(model_);
@@ -330,14 +308,14 @@ const TreeNodeChildren::value_type TreeNodeChildren::operator[](TreeNodeChildren
return *iter;
}
-TreeNodeChildren::size_type TreeNodeChildren::size() const
+TreeNodeConstChildren::size_type TreeNodeConstChildren::size() const
{
const auto parent = const_cast<GtkTreeIter*>(get_parent_gobject());
return gtk_tree_model_iter_n_children(model_->gobj(), parent);
}
-bool TreeNodeChildren::empty() const
+bool TreeNodeConstChildren::empty() const
{
// If the iterator is invalid (stamp == 0), assume a 'virtual' toplevel
// node. This behaviour is needed to implement Gtk::TreeModel::children().
diff --git a/gtk/src/treeiter.hg b/gtk/src/treeiter.hg
index 71065b2..bd38b79 100644
--- a/gtk/src/treeiter.hg
+++ b/gtk/src/treeiter.hg
@@ -22,9 +22,6 @@ _DEFS(gtkmm,gtk)
#include <iterator>
#include <type_traits>
#include <gtk/gtk.h> /* for GtkTreeIter */
-#ifdef GLIBMM_HAVE_SUN_REVERSE_ITERATOR
-#include <cstddef> /* for std::ptrdiff_t */
-#endif
namespace Gtk
{
@@ -32,7 +29,9 @@ namespace Gtk
class TreeModel;
template <typename T>
class TreeIter;
+class TreeConstRow;
class TreeRow;
+class TreeNodeConstChildren;
class TreeNodeChildren;
// Why all the base classes?
@@ -85,8 +84,11 @@ protected:
bool is_end_;
// For the conversion and assignment from iterator to const_iterator
- friend class Gtk::TreeIter<const Gtk::TreeRow>;
+ friend class Gtk::TreeIter<Gtk::TreeConstRow>;
+
+ friend class Gtk::TreeConstRow;
friend class Gtk::TreeRow;
+ friend class Gtk::TreeNodeConstChildren;
friend class Gtk::TreeNodeChildren;
#endif // DOXYGEN_SHOULD_SKIP_THIS
@@ -94,7 +96,7 @@ protected:
/** Base of TreeIter.
*
- * Contains the common parts of TreeIter<TreeRow> and TreeIter<const TreeRow>.
+ * Contains the common parts of TreeIter<TreeRow> and TreeIter<TreeConstRow>.
*
* @ingroup TreeView
*/
@@ -165,9 +167,9 @@ protected:
// carefully implemented by hand.
//TODO: document implementation details.
-/** A Gtk::TreeModel::iterator is a reference to a specific node on a specific
- * model.
+/** Typedefed as TreeModel::iterator and TreeModel::const_iterator.
*
+ * 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.
*
@@ -190,21 +192,19 @@ protected:
* the Gtk::TREE_MODEL_ITERS_PERSIST flag was added to indicate this behaviour -
* see Gtk::TreeModel::get_flags().
*
- * Typedefed as Gtk::TreeModel::iterator and Gtk::TreeModel::const_iterator.
- *
- * @tparam T <TreeRow> for an iterator, or <const TreeRow> for a const_iterator.
+ * @tparam T TreeRow for an iterator, TreeConstRow for a const_iterator.
*
* @ingroup TreeView
*/
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");
+ static_assert(std::is_same<T, TreeRow>::value || std::is_same<T, TreeConstRow>::value,
+ "TreeIter can only iterate over TreeRow or TreeConstRow");
public:
using iterator_category = std::bidirectional_iterator_tag;
- using value_type = TreeRow;
+ using value_type = T;
using difference_type = int;
using reference = T&;
using pointer = T*;
@@ -212,13 +212,13 @@ public:
TreeIter();
/// 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>
+ template <typename T2, typename = typename std::enable_if<
+ std::is_same<T, TreeConstRow>::value && std::is_same<T2, TreeRow>::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>
+ template <typename T2, typename = typename std::enable_if<
+ std::is_same<T, TreeConstRow>::value && std::is_same<T2, TreeRow>::value, T2>::type>
TreeIter& operator=(const TreeIter<T2>& src);
#ifndef DOXYGEN_SHOULD_SKIP_THIS
@@ -263,26 +263,100 @@ template <typename T>
inline bool operator!=(const TreeIter<T>& lhs, const TreeIter<T>& rhs)
{ return !lhs.equal(rhs); }
-template <class ColumnType>
+template <typename RowType, typename ColumnType>
class TreeValueProxy
{
public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
- inline TreeValueProxy(const TreeRow& row, const TreeModelColumn<ColumnType>& column);
+ inline TreeValueProxy(const RowType& row, const TreeModelColumn<ColumnType>& column);
#endif
- inline TreeValueProxy<ColumnType>& operator=(const ColumnType& data);
+ inline TreeValueProxy& operator=(const ColumnType& data);
inline operator ColumnType() const;
private:
- TreeRow& row_;
+ RowType& row_;
const TreeModelColumn<ColumnType>& column_;
// no copy assignment
- TreeValueProxy<ColumnType>& operator=(const TreeValueProxy<ColumnType>&) = delete;
+ TreeValueProxy& operator=(const TreeValueProxy&) = delete;
};
+/** Typedefed as TreeModel::ConstRow.
+ *
+ * %TreeConstRow is a const version of %TreeRow. %TreeConstRow does not contain
+ * methods for modifying the underlying TreeModel.
+ *
+ * @see TreeRow
+ * @ingroup TreeView
+ */
+class TreeConstRow : public TreeIterBase2
+{
+public:
+
+ /** Use this to 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 convenient syntax that does the same thing as get_value().
+ *
+ * @param column The model column.
+ */
+ template <typename ColumnType> inline
+ const TreeValueProxy<TreeConstRow, ColumnType> operator[](const TreeModelColumn<ColumnType>& column) const;
+
+ /** Gets the value of this @a column of this row.
+ *
+ * See also operator[]().
+ *
+ * @param column The model column.
+ * @result The value of this column of this row.
+ */
+ template <typename 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 query.
+ * @param[out] data An output argument which will contain the value of this column of this row.
+ */
+ template <typename 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 TreeNodeConstChildren& children() const;
+
+ /** Gets a const_iterator to the parent row of this row.
+ * @result A const_iterator to the parent row.
+ */
+ TreeIter<TreeConstRow> parent() const;
+
+ /** Gets a const_iterator to this row.
+ * @result A const_iterator to this row.
+ */
+ TreeIter<TreeConstRow> get_iter() const;
+
+ /** Discover whether this is a valid row.
+ * For instance,
+ * @code
+ * if (treerow)
+ * do_something();
+ * @endcode
+ *
+ * @newin{3,22}
+ */
+ explicit operator bool() const;
+
+private:
+ // Forwarders to Gtk::TreeModel virtual methods.
+ void get_value_impl(int column, Glib::ValueBase& value) const;
+
+}; // class TreeConstRow
+
/** Typedefed as TreeModel::Row.
*
* Dereference a TreeModel::iterator to get the Row. Use operator[] or set_value()
@@ -297,10 +371,16 @@ private:
*
* @ingroup TreeView
*/
-class TreeRow : public TreeIterBase2
+class TreeRow : public TreeConstRow
{
public:
+ // Inherit the const versions
+ using TreeConstRow::operator[];
+ using TreeConstRow::children;
+ using TreeConstRow::parent;
+ using TreeConstRow::get_iter;
+
/** 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.
@@ -309,22 +389,19 @@ public:
*
* @param column The model column.
*/
- template <class ColumnType> inline
- TreeValueProxy<ColumnType> operator[](const TreeModelColumn<ColumnType>& column);
-
- template <class ColumnType> inline
- const TreeValueProxy<ColumnType> operator[](const TreeModelColumn<ColumnType>& column) const;
+ template <typename ColumnType> inline
+ TreeValueProxy<TreeRow, ColumnType> operator[](const TreeModelColumn<ColumnType>& column);
/** 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[].
+ * See also operator[]().
*
* @param column The model column.
* @param data The new value to use for this column of this row.
*/
- template <class ColumnType>
+ template <typename ColumnType>
void set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data);
/** Use set_value(const TreeModelColumn<>& column, const ColumnType& data) unless
@@ -333,77 +410,24 @@ public:
* @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>
+ template <typename ColumnType>
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
- * of data for the model column.
- *
- * See also operator[].
- *
- * @param column The model column.
- * @result The value of 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 query.
- * @param[out] 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.
*/
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<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();
- * @endcode
- *
- * @newin{3,22}
- */
- explicit operator bool() const;
-
- /// Provides access to the underlying C GObject.
- GtkTreeIter* gobj() { return TreeIterBase::gobj(); }
-
- /// Provides access to the underlying C GObject.
- const GtkTreeIter* gobj() const { return TreeIterBase::gobj(); }
-
private:
// Forwarders to Gtk::TreeModel virtual methods.
void set_value_impl(int column, const Glib::ValueBase& value);
@@ -414,33 +438,33 @@ private:
//TODO: Document begin(), end(), size(), etc, in an STL-style way. murrayc.
-/** Virtual container of TreeModel::Row items.
+/** Typedefed as TreeModel::ConstChildren.
+ *
+ * Virtual container of TreeModel::ConstRow items.
*
- * typedefed as TreeModel::Children.
+ * %TreeNodeConstChildren is a const version of %TreeNodeChildren.
+ * %TreeNodeConstChildren does not contain methods for modifying the underlying TreeModel.
*
+ * @see TreeNodeChildren
* @ingroup TreeView
*/
-class TreeNodeChildren : public TreeIterBase2
+class TreeNodeConstChildren : public TreeIterBase2
{
public:
- using value_type = Gtk::TreeRow;
+ using value_type = Gtk::TreeConstRow;
using size_type = unsigned int;
using difference_type = int;
- using iterator = Gtk::TreeIter<Gtk::TreeRow>;
- using const_iterator = Gtk::TreeIter<const Gtk::TreeRow>;
+ using const_iterator = Gtk::TreeIter<Gtk::TreeConstRow>;
- 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;
size_type size() const;
bool empty() const;
- /** Discover whether this is a valid TreeNodeChildren.
+ /** Discover whether this is a valid container.
* For instance,
* @code
* if (children)
@@ -456,11 +480,42 @@ public:
#ifndef DOXYGEN_SHOULD_SKIP_THIS
- explicit TreeNodeChildren(TreeModel* model)
- : TreeIterBase2(model) {}
+ explicit TreeNodeConstChildren(const TreeModel* model)
+ : TreeIterBase2(const_cast<TreeModel*>(model)) {}
const GtkTreeIter* get_parent_gobject() const
- { return (gobject_.stamp != 0) ? &gobject_ : nullptr; }
+ { return (gobject_.stamp != 0) ? &gobject_ : nullptr; }
+
+#endif /* DOXYGEN_SHOULD_SKIP_THIS */
+
+}; // class TreeNodeConstChildren
+
+/** Typedefed as TreeModel::Children.
+ *
+ * Virtual container of TreeModel::Row items.
+ *
+ * @ingroup TreeView
+ */
+class TreeNodeChildren : public TreeNodeConstChildren
+{
+public:
+ using value_type = Gtk::TreeRow;
+ using iterator = Gtk::TreeIter<Gtk::TreeRow>;
+
+ // Inherit the const versions
+ using TreeNodeConstChildren::begin;
+ using TreeNodeConstChildren::end;
+ using TreeNodeConstChildren::operator[];
+
+ iterator begin();
+ iterator end();
+
+ value_type operator[](size_type index);
+
+#ifndef DOXYGEN_SHOULD_SKIP_THIS
+
+ explicit TreeNodeChildren(TreeModel* model)
+ : TreeNodeConstChildren(model) {}
#endif /* DOXYGEN_SHOULD_SKIP_THIS */
@@ -562,42 +617,45 @@ TreeIter<T>::operator bool() const
/**** Gtk::TreeValueProxy<> ************************************************/
-template <class ColumnType> inline
-TreeValueProxy<ColumnType>::TreeValueProxy(const TreeRow& row, const TreeModelColumn<ColumnType>& column)
+template <typename RowType, typename ColumnType> inline
+TreeValueProxy<RowType, ColumnType>::TreeValueProxy(const RowType& row, const TreeModelColumn<ColumnType>&
column)
:
- row_ (const_cast<TreeRow&>(row)),
+ row_ (const_cast<RowType&>(row)),
column_ (column)
{}
-template <class ColumnType> inline
-TreeValueProxy<ColumnType>& TreeValueProxy<ColumnType>::operator=(const ColumnType& data)
+template <typename RowType, typename ColumnType> inline
+TreeValueProxy<RowType, ColumnType>& TreeValueProxy<RowType, ColumnType>::operator=(const ColumnType& data)
{
+ // If row_ is a TreeConstRow and TreeValueProxy::operator=() is actually used,
+ // this will fail at compile time. TreeConstRow has no set_value() method.
+ // This failure is deliberate.
row_.set_value(column_, data);
return *this;
}
-template <class ColumnType> inline
-TreeValueProxy<ColumnType>::operator ColumnType() const
+template <typename RowType, typename ColumnType> inline
+TreeValueProxy<RowType, ColumnType>::operator ColumnType() const
{
return row_.get_value(column_);
}
-/**** Gtk::TreeRow *********************************************************/
+/**** Gtk::TreeConstRow and Gtk::TreeRow **************************************/
-template <class ColumnType> inline
-const TreeValueProxy<ColumnType> TreeRow::operator[](const TreeModelColumn<ColumnType>& column) const
+template <typename ColumnType> inline
+const TreeValueProxy<TreeConstRow, ColumnType> TreeConstRow::operator[](const TreeModelColumn<ColumnType>&
column) const
{
- return TreeValueProxy<ColumnType>(*this, column);
+ return TreeValueProxy<TreeConstRow, ColumnType>(*this, column);
}
-template <class ColumnType> inline
-TreeValueProxy<ColumnType> TreeRow::operator[](const TreeModelColumn<ColumnType>& column)
+template <typename ColumnType> inline
+TreeValueProxy<TreeRow, ColumnType> TreeRow::operator[](const TreeModelColumn<ColumnType>& column)
{
- return TreeValueProxy<ColumnType>(*this, column);
+ return TreeValueProxy<TreeRow, ColumnType>(*this, column);
}
-template <class ColumnType>
+template <typename ColumnType>
void TreeRow::set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data)
{
using ValueType = typename Gtk::TreeModelColumn<ColumnType>::ValueType;
@@ -609,7 +667,7 @@ void TreeRow::set_value(const TreeModelColumn<ColumnType>& column, const ColumnT
this->set_value_impl(column.index(), value);
}
-template <class ColumnType>
+template <typename ColumnType>
void TreeRow::set_value(int column, const ColumnType& data)
{
// This could fail at run-time, because the wrong ColumnType might be used.
@@ -624,8 +682,8 @@ void TreeRow::set_value(int column, const ColumnType& data)
this->set_value_impl(column, value);
}
-template <class ColumnType>
-ColumnType TreeRow::get_value(const TreeModelColumn<ColumnType>& column) const
+template <typename ColumnType>
+ColumnType TreeConstRow::get_value(const TreeModelColumn<ColumnType>& column) const
{
using ValueType = typename Gtk::TreeModelColumn<ColumnType>::ValueType;
@@ -635,8 +693,8 @@ ColumnType TreeRow::get_value(const TreeModelColumn<ColumnType>& column) const
return value.get();
}
-template <class ColumnType>
-void TreeRow::get_value(int column, ColumnType& data) const
+template <typename ColumnType>
+void TreeConstRow::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.
diff --git a/gtk/src/treemodel.ccg b/gtk/src/treemodel.ccg
index 5766464..a2835c4 100644
--- a/gtk/src/treemodel.ccg
+++ b/gtk/src/treemodel.ccg
@@ -93,6 +93,11 @@ TreeModel::iterator TreeModel::get_iter(const Path& path)
return iter;
}
+TreeModel::const_iterator TreeModel::get_iter(const Path& path) const
+{
+ return const_cast<TreeModel*>(this)->get_iter(path);
+}
+
TreeModel::iterator TreeModel::get_iter(const Glib::ustring& path_string)
{
Gtk::TreeModel::iterator iter (this);
@@ -100,15 +105,19 @@ TreeModel::iterator TreeModel::get_iter(const Glib::ustring& path_string)
return iter;
}
+TreeModel::const_iterator TreeModel::get_iter(const Glib::ustring& path_string) const
+{
+ return const_cast<TreeModel*>(this)->get_iter(path_string);
+}
+
TreeModel::Children TreeModel::children()
{
return TreeNodeChildren(this);
}
-TreeModel::Children TreeModel::children() const
+const TreeModel::ConstChildren TreeModel::children() const
{
- //TODO: Remove the const when we have a real const TreeNodeChildren, when we have a real const_iterator.
- return TreeNodeChildren(const_cast<TreeModel*>(this));
+ return TreeNodeConstChildren(this);
}
void TreeModel::set_value_impl(const iterator&, int, const Glib::ValueBase&)
diff --git a/gtk/src/treemodel.hg b/gtk/src/treemodel.hg
index f63b849..3023e7b 100644
--- a/gtk/src/treemodel.hg
+++ b/gtk/src/treemodel.hg
@@ -97,9 +97,11 @@ public:
typedef TreeModelColumnRecord ColumnRecord;
typedef TreeNodeChildren Children;
+ typedef TreeNodeConstChildren ConstChildren;
typedef Children::iterator iterator;
- typedef Children::const_iterator const_iterator;
+ typedef ConstChildren::const_iterator const_iterator;
+ typedef TreeConstRow ConstRow;
typedef TreeRow Row;
typedef TreePath Path;
typedef TreeRowReference RowReference;
@@ -113,8 +115,13 @@ public:
* @result A valid iterator pointing to the path, or an invalid iterator if that is not possible.
*/
iterator get_iter(const Path& path);
- //TODO: Add const_iterator get_iter(const Path& path) const;
- //Implement a const_iterator?
+
+ /** Returns a valid iterator pointing to @a path.
+ *
+ * @param path The @link Gtk::TreePath Gtk::TreeModel::Path@endlink.
+ * @result A valid iterator pointing to the path, or an invalid iterator if that is not possible.
+ */
+ const_iterator get_iter(const Path& path) const;
/** Returns a valid iterator pointing to @a path_string.
*
@@ -122,26 +129,31 @@ public:
* @result A valid iterator pointing to the path, or an invalid iterator if that is not possible.
*/
iterator get_iter(const Glib::ustring& path_string);
- //TODO: Implement a const_iterator? const_iterator get_iter(const Glib::ustring& path_string) const;
+
+ /** Returns a valid iterator pointing to @a path_string.
+ *
+ * @param path_string The path, as a string representation.
+ * @result A valid iterator pointing to the path, or an invalid iterator if that is not possible.
+ */
+ const_iterator get_iter(const Glib::ustring& path_string) const;
///This returns an STL-like container API, for iterating over the rows.
Children children();
- //TODO: Return a real TreeNodeChildren (a container of const_iterators), when we have a real
const_iterator.
///This returns an STL-like container API, for iterating over the rows.
- Children children() const;
+ const ConstChildren children() const;
_IGNORE(gtk_tree_model_foreach)
/** For example,
* void on_foreach(const Gtk::TreeModel::iterator& iter);
*
- * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
+ * If the callback function returns true, then the tree ceases to be walked, and foreach_iter() returns.
*/
typedef sigc::slot<bool(const TreeModel::iterator&)> SlotForeachIter;
/** Calls a callback slot on each node in the model in a depth-first fashion.
- * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
+ * If the callback function returns true, then the tree ceases to be walked, and foreach_iter() returns.
*
* @param slot The function to call for each selected node.
*/
@@ -150,12 +162,12 @@ public:
/** For example,
* void on_foreach(const Gtk::TreeModel::Path& path);
*
- * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
+ * If the callback function returns true, then the tree ceases to be walked, and foreach_path() returns.
*/
typedef sigc::slot<bool(const TreeModel::Path&)> SlotForeachPath;
/** Calls a callback slot on each node in the model in a depth-first fashion.
- * If the callback function returns true, then the tree ceases to be walked, and foreach() returns.
+ * If the callback function returns true, then the tree ceases to be walked, and foreach_path() returns.
*
* @param slot The function to call for each selected node.
*/
@@ -180,7 +192,7 @@ public:
_WRAP_METHOD(GType get_column_type(int index) const, gtk_tree_model_get_column_type)
//TODO: A C++-type version of get_column_type()?
- _WRAP_METHOD(TreeModel::Path get_path(const iterator& iter) const, gtk_tree_model_get_path)
+ _WRAP_METHOD(TreeModel::Path get_path(const const_iterator& iter) const, gtk_tree_model_get_path)
_WRAP_METHOD(void row_changed(const Path& path, const iterator& iter), gtk_tree_model_row_changed)
_WRAP_METHOD(void row_inserted(const Path& path, const iterator& iter), gtk_tree_model_row_inserted)
@@ -403,6 +415,7 @@ dnl
friend class Gtk::TreeModelFilter;
friend class Gtk::TreeModelSort;
+ friend class Gtk::TreeConstRow;
friend class Gtk::TreeRow;
};
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]