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