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