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