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