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