2 // Generated by gtkmmproc -- DO NOT MODIFY!
3 #ifndef _GTKMM_TREEITER_H
4 #define _GTKMM_TREEITER_H
10 /* Copyright(C) 1998-2002 The gtkmm Development Team
12 * This library is free software, ) you can redistribute it and/or
13 * modify it under the terms of the GNU Library General Public
14 * License as published by the Free Software Foundation, ) either
15 * version 2 of the License, or(at your option) any later version.
17 * This library is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY, ) without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * Library General Public License for more details.
22 * You should have received a copy of the GNU Library General Public
23 * License along with this library, ) if not, write to the Free
24 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 #include <gtkmm/treemodelcolumn.h>
29 #include <gtkmmconfig.h>
31 #include <gtk/gtktreemodel.h> /* for GtkTreeIter */
33 GLIBMM_USING_STD(forward_iterator_tag)
41 class TreeNodeChildren;
49 #ifndef DOXYGEN_SHOULD_SKIP_THIS
50 typedef TreeIterBase CppObjectType;
51 typedef GtkTreeIter BaseObjectType;
53 static GType get_type() G_GNUC_CONST;
54 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
58 explicit TreeIterBase(const GtkTreeIter* gobject); // always takes a copy
60 ///Provides access to the underlying C instance.
61 GtkTreeIter* gobj() { return &gobject_; }
63 ///Provides access to the underlying C instance.
64 const GtkTreeIter* gobj() const { return &gobject_; }
72 //A wrap() for TreeIterBase* wouldn't be very helpful.
78 // In order to offer STL-like iterator functionality, we cannot wrap
79 // GtkTreeIter directly. Most GTK+ functions that operate on GtkTreeIter
80 // are virtual functions in GtkTreeModel. Therefore, the C++ TreeIter
81 // must store a pointer to the Gtk::TreeModel to which it belongs.
83 // Another problem, which is much worse, is that the GTK+ tree iterator
84 // doesn't support the STL-style half-open interval [begin,end). Instead,
85 // it uses a [first,last] interval, and functions return FALSE to indicate
86 // the end was reached. Also, some functions accept a NULL GtkTreeIter*,
87 // which will be interpreted as the end() iterator.
89 // Most of the immense complexity in the Gtk::TreeIter implementation is
90 // needed for proper emulation of [begin,end) intervals. Unfortunately,
91 // it's not even possible to encapsulate everything in the TreeIter
92 // class. Almost all wrapper methods dealing with GtkTreeIter must be
93 // carefully implemented by hand. TODO: document implementation details
95 //TODO: Implement a const_iterator too:
96 //danielk says that this ConstTreeIter class should return a ConstTreeRow, which would not allow operator=.
98 /** A Gtk::TreeModel::iterator is a reference to a specific node on a specific
101 * It is a generic structure with an integer and three generic pointers.
102 * These are filled in by the model in a model-specific way.
104 * One can convert a path to an iterator by calling Gtk::TreeModel::get_iter().
106 * These iterators are the primary way of accessing a model and are similar to the iterators
107 * used by Gtk::TextBuffer. The model interface defines a set of operations
108 * using them for navigating the model.
110 * The lifecycle of an iterator can be a little confusing at first. Iterators
111 * are expected to always be valid for as long as the model is unchanged (and
112 * doesn't emit a signal).
113 * Additionally, some models guarantee that an iterator is valid for as
114 * long as the node it refers to is valid (most notably the Gtk::TreeStore and
117 * Although generally uninteresting, as one always has to
118 * allow for the case where iterators do not persist beyond a signal, some very
119 * important performance enhancements were made in the sort model. As a result,
120 * the Gtk::TREE_MODEL_ITERS_PERSIST flag was added to indicate this behaviour -
121 * see Gtk::TreeModel::get_flags().
123 * Typedefed as Gtk::TreeModel::iterator.
124 * The Gtk::TreeModel iterator.
127 class TreeIter : public TreeIterBase
130 typedef std::bidirectional_iterator_tag iterator_category;
131 typedef Gtk::TreeRow value_type;
132 typedef int difference_type;
133 typedef const Gtk::TreeRow& reference;
134 typedef const Gtk::TreeRow* pointer;
138 TreeIter& operator++();
139 const TreeIter operator++(int);
141 /** Please note that this is very slow compared to operator++().
143 TreeIter& operator--();
145 /** Please note that this is very slow compared to operator++().
147 const TreeIter operator--(int);
149 inline reference operator*() const;
150 inline pointer operator->() const;
152 bool equal(const TreeIter& other) const;
154 /** Discover whether the iterator is valid, and not equal to end().
156 operator bool() const;
158 /** This is only useful when implementing a custom Gtk::TreeModel class.
159 * Compare the iterator's stamp with your model's stamp to discover whether it is valid.
161 * @result The iterator's stamp.
163 int get_stamp() const;
165 /** This is only useful when implementing a custom Gtk::TreeModel class.
166 * Set the stamp to be equal to your model's stamp, to mark the iterator as valid.
167 * When your model's structure changes, you should increment your model's stamp
168 * to mark all older iterators as invalid. They will be recognised as invalid because
169 * they will then have an incorrect stamp.
171 void set_stamp(int stamp);
173 #ifndef DOXYGEN_SHOULD_SKIP_THIS
175 explicit TreeIter(TreeModel* model); // used in TreeModel methods
176 TreeIter(GtkTreeModel* model, const GtkTreeIter* iter); // used by signal proxies
178 void set_model_refptr(const Glib::RefPtr<TreeModel>& model);
179 void set_model_gobject(GtkTreeModel* model);
180 GtkTreeModel* get_model_gobject() const;
182 void setup_end_iterator(const TreeIter& last_valid);
184 const GtkTreeIter* get_gobject_if_not_end() const
185 { return (!is_end_) ? &gobject_ : 0; }
187 const GtkTreeIter* get_parent_gobject_if_end() const
188 { return (is_end_ && gobject_.stamp) ? &gobject_ : 0; }
192 // Yes, using a simple TreeModel* rather than Glib::RefPtr<TreeModel>
193 // violates the general policy. But Gtk::TreeIter should have a trivial
194 // copy constructor and assignment operator, i.e. it must contain only
195 // POD (plain old data).
197 // Gtk::TreeIter is copied a lot, particularly often as return value from
198 // methods. Postfix ++ must return by value, and STL algorithms usually
199 // pass iterators by value, too. With a RefPtr<> as member data, copying
200 // would no longer be trivial, and even cause frequent calls to reference()
201 // and unreference(). That usually doesn't matter much for GUI stuff, but
202 // Gtk::TreeModel is used as a generic container. Imagine a for-loop that
203 // checks whether iter != children.end() on each iteration.
208 friend class Gtk::TreeRow;
209 friend class Gtk::TreeNodeChildren;
210 friend class Gtk::TreeModel;
212 #endif // DOXYGEN_SHOULD_SKIP_THIS
215 /** @relates Gtk::TreeIter */
216 inline bool operator==(const TreeIter& lhs, const TreeIter& rhs)
217 { return lhs.equal(rhs); }
219 /** @relates Gtk::TreeIter */
220 inline bool operator!=(const TreeIter& lhs, const TreeIter& rhs)
221 { return !lhs.equal(rhs); }
224 template <class ColumnType>
228 #ifndef DOXYGEN_SHOULD_SKIP_THIS
229 inline TreeValueProxy(const TreeRow& row, const TreeModelColumn<ColumnType>& column);
232 inline TreeValueProxy<ColumnType>& operator=(const ColumnType& data);
233 inline operator ColumnType() const;
237 const TreeModelColumn<ColumnType>& column_;
239 // no copy assignment
240 TreeValueProxy<ColumnType>& operator=(const TreeValueProxy<ColumnType>&);
244 /** Typedefed as TreeModel::Row.
246 * Dereference a TreeModel::iterator to get the Row. Use operator[] or set_value() and get_value() to access the
247 * values in the columns of this row.
249 * If the model contains a hierarchy of rows (such as Gtk::TreeStore), then you can access the child rows with
252 * You can use a const TreeModel::Row& for any parameter that takes a const TreeModel::iterator&.
255 class TreeRow : public TreeIter //We use public inheritance so that we can cast from a TreeRow to a TreeIter.
259 /** Use this to set and get the value of this @a column of this row.
260 * This is a templated method, so the compiler will not allow you to provide an inappropriate type
261 * of data for the model column.
263 * This is just a more convient syntax that does the same thing as set_value() and get_value().
265 * @param column The model column..
267 template <class ColumnType> inline
268 TreeValueProxy<ColumnType> operator[](const TreeModelColumn<ColumnType>& column) const;
270 /** Sets the value of this @a column of this row.
271 * This is a templated method, so the compiler will not allow you to provide an inappropriate type
272 * of @a data for the model column.
274 * See also operator[].
276 * @param column The model column.
277 * @param data The new value to use for this column of this row.
279 template <class ColumnType>
280 void set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data) const;
282 /** Use set_value(const TreeModelColumn<>& column, const ColumnType& data) unless
283 * you do not know the column type at compile-time.
284 * If the @a data is of an inappropriate C++ type then this might fail at runtime.
285 * @param column The number of the column whose value you want to change.
286 * @param data The new value to use for this column of this row.
288 template <class ColumnType>
289 void set_value(int column, const ColumnType& data) const;
291 /** Gets the value of this @a column of this row.
292 * This is a templated method, so the compiler will not allow you to provide an inappropriate type
293 * of data for the model column.
295 * See also operator[].
297 * @param column The model column.
298 * @result The new value to use for this column of this row.
300 template <class ColumnType>
301 ColumnType get_value(const TreeModelColumn<ColumnType>& column) const;
303 /** Use get_value(const TreeModelColumn<>& column) unless
304 * you do not know the column type at compile-time.
305 * If the @a data output argument is of an inappropriate C++ type then this might fail at runtime.
306 * @param column The number of the column whose value you want to change.
307 * @retval data An output argument which will contain the value of this column of this row.
309 template <class ColumnType>
310 void get_value(int column, ColumnType& data) const;
312 /** This returns an STL-like container API, for iterating over the rows.
313 * See also Gtk::TreeModel::children() for the top-level children.
315 const TreeNodeChildren& children() const;
317 /** Gets an iterator to the parent row of this row.
318 * @result An iterator to the parent row.
320 TreeIter parent() const;
322 /** Discover whether this is a valid row.
324 operator bool() const;
326 /// Provides access to the underlying C GObject.
327 GtkTreeIter* gobj() { return TreeIter::gobj(); }
329 /// Provides access to the underlying C GObject.
330 const GtkTreeIter* gobj() const { return TreeIter::gobj(); }
333 // Forwarders to Gtk::TreeModel virtual methods.
334 void set_value_impl(int column, const Glib::ValueBase& value) const;
335 void get_value_impl(int column, Glib::ValueBase& value) const;
339 //TODO: Document begin(), end(), size(), etc, in an STL-style way. murrayc.
341 /** typedefed as TreeModel::Children.
342 * Virtual container of TreeModel::Row items.
345 class TreeNodeChildren : public TreeIter
348 typedef Gtk::TreeRow value_type;
349 typedef unsigned int size_type;
350 typedef int difference_type;
351 typedef Gtk::TreeIter iterator;
353 #ifndef GLIBMM_HAVE_SUN_REVERSE_ITERATOR
354 typedef std::reverse_iterator<iterator> reverse_iterator;
356 typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
357 int, int&, int*, ptrdiff_t> reverse_iterator;
360 typedef Gtk::TreeIter const_iterator; //TODO: Make it a real const_iterator.
362 #ifndef GLIBMM_HAVE_SUN_REVERSE_ITERATOR
363 typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
365 typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
366 int, const int&, const int*, ptrdiff_t> const_reverse_iterator;
370 const_iterator begin() const;
372 const_iterator end() const;
374 // Note: there is no advantage in not inlining these methods.
375 // We can't change them without breaking ABI anyway.
376 reverse_iterator rbegin() { return reverse_iterator(end()); }
377 reverse_iterator rend() { return reverse_iterator(begin()); }
378 const_reverse_iterator rbegin() const { return const_reverse_iterator(end()); }
379 const_reverse_iterator rend() const { return const_reverse_iterator(begin()); }
381 value_type operator[](size_type index) const;
383 size_type size() const;
385 operator bool() const { return !empty(); }
387 #ifndef DOXYGEN_SHOULD_SKIP_THIS
389 explicit TreeNodeChildren(TreeModel* model)
392 const GtkTreeIter* get_parent_gobject() const
393 { return (gobject_.stamp != 0) ? &gobject_ : 0; }
395 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
399 #ifndef DOXYGEN_SHOULD_SKIP_THIS
401 /**** Gtk::TreeIter ********************************************************/
404 TreeIter::reference TreeIter::operator*() const
406 return static_cast<const TreeRow&>(*this);
410 TreeIter::pointer TreeIter::operator->() const
412 return static_cast<const TreeRow*>(this);
416 /**** Gtk::TreeValueProxy<> ************************************************/
418 template <class ColumnType> inline
419 TreeValueProxy<ColumnType>::TreeValueProxy(const TreeRow& row, const TreeModelColumn<ColumnType>& column)
425 template <class ColumnType> inline
426 TreeValueProxy<ColumnType>& TreeValueProxy<ColumnType>::operator=(const ColumnType& data)
428 row_.set_value(column_, data);
432 template <class ColumnType> inline
433 TreeValueProxy<ColumnType>::operator ColumnType() const
435 return row_.get_value(column_);
439 /**** Gtk::TreeRow *********************************************************/
441 template <class ColumnType> inline
442 TreeValueProxy<ColumnType> TreeRow::operator[](const TreeModelColumn<ColumnType>& column) const
444 return TreeValueProxy<ColumnType>(*this, column);
447 template <class ColumnType>
448 void TreeRow::set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data) const
450 typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
453 value.init(column.type());
456 this->set_value_impl(column.index(), value);
459 template <class ColumnType>
460 void TreeRow::set_value(int column, const ColumnType& data) const
462 //This could fail at run-time, because the wrong ColumnType might be used.
463 //It's only for dynamically generated model columns.
465 typedef typename Gtk::TreeModelColumn<ColumnType> type_cppcolumn;
466 typedef typename type_cppcolumn::ValueType ValueType;
469 value.init(ValueType::value_type());
472 this->set_value_impl(column, value);
475 template <class ColumnType>
476 ColumnType TreeRow::get_value(const TreeModelColumn<ColumnType>& column) const
478 typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
481 this->get_value_impl(column.index(), value);
486 template <class ColumnType>
487 void TreeRow::get_value(int column, ColumnType& data) const
489 //This could fail at run-time, because the wrong ColumnType might be used.
490 //It's only for dynamically generated model columns.
492 typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
495 this->get_value_impl(column, value);
500 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
508 #ifndef DOXYGEN_SHOULD_SKIP_THIS
510 class Value<Gtk::TreeIterBase> : public Glib::Value_Boxed<Gtk::TreeIterBase>
512 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
516 #endif /* _GTKMM_TREEITER_H */