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