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