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