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