]> Pileus Git - ~andy/gtk/blob - gtk/gtktreemodel.c
Fix a typo in the docs
[~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.  
854  * This function is not intended for use in applications, because you 
855  * can just copy the structs by value 
856  * (<literal>GtkTreeIter new_iter = iter;</literal>).
857  * You must free this iter with gtk_tree_iter_free().
858  *
859  * Return value: a newly-allocated copy of @iter.
860  **/
861 GtkTreeIter *
862 gtk_tree_iter_copy (GtkTreeIter *iter)
863 {
864   GtkTreeIter *retval;
865
866   g_return_val_if_fail (iter != NULL, NULL);
867
868   retval = g_slice_new (GtkTreeIter);
869   *retval = *iter;
870
871   return retval;
872 }
873
874 /**
875  * gtk_tree_iter_free:
876  * @iter: A dynamically allocated tree iterator.
877  *
878  * Frees an iterator that has been allocated by gtk_tree_iter_copy().
879  * This function is mainly used for language bindings.
880  **/
881 void
882 gtk_tree_iter_free (GtkTreeIter *iter)
883 {
884   g_return_if_fail (iter != NULL);
885
886   g_slice_free (GtkTreeIter, iter);
887 }
888
889 GType
890 gtk_tree_iter_get_type (void)
891 {
892   static GType our_type = 0;
893   
894   if (our_type == 0)
895     our_type = g_boxed_type_register_static (I_("GtkTreeIter"),
896                                              (GBoxedCopyFunc) gtk_tree_iter_copy,
897                                              (GBoxedFreeFunc) gtk_tree_iter_free);
898
899   return our_type;
900 }
901
902 /**
903  * gtk_tree_model_get_flags:
904  * @tree_model: A #GtkTreeModel.
905  *
906  * Returns a set of flags supported by this interface.  The flags are a bitwise
907  * combination of #GtkTreeModelFlags.  The flags supported should not change
908  * during the lifecycle of the @tree_model.
909  *
910  * Return value: The flags supported by this interface.
911  **/
912 GtkTreeModelFlags
913 gtk_tree_model_get_flags (GtkTreeModel *tree_model)
914 {
915   GtkTreeModelIface *iface;
916
917   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
918
919   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
920   if (iface->get_flags)
921     return (* iface->get_flags) (tree_model);
922
923   return 0;
924 }
925
926 /**
927  * gtk_tree_model_get_n_columns:
928  * @tree_model: A #GtkTreeModel.
929  *
930  * Returns the number of columns supported by @tree_model.
931  *
932  * Return value: The number of columns.
933  **/
934 gint
935 gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
936 {
937   GtkTreeModelIface *iface;
938   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
939
940   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
941   g_return_val_if_fail (iface->get_n_columns != NULL, 0);
942
943   return (* iface->get_n_columns) (tree_model);
944 }
945
946 /**
947  * gtk_tree_model_get_column_type:
948  * @tree_model: A #GtkTreeModel.
949  * @index_: The column index.
950  *
951  * Returns the type of the column.
952  *
953  * Return value: The type of the column.
954  **/
955 GType
956 gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
957                                 gint          index)
958 {
959   GtkTreeModelIface *iface;
960
961   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
962
963   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
964   g_return_val_if_fail (iface->get_column_type != NULL, G_TYPE_INVALID);
965   g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
966
967   return (* iface->get_column_type) (tree_model, index);
968 }
969
970 /**
971  * gtk_tree_model_get_iter:
972  * @tree_model: A #GtkTreeModel.
973  * @iter: The uninitialized #GtkTreeIter.
974  * @path: The #GtkTreePath.
975  *
976  * Sets @iter to a valid iterator pointing to @path.
977  *
978  * Return value: %TRUE, if @iter was set.
979  **/
980 gboolean
981 gtk_tree_model_get_iter (GtkTreeModel *tree_model,
982                          GtkTreeIter  *iter,
983                          GtkTreePath  *path)
984 {
985   GtkTreeModelIface *iface;
986
987   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
988   g_return_val_if_fail (iter != NULL, FALSE);
989   g_return_val_if_fail (path != NULL, FALSE);
990
991   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
992   g_return_val_if_fail (iface->get_iter != NULL, FALSE);
993   g_return_val_if_fail (path->depth > 0, FALSE);
994
995   INITIALIZE_TREE_ITER (iter);
996
997   return (* iface->get_iter) (tree_model, iter, path);
998 }
999
1000 /**
1001  * gtk_tree_model_get_iter_from_string:
1002  * @tree_model: A #GtkTreeModel.
1003  * @iter: An uninitialized #GtkTreeIter.
1004  * @path_string: A string representation of a #GtkTreePath.
1005  *
1006  * Sets @iter to a valid iterator pointing to @path_string, if it
1007  * exists. Otherwise, @iter is left invalid and %FALSE is returned.
1008  *
1009  * Return value: %TRUE, if @iter was set.
1010  **/
1011 gboolean
1012 gtk_tree_model_get_iter_from_string (GtkTreeModel *tree_model,
1013                                      GtkTreeIter  *iter,
1014                                      const gchar  *path_string)
1015 {
1016   gboolean retval;
1017   GtkTreePath *path;
1018
1019   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1020   g_return_val_if_fail (iter != NULL, FALSE);
1021   g_return_val_if_fail (path_string != NULL, FALSE);
1022   
1023   path = gtk_tree_path_new_from_string (path_string);
1024   
1025   g_return_val_if_fail (path != NULL, FALSE);
1026
1027   retval = gtk_tree_model_get_iter (tree_model, iter, path);
1028   gtk_tree_path_free (path);
1029   
1030   return retval;
1031 }
1032
1033 /**
1034  * gtk_tree_model_get_string_from_iter:
1035  * @tree_model: A #GtkTreeModel.
1036  * @iter: An #GtkTreeIter.
1037  *
1038  * Generates a string representation of the iter. This string is a ':'
1039  * separated list of numbers. For example, "4:10:0:3" would be an
1040  * acceptable return value for this string.
1041  *
1042  * Return value: A newly-allocated string. Must be freed with g_free().
1043  *
1044  * Since: 2.2
1045  **/
1046 gchar *
1047 gtk_tree_model_get_string_from_iter (GtkTreeModel *tree_model,
1048                                      GtkTreeIter  *iter)
1049 {
1050   GtkTreePath *path;
1051   gchar *ret;
1052
1053   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1054   g_return_val_if_fail (iter != NULL, NULL);
1055
1056   path = gtk_tree_model_get_path (tree_model, iter);
1057
1058   g_return_val_if_fail (path != NULL, NULL);
1059
1060   ret = gtk_tree_path_to_string (path);
1061   gtk_tree_path_free (path);
1062
1063   return ret;
1064 }
1065
1066 /**
1067  * gtk_tree_model_get_iter_first:
1068  * @tree_model: A #GtkTreeModel.
1069  * @iter: The uninitialized #GtkTreeIter.
1070  * 
1071  * Initializes @iter with the first iterator in the tree (the one at the path
1072  * "0") and returns %TRUE.  Returns %FALSE if the tree is empty.
1073  * 
1074  * Return value: %TRUE, if @iter was set.
1075  **/
1076 gboolean
1077 gtk_tree_model_get_iter_first (GtkTreeModel *tree_model,
1078                                GtkTreeIter  *iter)
1079 {
1080   GtkTreePath *path;
1081   gboolean retval;
1082
1083   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1084   g_return_val_if_fail (iter != NULL, FALSE);
1085
1086   path = gtk_tree_path_new_first ();
1087   retval = gtk_tree_model_get_iter (tree_model, iter, path);
1088   gtk_tree_path_free (path);
1089
1090   return retval;
1091 }
1092
1093 /**
1094  * gtk_tree_model_get_path:
1095  * @tree_model: A #GtkTreeModel.
1096  * @iter: The #GtkTreeIter.
1097  *
1098  * Returns a newly-created #GtkTreePath referenced by @iter.  This path should
1099  * be freed with gtk_tree_path_free().
1100  *
1101  * Return value: a newly-created #GtkTreePath.
1102  **/
1103 GtkTreePath *
1104 gtk_tree_model_get_path (GtkTreeModel *tree_model,
1105                          GtkTreeIter  *iter)
1106 {
1107   GtkTreeModelIface *iface;
1108
1109   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
1110   g_return_val_if_fail (iter != NULL, NULL);
1111
1112   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1113   g_return_val_if_fail (iface->get_path != NULL, NULL);
1114
1115   return (* iface->get_path) (tree_model, iter);
1116 }
1117
1118 /**
1119  * gtk_tree_model_get_value:
1120  * @tree_model: A #GtkTreeModel.
1121  * @iter: The #GtkTreeIter.
1122  * @column: The column to lookup the value at.
1123  * @value: An empty #GValue to set.
1124  *
1125  * Initializes and sets @value to that at @column.
1126  * When done with @value, g_value_unset() needs to be called 
1127  * to free any allocated memory.
1128  */
1129 void
1130 gtk_tree_model_get_value (GtkTreeModel *tree_model,
1131                           GtkTreeIter  *iter,
1132                           gint          column,
1133                           GValue       *value)
1134 {
1135   GtkTreeModelIface *iface;
1136
1137   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1138   g_return_if_fail (iter != NULL);
1139   g_return_if_fail (value != NULL);
1140
1141   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1142   g_return_if_fail (iface->get_value != NULL);
1143
1144   (* iface->get_value) (tree_model, iter, column, value);
1145 }
1146
1147 /**
1148  * gtk_tree_model_iter_next:
1149  * @tree_model: A #GtkTreeModel.
1150  * @iter: The #GtkTreeIter.
1151  *
1152  * Sets @iter to point to the node following it at the current level.  If there
1153  * is no next @iter, %FALSE is returned and @iter is set to be invalid.
1154  *
1155  * Return value: %TRUE if @iter has been changed to the next node.
1156  **/
1157 gboolean
1158 gtk_tree_model_iter_next (GtkTreeModel  *tree_model,
1159                           GtkTreeIter   *iter)
1160 {
1161   GtkTreeModelIface *iface;
1162
1163   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1164   g_return_val_if_fail (iter != NULL, FALSE);
1165
1166   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1167   g_return_val_if_fail (iface->iter_next != NULL, FALSE);
1168
1169   return (* iface->iter_next) (tree_model, iter);
1170 }
1171
1172 /**
1173  * gtk_tree_model_iter_children:
1174  * @tree_model: A #GtkTreeModel.
1175  * @iter: The new #GtkTreeIter to be set to the child.
1176  * @parent: The #GtkTreeIter, or %NULL
1177  *
1178  * Sets @iter to point to the first child of @parent.  If @parent has no 
1179  * children, %FALSE is returned and @iter is set to be invalid.  @parent 
1180  * will remain a valid node after this function has been called.
1181  *
1182  * If @parent is %NULL returns the first node, equivalent to
1183  * <literal>gtk_tree_model_get_iter_first (tree_model, iter);</literal>
1184  *
1185  * Return value: %TRUE, if @child has been set to the first child.
1186  **/
1187 gboolean
1188 gtk_tree_model_iter_children (GtkTreeModel *tree_model,
1189                               GtkTreeIter  *iter,
1190                               GtkTreeIter  *parent)
1191 {
1192   GtkTreeModelIface *iface;
1193
1194   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1195   g_return_val_if_fail (iter != NULL, FALSE);
1196
1197   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1198   g_return_val_if_fail (iface->iter_children != NULL, FALSE);
1199
1200   INITIALIZE_TREE_ITER (iter);
1201
1202   return (* iface->iter_children) (tree_model, iter, parent);
1203 }
1204
1205 /**
1206  * gtk_tree_model_iter_has_child:
1207  * @tree_model: A #GtkTreeModel.
1208  * @iter: The #GtkTreeIter to test for children.
1209  *
1210  * Returns %TRUE if @iter has children, %FALSE otherwise.
1211  *
1212  * Return value: %TRUE if @iter has children.
1213  **/
1214 gboolean
1215 gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
1216                                GtkTreeIter  *iter)
1217 {
1218   GtkTreeModelIface *iface;
1219
1220   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1221   g_return_val_if_fail (iter != NULL, FALSE);
1222
1223   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1224   g_return_val_if_fail (iface->iter_has_child != NULL, FALSE);
1225
1226   return (* iface->iter_has_child) (tree_model, iter);
1227 }
1228
1229 /**
1230  * gtk_tree_model_iter_n_children:
1231  * @tree_model: A #GtkTreeModel.
1232  * @iter: The #GtkTreeIter, or %NULL.
1233  *
1234  * Returns the number of children that @iter has.  As a special case, if @iter
1235  * is %NULL, then the number of toplevel nodes is returned.
1236  *
1237  * Return value: The number of children of @iter.
1238  **/
1239 gint
1240 gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
1241                                 GtkTreeIter  *iter)
1242 {
1243   GtkTreeModelIface *iface;
1244
1245   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1246
1247   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1248   g_return_val_if_fail (iface->iter_n_children != NULL, 0);
1249
1250   return (* iface->iter_n_children) (tree_model, iter);
1251 }
1252
1253 /**
1254  * gtk_tree_model_iter_nth_child:
1255  * @tree_model: A #GtkTreeModel.
1256  * @iter: The #GtkTreeIter to set to the nth child.
1257  * @parent: The #GtkTreeIter to get the child from, or %NULL.
1258  * @n: Then index of the desired child.
1259  *
1260  * Sets @iter to be the child of @parent, using the given index.  The first
1261  * index is 0.  If @n is too big, or @parent has no children, @iter is set
1262  * to an invalid iterator and %FALSE is returned.  @parent will remain a valid
1263  * node after this function has been called.  As a special case, if @parent is
1264  * %NULL, then the @n<!-- -->th root node is set.
1265  *
1266  * Return value: %TRUE, if @parent has an @n<!-- -->th child.
1267  **/
1268 gboolean
1269 gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
1270                                GtkTreeIter  *iter,
1271                                GtkTreeIter  *parent,
1272                                gint          n)
1273 {
1274   GtkTreeModelIface *iface;
1275
1276   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1277   g_return_val_if_fail (iter != NULL, FALSE);
1278   g_return_val_if_fail (n >= 0, FALSE);
1279
1280   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1281   g_return_val_if_fail (iface->iter_nth_child != NULL, FALSE);
1282
1283   INITIALIZE_TREE_ITER (iter);
1284
1285   return (* iface->iter_nth_child) (tree_model, iter, parent, n);
1286 }
1287
1288 /**
1289  * gtk_tree_model_iter_parent:
1290  * @tree_model: A #GtkTreeModel
1291  * @iter: The new #GtkTreeIter to set to the parent.
1292  * @child: The #GtkTreeIter.
1293  *
1294  * Sets @iter to be the parent of @child.  If @child is at the toplevel, and
1295  * doesn't have a parent, then @iter is set to an invalid iterator and %FALSE
1296  * is returned.  @child will remain a valid node after this function has been
1297  * called.
1298  *
1299  * Return value: %TRUE, if @iter is set to the parent of @child.
1300  **/
1301 gboolean
1302 gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
1303                             GtkTreeIter  *iter,
1304                             GtkTreeIter  *child)
1305 {
1306   GtkTreeModelIface *iface;
1307
1308   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1309   g_return_val_if_fail (iter != NULL, FALSE);
1310   g_return_val_if_fail (child != NULL, FALSE);
1311   
1312   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1313   g_return_val_if_fail (iface->iter_parent != NULL, FALSE);
1314
1315   INITIALIZE_TREE_ITER (iter);
1316
1317   return (* iface->iter_parent) (tree_model, iter, child);
1318 }
1319
1320 /**
1321  * gtk_tree_model_ref_node:
1322  * @tree_model: A #GtkTreeModel.
1323  * @iter: The #GtkTreeIter.
1324  *
1325  * Lets the tree ref the node.  This is an optional method for models to
1326  * implement.  To be more specific, models may ignore this call as it exists
1327  * primarily for performance reasons.
1328  * 
1329  * This function is primarily meant as a way for views to let caching model 
1330  * know when nodes are being displayed (and hence, whether or not to cache that
1331  * node.)  For example, a file-system based model would not want to keep the
1332  * entire file-hierarchy in memory, just the sections that are currently being
1333  * displayed by every current view.
1334  *
1335  * A model should be expected to be able to get an iter independent of its
1336  * reffed state.
1337  **/
1338 void
1339 gtk_tree_model_ref_node (GtkTreeModel *tree_model,
1340                          GtkTreeIter  *iter)
1341 {
1342   GtkTreeModelIface *iface;
1343
1344   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1345
1346   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1347   if (iface->ref_node)
1348     (* iface->ref_node) (tree_model, iter);
1349 }
1350
1351 /**
1352  * gtk_tree_model_unref_node:
1353  * @tree_model: A #GtkTreeModel.
1354  * @iter: The #GtkTreeIter.
1355  *
1356  * Lets the tree unref the node.  This is an optional method for models to
1357  * implement.  To be more specific, models may ignore this call as it exists
1358  * primarily for performance reasons.
1359  *
1360  * For more information on what this means, see gtk_tree_model_ref_node().
1361  * Please note that nodes that are deleted are not unreffed.
1362  **/
1363 void
1364 gtk_tree_model_unref_node (GtkTreeModel *tree_model,
1365                            GtkTreeIter  *iter)
1366 {
1367   GtkTreeModelIface *iface;
1368
1369   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1370   g_return_if_fail (iter != NULL);
1371
1372   iface = GTK_TREE_MODEL_GET_IFACE (tree_model);
1373   if (iface->unref_node)
1374     (* iface->unref_node) (tree_model, iter);
1375 }
1376
1377 /**
1378  * gtk_tree_model_get:
1379  * @tree_model: a #GtkTreeModel
1380  * @iter: a row in @tree_model
1381  * @Varargs: pairs of column number and value return locations, terminated by -1
1382  *
1383  * Gets the value of one or more cells in the row referenced by @iter.
1384  * The variable argument list should contain integer column numbers,
1385  * each column number followed by a place to store the value being
1386  * retrieved.  The list is terminated by a -1. For example, to get a
1387  * value from column 0 with type %G_TYPE_STRING, you would
1388  * write: <literal>gtk_tree_model_get (model, iter, 0, &amp;place_string_here, -1)</literal>,
1389  * where <literal>place_string_here</literal> is a <type>gchar*</type> to be 
1390  * filled with the string.
1391  * If appropriate, the returned values have to be freed or unreferenced.
1392  *
1393  **/
1394 void
1395 gtk_tree_model_get (GtkTreeModel *tree_model,
1396                     GtkTreeIter  *iter,
1397                     ...)
1398 {
1399   va_list var_args;
1400
1401   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1402   g_return_if_fail (iter != NULL);
1403
1404   va_start (var_args, iter);
1405   gtk_tree_model_get_valist (tree_model, iter, var_args);
1406   va_end (var_args);
1407 }
1408
1409 /**
1410  * gtk_tree_model_get_valist:
1411  * @tree_model: a #GtkTreeModel
1412  * @iter: a row in @tree_model
1413  * @var_args: <type>va_list</type> of column/return location pairs
1414  *
1415  * See gtk_tree_model_get(), this version takes a <type>va_list</type> 
1416  * for language bindings to use.
1417  **/
1418 void
1419 gtk_tree_model_get_valist (GtkTreeModel *tree_model,
1420                            GtkTreeIter  *iter,
1421                            va_list      var_args)
1422 {
1423   gint column;
1424
1425   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1426   g_return_if_fail (iter != NULL);
1427
1428   column = va_arg (var_args, gint);
1429
1430   while (column != -1)
1431     {
1432       GValue value = { 0, };
1433       gchar *error = NULL;
1434
1435       if (column >= gtk_tree_model_get_n_columns (tree_model))
1436         {
1437           g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC, column);
1438           break;
1439         }
1440
1441       gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, column, &value);
1442
1443       G_VALUE_LCOPY (&value, var_args, 0, &error);
1444       if (error)
1445         {
1446           g_warning ("%s: %s", G_STRLOC, error);
1447           g_free (error);
1448
1449           /* we purposely leak the value here, it might not be
1450            * in a sane state if an error condition occoured
1451            */
1452           break;
1453         }
1454
1455       g_value_unset (&value);
1456
1457       column = va_arg (var_args, gint);
1458     }
1459 }
1460
1461 /**
1462  * gtk_tree_model_row_changed:
1463  * @tree_model: A #GtkTreeModel
1464  * @path: A #GtkTreePath pointing to the changed row
1465  * @iter: A valid #GtkTreeIter pointing to the changed row
1466  * 
1467  * Emits the "row-changed" signal on @tree_model.
1468  **/
1469 void
1470 gtk_tree_model_row_changed (GtkTreeModel *tree_model,
1471                             GtkTreePath  *path,
1472                             GtkTreeIter  *iter)
1473 {
1474   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1475   g_return_if_fail (path != NULL);
1476   g_return_if_fail (iter != NULL);
1477
1478   g_signal_emit (tree_model, tree_model_signals[ROW_CHANGED], 0, path, iter);
1479 }
1480
1481 /**
1482  * gtk_tree_model_row_inserted:
1483  * @tree_model: A #GtkTreeModel
1484  * @path: A #GtkTreePath pointing to the inserted row
1485  * @iter: A valid #GtkTreeIter pointing to the inserted row
1486  * 
1487  * Emits the "row-inserted" signal on @tree_model
1488  **/
1489 void
1490 gtk_tree_model_row_inserted (GtkTreeModel *tree_model,
1491                              GtkTreePath  *path,
1492                              GtkTreeIter  *iter)
1493 {
1494   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1495   g_return_if_fail (path != NULL);
1496   g_return_if_fail (iter != NULL);
1497
1498   g_signal_emit (tree_model, tree_model_signals[ROW_INSERTED], 0, path, iter);
1499 }
1500
1501 /**
1502  * gtk_tree_model_row_has_child_toggled:
1503  * @tree_model: A #GtkTreeModel
1504  * @path: A #GtkTreePath pointing to the changed row
1505  * @iter: A valid #GtkTreeIter pointing to the changed row
1506  * 
1507  * Emits the "row-has-child-toggled" signal on @tree_model.  This should be
1508  * called by models after the child state of a node changes.
1509  **/
1510 void
1511 gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model,
1512                                       GtkTreePath  *path,
1513                                       GtkTreeIter  *iter)
1514 {
1515   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1516   g_return_if_fail (path != NULL);
1517   g_return_if_fail (iter != NULL);
1518
1519   g_signal_emit (tree_model, tree_model_signals[ROW_HAS_CHILD_TOGGLED], 0, path, iter);
1520 }
1521
1522 /**
1523  * gtk_tree_model_row_deleted:
1524  * @tree_model: A #GtkTreeModel
1525  * @path: A #GtkTreePath pointing to the previous location of the deleted row.
1526  * 
1527  * Emits the "row-deleted" signal on @tree_model.  This should be called by
1528  * models after a row has been removed.  The location pointed to by @path 
1529  * should be the location that the row previously was at.  It may not be a 
1530  * valid location anymore.
1531  **/
1532 void
1533 gtk_tree_model_row_deleted (GtkTreeModel *tree_model,
1534                             GtkTreePath  *path)
1535 {
1536   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1537   g_return_if_fail (path != NULL);
1538
1539   g_signal_emit (tree_model, tree_model_signals[ROW_DELETED], 0, path);
1540 }
1541
1542 /**
1543  * gtk_tree_model_rows_reordered:
1544  * @tree_model: A #GtkTreeModel
1545  * @path: A #GtkTreePath pointing to the tree node whose children have been 
1546  *      reordered
1547  * @iter: A valid #GtkTreeIter pointing to the node whose children have been 
1548  *      reordered, or %NULL if the depth of @path is 0.
1549  * @new_order: an array of integers mapping the current position of each child
1550  *      to its old position before the re-ordering,
1551  *      i.e. @new_order<literal>[newpos] = oldpos</literal>.
1552  * 
1553  * Emits the "rows-reordered" signal on @tree_model.  This should be called by
1554  * models when their rows have been reordered.  
1555  **/
1556 void
1557 gtk_tree_model_rows_reordered (GtkTreeModel *tree_model,
1558                                GtkTreePath  *path,
1559                                GtkTreeIter  *iter,
1560                                gint         *new_order)
1561 {
1562   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1563   g_return_if_fail (new_order != NULL);
1564
1565   g_signal_emit (tree_model, tree_model_signals[ROWS_REORDERED], 0, path, iter, new_order);
1566 }
1567
1568
1569 static gboolean
1570 gtk_tree_model_foreach_helper (GtkTreeModel            *model,
1571                                GtkTreeIter             *iter,
1572                                GtkTreePath             *path,
1573                                GtkTreeModelForeachFunc  func,
1574                                gpointer                 user_data)
1575 {
1576   do
1577     {
1578       GtkTreeIter child;
1579
1580       if ((* func) (model, path, iter, user_data))
1581         return TRUE;
1582
1583       if (gtk_tree_model_iter_children (model, &child, iter))
1584         {
1585           gtk_tree_path_down (path);
1586           if (gtk_tree_model_foreach_helper (model, &child, path, func, user_data))
1587             return TRUE;
1588           gtk_tree_path_up (path);
1589         }
1590
1591       gtk_tree_path_next (path);
1592     }
1593   while (gtk_tree_model_iter_next (model, iter));
1594
1595   return FALSE;
1596 }
1597
1598 /**
1599  * gtk_tree_model_foreach:
1600  * @model: A #GtkTreeModel
1601  * @func: A function to be called on each row
1602  * @user_data: User data to passed to func.
1603  * 
1604  * Calls func on each node in model in a depth-first fashion.  
1605  * If @func returns %TRUE, then the tree ceases to be walked, and 
1606  * gtk_tree_model_foreach() returns.
1607  **/
1608 void
1609 gtk_tree_model_foreach (GtkTreeModel            *model,
1610                         GtkTreeModelForeachFunc  func,
1611                         gpointer                 user_data)
1612 {
1613   GtkTreePath *path;
1614   GtkTreeIter iter;
1615
1616   g_return_if_fail (GTK_IS_TREE_MODEL (model));
1617   g_return_if_fail (func != NULL);
1618
1619   path = gtk_tree_path_new_first ();
1620   if (gtk_tree_model_get_iter (model, &iter, path) == FALSE)
1621     {
1622       gtk_tree_path_free (path);
1623       return;
1624     }
1625
1626   gtk_tree_model_foreach_helper (model, &iter, path, func, user_data);
1627   gtk_tree_path_free (path);
1628 }
1629
1630
1631 /*
1632  * GtkTreeRowReference
1633  */
1634
1635 static void gtk_tree_row_reference_unref_path (GtkTreePath  *path,
1636                                                GtkTreeModel *model,
1637                                                gint          depth);
1638
1639
1640 GType
1641 gtk_tree_row_reference_get_type (void)
1642 {
1643   static GType our_type = 0;
1644   
1645   if (our_type == 0)
1646     our_type = g_boxed_type_register_static (I_("GtkTreeRowReference"),
1647                                              (GBoxedCopyFunc) gtk_tree_row_reference_copy,
1648                                              (GBoxedFreeFunc) gtk_tree_row_reference_free);
1649
1650   return our_type;
1651 }
1652
1653
1654 struct _GtkTreeRowReference
1655 {
1656   GObject *proxy;
1657   GtkTreeModel *model;
1658   GtkTreePath *path;
1659 };
1660
1661
1662 static void
1663 release_row_references (gpointer data)
1664 {
1665   RowRefList *refs = data;
1666   GSList *tmp_list = NULL;
1667
1668   tmp_list = refs->list;
1669   while (tmp_list != NULL)
1670     {
1671       GtkTreeRowReference *reference = tmp_list->data;
1672
1673       if (reference->proxy == (GObject *)reference->model)
1674         reference->model = NULL;
1675       reference->proxy = NULL;
1676
1677       /* we don't free the reference, users are responsible for that. */
1678
1679       tmp_list = g_slist_next (tmp_list);
1680     }
1681
1682   g_slist_free (refs->list);
1683   g_free (refs);
1684 }
1685
1686 static void
1687 gtk_tree_row_ref_inserted (RowRefList  *refs,
1688                            GtkTreePath *path,
1689                            GtkTreeIter *iter)
1690 {
1691   GSList *tmp_list;
1692
1693   if (refs == NULL)
1694     return;
1695
1696   /* This function corrects the path stored in the reference to
1697    * account for an insertion. Note that it's called _after_ the insertion
1698    * with the path to the newly-inserted row. Which means that
1699    * the inserted path is in a different "coordinate system" than
1700    * the old path (e.g. if the inserted path was just before the old path,
1701    * then inserted path and old path will be the same, and old path must be
1702    * moved down one).
1703    */
1704
1705   tmp_list = refs->list;
1706
1707   while (tmp_list != NULL)
1708     {
1709       GtkTreeRowReference *reference = tmp_list->data;
1710
1711       if (reference->path == NULL)
1712         goto done;
1713
1714       if (reference->path->depth >= path->depth)
1715         {
1716           gint i;
1717           gboolean ancestor = TRUE;
1718
1719           for (i = 0; i < path->depth - 1; i ++)
1720             {
1721               if (path->indices[i] != reference->path->indices[i])
1722                 {
1723                   ancestor = FALSE;
1724                   break;
1725                 }
1726             }
1727           if (ancestor == FALSE)
1728             goto done;
1729
1730           if (path->indices[path->depth-1] <= reference->path->indices[path->depth-1])
1731             reference->path->indices[path->depth-1] += 1;
1732         }
1733     done:
1734       tmp_list = g_slist_next (tmp_list);
1735     }
1736 }
1737
1738 static void
1739 gtk_tree_row_ref_deleted (RowRefList  *refs,
1740                           GtkTreePath *path)
1741 {
1742   GSList *tmp_list;
1743
1744   if (refs == NULL)
1745     return;
1746
1747   /* This function corrects the path stored in the reference to
1748    * account for an deletion. Note that it's called _after_ the
1749    * deletion with the old path of the just-deleted row. Which means
1750    * that the deleted path is the same now-defunct "coordinate system"
1751    * as the path saved in the reference, which is what we want to fix.
1752    */
1753
1754   tmp_list = refs->list;
1755
1756   while (tmp_list != NULL)
1757     {
1758       GtkTreeRowReference *reference = tmp_list->data;
1759
1760       if (reference->path)
1761         {
1762           gint i;
1763
1764           if (path->depth > reference->path->depth)
1765             goto next;
1766           for (i = 0; i < path->depth - 1; i++)
1767             {
1768               if (path->indices[i] != reference->path->indices[i])
1769                 goto next;
1770             }
1771
1772           /* We know it affects us. */
1773           if (path->indices[i] == reference->path->indices[i])
1774             {
1775               if (reference->path->depth > path->depth)
1776                 /* some parent was deleted, trying to unref any node
1777                  * between the deleted parent and the node the reference
1778                  * is pointing to is bad, as those nodes are already gone.
1779                  */
1780                 gtk_tree_row_reference_unref_path (reference->path, reference->model, path->depth - 1);
1781               else
1782                 gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth - 1);
1783               gtk_tree_path_free (reference->path);
1784               reference->path = NULL;
1785             }
1786           else if (path->indices[i] < reference->path->indices[i])
1787             {
1788               reference->path->indices[path->depth-1]-=1;
1789             }
1790         }
1791
1792 next:
1793       tmp_list = g_slist_next (tmp_list);
1794     }
1795 }
1796
1797 static void
1798 gtk_tree_row_ref_reordered (RowRefList  *refs,
1799                             GtkTreePath *path,
1800                             GtkTreeIter *iter,
1801                             gint        *new_order)
1802 {
1803   GSList *tmp_list;
1804   gint length;
1805
1806   if (refs == NULL)
1807     return;
1808
1809   tmp_list = refs->list;
1810
1811   while (tmp_list != NULL)
1812     {
1813       GtkTreeRowReference *reference = tmp_list->data;
1814
1815       length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (reference->model), iter);
1816
1817       if (length < 2)
1818         return;
1819
1820       if ((reference->path) &&
1821           (gtk_tree_path_is_ancestor (path, reference->path)))
1822         {
1823           gint ref_depth = gtk_tree_path_get_depth (reference->path);
1824           gint depth = gtk_tree_path_get_depth (path);
1825
1826           if (ref_depth > depth)
1827             {
1828               gint i;
1829               gint *indices = gtk_tree_path_get_indices (reference->path);
1830
1831               for (i = 0; i < length; i++)
1832                 {
1833                   if (new_order[i] == indices[depth])
1834                     {
1835                       indices[depth] = i;
1836                       break;
1837                     }
1838                 }
1839             }
1840         }
1841
1842       tmp_list = g_slist_next (tmp_list);
1843     }
1844 }
1845
1846 /* We do this recursively so that we can unref children nodes before their parent */
1847 static void
1848 gtk_tree_row_reference_unref_path_helper (GtkTreePath  *path,
1849                                           GtkTreeModel *model,
1850                                           GtkTreeIter  *parent_iter,
1851                                           gint          depth,
1852                                           gint          current_depth)
1853 {
1854   GtkTreeIter iter;
1855
1856   if (depth == current_depth)
1857     return;
1858
1859   gtk_tree_model_iter_nth_child (model, &iter, parent_iter, path->indices[current_depth]);
1860   gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, current_depth + 1);
1861   gtk_tree_model_unref_node (model, &iter);
1862 }
1863
1864 static void
1865 gtk_tree_row_reference_unref_path (GtkTreePath  *path,
1866                                    GtkTreeModel *model,
1867                                    gint          depth)
1868 {
1869   GtkTreeIter iter;
1870
1871   if (depth <= 0)
1872     return;
1873   
1874   gtk_tree_model_iter_nth_child (model, &iter, NULL, path->indices[0]);
1875   gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth, 1);
1876   gtk_tree_model_unref_node (model, &iter);
1877 }
1878
1879 /**
1880  * gtk_tree_row_reference_new:
1881  * @model: A #GtkTreeModel
1882  * @path: A valid #GtkTreePath to monitor
1883  * 
1884  * Creates a row reference based on @path.  This reference will keep pointing 
1885  * to the node pointed to by @path, so long as it exists.  It listens to all
1886  * signals emitted by @model, and updates its path appropriately.  If @path
1887  * isn't a valid path in @model, then %NULL is returned.
1888  * 
1889  * Return value: A newly allocated #GtkTreeRowReference, or %NULL
1890  **/
1891 GtkTreeRowReference *
1892 gtk_tree_row_reference_new (GtkTreeModel *model,
1893                             GtkTreePath  *path)
1894 {
1895   g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1896   g_return_val_if_fail (path != NULL, NULL);
1897
1898   /* We use the model itself as the proxy object; and call
1899    * gtk_tree_row_reference_inserted(), etc, in the
1900    * class closure (default handler) marshalers for the signal.
1901    */  
1902   return gtk_tree_row_reference_new_proxy (G_OBJECT (model), model, path);
1903 }
1904
1905 /**
1906  * gtk_tree_row_reference_new_proxy:
1907  * @proxy: A proxy #GObject
1908  * @model: A #GtkTreeModel
1909  * @path: A valid #GtkTreePath to monitor
1910  * 
1911  * You do not need to use this function.  Creates a row reference based on
1912  * @path.  This reference will keep pointing to the node pointed to by @path, 
1913  * so long as it exists.  If @path isn't a valid path in @model, then %NULL is
1914  * returned.  However, unlike references created with
1915  * gtk_tree_row_reference_new(), it does not listen to the model for changes.
1916  * The creator of the row reference must do this explicitly using
1917  * gtk_tree_row_reference_inserted(), gtk_tree_row_reference_deleted(),
1918  * gtk_tree_row_reference_reordered().
1919  * 
1920  * These functions must be called exactly once per proxy when the
1921  * corresponding signal on the model is emitted. This single call
1922  * updates all row references for that proxy. Since built-in GTK+
1923  * objects like #GtkTreeView already use this mechanism internally,
1924  * using them as the proxy object will produce unpredictable results.
1925  * Further more, passing the same object as @model and @proxy
1926  * doesn't work for reasons of internal implementation.
1927  *
1928  * This type of row reference is primarily meant by structures that need to
1929  * carefully monitor exactly when a row reference updates itself, and is not
1930  * generally needed by most applications.
1931  *
1932  * Return value: A newly allocated #GtkTreeRowReference, or %NULL
1933  **/
1934 GtkTreeRowReference *
1935 gtk_tree_row_reference_new_proxy (GObject      *proxy,
1936                                   GtkTreeModel *model,
1937                                   GtkTreePath  *path)
1938 {
1939   GtkTreeRowReference *reference;
1940   RowRefList *refs;
1941   GtkTreeIter parent_iter;
1942   gint i;
1943
1944   g_return_val_if_fail (G_IS_OBJECT (proxy), NULL);
1945   g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1946   g_return_val_if_fail (path != NULL, NULL);
1947   g_return_val_if_fail (path->depth > 0, NULL);
1948
1949   /* check that the path is valid */
1950   if (gtk_tree_model_get_iter (model, &parent_iter, path) == FALSE)
1951     return NULL;
1952
1953   /* Now we want to ref every node */
1954   gtk_tree_model_iter_nth_child (model, &parent_iter, NULL, path->indices[0]);
1955   gtk_tree_model_ref_node (model, &parent_iter);
1956
1957   for (i = 1; i < path->depth; i++)
1958     {
1959       GtkTreeIter iter;
1960       gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, path->indices[i]);
1961       gtk_tree_model_ref_node (model, &iter);
1962       parent_iter = iter;
1963     }
1964
1965   /* Make the row reference */
1966   reference = g_new (GtkTreeRowReference, 1);
1967
1968   g_object_ref (proxy);
1969   g_object_ref (model);
1970   reference->proxy = proxy;
1971   reference->model = model;
1972   reference->path = gtk_tree_path_copy (path);
1973
1974   refs = g_object_get_data (G_OBJECT (proxy), ROW_REF_DATA_STRING);
1975
1976   if (refs == NULL)
1977     {
1978       refs = g_new (RowRefList, 1);
1979       refs->list = NULL;
1980
1981       g_object_set_data_full (G_OBJECT (proxy),
1982                               I_(ROW_REF_DATA_STRING),
1983                               refs, release_row_references);
1984     }
1985
1986   refs->list = g_slist_prepend (refs->list, reference);
1987
1988   return reference;
1989 }
1990
1991 /**
1992  * gtk_tree_row_reference_get_path:
1993  * @reference: A #GtkTreeRowReference
1994  * 
1995  * Returns a path that the row reference currently points to, or %NULL if the
1996  * path pointed to is no longer valid.
1997  * 
1998  * Return value: A current path, or %NULL.
1999  **/
2000 GtkTreePath *
2001 gtk_tree_row_reference_get_path (GtkTreeRowReference *reference)
2002 {
2003   g_return_val_if_fail (reference != NULL, NULL);
2004
2005   if (reference->proxy == NULL)
2006     return NULL;
2007
2008   if (reference->path == NULL)
2009     return NULL;
2010
2011   return gtk_tree_path_copy (reference->path);
2012 }
2013
2014 /**
2015  * gtk_tree_row_reference_get_model:
2016  * @reference: A #GtkTreeRowReference
2017  *
2018  * Returns the model that the row reference is monitoring.
2019  *
2020  * Return value: the model
2021  *
2022  * Since: 2.8
2023  */
2024 GtkTreeModel *
2025 gtk_tree_row_reference_get_model (GtkTreeRowReference *reference)
2026 {
2027   g_return_val_if_fail (reference != NULL, NULL);
2028
2029   return reference->model;
2030 }
2031
2032 /**
2033  * gtk_tree_row_reference_valid:
2034  * @reference: A #GtkTreeRowReference, or %NULL
2035  * 
2036  * Returns %TRUE if the @reference is non-%NULL and refers to a current valid
2037  * path.
2038  * 
2039  * Return value: %TRUE if @reference points to a valid path.
2040  **/
2041 gboolean
2042 gtk_tree_row_reference_valid (GtkTreeRowReference *reference)
2043 {
2044   if (reference == NULL || reference->path == NULL)
2045     return FALSE;
2046
2047   return TRUE;
2048 }
2049
2050
2051 /**
2052  * gtk_tree_row_reference_copy:
2053  * @reference: a #GtkTreeRowReference
2054  * 
2055  * Copies a #GtkTreeRowReference.
2056  * 
2057  * Return value: a copy of @reference.
2058  *
2059  * Since: 2.2
2060  **/
2061 GtkTreeRowReference *
2062 gtk_tree_row_reference_copy (GtkTreeRowReference *reference)
2063 {
2064   return gtk_tree_row_reference_new_proxy (reference->proxy,
2065                                            reference->model,
2066                                            reference->path);
2067 }
2068
2069 /**
2070  * gtk_tree_row_reference_free:
2071  * @reference: A #GtkTreeRowReference, or %NULL
2072  * 
2073  * Free's @reference. @reference may be %NULL.
2074  **/
2075 void
2076 gtk_tree_row_reference_free (GtkTreeRowReference *reference)
2077 {
2078   RowRefList *refs;
2079
2080   if (reference == NULL)
2081     return;
2082
2083   refs = g_object_get_data (G_OBJECT (reference->proxy), ROW_REF_DATA_STRING);
2084
2085   if (refs == NULL)
2086     {
2087       g_warning (G_STRLOC": bad row reference, proxy has no outstanding row references");
2088       return;
2089     }
2090
2091   refs->list = g_slist_remove (refs->list, reference);
2092
2093   if (refs->list == NULL)
2094     {
2095       g_object_set_data (G_OBJECT (reference->proxy),
2096                          I_(ROW_REF_DATA_STRING),
2097                          NULL);
2098     }
2099
2100   if (reference->path)
2101     {
2102       gtk_tree_row_reference_unref_path (reference->path, reference->model, reference->path->depth);
2103       gtk_tree_path_free (reference->path);
2104     }
2105
2106   g_object_unref (reference->proxy);
2107   g_object_unref (reference->model);
2108   g_free (reference);
2109 }
2110
2111 /**
2112  * gtk_tree_row_reference_inserted:
2113  * @proxy: A #GObject
2114  * @path: The row position that was inserted
2115  * 
2116  * Lets a set of row reference created by gtk_tree_row_reference_new_proxy()
2117  * know that the model emitted the "row_inserted" signal.
2118  **/
2119 void
2120 gtk_tree_row_reference_inserted (GObject     *proxy,
2121                                  GtkTreePath *path)
2122 {
2123   g_return_if_fail (G_IS_OBJECT (proxy));
2124
2125   gtk_tree_row_ref_inserted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, NULL);
2126 }
2127
2128 /**
2129  * gtk_tree_row_reference_deleted:
2130  * @proxy: A #GObject
2131  * @path: The path position that was deleted
2132  * 
2133  * Lets a set of row reference created by gtk_tree_row_reference_new_proxy()
2134  * know that the model emitted the "row_deleted" signal.
2135  **/
2136 void
2137 gtk_tree_row_reference_deleted (GObject     *proxy,
2138                                 GtkTreePath *path)
2139 {
2140   g_return_if_fail (G_IS_OBJECT (proxy));
2141
2142   gtk_tree_row_ref_deleted ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path);
2143 }
2144
2145 /**
2146  * gtk_tree_row_reference_reordered:
2147  * @proxy: A #GObject
2148  * @path: The parent path of the reordered signal
2149  * @iter: The iter pointing to the parent of the reordered
2150  * @new_order: The new order of rows
2151  * 
2152  * Lets a set of row reference created by gtk_tree_row_reference_new_proxy()
2153  * know that the model emitted the "rows_reordered" signal.
2154  **/
2155 void
2156 gtk_tree_row_reference_reordered (GObject     *proxy,
2157                                   GtkTreePath *path,
2158                                   GtkTreeIter *iter,
2159                                   gint        *new_order)
2160 {
2161   g_return_if_fail (G_IS_OBJECT (proxy));
2162
2163   gtk_tree_row_ref_reordered ((RowRefList *)g_object_get_data (proxy, ROW_REF_DATA_STRING), path, iter, new_order);
2164 }
2165
2166 #define __GTK_TREE_MODEL_C__
2167 #include "gtkaliasdef.c"