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