Install ardour as a binary, a script and a set of shared
[ardour.git] / libs / gtkmm2 / gtk / gtkmm / treeiter.h
1 // -*- c++ -*-
2 // Generated by gtkmmproc -- DO NOT MODIFY!
3 #ifndef _GTKMM_TREEITER_H
4 #define _GTKMM_TREEITER_H
5
6 #include <glibmm.h>
7
8 /* $Id$ */
9
10 /* Copyright(C) 1998-2002 The gtkmm Development Team
11  *
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.
16  *
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.
21  *
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.
25  */
26
27
28 #include <gtkmm/treemodelcolumn.h>
29 #include <gtkmmconfig.h>
30 #include <iterator>
31 #include <gtk/gtktreemodel.h> /* for GtkTreeIter */
32
33 GLIBMM_USING_STD(forward_iterator_tag)
34
35
36 namespace Gtk
37 {
38
39 class TreeModel;
40 class TreeRow;
41 class TreeNodeChildren;
42
43 /**
44  * @ingroup TreeView
45  */
46 class TreeIterBase
47 {
48   public:
49 #ifndef DOXYGEN_SHOULD_SKIP_THIS
50   typedef TreeIterBase CppObjectType;
51   typedef GtkTreeIter BaseObjectType;
52
53   static GType get_type() G_GNUC_CONST;
54 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
55
56   TreeIterBase();
57
58   explicit TreeIterBase(const GtkTreeIter* gobject); // always takes a copy
59
60   ///Provides access to the underlying C instance.
61   GtkTreeIter*       gobj()       { return &gobject_; }
62
63   ///Provides access to the underlying C instance.
64   const GtkTreeIter* gobj() const { return &gobject_; }
65
66 protected:
67   GtkTreeIter gobject_;
68
69 private:
70   
71   
72   //A wrap() for TreeIterBase* wouldn't be very helpful.
73
74
75 };
76
77
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.
82 //
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.
88 //
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
94
95 //TODO: Implement a const_iterator too:
96 //danielk says that this ConstTreeIter class should return a ConstTreeRow, which would not allow operator=.
97
98 /** A Gtk::TreeModel::iterator is a reference to a specific node on a specific
99  * model.
100  *
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.
103  *
104  * One can convert a path to an iterator by calling Gtk::TreeModel::get_iter().
105  *
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.
109  *
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
115  * Gtk::ListStore).
116  *
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().
122  *
123  * Typedefed as Gtk::TreeModel::iterator.
124  * The Gtk::TreeModel iterator.
125  * @ingroup TreeView
126  */
127 class TreeIter : public TreeIterBase
128 {
129 public:
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;
135
136   TreeIter();
137
138   TreeIter&      operator++();
139   const TreeIter operator++(int);
140
141   /** Please note that this is very slow compared to operator++().
142    */
143   TreeIter&      operator--();
144
145   /** Please note that this is very slow compared to operator++().
146    */
147   const TreeIter operator--(int);
148   
149   inline reference operator*()  const;
150   inline pointer   operator->() const;
151
152   bool equal(const TreeIter& other) const;
153
154   /** Discover whether the iterator is valid, and not equal to end().
155    */
156   operator bool() const;
157
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.
160    * @see set_stamp().
161    * @result The iterator's stamp.
162    */
163   int get_stamp() const;
164
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.
170    */
171   void set_stamp(int stamp);
172
173 #ifndef DOXYGEN_SHOULD_SKIP_THIS
174
175   explicit TreeIter(TreeModel* model); // used in TreeModel methods
176   TreeIter(GtkTreeModel* model, const GtkTreeIter* iter); // used by signal proxies
177
178   void set_model_refptr(const Glib::RefPtr<TreeModel>& model);
179   void set_model_gobject(GtkTreeModel* model);
180   GtkTreeModel* get_model_gobject() const;
181
182   void setup_end_iterator(const TreeIter& last_valid);
183
184   const GtkTreeIter* get_gobject_if_not_end() const
185     { return (!is_end_) ? &gobject_ : 0; }
186
187   const GtkTreeIter* get_parent_gobject_if_end() const
188     { return (is_end_ && gobject_.stamp) ? &gobject_ : 0; }
189
190 protected:
191
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).
196   //
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.
204
205   TreeModel* model_;
206   bool       is_end_;
207
208   friend class Gtk::TreeRow;
209   friend class Gtk::TreeNodeChildren;
210   friend class Gtk::TreeModel;
211
212 #endif // DOXYGEN_SHOULD_SKIP_THIS
213 };
214
215 /** @relates Gtk::TreeIter */
216 inline bool operator==(const TreeIter& lhs, const TreeIter& rhs)
217   { return lhs.equal(rhs); }
218
219 /** @relates Gtk::TreeIter */
220 inline bool operator!=(const TreeIter& lhs, const TreeIter& rhs)
221   { return !lhs.equal(rhs); }
222
223
224 template <class ColumnType>
225 class TreeValueProxy
226 {
227 public:
228 #ifndef DOXYGEN_SHOULD_SKIP_THIS
229   inline TreeValueProxy(const TreeRow& row, const TreeModelColumn<ColumnType>& column);
230 #endif
231
232   inline TreeValueProxy<ColumnType>& operator=(const ColumnType& data);
233   inline operator ColumnType() const;
234
235 private:
236   const TreeRow&                      row_;
237   const TreeModelColumn<ColumnType>&  column_;
238
239   // no copy assignment
240   TreeValueProxy<ColumnType>& operator=(const TreeValueProxy<ColumnType>&);
241 };
242
243
244 /** Typedefed as TreeModel::Row.
245  *
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.
248  *
249  * If the model contains a hierarchy of rows (such as Gtk::TreeStore), then you can access the child rows with
250  * children().
251  *
252  * You can use a const TreeModel::Row& for any parameter that takes a const TreeModel::iterator&.
253  * @ingroup TreeView
254  */
255 class TreeRow : public TreeIter //We use public inheritance so that we can cast from a TreeRow to a TreeIter.
256 {
257 public:
258
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.
262    *
263    * This is just a more convient syntax that does the same thing as set_value() and get_value().
264    *
265    * @param column The model column..
266    */
267   template <class ColumnType> inline
268   TreeValueProxy<ColumnType> operator[](const TreeModelColumn<ColumnType>& column) const;
269
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.
273    *
274    * See also operator[].
275    *
276    * @param column The model column.
277    * @param data The new value to use for this column of this row.
278    */
279   template <class ColumnType>
280   void set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data) const;
281
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.
287    */
288   template <class ColumnType>
289   void set_value(int column, const ColumnType& data) const;
290
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.
294    *
295    * See also operator[].
296    *
297    * @param column The model column.
298    * @result The new value to use for this column of this row.
299    */
300   template <class ColumnType>
301   ColumnType get_value(const TreeModelColumn<ColumnType>& column) const;
302
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.
308    */
309   template <class ColumnType>
310   void get_value(int column, ColumnType& data) const;
311
312   /** This returns an STL-like container API, for iterating over the rows.
313    * See also Gtk::TreeModel::children() for the top-level children.
314    */
315   const TreeNodeChildren& children() const;
316
317   /** Gets an iterator to the parent row of this row.
318    * @result An iterator to the parent row.
319    */
320   TreeIter parent() const;
321
322   /** Discover whether this is a valid row.
323    */
324   operator bool() const;
325
326   /// Provides access to the underlying C GObject.  
327   GtkTreeIter*       gobj()       { return TreeIter::gobj(); }
328
329   /// Provides access to the underlying C GObject.  
330   const GtkTreeIter* gobj() const { return TreeIter::gobj(); }
331
332 private:
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;
336 };
337
338
339 //TODO: Document begin(), end(), size(), etc, in an STL-style way. murrayc.
340
341 /** typedefed as TreeModel::Children.
342  * Virtual container of TreeModel::Row items.
343  * @ingroup TreeView
344  */
345 class TreeNodeChildren : public TreeIter
346 {
347 public:
348   typedef Gtk::TreeRow  value_type;
349   typedef unsigned int  size_type;
350   typedef int           difference_type;
351   typedef Gtk::TreeIter iterator;
352
353   #ifndef GLIBMM_HAVE_SUN_REVERSE_ITERATOR
354     typedef std::reverse_iterator<iterator> reverse_iterator;
355   #else
356     typedef std::reverse_iterator<iterator, std::random_access_iterator_tag,
357                                   int, int&, int*, ptrdiff_t> reverse_iterator;
358   #endif
359
360     typedef Gtk::TreeIter const_iterator; //TODO: Make it a real const_iterator.
361
362   #ifndef GLIBMM_HAVE_SUN_REVERSE_ITERATOR
363     typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
364   #else
365     typedef std::reverse_iterator<const_iterator, std::random_access_iterator_tag,
366                                   int, const int&, const int*, ptrdiff_t> const_reverse_iterator;
367   #endif
368
369   iterator begin();
370   const_iterator begin() const;
371   iterator end();
372   const_iterator end()   const;
373
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()); }
380
381   value_type operator[](size_type index) const;
382
383   size_type size() const;
384   bool empty() const;
385   operator bool() const { return !empty(); }
386
387 #ifndef DOXYGEN_SHOULD_SKIP_THIS
388
389   explicit TreeNodeChildren(TreeModel* model)
390     : TreeIter(model) {}
391
392   const GtkTreeIter* get_parent_gobject() const
393     { return (gobject_.stamp != 0) ? &gobject_ : 0; }
394
395 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
396 };
397
398
399 #ifndef DOXYGEN_SHOULD_SKIP_THIS
400
401 /**** Gtk::TreeIter ********************************************************/
402
403 inline
404 TreeIter::reference TreeIter::operator*() const
405 {
406   return static_cast<const TreeRow&>(*this);
407 }
408
409 inline
410 TreeIter::pointer TreeIter::operator->() const
411 {
412   return static_cast<const TreeRow*>(this);
413 }
414
415
416 /**** Gtk::TreeValueProxy<> ************************************************/
417
418 template <class ColumnType> inline
419 TreeValueProxy<ColumnType>::TreeValueProxy(const TreeRow& row, const TreeModelColumn<ColumnType>& column)
420 :
421   row_    (row),
422   column_ (column)
423 {}
424
425 template <class ColumnType> inline
426 TreeValueProxy<ColumnType>& TreeValueProxy<ColumnType>::operator=(const ColumnType& data)
427 {
428   row_.set_value(column_, data);
429   return *this;
430 }
431
432 template <class ColumnType> inline
433 TreeValueProxy<ColumnType>::operator ColumnType() const
434 {
435   return row_.get_value(column_);
436 }
437
438
439 /**** Gtk::TreeRow *********************************************************/
440
441 template <class ColumnType> inline
442 TreeValueProxy<ColumnType> TreeRow::operator[](const TreeModelColumn<ColumnType>& column) const
443 {
444   return TreeValueProxy<ColumnType>(*this, column);
445 }
446
447 template <class ColumnType>
448 void TreeRow::set_value(const TreeModelColumn<ColumnType>& column, const ColumnType& data) const
449 {
450   typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
451
452   ValueType value;
453   value.init(column.type());
454
455   value.set(data);
456   this->set_value_impl(column.index(), value);
457 }
458
459 template <class ColumnType>
460 void TreeRow::set_value(int column, const ColumnType& data) const
461 {
462   //This could fail at run-time, because the wrong ColumnType might be used.
463   //It's only for dynamically generated model columns.
464
465   typedef typename Gtk::TreeModelColumn<ColumnType> type_cppcolumn;
466   typedef typename type_cppcolumn::ValueType ValueType;
467
468   ValueType value;
469   value.init(ValueType::value_type());
470
471   value.set(data);
472   this->set_value_impl(column, value);
473 }
474
475 template <class ColumnType>
476 ColumnType TreeRow::get_value(const TreeModelColumn<ColumnType>& column) const
477 {
478   typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
479
480   ValueType value;
481   this->get_value_impl(column.index(), value);
482
483   return value.get();
484 }
485
486 template <class ColumnType>
487 void TreeRow::get_value(int column, ColumnType& data) const
488 {
489   //This could fail at run-time, because the wrong ColumnType might be used.
490   //It's only for dynamically generated model columns.
491
492   typedef typename Gtk::TreeModelColumn<ColumnType>::ValueType ValueType;
493
494   ValueType value;
495   this->get_value_impl(column, value);
496
497   data = value.get();
498 }
499
500 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
501
502 } // namespace Gtk
503
504
505 namespace Glib
506 {
507
508 #ifndef DOXYGEN_SHOULD_SKIP_THIS
509 template <>
510 class Value<Gtk::TreeIterBase> : public Glib::Value_Boxed<Gtk::TreeIterBase>
511 {};
512 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
513
514 } // namespace Glib
515
516 #endif /* _GTKMM_TREEITER_H */
517