]> Pileus Git - ~andy/gtk/blob - gtk/gtktreemodel.c
GtkTreeModel: add more detailed documentation on reference counting
[~andy/gtk] / gtk / gtktreemodel.c
1 /* gtktreemodel.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "config.h"
21 #include <stdlib.h>
22 #include <string.h>
23 #include <glib.h>
24 #include <glib/gprintf.h>
25 #include <gobject/gvaluecollector.h>
26 #include "gtktreemodel.h"
27 #include "gtktreeview.h"
28 #include "gtktreeprivate.h"
29 #include "gtkmarshalers.h"
30 #include "gtkintl.h"
31
32 /**
33  * SECTION:gtktreemodel
34  * @Title: GtkTreeModel
35  * @Short_description: The tree interface used by GtkTreeView
36  * @See_also: #GtkTreeView, #GtkTreeStore, #GtkListStore,
37  *     <link linkend="gtk-GtkTreeView-drag-and-drop">GtkTreeDnd</link>,
38  *     #GtkTreeSortable
39  *
40  * The #GtkTreeModel interface defines a generic tree interface for
41  * use by the #GtkTreeView widget. It is an abstract interface, and
42  * is designed to be usable with any appropriate data structure. The
43  * programmer just has to implement this interface on their own data
44  * type for it to be viewable by a #GtkTreeView widget.
45  *
46  * The model is represented as a hierarchical tree of strongly-typed,
47  * columned data. In other words, the model can be seen as a tree where
48  * every node has different values depending on which column is being
49  * queried. The type of data found in a column is determined by using
50  * the GType system (ie. #G_TYPE_INT, #GTK_TYPE_BUTTON, #G_TYPE_POINTER,
51  * etc). The types are homogeneous per column across all nodes. It is
52  * important to note that this interface only provides a way of examining
53  * a model and observing changes. The implementation of each individual
54  * model decides how and if changes are made.
55  *
56  * In order to make life simpler for programmers who do not need to
57  * write their own specialized model, two generic models are provided
58  * &mdash; the #GtkTreeStore and the #GtkListStore. To use these, the
59  * developer simply pushes data into these models as necessary. These
60  * models provide the data structure as well as all appropriate tree
61  * interfaces. As a result, implementing drag and drop, sorting, and
62  * storing data is trivial. For the vast majority of trees and lists,
63  * these two models are sufficient.
64  *
65  * Models are accessed on a node/column level of granularity. One can
66  * query for the value of a model at a certain node and a certain
67  * column on that node. There are two structures used to reference
68  * a particular node in a model. They are the #GtkTreePath and the
69  * #GtkTreeIter<footnote><para>Here, <abbrev>iter</abbrev> is short
70  * for <quote>iterator</quote></para></footnote>. Most of the interface
71  * consists of operations on a #GtkTreeIter.
72  *
73  * A path is essentially a potential node. It is a location on a model
74  * that may or may not actually correspond to a node on a specific
75  * model. The #GtkTreePath struct can be converted into either an
76  * array of unsigned integers or a string. The string form is a list
77  * of numbers separated by a colon. Each number refers to the offset
78  * at that level. Thus, the path <quote>0</quote> refers to the root
79  * node and the path <quote>2:4</quote> refers to the fifth child of
80  * the third node.
81  *
82  * By contrast, a #GtkTreeIter is a reference to a specific node on
83  * a specific model. It is a generic struct with an integer and three
84  * generic pointers. These are filled in by the model in a model-specific
85  * way. One can convert a path to an iterator by calling
86  * gtk_tree_model_get_iter(). These iterators are the primary way
87  * of accessing a model and are similar to the iterators used by
88  * #GtkTextBuffer. They are generally statically allocated on the
89  * stack and only used for a short time. The model interface defines
90  * a set of operations using them for navigating the model.
91  *
92  * It is expected that models fill in the iterator with private data.
93  * For example, the #GtkListStore model, which is internally a simple
94  * linked list, stores a list node in one of the pointers. The
95  * #GtkTreeModelSort stores an array and an offset in two of the
96  * pointers. Additionally, there is an integer field. This field is
97  * generally filled with a unique stamp per model. This stamp is for
98  * catching errors resulting from using invalid iterators with a model.
99  *
100  * The lifecycle of an iterator can be a little confusing at first.
101  * Iterators are expected to always be valid for as long as the model
102  * is unchanged (and doesn't emit a signal). The model is considered
103  * to own all outstanding iterators and nothing needs to be done to
104  * free them from the user's point of view. Additionally, some models
105  * guarantee that an iterator is valid for as long as the node it refers
106  * to is valid (most notably the #GtkTreeStore and #GtkListStore).
107  * Although generally uninteresting, as one always has to allow for
108  * the case where iterators do not persist beyond a signal, some very
109  * important performance enhancements were made in the sort model.
110  * As a result, the #GTK_TREE_MODEL_ITERS_PERSIST flag was added to
111  * indicate this behavior.
112  *
113  * To help show some common operation of a model, some examples are
114  * provided. The first example shows three ways of getting the iter at
115  * the location <quote>3:2:5</quote>. While the first method shown is
116  * easier, the second is much more common, as you often get paths from
117  * callbacks.
118  *
119  * <example>
120  * <title>Acquiring a <structname>GtkTreeIter</structname></title>
121  * <programlisting>
122  *  /&ast; Three ways of getting the iter pointing to the location &ast;/
123  * GtkTreePath *path;
124  * GtkTreeIter iter;
125  * GtkTreeIter parent_iter;
126  *
127  * /&ast; get the iterator from a string &ast;/
128  * gtk_tree_model_get_iter_from_string (model, &amp;iter, "3:2:5");
129  *
130  * /&ast; get the iterator from a path &ast;/
131  * path = gtk_tree_path_new_from_string ("3:2:5");
132  * gtk_tree_model_get_iter (model, &amp;iter, path);
133  * gtk_tree_path_free (path);
134  *
135  * /&ast; walk the tree to find the iterator &ast;/
136  * gtk_tree_model_iter_nth_child (model, &amp;iter, NULL, 3);
137  * parent_iter = iter;
138  * gtk_tree_model_iter_nth_child (model, &amp;iter, &amp;parent_iter, 2);
139  * parent_iter = iter;
140  * gtk_tree_model_iter_nth_child (model, &amp;iter, &amp;parent_iter, 5);
141  * </programlisting>
142  * </example>
143  *
144  * This second example shows a quick way of iterating through a list
145  * and getting a string and an integer from each row. The
146  * <function>populate_model</function> function used below is not
147  * shown, as it is specific to the #GtkListStore. For information on
148  * how to write such a function, see the #GtkListStore documentation.
149  *
150  * <example>
151  * <title>Reading data from a <structname>GtkTreeModel</structname></title>
152  * <programlisting>
153  * enum
154  * {
155  *   STRING_COLUMN,
156  *   INT_COLUMN,
157  *   N_COLUMNS
158  * };
159  *
160  * ...
161  *
162  * GtkTreeModel *list_store;
163  * GtkTreeIter iter;
164  * gboolean valid;
165  * gint row_count = 0;
166  *
167  * /&ast; make a new list_store &ast;/
168  * list_store = gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_INT);
169  *
170  * /&ast; Fill the list store with data &ast;/
171  * populate_model (list_store);
172  *
173  * /&ast; Get the first iter in the list &ast;/
174  * valid = gtk_tree_model_get_iter_first (list_store, &amp;iter);
175  *
176  * while (valid)
177  *  {
178  *    /&ast; Walk through the list, reading each row &ast;/
179  *    gchar *str_data;
180  *    gint   int_data;
181  *
182  *    /&ast; Make sure you terminate calls to gtk_tree_model_get()
183  *     &ast; with a '-1' value
184  *     &ast;/
185  *    gtk_tree_model_get (list_store, &amp;iter,
186  *                        STRING_COLUMN, &amp;str_data,
187  *                        INT_COLUMN, &amp;int_data,
188  *                        -1);
189  *
190  *    /&ast; Do something with the data &ast;/
191  *    g_print ("Row &percnt;d: (&percnt;s,&percnt;d)\n", row_count, str_data, int_data);
192  *    g_free (str_data);
193  *
194  *    row_count++;
195  *    valid = gtk_tree_model_iter_next (list_store, &amp;iter);
196  *  }
197  * </programlisting>
198  * </example>
199  *
200  * The #GtkTreeModel interface contains two methods for reference
201  * counting: gtk_tree_model_ref_node() and gtk_tree_model_unref_node().
202  * These two methods are optional to implement. The reference counting
203  * is meant as a way for views to let models know when nodes are being
204  * displayed. #GtkTreeView will take a reference on a node when it is
205  * visible, which means the node is either in the toplevel or expanded.
206  * Being displayed does not mean that the node is currently directly
207  * visible to the user in the viewport. Based on this reference counting
208  * scheme a caching model, for example, can decide whether or not to cache
209  * a node based on the reference count. A file-system based model would
210  * not want to keep the entire file hierarchy in memory, but just the
211  * folders that are currently expanded in every current view.
212  *
213  * When working with reference counting, the following rules must be taken
214  * into account:
215  * <itemizedlist>
216  * <listitem><para>Never take a reference on a node without owning a
217  * reference on its parent. This means that all parent nodes of a referenced
218  * node must be referenced as well.</para></listitem>
219  * <listitem><para>Outstanding references on a deleted node are not released.
220  * This is not possible because the node has already been deleted by the
221  * time the row-deleted signal is received.
222  * </para></listitem>
223  * <listitem><para>Models are not obligated to emit a signal on rows of
224  * which none of its siblings are referenced. To phrase this differently,
225  * signals are only required for levels in which nodes are referenced. For
226  * the root level however, signals must be emitted at all times (however the
227  * root level is always referenced when any view is attached).
228  * </para></listitem>
229  * </itemizedlist>
230  */
231
232 #define INITIALIZE_TREE_ITER(Iter) \
233     G_STMT_START{ \
234       (Iter)->stamp = 0; \
235       (Iter)->user_data  = NULL; \
236       (Iter)->user_data2 = NULL; \
237       (Iter)->user_data3 = NULL; \
238     }G_STMT_END
239
240 #define ROW_REF_DATA_STRING "gtk-tree-row-refs"
241
242 enum {
243   ROW_CHANGED,
244   ROW_INSERTED,
245   ROW_HAS_CHILD_TOGGLED,
246   ROW_DELETED,
247   ROWS_REORDERED,
248   LAST_SIGNAL
249 };
250
251 static guint tree_model_signals[LAST_SIGNAL] = { 0 };
252
253 struct _GtkTreePath
254 {
255   gint depth;    /* Number of elements */
256   gint alloc;    /* Number of allocated elements */
257   gint *indices;
258 };
259
260 typedef struct
261 {
262   GSList *list;
263 } RowRefList;
264
265 static void      gtk_tree_model_base_init   (gpointer           g_class);
266
267 /* custom closures */
268 static void      row_inserted_marshal       (GClosure          *closure,
269                                              GValue /* out */  *return_value,
270                                              guint              n_param_value,
271                                              const GValue      *param_values,
272                                              gpointer           invocation_hint,
273                                              gpointer           marshal_data);
274 static void      row_deleted_marshal        (GClosure          *closure,
275                                              GValue /* out */  *return_value,
276                                              guint              n_param_value,
277                                              const GValue      *param_values,
278                                              gpointer           invocation_hint,
279                                              gpointer           marshal_data);
280 static void      rows_reordered_marshal     (GClosure          *closure,
281                                              GValue /* out */  *return_value,
282                                              guint              n_param_value,
283                                              const GValue      *param_values,
284                                              gpointer           invocation_hint,
285                                              gpointer           marshal_data);
286
287 static void      gtk_tree_row_ref_inserted  (RowRefList        *refs,
288                                              GtkTreePath       *path,
289                                              GtkTreeIter       *iter);
290 static void      gtk_tree_row_ref_deleted   (RowRefList        *refs,
291                                              GtkTreePath       *path);
292 static void      gtk_tree_row_ref_reordered (RowRefList        *refs,
293                                              GtkTreePath       *path,
294                                              GtkTreeIter       *iter,
295                                              gint              *new_order);
296
297 GType
298 gtk_tree_model_get_type (void)
299 {
300   static GType tree_model_type = 0;
301
302   if (! tree_model_type)
303     {
304       const GTypeInfo tree_model_info =
305       {
306         sizeof (GtkTreeModelIface), /* class_size */
307         gtk_tree_model_base_init,   /* base_init */
308         NULL,           /* base_finalize */
309         NULL,
310         NULL,           /* class_finalize */
311         NULL,           /* class_data */
312         0,
313         0,              /* n_preallocs */
314         NULL
315       };
316
317       tree_model_type =
318         g_type_register_static (G_TYPE_INTERFACE, I_("GtkTreeModel"),
319                                 &tree_model_info, 0);
320
321       g_type_interface_add_prerequisite (tree_model_type, G_TYPE_OBJECT);
322     }
323
324   return tree_model_type;
325 }
326
327 static void
328 gtk_tree_model_base_init (gpointer g_class)
329 {
330   static gboolean initialized = FALSE;
331   GClosure *closure;
332
333   if (! initialized)
334     {
335       GType row_inserted_params[2];
336       GType row_deleted_params[1];
337       GType rows_reordered_params[3];
338
339       row_inserted_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
340       row_inserted_params[1] = GTK_TYPE_TREE_ITER;
341
342       row_deleted_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
343
344       rows_reordered_params[0] = GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE;
345       rows_reordered_params[1] = GTK_TYPE_TREE_ITER;
346       rows_reordered_params[2] = G_TYPE_POINTER;
347
348       /**
349        * GtkTreeModel::row-changed:
350        * @tree_model: the #GtkTreeModel on which the signal is emitted
351        * @path: a #GtkTreePath identifying the changed row
352        * @iter: a valid #GtkTreeIter pointing to the changed row
353        *
354        * This signal is emitted when a row in the model has changed.
355        */
356       tree_model_signals[ROW_CHANGED] =
357         g_signal_new (I_("row-changed"),
358                       GTK_TYPE_TREE_MODEL,
359                       G_SIGNAL_RUN_LAST, 
360                       G_STRUCT_OFFSET (GtkTreeModelIface, row_changed),
361                       NULL, NULL,
362                       _gtk_marshal_VOID__BOXED_BOXED,
363                       G_TYPE_NONE, 2,
364                       GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE,
365                       GTK_TYPE_TREE_ITER);
366
367       /* We need to get notification about structure changes
368        * to update row references., so instead of using the
369        * standard g_signal_new() with an offset into our interface
370        * structure, we use a customs closures for the class
371        * closures (default handlers) that first update row references
372        * and then calls the function from the interface structure.
373        *
374        * The reason we don't simply update the row references from
375        * the wrapper functions (gtk_tree_model_row_inserted(), etc.)
376        * is to keep proper ordering with respect to signal handlers
377        * connected normally and after.
378        */
379
380       /**
381        * GtkTreeModel::row-inserted:
382        * @tree_model: the #GtkTreeModel on which the signal is emitted
383        * @path: a #GtkTreePath identifying the new row
384        * @iter: a valid #GtkTreeIter pointing to the new row
385        *
386        * This signal is emitted when a new row has been inserted in
387        * the model.
388        *
389        * Note that the row may still be empty at this point, since
390        * it is a common pattern to first insert an empty row, and
391        * then fill it with the desired values.
392        */
393       closure = g_closure_new_simple (sizeof (GClosure), NULL);
394       g_closure_set_marshal (closure, row_inserted_marshal);
395       tree_model_signals[ROW_INSERTED] =
396         g_signal_newv (I_("row-inserted"),
397                        GTK_TYPE_TREE_MODEL,
398                        G_SIGNAL_RUN_FIRST,
399                        closure,
400                        NULL, NULL,
401                        _gtk_marshal_VOID__BOXED_BOXED,
402                        G_TYPE_NONE, 2,
403                        row_inserted_params);
404
405       /**
406        * GtkTreeModel::row-has-child-toggled:
407        * @tree_model: the #GtkTreeModel on which the signal is emitted
408        * @path: a #GtkTreePath identifying the row
409        * @iter: a valid #GtkTreeIter pointing to the row
410        *
411        * This signal is emitted when a row has gotten the first child
412        * row or lost its last child row.
413        */
414       tree_model_signals[ROW_HAS_CHILD_TOGGLED] =
415         g_signal_new (I_("row-has-child-toggled"),
416                       GTK_TYPE_TREE_MODEL,
417                       G_SIGNAL_RUN_LAST,
418                       G_STRUCT_OFFSET (GtkTreeModelIface, row_has_child_toggled),
419                       NULL, NULL,
420                       _gtk_marshal_VOID__BOXED_BOXED,
421                       G_TYPE_NONE, 2,
422                       GTK_TYPE_TREE_PATH | G_SIGNAL_TYPE_STATIC_SCOPE,
423                       GTK_TYPE_TREE_ITER);
424
425       /**
426        * GtkTreeModel::row-deleted:
427        * @tree_model: the #GtkTreeModel on which the signal is emitted
428        * @path: a #GtkTreePath identifying the row
429        *
430        * This signal is emitted when a row has been deleted.
431        *
432        * Note that no iterator is passed to the signal handler,
433        * since the row is already deleted.
434        *
435        * This should be called by models after a row has been removed.
436        * The location pointed to by @path should be the location that
437        * the row previously was at. It may not be a valid location anymore.
438        */
439       closure = g_closure_new_simple (sizeof (GClosure), NULL);
440       g_closure_set_marshal (closure, row_deleted_marshal);
441       tree_model_signals[ROW_DELETED] =
442         g_signal_newv (I_("row-deleted"),
443                        GTK_TYPE_TREE_MODEL,
444                        G_SIGNAL_RUN_FIRST,
445                        closure,
446                        NULL, NULL,
447                        _gtk_marshal_VOID__BOXED,
448                        G_TYPE_NONE, 1,
449                        row_deleted_params);
450
451       /**
452        * GtkTreeModel::rows-reordered: (skip)
453        * @tree_model: the #GtkTreeModel on which the signal is emitted
454        * @path: a #GtkTreePath identifying the tree node whose children
455        *     have been reordered
456        * @iter: a valid #GtkTreeIter pointing to the node whose
457        * @new_order: an array of integers mapping the current position
458        *     of each child to its old position before the re-ordering,
459        *     i.e. @new_order<literal>[newpos] = oldpos</literal>
460        *
461        * This signal is emitted when the children of a node in the
462        * #GtkTreeModel have been reordered.
463        *
464        * Note that this signal is <emphasis>not</emphasis> emitted
465        * when rows are reordered by DND, since this is implemented
466        * by removing and then reinserting the row.
467        */
468       closure = g_closure_new_simple (sizeof (GClosure), NULL);
469       g_closure_set_marshal (closure, rows_reordered_marshal);
470       tree_model_signals[ROWS_REORDERED] =
471         g_signal_newv (I_("rows-reordered"),
472                        GTK_TYPE_TREE_MODEL,
473                        G_SIGNAL_RUN_FIRST,
474                        closure,
475                        NULL, NULL,
476                        _gtk_marshal_VOID__BOXED_BOXED_POINTER,
477                        G_TYPE_NONE, 3,
478                        rows_reordered_params);
479       initialized = TRUE;
480     }
481 }
482
483 static void
484 row_inserted_marshal (GClosure          *closure,
485                       GValue /* out */  *return_value,
486                       guint              n_param_values,
487                       const GValue      *param_values,
488                       gpointer           invocation_hint,
489                       gpointer           marshal_data)
490 {
491   GtkTreeModelIface *iface;
492
493   void (* row_inserted_callback) (GtkTreeModel *tree_model,
494                                   GtkTreePath *path,
495                                   GtkTreeIter *iter) = NULL;
496
497   GObject *model = g_value_get_object (param_values + 0);
498   GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
499   GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
500
501   /* first, we need to update internal row references */
502   gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
503                              path, iter);
504
505   /* fetch the interface ->row_inserted implementation */
506   iface = GTK_TREE_MODEL_GET_IFACE (model);
507   row_inserted_callback = G_STRUCT_MEMBER (gpointer, iface,
508                               G_STRUCT_OFFSET (GtkTreeModelIface,
509                                                row_inserted));
510
511   /* Call that default signal handler, it if has been set */
512   if (row_inserted_callback)
513     row_inserted_callback (GTK_TREE_MODEL (model), path, iter);
514 }
515
516 static void
517 row_deleted_marshal (GClosure          *closure,
518                      GValue /* out */  *return_value,
519                      guint              n_param_values,
520                      const GValue      *param_values,
521                      gpointer           invocation_hint,
522                      gpointer           marshal_data)
523 {
524   GtkTreeModelIface *iface;
525   void (* row_deleted_callback) (GtkTreeModel *tree_model,
526                                  GtkTreePath  *path) = NULL;
527   GObject *model = g_value_get_object (param_values + 0);
528   GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
529
530   /* first, we need to update internal row references */
531   gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
532                             path);
533
534   /* fetch the interface ->row_deleted implementation */
535   iface = GTK_TREE_MODEL_GET_IFACE (model);
536   row_deleted_callback = G_STRUCT_MEMBER (gpointer, iface,
537                               G_STRUCT_OFFSET (GtkTreeModelIface,
538                                                row_deleted));
539
540   /* Call that default signal handler, it if has been set */
541   if (row_deleted_callback)
542     row_deleted_callback (GTK_TREE_MODEL (model), path);
543 }
544
545 static void
546 rows_reordered_marshal (GClosure          *closure,
547                         GValue /* out */  *return_value,
548                         guint              n_param_values,
549                         const GValue      *param_values,
550                         gpointer           invocation_hint,
551                         gpointer           marshal_data)
552 {
553   GtkTreeModelIface *iface;
554   void (* rows_reordered_callback) (GtkTreeModel *tree_model,
555                                     GtkTreePath  *path,
556                                     GtkTreeIter  *iter,
557                                     gint         *new_order);
558
559   GObject *model = g_value_get_object (param_values + 0);
560   GtkTreePath *path = (GtkTreePath *)g_value_get_boxed (param_values + 1);
561   GtkTreeIter *iter = (GtkTreeIter *)g_value_get_boxed (param_values + 2);
562   gint *new_order = (gint *)g_value_get_pointer (param_values + 3);
563
564   /* first, we need to update internal row references */
565   gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (model, ROW_REF_DATA_STRING),
566                               path, iter, new_order);
567
568   /* fetch the interface ->rows_reordered implementation */
569   iface = GTK_TREE_MODEL_GET_IFACE (model);
570   rows_reordered_callback = G_STRUCT_MEMBER (gpointer, iface,
571                               G_STRUCT_OFFSET (GtkTreeModelIface,
572                                                rows_reordered));
573
574   /* Call that default signal handler, it if has been set */
575   if (rows_reordered_callback)
576     rows_reordered_callback (GTK_TREE_MODEL (model), path, iter, new_order);
577 }
578
579 /**
580  * gtk_tree_path_new:
581  *
582  * Creates a new #GtkTreePath.
583  * This structure refers to a row.
584  *
585  * Return value: A newly created #GtkTreePath.
586  */
587 GtkTreePath *
588 gtk_tree_path_new (void)
589 {
590   GtkTreePath *retval;
591   retval = g_slice_new (GtkTreePath);
592   retval->depth = 0;
593   retval->alloc = 0;
594   retval->indices = NULL;
595
596   return retval;
597 }
598
599 /**
600  * gtk_tree_path_new_from_string:
601  * @path: The string representation of a path
602  *
603  * Creates a new #GtkTreePath initialized to @path.
604  *
605  * @path is expected to be a colon separated list of numbers.
606  * For example, the string "10:4:0" would create a path of depth
607  * 3 pointing to the 11th child of the root node, the 5th
608  * child of that 11th child, and the 1st child of that 5th child.
609  * If an invalid path string is passed in, %NULL is returned.
610  *
611  * Return value: A newly-created #GtkTreePath, or %NULL
612  */
613 GtkTreePath *
614 gtk_tree_path_new_from_string (const gchar *path)
615 {
616   GtkTreePath *retval;
617   const gchar *orig_path = path;
618   gchar *ptr;
619   gint i;
620
621   g_return_val_if_fail (path != NULL, NULL);
622   g_return_val_if_fail (*path != '\000', NULL);
623
624   retval = gtk_tree_path_new ();
625
626   while (1)
627     {
628       i = strtol (path, &ptr, 10);
629       if (i < 0)
630         {
631           g_warning (G_STRLOC ": Negative numbers in path %s passed to gtk_tree_path_new_from_string", orig_path);
632           gtk_tree_path_free (retval);
633           return NULL;
634         }
635
636       gtk_tree_path_append_index (retval, i);
637
638       if (*ptr == '\000')
639         break;
640       if (ptr == path || *ptr != ':')
641         {
642           g_warning (G_STRLOC ": Invalid path %s passed to gtk_tree_path_new_from_string", orig_path);
643           gtk_tree_path_free (retval);
644           return NULL;
645         }
646       path = ptr + 1;
647     }
648
649   return retval;
650 }
651
652 /**
653  * gtk_tree_path_new_from_indices:
654  * @first_index: first integer
655  * @varargs: list of integers terminated by -1
656  *
657  * Creates a new path with @first_index and @varargs as indices.
658  *
659  * Return value: A newly created #GtkTreePath
660  *
661  * Since: 2.2
662  */
663 GtkTreePath *
664 gtk_tree_path_new_from_indices (gint first_index,
665                                 ...)
666 {
667   int arg;
668   va_list args;
669   GtkTreePath *path;
670
671   path = gtk_tree_path_new ();
672
673   va_start (args, first_index);
674   arg = first_index;
675
676   while (arg != -1)
677     {
678       gtk_tree_path_append_index (path, arg);
679       arg = va_arg (args, gint);
680     }
681
682   va_end (args);
683
684   return path;
685 }
686
687 /**
688  * gtk_tree_path_to_string:
689  * @path: A #GtkTreePath
690  *
691  * Generates a string representation of the path.
692  *
693  * This string is a ':' separated list of numbers.
694  * For example, "4:10:0:3" would be an acceptable
695  * return value for this string.
696  *
697  * Return value: A newly-allocated string.
698  *     Must be freed with g_free().
699  */
700 gchar *
701 gtk_tree_path_to_string (GtkTreePath *path)
702 {
703   gchar *retval, *ptr, *end;
704   gint i, n;
705
706   g_return_val_if_fail (path != NULL, NULL);
707
708   if (path->depth == 0)
709     return NULL;
710
711   n = path->depth * 12;
712   ptr = retval = g_new0 (gchar, n);
713   end = ptr + n;
714   g_snprintf (retval, end - ptr, "%d", path->indices[0]);
715   while (*ptr != '\000')
716     ptr++;
717
718   for (i = 1; i < path->depth; i++)
719     {
720       g_snprintf (ptr, end - ptr, ":%d", path->indices[i]);
721       while (*ptr != '\000')
722         ptr++;
723     }
724
725   return retval;
726 }
727
728 /**
729  * gtk_tree_path_new_first:
730  *
731  * Creates a new #GtkTreePath.
732  *
733  * The string representation of this path is "0".
734  *
735  * Return value: A new #GtkTreePath
736  */
737 GtkTreePath *
738 gtk_tree_path_new_first (void)
739 {
740   GtkTreePath *retval;
741
742   retval = gtk_tree_path_new ();
743   gtk_tree_path_append_index (retval, 0);
744
745   return retval;
746 }
747
748 /**
749  * gtk_tree_path_append_index:
750  * @path: a #GtkTreePath
751  * @index_: the index
752  *
753  * Appends a new index to a path.
754  *
755  * As a result, the depth of the path is increased.
756  */
757 void
758 gtk_tree_path_append_index (GtkTreePath *path,
759                             gint         index_)
760 {
761   g_return_if_fail (path != NULL);
762   g_return_if_fail (index_ >= 0);
763
764   if (path->depth == path->alloc)
765     {
766       gint *indices;
767       path->alloc = MAX (path->alloc * 2, 1);
768       indices = g_new (gint, path->alloc);
769       memcpy (indices, path->indices, path->depth * sizeof (gint));
770       g_free (path->indices);
771       path->indices = indices;
772     }
773
774   path->depth += 1;
775   path->indices[path->depth - 1] = index_;
776 }
777
778 /**
779  * gtk_tree_path_prepend_index:
780  * @path: a #GtkTreePath
781  * @index_: the index
782  *
783  * Prepends a new index to a path.
784  *
785  * As a result, the depth of the path is increased.
786  */
787 void
788 gtk_tree_path_prepend_index (GtkTreePath *path,
789                              gint       index)
790 {
791   if (path->depth == path->alloc)
792     {
793       gint *indices;
794       path->alloc = MAX (path->alloc * 2, 1);
795       indices = g_new (gint, path->alloc);
796       memcpy (indices + 1, path->indices, path->depth * sizeof (gint));
797       g_free (path->indices);
798       path->indices = indices;
799     }
800   else if (path->depth > 0)
801     memmove (path->indices + 1, path->indices, path->depth * sizeof (gint));
802
803   path->depth += 1;
804   path->indices[0] = index;
805 }
806
807 /**
808  * gtk_tree_path_get_depth:
809  * @path: a #GtkTreePath
810  *
811  * Returns the current depth of @path.
812  *
813  * Return value: The depth of @path
814  */
815 gint
816 gtk_tree_path_get_depth (GtkTreePath *path)
817 {
818   g_return_val_if_fail (path != NULL, 0);
819
820   return path->depth;
821 }
822
823 /**
824  * gtk_tree_path_get_indices: (skip)
825  * @path: a #GtkTreePath
826  *
827  * Returns the current indices of @path.
828  *
829  * This is an array of integers, each representing a node in a tree.
830  * This value should not be freed.
831  *
832  * The length of the array can be obtained with gtk_tree_path_get_depth().
833  *
834  * Return value: The current indices, or %NULL
835  */
836 gint *
837 gtk_tree_path_get_indices (GtkTreePath *path)
838 {
839   g_return_val_if_fail (path != NULL, NULL);
840
841   return path->indices;
842 }
843
844 /**
845  * gtk_tree_path_get_indices_with_depth:
846  * @path: a #GtkTreePath
847  * @depth: (allow-none): return location for number of elements
848  *     returned in the integer array, or %NULL
849  *
850  * Returns the current indices of @path.
851  *
852  * This is an array of integers, each representing a node in a tree.
853  * It also returns the number of elements in the array.
854  * The array should not be freed.
855  *
856  * Return value: (array length=depth) (transfer none): The current
857  *     indices, or %NULL
858  *
859  * Since: 3.0
860  *
861  * Rename to: gtk_tree_path_get_indices
862  */
863 gint *
864 gtk_tree_path_get_indices_with_depth (GtkTreePath *path,
865                                       gint        *depth)
866 {
867   g_return_val_if_fail (path != NULL, NULL);
868
869   if (depth)
870     *depth = path->depth;
871
872   return path->indices;
873 }
874
875 /**
876  * gtk_tree_path_free:
877  * @path: a #GtkTreePath
878  *
879  * Frees @path.
880  */
881 void
882 gtk_tree_path_free (GtkTreePath *path)
883 {
884   if (!path)
885     return;
886
887   g_free (path->indices);
888   g_slice_free (GtkTreePath, path);
889 }
890
891 /**
892  * gtk_tree_path_copy:
893  * @path: a #GtkTreePath
894  *
895  * Creates a new #GtkTreePath as a copy of @path.
896  *
897  * Return value: a new #GtkTreePath
898  */
899 GtkTreePath *
900 gtk_tree_path_copy (const GtkTreePath *path)
901 {
902   GtkTreePath *retval;
903
904   g_return_val_if_fail (path != NULL, NULL);
905
906   retval = g_slice_new (GtkTreePath);
907   retval->depth = path->depth;
908   retval->alloc = retval->depth;
909   retval->indices = g_new (gint, path->alloc);
910   memcpy (retval->indices, path->indices, path->depth * sizeof (gint));
911   return retval;
912 }
913
914 G_DEFINE_BOXED_TYPE (GtkTreePath, gtk_tree_path,
915                      gtk_tree_path_copy,
916                      gtk_tree_path_free)
917
918 /**
919  * gtk_tree_path_compare:
920  * @a: a #GtkTreePath
921  * @b: a #GtkTreePath to compare with
922  *
923  * Compares two paths.
924  *
925  * If @a appears before @b in a tree, then -1 is returned.
926  * If @b appears before @a, then 1 is returned.
927  * If the two nodes are equal, then 0 is returned.
928  *
929  * Return value: the relative positions of @a and @b
930  */
931 gint
932 gtk_tree_path_compare (const GtkTreePath *a,
933                        const GtkTreePath *b)
934 {
935   gint p = 0, q = 0;
936
937   g_return_val_if_fail (a != NULL, 0);
938   g_return_val_if_fail (b != NULL, 0);
939   g_return_val_if_fail (a->depth > 0, 0);
940   g_return_val_if_fail (b->depth > 0, 0);
941
942   do
943     {
944       if (a->indices[p] == b->indices[q])
945         continue;
946       return (a->indices[p] < b->indices[q]?-1:1);
947     }
948   while (++p < a->depth && ++q < b->depth);
949   if (a->depth == b->depth)
950     return 0;
951   return (a->depth < b->depth?-1:1);
952 }
953
954 /**
955  * gtk_tree_path_is_ancestor:
956  * @path: a #GtkTreePath
957  * @descendant: another #GtkTreePath
958  *
959  * Returns %TRUE if @descendant is a descendant of @path.
960  *
961  * Return value: %TRUE if @descendant is contained inside @path
962  */
963 gboolean
964 gtk_tree_path_is_ancestor (GtkTreePath *path,
965                            GtkTreePath *descendant)
966 {
967   gint i;
968
969   g_return_val_if_fail (path != NULL, FALSE);
970   g_return_val_if_fail (descendant != NULL, FALSE);
971
972   /* can't be an ancestor if we're deeper */
973   if (path->depth >= descendant->depth)
974     return FALSE;
975
976   i = 0;
977   while (i < path->depth)
978     {
979       if (path->indices[i] != descendant->indices[i])
980         return FALSE;
981       ++i;
982     }
983
984   return TRUE;
985 }
986
987 /**
988  * gtk_tree_path_is_descendant:
989  * @path: a #GtkTreePath
990  * @ancestor: another #GtkTreePath
991  *
992  * Returns %TRUE if @path is a descendant of @ancestor.
993  *
994  * Return value: %TRUE if @ancestor contains @path somewhere below it
995  */
996 gboolean
997 gtk_tree_path_is_descendant (GtkTreePath *path,
998                              GtkTreePath *ancestor)
999 {
1000   gint i;
1001
1002   g_return_val_if_fail (path != NULL, FALSE);
1003   g_return_val_if_fail (ancestor != NULL, FALSE);
1004
1005   /* can't be a descendant if we're shallower in the tree */
1006   if (path->depth <= ancestor->depth)
1007     return FALSE;
1008
1009   i = 0;
1010   while (i < ancestor->depth)
1011     {
1012       if (path->indices[i] != ancestor->indices[i])
1013         return FALSE;
1014       ++i;
1015     }
1016
1017   return TRUE;
1018 }
1019
1020
1021 /**
1022  * gtk_tree_path_next:
1023  * @path: a #GtkTreePath
1024  *
1025  * Moves the @path to point to the next node at the current depth.
1026  */
1027 void
1028 gtk_tree_path_next (GtkTreePath *path)
1029 {
1030   g_return_if_fail (path != NULL);
1031   g_return_if_fail (path->depth > 0);
1032
1033   path->indices[path->depth - 1] ++;
1034 }
1035
1036 /**
1037  * gtk_tree_path_prev:
1038  * @path: a #GtkTreePath
1039  *
1040  * Moves the @path to point to the previous node at the
1041  * current depth, if it exists.
1042  *
1043  * Return value: %TRUE if @path has a previous node, and
1044  *     the move was made
1045  */
1046 gboolean
1047 gtk_tree_path_prev (GtkTreePath *path)
1048 {
1049   g_return_val_if_fail (path != NULL, FALSE);
1050
1051   if (path->depth == 0)
1052     return FALSE;
1053
1054   if (path->indices[path->depth - 1] == 0)
1055     return FALSE;
1056
1057   path->indices[path->depth - 1] -= 1;
1058
1059   return TRUE;
1060 }
1061
1062 /**
1063  * gtk_tree_path_up:
1064  * @path: a #GtkTreePath
1065  *
1066  * Moves the @path to point to its parent node, if it has a parent.
1067  *
1068  * Return value: %TRUE if @path has a parent, and the move was made
1069  */
1070 gboolean
1071 gtk_tree_path_up (GtkTreePath *path)
1072 {
1073   g_return_val_if_fail (path != NULL, FALSE);
1074
1075   if (path->depth == 0)
1076     return FALSE;
1077
1078   path->depth--;
1079
1080   return TRUE;
1081 }
1082
1083 /**
1084  * gtk_tree_path_down:
1085  * @path: a #GtkTreePath
1086  *
1087  * Moves @path to point to the first child of the current path.
1088  */
1089 void
1090 gtk_tree_path_down (GtkTreePath *path)
1091 {
1092   g_return_if_fail (path != NULL);
1093
1094   gtk_tree_path_append_index (path, 0);
1095 }
1096
1097 /**
1098  * gtk_tree_iter_copy:
1099  * @iter: a #GtkTreeIter
1100  *
1101  * Creates a dynamically allocated tree iterator as a copy of @iter.
1102  *
1103  * This function is not intended for use in applications,
1104  * because you can just copy the structs by value
1105  * (<literal>GtkTreeIter new_iter = iter;</literal>).
1106  * You must free this iter with gtk_tree_iter_free().
1107  *
1108  * Return value: a newly-allocated copy of @iter
1109  */
1110 GtkTreeIter *
1111 gtk_tree_iter_copy (GtkTreeIter *iter)
1112 {
1113   GtkTreeIter *retval;
1114
1115   g_return_val_if_fail (iter != NULL, NULL);
1116
1117   retval = g_slice_new (GtkTreeIter);
1118   *retval = *iter;
1119
1120   return retval;
1121 }
1122
1123 /**
1124  * gtk_tree_iter_free:
1125  * @iter: a dynamically allocated tree iterator
1126  *
1127  * Frees an iterator that has been allocated by gtk_tree_iter_copy().
1128  *
1129  * This function is mainly used for language bindings.
1130  */
1131 void
1132 gtk_tree_iter_free (GtkTreeIter *iter)
1133 {
1134   g_return_if_fail (iter != NULL);
1135
1136   g_slice_free (GtkTreeIter, iter);
1137 }
1138
1139 G_DEFINE_BOXED_TYPE (GtkTreeIter,  gtk_tree_iter,
1140                      gtk_tree_iter_copy,
1141                      gtk_tree_iter_free)
1142
1143 /**
1144  * gtk_tree_model_get_flags:
1145  * @tree_model: a #GtkTreeModel
1146  *
1147  * Returns a set of flags supported by this interface.
1148  *
1149  * The flags are a bitwise combination of #GtkTreeModelFlags.
1150  * The flags supported should not change during the lifetime
1151  * of the @tree_model.
1152  *
1153  * Return value: the flags supported by this interface
1154  */
1155 GtkTreeModelFlags
1156 gtk_tree_model_get_flags (GtkTreeModel *tree_model)
1157 {
1158   GtkTreeModelIface *iface;
1159
1160   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1161
1162   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1163   if (iface->get_flags)
1164     return (* iface->get_flags) (tree_model);
1165
1166   return 0;
1167 }
1168
1169 /**
1170  * gtk_tree_model_get_n_columns:
1171  * @tree_model: a #GtkTreeModel
1172  *
1173  * Returns the number of columns supported by @tree_model.
1174  *
1175  * Return value: the number of columns
1176  */
1177 gint
1178 gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
1179 {
1180   GtkTreeModelIface *iface;
1181   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1182
1183   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1184   g_return_val_if_fail (iface->get_n_columns != NULL, 0);
1185
1186   return (* iface->get_n_columns) (tree_model);
1187 }
1188
1189 /**
1190  * gtk_tree_model_get_column_type:
1191  * @tree_model: a #GtkTreeModel
1192  * @index_: the column index
1193  *
1194  * Returns the type of the column.
1195  *
1196  * Return value: (transfer none): the type of the column
1197  */
1198 GType
1199 gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
1200                                 gint          index)
1201 {
1202   GtkTreeModelIface *iface;
1203
1204   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
1205
1206   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1207   g_return_val_if_fail (iface->get_column_type != NULL, G_TYPE_INVALID);
1208   g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
1209
1210   return (* iface->get_column_type) (tree_model, index);
1211 }
1212
1213 /**
1214  * gtk_tree_model_get_iter:
1215  * @tree_model: a #GtkTreeModel
1216  * @iter: (out): the uninitialized #GtkTreeIter
1217  * @path: the #GtkTreePath
1218  *
1219  * Sets @iter to a valid iterator pointing to @path.  If @path does
1220  * not exist, * @iter is set to an invalid iterator and %FALSE is returned.
1221  *
1222  * Return value: %TRUE, if @iter was set
1223  */
1224 gboolean
1225 gtk_tree_model_get_iter (GtkTreeModel *tree_model,
1226                          GtkTreeIter  *iter,
1227                          GtkTreePath  *path)
1228 {
1229   GtkTreeModelIface *iface;
1230
1231   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1232   g_return_val_if_fail (iter != NULL, FALSE);
1233   g_return_val_if_fail (path != NULL, FALSE);
1234
1235   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1236   g_return_val_if_fail (iface->get_iter != NULL, FALSE);
1237   g_return_val_if_fail (path->depth > 0, FALSE);
1238
1239   INITIALIZE_TREE_ITER (iter);
1240
1241   return (* iface->get_iter) (tree_model, iter, path);
1242 }
1243
1244 /**
1245  * gtk_tree_model_get_iter_from_string:
1246  * @tree_model: a #GtkTreeModel
1247  * @iter: (out): an uninitialized #GtkTreeIter
1248  * @path_string: a string representation of a #GtkTreePath
1249  *
1250  * Sets @iter to a valid iterator pointing to @path_string, if it
1251  * exists. Otherwise, @iter is left invalid and %FALSE is returned.
1252  *
1253  * Return value: %TRUE, if @iter was set
1254  */
1255 gboolean
1256 gtk_tree_model_get_iter_from_string (GtkTreeModel *tree_model,
1257                                      GtkTreeIter  *iter,
1258                                      const gchar  *path_string)
1259 {
1260   gboolean retval;
1261   GtkTreePath *path;
1262
1263   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1264   g_return_val_if_fail (iter != NULL, FALSE);
1265   g_return_val_if_fail (path_string != NULL, FALSE);
1266
1267   path = gtk_tree_path_new_from_string (path_string);
1268
1269   g_return_val_if_fail (path != NULL, FALSE);
1270
1271   retval = gtk_tree_model_get_iter (tree_model, iter, path);
1272   gtk_tree_path_free (path);
1273
1274   return retval;
1275 }
1276
1277 /**
1278  * gtk_tree_model_get_string_from_iter:
1279  * @tree_model: a #GtkTreeModel
1280  * @iter: a #GtkTreeIter
1281  *
1282  * Generates a string representation of the iter.
1283  *
1284  * This string is a ':' separated list of numbers.
1285  * For example, "4:10:0:3" would be an acceptable
1286  * return value for this string.
1287  *
1288  * Return value: a newly-allocated string.
1289  *     Must be freed with g_free().
1290  *
1291  * Since: 2.2
1292  */
1293 gchar *
1294 gtk_tree_model_get_string_from_iter (GtkTreeModel *tree_model,
1295                                      GtkTreeIter  *iter)
1296 {
1297   GtkTreePath *path;
1298   gchar *ret;
1299
1300   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1301   g_return_val_if_fail (iter != NULL, NULL);
1302
1303   path = gtk_tree_model_get_path (tree_model, iter);
1304
1305   g_return_val_if_fail (path != NULL, NULL);
1306
1307   ret = gtk_tree_path_to_string (path);
1308   gtk_tree_path_free (path);
1309
1310   return ret;
1311 }
1312
1313 /**
1314  * gtk_tree_model_get_iter_first:
1315  * @tree_model: a #GtkTreeModel
1316  * @iter: (out): the uninitialized #GtkTreeIter
1317  *
1318  * Initializes @iter with the first iterator in the tree
1319  * (the one at the path "0") and returns %TRUE. Returns
1320  * %FALSE if the tree is empty.
1321  *
1322  * Return value: %TRUE, if @iter was set
1323  */
1324 gboolean
1325 gtk_tree_model_get_iter_first (GtkTreeModel *tree_model,
1326                                GtkTreeIter  *iter)
1327 {
1328   GtkTreePath *path;
1329   gboolean retval;
1330
1331   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1332   g_return_val_if_fail (iter != NULL, FALSE);
1333
1334   path = gtk_tree_path_new_first ();
1335   retval = gtk_tree_model_get_iter (tree_model, iter, path);
1336   gtk_tree_path_free (path);
1337
1338   return retval;
1339 }
1340
1341 /**
1342  * gtk_tree_model_get_path:
1343  * @tree_model: a #GtkTreeModel
1344  * @iter: the #GtkTreeIter
1345  *
1346  * Returns a newly-created #GtkTreePath referenced by @iter.
1347  *
1348  * This path should be freed with gtk_tree_path_free().
1349  *
1350  * Return value: a newly-created #GtkTreePath
1351  */
1352 GtkTreePath *
1353 gtk_tree_model_get_path (GtkTreeModel *tree_model,
1354                          GtkTreeIter  *iter)
1355 {
1356   GtkTreeModelIface *iface;
1357
1358   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1359   g_return_val_if_fail (iter != NULL, NULL);
1360
1361   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1362   g_return_val_if_fail (iface->get_path != NULL, NULL);
1363
1364   return (* iface->get_path) (tree_model, iter);
1365 }
1366
1367 /**
1368  * gtk_tree_model_get_value:
1369  * @tree_model: a #GtkTreeModel
1370  * @iter: the #GtkTreeIter
1371  * @column: the column to lookup the value at
1372  * @value: (out) (transfer none): an empty #GValue to set
1373  *
1374  * Initializes and sets @value to that at @column.
1375  *
1376  * When done with @value, g_value_unset() needs to be called
1377  * to free any allocated memory.
1378  */
1379 void
1380 gtk_tree_model_get_value (GtkTreeModel *tree_model,
1381                           GtkTreeIter  *iter,
1382                           gint          column,
1383                           GValue       *value)
1384 {
1385   GtkTreeModelIface *iface;
1386
1387   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1388   g_return_if_fail (iter != NULL);
1389   g_return_if_fail (value != NULL);
1390
1391   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1392   g_return_if_fail (iface->get_value != NULL);
1393
1394   (* iface->get_value) (tree_model, iter, column, value);
1395 }
1396
1397 /**
1398  * gtk_tree_model_iter_next:
1399  * @tree_model: a #GtkTreeModel
1400  * @iter: (in): the #GtkTreeIter
1401  *
1402  * Sets @iter to point to the node following it at the current level.
1403  *
1404  * If there is no next @iter, %FALSE is returned and @iter is set
1405  * to be invalid.
1406  *
1407  * Return value: %TRUE if @iter has been changed to the next node
1408  */
1409 gboolean
1410 gtk_tree_model_iter_next (GtkTreeModel  *tree_model,
1411                           GtkTreeIter   *iter)
1412 {
1413   GtkTreeModelIface *iface;
1414
1415   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1416   g_return_val_if_fail (iter != NULL, FALSE);
1417
1418   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1419   g_return_val_if_fail (iface->iter_next != NULL, FALSE);
1420
1421   return (* iface->iter_next) (tree_model, iter);
1422 }
1423
1424 static gboolean
1425 gtk_tree_model_iter_previous_default (GtkTreeModel *tree_model,
1426                                       GtkTreeIter  *iter)
1427 {
1428   gboolean retval;
1429   GtkTreePath *path;
1430
1431   path = gtk_tree_model_get_path (tree_model, iter);
1432   if (path == NULL)
1433     return FALSE;
1434
1435   retval = gtk_tree_path_prev (path) &&
1436            gtk_tree_model_get_iter (tree_model, iter, path);
1437   if (retval == FALSE)
1438     iter->stamp = 0;
1439
1440   gtk_tree_path_free (path);
1441
1442   return retval;
1443 }
1444
1445 /**
1446  * gtk_tree_model_iter_previous:
1447  * @tree_model: a #GtkTreeModel
1448  * @iter: (in): the #GtkTreeIter
1449  *
1450  * Sets @iter to point to the previous node at the current level.
1451  *
1452  * If there is no previous @iter, %FALSE is returned and @iter is
1453  * set to be invalid.
1454  *
1455  * Return value: %TRUE if @iter has been changed to the previous node
1456  *
1457  * Since: 3.0
1458  */
1459 gboolean
1460 gtk_tree_model_iter_previous (GtkTreeModel *tree_model,
1461                               GtkTreeIter  *iter)
1462 {
1463   gboolean retval;
1464   GtkTreeModelIface *iface;
1465
1466   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1467   g_return_val_if_fail (iter != NULL, FALSE);
1468
1469   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1470
1471   if (iface->iter_previous)
1472     retval = (* iface->iter_previous) (tree_model, iter);
1473   else
1474     retval = gtk_tree_model_iter_previous_default (tree_model, iter);
1475
1476   return retval;
1477 }
1478
1479 /**
1480  * gtk_tree_model_iter_children:
1481  * @tree_model: a #GtkTreeModel
1482  * @iter: (out): the new #GtkTreeIter to be set to the child
1483  * @parent: (allow-none): the #GtkTreeIter, or %NULL
1484  *
1485  * Sets @iter to point to the first child of @parent.
1486  *
1487  * If @parent has no children, %FALSE is returned and @iter is
1488  * set to be invalid. @parent will remain a valid node after this
1489  * function has been called.
1490  *
1491  * If @parent is %NULL returns the first node, equivalent to
1492  * <literal>gtk_tree_model_get_iter_first (tree_model, iter);</literal>
1493  *
1494  * Return value: %TRUE, if @child has been set to the first child
1495  */
1496 gboolean
1497 gtk_tree_model_iter_children (GtkTreeModel *tree_model,
1498                               GtkTreeIter  *iter,
1499                               GtkTreeIter  *parent)
1500 {
1501   GtkTreeModelIface *iface;
1502
1503   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1504   g_return_val_if_fail (iter != NULL, FALSE);
1505
1506   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1507   g_return_val_if_fail (iface->iter_children != NULL, FALSE);
1508
1509   INITIALIZE_TREE_ITER (iter);
1510
1511   return (* iface->iter_children) (tree_model, iter, parent);
1512 }
1513
1514 /**
1515  * gtk_tree_model_iter_has_child:
1516  * @tree_model: a #GtkTreeModel
1517  * @iter: the #GtkTreeIter to test for children
1518  *
1519  * Returns %TRUE if @iter has children, %FALSE otherwise.
1520  *
1521  * Return value: %TRUE if @iter has children
1522  */
1523 gboolean
1524 gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
1525                                GtkTreeIter  *iter)
1526 {
1527   GtkTreeModelIface *iface;
1528
1529   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1530   g_return_val_if_fail (iter != NULL, FALSE);
1531
1532   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1533   g_return_val_if_fail (iface->iter_has_child != NULL, FALSE);
1534
1535   return (* iface->iter_has_child) (tree_model, iter);
1536 }
1537
1538 /**
1539  * gtk_tree_model_iter_n_children:
1540  * @tree_model: a #GtkTreeModel
1541  * @iter: (allow-none): the #GtkTreeIter, or %NULL
1542  *
1543  * Returns the number of children that @iter has.
1544  *
1545  * As a special case, if @iter is %NULL, then the number
1546  * of toplevel nodes is returned.
1547  *
1548  * Return value: the number of children of @iter
1549  */
1550 gint
1551 gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
1552                                 GtkTreeIter  *iter)
1553 {
1554   GtkTreeModelIface *iface;
1555
1556   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1557
1558   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1559   g_return_val_if_fail (iface->iter_n_children != NULL, 0);
1560
1561   return (* iface->iter_n_children) (tree_model, iter);
1562 }
1563
1564 /**
1565  * gtk_tree_model_iter_nth_child:
1566  * @tree_model: a #GtkTreeModel
1567  * @iter: (out): the #GtkTreeIter to set to the nth child
1568  * @parent: (allow-none): the #GtkTreeIter to get the child from, or %NULL.
1569  * @n: the index of the desired child
1570  *
1571  * Sets @iter to be the child of @parent, using the given index.
1572  *
1573  * The first index is 0. If @n is too big, or @parent has no children,
1574  * @iter is set to an invalid iterator and %FALSE is returned. @parent
1575  * will remain a valid node after this function has been called. As a
1576  * special case, if @parent is %NULL, then the @n<!-- -->th root node
1577  * is set.
1578  *
1579  * Return value: %TRUE, if @parent has an @n<!-- -->th child
1580  */
1581 gboolean
1582 gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
1583                                GtkTreeIter  *iter,
1584                                GtkTreeIter  *parent,
1585                                gint          n)
1586 {
1587   GtkTreeModelIface *iface;
1588
1589   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1590   g_return_val_if_fail (iter != NULL, FALSE);
1591   g_return_val_if_fail (n >= 0, FALSE);
1592
1593   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1594   g_return_val_if_fail (iface->iter_nth_child != NULL, FALSE);
1595
1596   INITIALIZE_TREE_ITER (iter);
1597
1598   return (* iface->iter_nth_child) (tree_model, iter, parent, n);
1599 }
1600
1601 /**
1602  * gtk_tree_model_iter_parent:
1603  * @tree_model: a #GtkTreeModel
1604  * @iter: (out): the new #GtkTreeIter to set to the parent
1605  * @child: the #GtkTreeIter
1606  *
1607  * Sets @iter to be the parent of @child.
1608  *
1609  * If @child is at the toplevel, and doesn't have a parent, then
1610  * @iter is set to an invalid iterator and %FALSE is returned.
1611  * @child will remain a valid node after this function has been
1612  * called.
1613  *
1614  * Return value: %TRUE, if @iter is set to the parent of @child
1615  */
1616 gboolean
1617 gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
1618                             GtkTreeIter  *iter,
1619                             GtkTreeIter  *child)
1620 {
1621   GtkTreeModelIface *iface;
1622
1623   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1624   g_return_val_if_fail (iter != NULL, FALSE);
1625   g_return_val_if_fail (child != NULL, FALSE);
1626
1627   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1628   g_return_val_if_fail (iface->iter_parent != NULL, FALSE);
1629
1630   INITIALIZE_TREE_ITER (iter);
1631
1632   return (* iface->iter_parent) (tree_model, iter, child);
1633 }
1634
1635 /**
1636  * gtk_tree_model_ref_node:
1637  * @tree_model: a #GtkTreeModel
1638  * @iter: the #GtkTreeIter
1639  *
1640  * Lets the tree ref the node.
1641  *
1642  * This is an optional method for models to implement.
1643  * To be more specific, models may ignore this call as it exists
1644  * primarily for performance reasons.
1645  *
1646  * This function is primarily meant as a way for views to let
1647  * caching models know when nodes are being displayed (and hence,
1648  * whether or not to cache that node). Being displayed means a node
1649  * is in an expanded branch, regardless of whether the node is currently
1650  * visible in the viewport. For example, a file-system based model
1651  * would not want to keep the entire file-hierarchy in memory,
1652  * just the sections that are currently being displayed by
1653  * every current view.
1654  *
1655  * A model should be expected to be able to get an iter independent
1656  * of its reffed state.
1657  */
1658 void
1659 gtk_tree_model_ref_node (GtkTreeModel *tree_model,
1660                          GtkTreeIter  *iter)
1661 {
1662   GtkTreeModelIface *iface;
1663
1664   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1665
1666   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1667   if (iface->ref_node)
1668     (* iface->ref_node) (tree_model, iter);
1669 }
1670
1671 /**
1672  * gtk_tree_model_unref_node:
1673  * @tree_model: a #GtkTreeModel
1674  * @iter: the #GtkTreeIter
1675  *
1676  * Lets the tree unref the node.
1677  *
1678  * This is an optional method for models to implement.
1679  * To be more specific, models may ignore this call as it exists
1680  * primarily for performance reasons. For more information on what
1681  * this means, see gtk_tree_model_ref_node().
1682  *
1683  * Please note that nodes that are deleted are not unreffed.
1684  */
1685 void
1686 gtk_tree_model_unref_node (GtkTreeModel *tree_model,
1687                            GtkTreeIter  *iter)
1688 {
1689   GtkTreeModelIface *iface;
1690
1691   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1692   g_return_if_fail (iter != NULL);
1693
1694   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1695   if (iface->unref_node)
1696     (* iface->unref_node) (tree_model, iter);
1697 }
1698
1699 /**
1700  * gtk_tree_model_get:
1701  * @tree_model: a #GtkTreeModel
1702  * @iter: a row in @tree_model
1703  * @Varargs: pairs of column number and value return locations,
1704  *     terminated by -1
1705  *
1706  * Gets the value of one or more cells in the row referenced by @iter.
1707  * The variable argument list should contain integer column numbers,
1708  * each column number followed by a place to store the value being
1709  * retrieved.  The list is terminated by a -1. For example, to get a
1710  * value from column 0 with type %G_TYPE_STRING, you would
1711  * write: <literal>gtk_tree_model_get (model, iter, 0, &amp;place_string_here, -1)</literal>,
1712  * where <literal>place_string_here</literal> is a <type>gchar*</type>
1713  * to be filled with the string.
1714  *
1715  * Returned values with type %G_TYPE_OBJECT have to be unreferenced,
1716  * values with type %G_TYPE_STRING or %G_TYPE_BOXED have to be freed.
1717  * Other values are passed by value.
1718  */
1719 void
1720 gtk_tree_model_get (GtkTreeModel *tree_model,
1721                     GtkTreeIter  *iter,
1722                     ...)
1723 {
1724   va_list var_args;
1725
1726   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1727   g_return_if_fail (iter != NULL);
1728
1729   va_start (var_args, iter);
1730   gtk_tree_model_get_valist (tree_model, iter, var_args);
1731   va_end (var_args);
1732 }
1733
1734 /**
1735  * gtk_tree_model_get_valist:
1736  * @tree_model: a #GtkTreeModel
1737  * @iter: a row in @tree_model
1738  * @var_args: <type>va_list</type> of column/return location pairs
1739  *
1740  * See gtk_tree_model_get(), this version takes a <type>va_list</type>
1741  * for language bindings to use.
1742  */
1743 void
1744 gtk_tree_model_get_valist (GtkTreeModel *tree_model,
1745                            GtkTreeIter  *iter,
1746                            va_list      var_args)
1747 {
1748   gint column;
1749
1750   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1751   g_return_if_fail (iter != NULL);
1752
1753   column = va_arg (var_args, gint);
1754
1755   while (column != -1)
1756     {
1757       GValue value = { 0, };
1758       gchar *error = NULL;
1759
1760       if (column >= gtk_tree_model_get_n_columns (tree_model))
1761         {
1762           g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC, column);
1763           break;
1764         }
1765
1766       gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, column, &value);
1767
1768       G_VALUE_LCOPY (&value, var_args, 0, &error);
1769       if (error)
1770         {
1771           g_warning ("%s: %s", G_STRLOC, error);
1772           g_free (error);
1773
1774           /* we purposely leak the value here, it might not be
1775            * in a sane state if an error condition occurred
1776            */
1777           break;
1778         }
1779
1780       g_value_unset (&value);
1781
1782       column = va_arg (var_args, gint);
1783     }
1784 }
1785
1786 /**
1787  * gtk_tree_model_row_changed:
1788  * @tree_model: a #GtkTreeModel
1789  * @path: a #GtkTreePath pointing to the changed row
1790  * @iter: a valid #GtkTreeIter pointing to the changed row
1791  *
1792  * Emits the #GtkTreeModel::row-changed signal on @tree_model.
1793  */
1794 void
1795 gtk_tree_model_row_changed (GtkTreeModel *tree_model,
1796                             GtkTreePath  *path,
1797                             GtkTreeIter  *iter)
1798 {
1799   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1800   g_return_if_fail (path != NULL);
1801   g_return_if_fail (iter != NULL);
1802
1803   g_signal_emit (tree_model, tree_model_signals[ROW_CHANGED], 0, path, iter);
1804 }
1805
1806 /**
1807  * gtk_tree_model_row_inserted:
1808  * @tree_model: a #GtkTreeModel
1809  * @path: a #GtkTreePath pointing to the inserted row
1810  * @iter: a valid #GtkTreeIter pointing to the inserted row
1811  *
1812  * Emits the #GtkTreeModel::row-inserted signal on @tree_model.
1813  */
1814 void
1815 gtk_tree_model_row_inserted (GtkTreeModel *tree_model,
1816                              GtkTreePath  *path,
1817                              GtkTreeIter  *iter)
1818 {
1819   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1820   g_return_if_fail (path != NULL);
1821   g_return_if_fail (iter != NULL);
1822
1823   g_signal_emit (tree_model, tree_model_signals[ROW_INSERTED], 0, path, iter);
1824 }
1825
1826 /**
1827  * gtk_tree_model_row_has_child_toggled:
1828  * @tree_model: a #GtkTreeModel
1829  * @path: a #GtkTreePath pointing to the changed row
1830  * @iter: a valid #GtkTreeIter pointing to the changed row
1831  *
1832  * Emits the #GtkTreeModel::row-has-child-toggled signal on
1833  * @tree_model. This should be called by models after the child
1834  * state of a node changes.
1835  */
1836 void
1837 gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model,
1838                                       GtkTreePath  *path,
1839                                       GtkTreeIter  *iter)
1840 {
1841   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1842   g_return_if_fail (path != NULL);
1843   g_return_if_fail (iter != NULL);
1844
1845   g_signal_emit (tree_model, tree_model_signals[ROW_HAS_CHILD_TOGGLED], 0, path, iter);
1846 }
1847
1848 /**
1849  * gtk_tree_model_row_deleted:
1850  * @tree_model: a #GtkTreeModel
1851  * @path: a #GtkTreePath pointing to the previous location of
1852  *     the deleted row
1853  *
1854  * Emits the #GtkTreeModel::row-deleted signal on @tree_model.
1855  *
1856  * This should be called by models after a row has been removed.
1857  * The location pointed to by @path should be the location that
1858  * the row previously was at. It may not be a valid location anymore.
1859  *
1860  * Nodes that are deleted are not unreffed, this means that any
1861  * outstanding references on the deleted node should not be released.
1862  */
1863 void
1864 gtk_tree_model_row_deleted (GtkTreeModel *tree_model,
1865                             GtkTreePath  *path)
1866 {
1867   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1868   g_return_if_fail (path != NULL);
1869
1870   g_signal_emit (tree_model, tree_model_signals[ROW_DELETED], 0, path);
1871 }
1872
1873 /**
1874  * gtk_tree_model_rows_reordered: (skip)
1875  * @tree_model: a #GtkTreeModel
1876  * @path: a #GtkTreePath pointing to the tree node whose children
1877  *     have been reordered
1878  * @iter: a valid #GtkTreeIter pointing to the node whose children
1879  *     have been reordered, or %NULL if the depth of @path is 0
1880  * @new_order: an array of integers mapping the current position of
1881  *     each child to its old position before the re-ordering,
1882  *     i.e. @new_order<literal>[newpos] = oldpos</literal>
1883  *
1884  * Emits the #GtkTreeModel::rows-reordered signal on @tree_model.
1885  *
1886  * This should be called by models when their rows have been
1887  * reordered.
1888  */
1889 void
1890 gtk_tree_model_rows_reordered (GtkTreeModel *tree_model,
1891                                GtkTreePath  *path,
1892                                GtkTreeIter  *iter,
1893                                gint         *new_order)
1894 {
1895   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1896   g_return_if_fail (new_order != NULL);
1897
1898   g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
1899 }
1900
1901
1902 static gboolean
1903 gtk_tree_model_foreach_helper (GtkTreeModel            *model,
1904                                GtkTreeIter             *iter,
1905                                GtkTreePath             *path,
1906                                GtkTreeModelForeachFunc  func,
1907                                gpointer                 user_data)
1908 {
1909   do
1910     {
1911       GtkTreeIter child;
1912
1913       if ((* func) (model, path, iter, user_data))
1914         return TRUE;
1915
1916       if (gtk_tree_model_iter_children (model, &child, iter))
1917         {
1918           gtk_tree_path_down (path);
1919           if (gtk_tree_model_foreach_helper (model, &child, path, func, user_data))
1920             return TRUE;
1921           gtk_tree_path_up (path);
1922         }
1923
1924       gtk_tree_path_next (path);
1925     }
1926   while (gtk_tree_model_iter_next (model, iter));
1927
1928   return FALSE;
1929 }
1930
1931 /**
1932  * gtk_tree_model_foreach:
1933  * @model: a #GtkTreeModel
1934  * @func: (scope call): a function to be called on each row
1935  * @user_data: user data to passed to @func
1936  *
1937  * Calls func on each node in model in a depth-first fashion.
1938  *
1939  * If @func returns %TRUE, then the tree ceases to be walked,
1940  * and gtk_tree_model_foreach() returns.
1941  */
1942 void
1943 gtk_tree_model_foreach (GtkTreeModel            *model,
1944                         GtkTreeModelForeachFunc  func,
1945                         gpointer                 user_data)
1946 {
1947   GtkTreePath *path;
1948   GtkTreeIter iter;
1949
1950   g_return_if_fail (GTK_IS_TREE_MODEL (model));
1951   g_return_if_fail (func != NULL);
1952
1953   path = gtk_tree_path_new_first ();
1954   if (gtk_tree_model_get_iter (model, &iter, path) == FALSE)
1955     {
1956       gtk_tree_path_free (path);
1957       return;
1958     }
1959
1960   gtk_tree_model_foreach_helper (model, &iter, path, func, user_data);
1961   gtk_tree_path_free (path);
1962 }
1963
1964
1965 /*
1966  * GtkTreeRowReference
1967  */
1968
1969 static void gtk_tree_row_reference_unref_path (GtkTreePath  *path,
1970                                                GtkTreeModel *model,
1971                                                gint          depth);
1972
1973
1974 G_DEFINE_BOXED_TYPE (GtkTreeRowReference, gtk_tree_row_reference,
1975                      gtk_tree_row_reference_copy,
1976                      gtk_tree_row_reference_free)
1977
1978 struct _GtkTreeRowReference
1979 {
1980   GObject *proxy;
1981   GtkTreeModel *model;
1982   GtkTreePath *path;
1983 };
1984
1985
1986 static void
1987 release_row_references (gpointer data)
1988 {
1989   RowRefList *refs = data;
1990   GSList *tmp_list = NULL;
1991
1992   tmp_list = refs->list;
1993   while (tmp_list != NULL)
1994     {
1995       GtkTreeRowReference *reference = tmp_list->data;
1996
1997       if (reference->proxy == (GObject *)reference->model)
1998         reference->model = NULL;
1999       reference->proxy = NULL;
2000
2001       /* we don't free the reference, users are responsible for that. */
2002
2003       tmp_list = g_slist_next (tmp_list);
2004     }
2005
2006   g_slist_free (refs->list);
2007   g_free (refs);
2008 }
2009
2010 static void
2011 gtk_tree_row_ref_inserted (RowRefList  *refs,
2012                            GtkTreePath *path,
2013                            GtkTreeIter *iter)
2014 {
2015   GSList *tmp_list;
2016
2017   if (refs == NULL)
2018     return;
2019
2020   /* This function corrects the path stored in the reference to
2021    * account for an insertion. Note that it's called _after_ the
2022    * insertion with the path to the newly-inserted row. Which means
2023    * that the inserted path is in a different "coordinate system" than
2024    * the old path (e.g. if the inserted path was just before the old
2025    * path, then inserted path and old path will be the same, and old
2026    * path must be moved down one).
2027    */
2028
2029   tmp_list = refs->list;
2030
2031   while (tmp_list != NULL)
2032     {
2033       GtkTreeRowReference *reference = tmp_list->data;
2034
2035       if (reference->path == NULL)
2036         goto done;
2037
2038       if (reference->path->depth >= path->depth)
2039         {
2040           gint i;
2041           gboolean ancestor = TRUE;
2042
2043           for (i = 0; i < path->depth - 1; i ++)
2044             {
2045               if (path->indices[i] != reference->path->indices[i])
2046                 {
2047                   ancestor = FALSE;
2048                   break;
2049                 }
2050             }
2051           if (ancestor == FALSE)
2052             goto done;
2053
2054           if (path->indices[path->depth-1] <= reference->path->indices[path->depth-1])
2055             reference->path->indices[path->depth-1] += 1;
2056         }
2057     done:
2058       tmp_list = g_slist_next (tmp_list);
2059     }
2060 }
2061
2062 static void
2063 gtk_tree_row_ref_deleted (RowRefList  *refs,
2064                           GtkTreePath *path)
2065 {
2066   GSList *tmp_list;
2067
2068   if (refs == NULL)
2069     return;
2070
2071   /* This function corrects the path stored in the reference to
2072    * account for an deletion. Note that it's called _after_ the
2073    * deletion with the old path of the just-deleted row. Which means
2074    * that the deleted path is the same now-defunct "coordinate system"
2075    * as the path saved in the reference, which is what we want to fix.
2076    */
2077
2078   tmp_list = refs->list;
2079
2080   while (tmp_list != NULL)
2081     {
2082       GtkTreeRowReference *reference = tmp_list->data;
2083
2084       if (reference->path)
2085         {
2086           gint i;
2087
2088           if (path->depth > reference->path->depth)
2089             goto next;
2090           for (i = 0; i < path->depth - 1; i++)
2091             {
2092               if (path->indices[i] != reference->path->indices[i])
2093                 goto next;
2094             }
2095
2096           /* We know it affects us. */
2097           if (path->indices[i] == reference->path->indices[i])
2098             {
2099               if (reference->path->depth > path->depth)
2100                 /* some parent was deleted, trying to unref any node
2101                  * between the deleted parent and the node the reference
2102                  * is pointing to is bad, as those nodes are already gone.
2103                  */
2104                 gtk_tree_row_reference_unref_path (reference->path, reference->model, path->depth - 1);
2105               else
2106                 gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth - 1);
2107               gtk_tree_path_free (reference->path);
2108               reference->path = NULL;
2109             }
2110           else if (path->indices[i] < reference->path->indices[i])
2111             {
2112               reference->path->indices[path->depth-1]-=1;
2113             }
2114         }
2115
2116 next:
2117       tmp_list = g_slist_next (tmp_list);
2118     }
2119 }
2120
2121 static void
2122 gtk_tree_row_ref_reordered (RowRefList  *refs,
2123                             GtkTreePath *path,
2124                             GtkTreeIter *iter,
2125                             gint        *new_order)
2126 {
2127   GSList *tmp_list;
2128   gint length;
2129
2130   if (refs == NULL)
2131     return;
2132
2133   tmp_list = refs->list;
2134
2135   while (tmp_list != NULL)
2136     {
2137       GtkTreeRowReference *reference = tmp_list->data;
2138
2139       length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (reference->model), iter);
2140
2141       if (length < 2)
2142         return;
2143
2144       if ((reference->path) &&
2145           (gtk_tree_path_is_ancestor (path, reference->path)))
2146         {
2147           gint ref_depth = gtk_tree_path_get_depth (reference->path);
2148           gint depth = gtk_tree_path_get_depth (path);
2149
2150           if (ref_depth > depth)
2151             {
2152               gint i;
2153               gint *indices = gtk_tree_path_get_indices (reference->path);
2154
2155               for (i = 0; i < length; i++)
2156                 {
2157                   if (new_order[i] == indices[depth])
2158                     {
2159                       indices[depth] = i;
2160                       break;
2161                     }
2162                 }
2163             }
2164         }
2165
2166       tmp_list = g_slist_next (tmp_list);
2167     }
2168 }
2169
2170 /* We do this recursively so that we can unref children nodes
2171  * before their parent
2172  */
2173 static void
2174 gtk_tree_row_reference_unref_path_helper (GtkTreePath  *path,
2175                                           GtkTreeModel *model,
2176                                           GtkTreeIter  *parent_iter,
2177                                           gint          depth,
2178                                           gint          current_depth)
2179 {
2180   GtkTreeIter iter;
2181
2182   if (depth == current_depth)
2183     return;
2184
2185   gtk_tree_model_iter_nth_child (model, &iter, parent_iter, path->indices[current_depth]);
2186   gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, current_depth + 1);
2187   gtk_tree_model_unref_node (model, &iter);
2188 }
2189
2190 static void
2191 gtk_tree_row_reference_unref_path (GtkTreePath  *path,
2192                                    GtkTreeModel *model,
2193                                    gint          depth)
2194 {
2195   GtkTreeIter iter;
2196
2197   if (depth <= 0)
2198     return;
2199
2200   gtk_tree_model_iter_nth_child (model, &iter, NULL, path->indices[0]);
2201   gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, 1);
2202   gtk_tree_model_unref_node (model, &iter);
2203 }
2204
2205 /**
2206  * gtk_tree_row_reference_new:
2207  * @model: a #GtkTreeModel
2208  * @path: a valid #GtkTreePath to monitor
2209  *
2210  * Creates a row reference based on @path.
2211  *
2212  * This reference will keep pointing to the node pointed to
2213  * by @path, so long as it exists. It listens to all signals
2214  * emitted by @model, and updates its path appropriately. If
2215  * @path isn't a valid path in @model, then %NULL is returned.
2216  *
2217  * Return value: a newly allocated #GtkTreeRowReference, or %NULL
2218  */
2219 GtkTreeRowReference *
2220 gtk_tree_row_reference_new (GtkTreeModel *model,
2221                             GtkTreePath  *path)
2222 {
2223   g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2224   g_return_val_if_fail (path != NULL, NULL);
2225
2226   /* We use the model itself as the proxy object; and call
2227    * gtk_tree_row_reference_inserted(), etc, in the
2228    * class closure (default handler) marshalers for the signal.
2229    */
2230   return gtk_tree_row_reference_new_proxy (G_OBJECT (model), model, path);
2231 }
2232
2233 /**
2234  * gtk_tree_row_reference_new_proxy:
2235  * @proxy: a proxy #GObject
2236  * @model: a #GtkTreeModel
2237  * @path: a valid #GtkTreePath to monitor
2238  *
2239  * You do not need to use this function.
2240  *
2241  * Creates a row reference based on @path.
2242  *
2243  * This reference will keep pointing to the node pointed to
2244  * by @path, so long as it exists. If @path isn't a valid
2245  * path in @model, then %NULL is returned. However, unlike
2246  * references created with gtk_tree_row_reference_new(), it
2247  * does not listen to the model for changes. The creator of
2248  * the row reference must do this explicitly using
2249  * gtk_tree_row_reference_inserted(), gtk_tree_row_reference_deleted(),
2250  * gtk_tree_row_reference_reordered().
2251  *
2252  * These functions must be called exactly once per proxy when the
2253  * corresponding signal on the model is emitted. This single call
2254  * updates all row references for that proxy. Since built-in GTK+
2255  * objects like #GtkTreeView already use this mechanism internally,
2256  * using them as the proxy object will produce unpredictable results.
2257  * Further more, passing the same object as @model and @proxy
2258  * doesn't work for reasons of internal implementation.
2259  *
2260  * This type of row reference is primarily meant by structures that
2261  * need to carefully monitor exactly when a row reference updates
2262  * itself, and is not generally needed by most applications.
2263  *
2264  * Return value: a newly allocated #GtkTreeRowReference, or %NULL
2265  */
2266 GtkTreeRowReference *
2267 gtk_tree_row_reference_new_proxy (GObject      *proxy,
2268                                   GtkTreeModel *model,
2269                                   GtkTreePath  *path)
2270 {
2271   GtkTreeRowReference *reference;
2272   RowRefList *refs;
2273   GtkTreeIter parent_iter;
2274   gint i;
2275
2276   g_return_val_if_fail (G_IS_OBJECT (proxy), NULL);
2277   g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
2278   g_return_val_if_fail (path != NULL, NULL);
2279   g_return_val_if_fail (path->depth > 0, NULL);
2280
2281   /* check that the path is valid */
2282   if (gtk_tree_model_get_iter (model, &parent_iter, path) == FALSE)
2283     return NULL;
2284
2285   /* Now we want to ref every node */
2286   gtk_tree_model_iter_nth_child (model, &parent_iter, NULL, path->indices[0]);
2287   gtk_tree_model_ref_node (model, &parent_iter);
2288
2289   for (i = 1; i < path->depth; i++)
2290     {
2291       GtkTreeIter iter;
2292       gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, path->indices[i]);
2293       gtk_tree_model_ref_node (model, &iter);
2294       parent_iter = iter;
2295     }
2296
2297   /* Make the row reference */
2298   reference = g_new (GtkTreeRowReference, 1);
2299
2300   g_object_ref (proxy);
2301   g_object_ref (model);
2302   reference->proxy = proxy;
2303   reference->model = model;
2304   reference->path = gtk_tree_path_copy (path);
2305
2306   refs = g_object_get_data (G_OBJECT (proxy), ROW_REF_DATA_STRING);
2307
2308   if (refs == NULL)
2309     {
2310       refs = g_new (RowRefList, 1);
2311       refs->list = NULL;
2312
2313       g_object_set_data_full (G_OBJECT (proxy),
2314                               I_(ROW_REF_DATA_STRING),
2315                               refs, release_row_references);
2316     }
2317
2318   refs->list = g_slist_prepend (refs->list, reference);
2319
2320   return reference;
2321 }
2322
2323 /**
2324  * gtk_tree_row_reference_get_path:
2325  * @reference: a #GtkTreeRowReference
2326  *
2327  * Returns a path that the row reference currently points to,
2328  * or %NULL if the path pointed to is no longer valid.
2329  *
2330  * Return value: a current path, or %NULL
2331  */
2332 GtkTreePath *
2333 gtk_tree_row_reference_get_path (GtkTreeRowReference *reference)
2334 {
2335   g_return_val_if_fail (reference != NULL, NULL);
2336
2337   if (reference->proxy == NULL)
2338     return NULL;
2339
2340   if (reference->path == NULL)
2341     return NULL;
2342
2343   return gtk_tree_path_copy (reference->path);
2344 }
2345
2346 /**
2347  * gtk_tree_row_reference_get_model:
2348  * @reference: a #GtkTreeRowReference
2349  *
2350  * Returns the model that the row reference is monitoring.
2351  *
2352  * Return value: (transfer none): the model
2353  *
2354  * Since: 2.8
2355  */
2356 GtkTreeModel *
2357 gtk_tree_row_reference_get_model (GtkTreeRowReference *reference)
2358 {
2359   g_return_val_if_fail (reference != NULL, NULL);
2360
2361   return reference->model;
2362 }
2363
2364 /**
2365  * gtk_tree_row_reference_valid:
2366  * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2367  *
2368  * Returns %TRUE if the @reference is non-%NULL and refers to
2369  * a current valid path.
2370  *
2371  * Return value: %TRUE if @reference points to a valid path
2372  */
2373 gboolean
2374 gtk_tree_row_reference_valid (GtkTreeRowReference *reference)
2375 {
2376   if (reference == NULL || reference->path == NULL)
2377     return FALSE;
2378
2379   return TRUE;
2380 }
2381
2382
2383 /**
2384  * gtk_tree_row_reference_copy:
2385  * @reference: a #GtkTreeRowReference
2386  *
2387  * Copies a #GtkTreeRowReference.
2388  *
2389  * Return value: a copy of @reference
2390  *
2391  * Since: 2.2
2392  */
2393 GtkTreeRowReference *
2394 gtk_tree_row_reference_copy (GtkTreeRowReference *reference)
2395 {
2396   return gtk_tree_row_reference_new_proxy (reference->proxy,
2397                                            reference->model,
2398                                            reference->path);
2399 }
2400
2401 /**
2402  * gtk_tree_row_reference_free:
2403  * @reference: (allow-none): a #GtkTreeRowReference, or %NULL
2404  *
2405  * Free's @reference. @reference may be %NULL
2406  */
2407 void
2408 gtk_tree_row_reference_free (GtkTreeRowReference *reference)
2409 {
2410   RowRefList *refs;
2411
2412   if (reference == NULL)
2413     return;
2414
2415   refs = g_object_get_data (G_OBJECT (reference->proxy), ROW_REF_DATA_STRING);
2416
2417   if (refs == NULL)
2418     {
2419       g_warning (G_STRLOC": bad row reference, proxy has no outstanding row references");
2420       return;
2421     }
2422
2423   refs->list = g_slist_remove (refs->list, reference);
2424
2425   if (refs->list == NULL)
2426     {
2427       g_object_set_data (G_OBJECT (reference->proxy),
2428                          I_(ROW_REF_DATA_STRING),
2429                          NULL);
2430     }
2431
2432   if (reference->path)
2433     {
2434       gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth);
2435       gtk_tree_path_free (reference->path);
2436     }
2437
2438   g_object_unref (reference->proxy);
2439   g_object_unref (reference->model);
2440   g_free (reference);
2441 }
2442
2443 /**
2444  * gtk_tree_row_reference_inserted:
2445  * @proxy: a #GObject
2446  * @path: the row position that was inserted
2447  *
2448  * Lets a set of row reference created by
2449  * gtk_tree_row_reference_new_proxy() know that the
2450  * model emitted the #GtkTreeModel::row-inserted signal.
2451  */
2452 void
2453 gtk_tree_row_reference_inserted (GObject     *proxy,
2454                                  GtkTreePath *path)
2455 {
2456   g_return_if_fail (G_IS_OBJECT (proxy));
2457
2458   gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, NULL);
2459 }
2460
2461 /**
2462  * gtk_tree_row_reference_deleted:
2463  * @proxy: a #GObject
2464  * @path: the path position that was deleted
2465  *
2466  * Lets a set of row reference created by
2467  * gtk_tree_row_reference_new_proxy() know that the
2468  * model emitted the #GtkTreeModel::row-deleted signal.
2469  */
2470 void
2471 gtk_tree_row_reference_deleted (GObject     *proxy,
2472                                 GtkTreePath *path)
2473 {
2474   g_return_if_fail (G_IS_OBJECT (proxy));
2475
2476   gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path);
2477 }
2478
2479 /**
2480  * gtk_tree_row_reference_reordered: (skip)
2481  * @proxy: a #GObject
2482  * @path: the parent path of the reordered signal
2483  * @iter: the iter pointing to the parent of the reordered
2484  * @new_order: the new order of rows
2485  *
2486  * Lets a set of row reference created by
2487  * gtk_tree_row_reference_new_proxy() know that the
2488  * model emitted the #GtkTreeModel::rows-reordered signal.
2489  */
2490 void
2491 gtk_tree_row_reference_reordered (GObject     *proxy,
2492                                   GtkTreePath *path,
2493                                   GtkTreeIter *iter,
2494                                   gint        *new_order)
2495 {
2496   g_return_if_fail (G_IS_OBJECT (proxy));
2497
2498   gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, iter, new_order);
2499 }