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