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