]> Pileus Git - ~andy/gtk/blob - gtk/gtktreemodel.c
Add support for invalid nodes. (_gtk_rbnode_rotate_right): Ditto.
[~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 <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <glib.h>
24 #include <gobject/gvaluecollector.h>
25 #include "gtktreemodel.h"
26 #include "gtktreeview.h"
27 #include "gtktreeprivate.h"
28 #include "gtksignal.h"
29
30
31 struct _GtkTreePath
32 {
33   gint depth;
34   gint *indices;
35 };
36
37 static void gtk_tree_model_base_init (gpointer g_class);
38
39
40 GtkType
41 gtk_tree_model_get_type (void)
42 {
43   static GtkType tree_model_type = 0;
44
45   if (! tree_model_type)
46     {
47       static const GTypeInfo tree_model_info =
48       {
49         sizeof (GtkTreeModelIface), /* class_size */
50         gtk_tree_model_base_init,   /* base_init */
51         NULL,           /* base_finalize */
52         NULL,
53         NULL,           /* class_finalize */
54         NULL,           /* class_data */
55         0,
56         0,              /* n_preallocs */
57         NULL
58       };
59
60       tree_model_type = g_type_register_static (G_TYPE_INTERFACE, "GtkTreeModel", &tree_model_info, 0);
61       g_type_interface_add_prerequisite (tree_model_type, G_TYPE_OBJECT);
62     }
63
64   return tree_model_type;
65 }
66
67 static void
68 gtk_tree_model_base_init (gpointer g_class)
69 {
70   static gboolean initialized = FALSE;
71
72   if (! initialized)
73     {
74       g_signal_new ("row_changed",
75                     GTK_TYPE_TREE_MODEL,
76                     G_SIGNAL_RUN_LAST,
77                     G_STRUCT_OFFSET (GtkTreeModelIface, row_changed),
78                     NULL, NULL,
79                     gtk_marshal_VOID__BOXED_BOXED,
80                     G_TYPE_NONE, 2,
81                     GTK_TYPE_TREE_PATH,
82                     GTK_TYPE_TREE_ITER);
83       g_signal_new ("row_inserted",
84                     GTK_TYPE_TREE_MODEL,
85                     G_SIGNAL_RUN_LAST,
86                     G_STRUCT_OFFSET (GtkTreeModelIface, row_inserted),
87                     NULL, NULL,
88                     gtk_marshal_VOID__BOXED_BOXED,
89                     G_TYPE_NONE, 2,
90                     GTK_TYPE_TREE_PATH,
91                     GTK_TYPE_TREE_ITER);
92       g_signal_new ("row_has_child_toggled",
93                     GTK_TYPE_TREE_MODEL,
94                     G_SIGNAL_RUN_LAST,
95                     G_STRUCT_OFFSET (GtkTreeModelIface, row_has_child_toggled),
96                     NULL, NULL,
97                     gtk_marshal_VOID__BOXED_BOXED,
98                     G_TYPE_NONE, 2,
99                     GTK_TYPE_TREE_PATH,
100                     GTK_TYPE_TREE_ITER);
101       g_signal_new ("row_deleted",
102                     GTK_TYPE_TREE_MODEL,
103                     G_SIGNAL_RUN_LAST,
104                     G_STRUCT_OFFSET (GtkTreeModelIface, row_deleted),
105                     NULL, NULL,
106                     gtk_marshal_VOID__BOXED,
107                     G_TYPE_NONE, 1,
108                     GTK_TYPE_TREE_PATH);
109       g_signal_new ("rows_reordered",
110                     GTK_TYPE_TREE_MODEL,
111                     G_SIGNAL_RUN_LAST,
112                     G_STRUCT_OFFSET (GtkTreeModelIface, rows_reordered),
113                     NULL, NULL,
114                     gtk_marshal_VOID__BOXED_BOXED_POINTER,
115                     G_TYPE_NONE, 3,
116                     GTK_TYPE_TREE_PATH,
117                     GTK_TYPE_TREE_ITER,
118                     G_TYPE_POINTER);
119       initialized = TRUE;
120     }
121 }
122
123 /**
124  * gtk_tree_path_new:
125  *
126  * Creates a new #GtkTreePath.
127  *
128  * Return value: A newly created #GtkTreePath.
129  **/
130 /* GtkTreePath Operations */
131 GtkTreePath *
132 gtk_tree_path_new (void)
133 {
134   GtkTreePath *retval;
135   retval = (GtkTreePath *) g_new (GtkTreePath, 1);
136   retval->depth = 0;
137   retval->indices = NULL;
138
139   return retval;
140 }
141
142 /**
143  * gtk_tree_path_new_from_string:
144  * @path: The string representation of a path.
145  *
146  * Creates a new #GtkTreePath initialized to @path.  @path is expected to be a
147  * colon separated list of numbers.  For example, the string "10:4:0" would
148  * create a path of depth 3 pointing to the 11th child of the root node, the 5th
149  * child of that 11th child, and the 1st child of that 5th child.  If an invalid
150  * path is past in, NULL is returned.
151  *
152  * Return value: A newly created #GtkTreePath, or NULL
153  **/
154 GtkTreePath *
155 gtk_tree_path_new_from_string (const gchar *path)
156 {
157   GtkTreePath *retval;
158   const gchar *orig_path = path;
159   gchar *ptr;
160   gint i;
161
162   g_return_val_if_fail (path != NULL, NULL);
163   g_return_val_if_fail (*path != '\000', NULL);
164
165   retval = gtk_tree_path_new ();
166
167   while (1)
168     {
169       i = strtol (path, &ptr, 10);
170       gtk_tree_path_append_index (retval, i);
171
172       if (i < 0)
173         {
174           g_warning (G_STRLOC ": Negative numbers in path %s passed to gtk_tree_path_new_from_string", orig_path);
175           gtk_tree_path_free (retval);
176           return NULL;
177         }
178       if (*ptr == '\000')
179         break;
180       if (ptr == path || *ptr != ':')
181         {
182           g_warning (G_STRLOC ": Invalid path %s passed to gtk_tree_path_new_from_string", orig_path);
183           gtk_tree_path_free (retval);
184           return NULL;
185         }
186       path = ptr + 1;
187     }
188
189   return retval;
190 }
191
192 /**
193  * gtk_tree_path_to_string:
194  * @path: A #GtkTreePath
195  *
196  * Generates a string representation of the path.  This string is a ':'
197  * separated list of numbers.  For example, "4:10:0:3" would be an acceptable return value for this string.
198  *
199  * Return value: A newly allocated string.  Must be freed with #g_free.
200  **/
201 gchar *
202 gtk_tree_path_to_string (GtkTreePath *path)
203 {
204   gchar *retval, *ptr;
205   gint i;
206
207   g_return_val_if_fail (path != NULL, NULL);
208
209   if (path->depth == 0)
210     return NULL;
211
212   ptr = retval = (gchar *) g_new0 (char *, path->depth*8);
213   sprintf (retval, "%d", path->indices[0]);
214   while (*ptr != '\000')
215     ptr++;
216
217   for (i = 1; i < path->depth; i++)
218     {
219       sprintf (ptr, ":%d", path->indices[i]);
220       while (*ptr != '\000')
221         ptr++;
222     }
223
224   return retval;
225 }
226
227 /**
228  * gtk_tree_path_new_root:
229  *
230  * Creates a new root #GtkTreePath.  The string representation of this path is
231  * "0"
232  *
233  * Return value: A new #GtkTreePath.
234  **/
235 GtkTreePath *
236 gtk_tree_path_new_root (void)
237 {
238   GtkTreePath *retval;
239
240   retval = gtk_tree_path_new ();
241   gtk_tree_path_append_index (retval, 0);
242
243   return retval;
244 }
245
246 /**
247  * gtk_tree_path_append_index:
248  * @path: A #GtkTreePath.
249  * @index: The index.
250  *
251  * Appends a new index to a path.  As a result, the depth of the path is
252  * increased.
253  **/
254 void
255 gtk_tree_path_append_index (GtkTreePath *path,
256                             gint         index)
257 {
258   g_return_if_fail (path != NULL);
259   g_return_if_fail (index >= 0);
260
261   path->depth += 1;
262   path->indices = g_realloc (path->indices, path->depth * sizeof(gint));
263   path->indices[path->depth - 1] = index;
264 }
265
266 /**
267  * gtk_tree_path_prepend_index:
268  * @path: A #GtkTreePath.
269  * @index: The index.
270  *
271  * Prepends a new index to a path.  As a result, the depth of the path is
272  * increased.
273  **/
274 void
275 gtk_tree_path_prepend_index (GtkTreePath *path,
276                              gint       index)
277 {
278   gint *new_indices = g_new (gint, ++path->depth);
279   if (path->indices == NULL)
280     {
281       path->indices = new_indices;
282       path->indices[0] = index;
283       return;
284     }
285   memcpy (new_indices + 1, path->indices, (path->depth - 1)*sizeof (gint));
286   g_free (path->indices);
287   path->indices = new_indices;
288   path->indices[0] = index;
289 }
290
291 /**
292  * gtk_tree_path_get_depth:
293  * @path: A #GtkTreePath.
294  *
295  * Returns the current depth of @path.
296  *
297  * Return value: The depth of @path
298  **/
299 gint
300 gtk_tree_path_get_depth (GtkTreePath *path)
301 {
302   g_return_val_if_fail (path != NULL, 0);
303
304   return path->depth;
305 }
306
307 /**
308  * gtk_tree_path_get_indices:
309  * @path: A #GtkTreePath.
310  *
311  * Returns the current indices of @path.  This is an array of integers, each
312  * representing a node in a tree.
313  *
314  * Return value: The current indices, or NULL.
315  **/
316 gint *
317 gtk_tree_path_get_indices (GtkTreePath *path)
318 {
319   g_return_val_if_fail (path != NULL, NULL);
320
321   return path->indices;
322 }
323
324 /**
325  * gtk_tree_path_free:
326  * @path: A #GtkTreePath.
327  *
328  * Frees @path.
329  **/
330 void
331 gtk_tree_path_free (GtkTreePath *path)
332 {
333   g_return_if_fail (path != NULL);
334
335   g_free (path->indices);
336   g_free (path);
337 }
338
339 /**
340  * gtk_tree_path_copy:
341  * @path: A #GtkTreePath.
342  *
343  * Creates a new #GtkTreePath as a copy of @path.
344  *
345  * Return value: A new #GtkTreePath.
346  **/
347 GtkTreePath *
348 gtk_tree_path_copy (GtkTreePath *path)
349 {
350   GtkTreePath *retval;
351
352   g_return_val_if_fail (path != NULL, NULL);
353
354   retval = g_new (GtkTreePath, 1);
355   retval->depth = path->depth;
356   retval->indices = g_new (gint, path->depth);
357   memcpy (retval->indices, path->indices, path->depth * sizeof (gint));
358   return retval;
359 }
360
361 /**
362  * gtk_tree_path_compare:
363  * @a: A #GtkTreePath.
364  * @b: A #GtkTreePath to compare with.
365  *
366  * Compares two paths.  If @a appears before @b in a tree, then -1, is returned.
367  * If @b appears before @a, then 1 is returned.  If the two nodes are equal,
368  * then 0 is returned.
369  *
370  * Return value: The relative positions of @a and @b
371  **/
372 gint
373 gtk_tree_path_compare (const GtkTreePath *a,
374                        const GtkTreePath *b)
375 {
376   gint p = 0, q = 0;
377
378   g_return_val_if_fail (a != NULL, 0);
379   g_return_val_if_fail (b != NULL, 0);
380   g_return_val_if_fail (a->depth > 0, 0);
381   g_return_val_if_fail (b->depth > 0, 0);
382
383   do
384     {
385       if (a->indices[p] == b->indices[q])
386         continue;
387       return (a->indices[p] < b->indices[q]?-1:1);
388     }
389   while (++p < a->depth && ++q < b->depth);
390   if (a->depth == b->depth)
391     return 0;
392   return (a->depth < b->depth?-1:1);
393 }
394
395 /**
396  * gtk_tree_path_is_ancestor:
397  * @path: a #GtkTreePath
398  * @descendant: another #GtkTreePath
399  *
400  *
401  *
402  * Return value: %TRUE if @descendant is contained inside @path
403  **/
404 gboolean
405 gtk_tree_path_is_ancestor (GtkTreePath *path,
406                            GtkTreePath *descendant)
407 {
408   gint i;
409
410   g_return_val_if_fail (path != NULL, FALSE);
411   g_return_val_if_fail (descendant != NULL, FALSE);
412
413   /* can't be an ancestor if we're deeper */
414   if (path->depth >= descendant->depth)
415     return FALSE;
416
417   i = 0;
418   while (i < path->depth)
419     {
420       if (path->indices[i] != descendant->indices[i])
421         return FALSE;
422       ++i;
423     }
424
425   return TRUE;
426 }
427
428 /**
429  * gtk_tree_path_is_descendant:
430  * @path: a #GtkTreePath
431  * @ancestor: another #GtkTreePath
432  *
433  *
434  *
435  * Return value: %TRUE if @ancestor contains @path somewhere below it
436  **/
437 gboolean
438 gtk_tree_path_is_descendant (GtkTreePath *path,
439                              GtkTreePath *ancestor)
440 {
441   gint i;
442
443   g_return_val_if_fail (path != NULL, FALSE);
444   g_return_val_if_fail (ancestor != NULL, FALSE);
445
446   /* can't be a descendant if we're shallower in the tree */
447   if (path->depth <= ancestor->depth)
448     return FALSE;
449
450   i = 0;
451   while (i < ancestor->depth)
452     {
453       if (path->indices[i] != ancestor->indices[i])
454         return FALSE;
455       ++i;
456     }
457
458   return TRUE;
459 }
460
461
462 /**
463  * gtk_tree_path_next:
464  * @path: A #GtkTreePath.
465  *
466  * Moves the @path to point to the next node at the current depth.
467  **/
468 void
469 gtk_tree_path_next (GtkTreePath *path)
470 {
471   g_return_if_fail (path != NULL);
472   g_return_if_fail (path->depth > 0);
473
474   path->indices[path->depth - 1] ++;
475 }
476
477 /**
478  * gtk_tree_path_prev:
479  * @path: A #GtkTreePath.
480  *
481  * Moves the @path to point to the previous node at the current depth, if it exists.
482  *
483  * Return value: TRUE if @path has a previous node, and the move was made.
484  **/
485 gboolean
486 gtk_tree_path_prev (GtkTreePath *path)
487 {
488   g_return_val_if_fail (path != NULL, FALSE);
489
490   if (path->indices[path->depth - 1] == 0)
491     return FALSE;
492
493   path->indices[path->depth - 1] -= 1;
494
495   return TRUE;
496 }
497
498 /**
499  * gtk_tree_path_up:
500  * @path: A #GtkTreePath.
501  *
502  * Moves the @path to point to it's parent node, if it has a parent.
503  *
504  * Return value: TRUE if @path has a parent, and the move was made.
505  **/
506 gboolean
507 gtk_tree_path_up (GtkTreePath *path)
508 {
509   g_return_val_if_fail (path != NULL, FALSE);
510
511   if (path->depth == 0)
512     return FALSE;
513
514   path->depth--;
515
516   return TRUE;
517 }
518
519 /**
520  * gtk_tree_path_down:
521  * @path: A #GtkTreePath.
522  *
523  * Moves @path to point to the first child of the current path.
524  **/
525 void
526 gtk_tree_path_down (GtkTreePath *path)
527 {
528   g_return_if_fail (path != NULL);
529
530   gtk_tree_path_append_index (path, 0);
531 }
532
533 /**
534  * gtk_tree_iter_copy:
535  * @iter: A #GtkTreeIter.
536  *
537  * Creates a dynamically allocated tree iterator as a copy of @iter.  This
538  * function is not intended for use in applications, because you can just copy
539  * the structs by value (GtkTreeIter new_iter = iter;).  You
540  * must free this iter with gtk_tree_iter_free ().
541  *
542  * Return value: a newly allocated copy of @iter.
543  **/
544 GtkTreeIter *
545 gtk_tree_iter_copy (GtkTreeIter *iter)
546 {
547   GtkTreeIter *retval;
548
549   g_return_val_if_fail (iter != NULL, NULL);
550
551   retval = g_new (GtkTreeIter, 1);
552   *retval = *iter;
553
554   return retval;
555 }
556
557 /**
558  * gtk_tree_iter_free:
559  * @iter: A dynamically allocated tree iterator.
560  *
561  * Free an iterator that has been allocated on the heap.  This function is
562  * mainly used for language bindings.
563  **/
564 void
565 gtk_tree_iter_free (GtkTreeIter *iter)
566 {
567   g_return_if_fail (iter != NULL);
568
569   g_free (iter);
570 }
571
572 /**
573  * gtk_tree_model_get_flags:
574  * @tree_model: A #GtkTreeModel.
575  *
576  * Returns a set of flags supported by this interface.  The flags are a bitwise
577  * combination of #GtkTreeModelFlags.  The flags supported should not change
578  * during the lifecycle of the tree_model.
579  *
580  * Return value: The flags supported by this interface.
581  **/
582 GtkTreeModelFlags
583 gtk_tree_model_get_flags (GtkTreeModel *tree_model)
584 {
585   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
586
587   if (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags)
588     return (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags) (tree_model);
589
590   return 0;
591 }
592
593 /**
594  * gtk_tree_model_get_n_columns:
595  * @tree_model: A #GtkTreeModel.
596  *
597  * Returns the number of columns supported by the #tree_model
598  *
599  * Return value: The number of columns.
600  **/
601 gint
602 gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
603 {
604   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
605   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_n_columns != NULL, 0);
606
607   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_n_columns) (tree_model);
608 }
609
610 /**
611  * gtk_tree_model_get_column_type:
612  * @tree_model: A #GtkTreeModel.
613  * @index: The column index.
614  *
615  * Returns the type of the column.
616  *
617  * Return value: The type of the column.
618  **/
619 GType
620 gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
621                                 gint          index)
622 {
623   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
624   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type != NULL, G_TYPE_INVALID);
625   g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
626
627   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type) (tree_model, index);
628 }
629
630 /**
631  * gtk_tree_model_get_iter:
632  * @tree_model: A #GtkTreeModel.
633  * @iter: The uninitialized #GtkTreeIter.
634  * @path: The #GtkTreePath.
635  *
636  * Sets @iter to a valid iterator pointing to @path.
637  *
638  * Return value: TRUE, if @iter was set.
639  **/
640 gboolean
641 gtk_tree_model_get_iter (GtkTreeModel *tree_model,
642                          GtkTreeIter  *iter,
643                          GtkTreePath  *path)
644 {
645   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
646   g_return_val_if_fail (iter != NULL, FALSE);
647   g_return_val_if_fail (path != NULL, FALSE);
648   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_iter != NULL, FALSE);
649   g_return_val_if_fail (path->depth > 0, FALSE);
650
651   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_iter) (tree_model, iter, path);
652 }
653
654 /**
655  * gtk_tree_model_get_iter_from_string:
656  * @tree_model: A #GtkTreeModel.
657  * @iter: An uninitialized #GtkTreeIter.
658  * @path_string: A string representation of a #GtkTreePath.
659  *
660  * Sets @iter to a valid iterator pointing to @path_string, if it
661  * exists. Otherwise, @iter is left invalid and %FALSE is returned.
662  *
663  * Return value: TRUE, if @iter was set.
664  **/
665 gboolean
666 gtk_tree_model_get_iter_from_string (GtkTreeModel *tree_model,
667                                      GtkTreeIter  *iter,
668                                      const gchar  *path_string)
669 {
670   gboolean retval;
671   GtkTreePath *path;
672
673   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
674   g_return_val_if_fail (iter != NULL, FALSE);
675   g_return_val_if_fail (path_string != NULL, FALSE);
676   
677   path = gtk_tree_path_new_from_string (path_string);
678   
679   g_return_val_if_fail (path != NULL, FALSE);
680
681   retval = gtk_tree_model_get_iter (tree_model, iter, path);
682   gtk_tree_path_free (path);
683   
684   return retval;
685 }
686
687
688 /**
689  * gtk_tree_model_get_iter_root:
690  * @tree_model: A #GtkTreeModel.
691  * @iter: The uninitialized #GtkTreeIter.
692  * 
693  * Initialized @iter with the root iterator in the tree (the one at the root
694  * path) and returns %TRUE.   Returns %FALSE if the tree is empty.
695  * 
696  * Return value: TRUE, if @iter was set.
697  **/
698 gboolean
699 gtk_tree_model_get_iter_root (GtkTreeModel *tree_model,
700                               GtkTreeIter  *iter)
701 {
702   GtkTreePath *path;
703   gboolean retval;
704
705   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
706   g_return_val_if_fail (iter != NULL, FALSE);
707
708   path = gtk_tree_path_new_root ();
709   retval = gtk_tree_model_get_iter (tree_model, iter, path);
710   gtk_tree_path_free (path);
711
712   return retval;
713 }
714
715 /**
716  * gtk_tree_model_get_path:
717  * @tree_model: A #GtkTreeModel.
718  * @iter: The #GtkTreeIter.
719  *
720  * Returns a newly created #GtkTreePath referenced by @iter.  This path should
721  * be freed with #gtk_tree_path_free.
722  *
723  * Return value: a newly created #GtkTreePath.
724  **/
725 GtkTreePath *
726 gtk_tree_model_get_path (GtkTreeModel *tree_model,
727                          GtkTreeIter  *iter)
728 {
729   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
730   g_return_val_if_fail (iter != NULL, NULL);
731   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_path != NULL, NULL);
732
733   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_path) (tree_model, iter);
734 }
735
736 /**
737  * gtk_tree_model_get_value:
738  * @tree_model: A #GtkTreeModel.
739  * @iter: The #GtkTreeIter.
740  * @column: The column to lookup the value at.
741  * @value: An empty #GValue to set.
742  *
743  * Sets initializes and sets @value to that at @column.  When done with @value,
744  * #g_value_unset needs to be called to free any allocated memory.
745  **/
746 void
747 gtk_tree_model_get_value (GtkTreeModel *tree_model,
748                           GtkTreeIter  *iter,
749                           gint          column,
750                           GValue       *value)
751 {
752   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
753   g_return_if_fail (iter != NULL);
754   g_return_if_fail (value != NULL);
755   g_return_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_value != NULL);
756
757   (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_value) (tree_model, iter, column, value);
758 }
759
760 /**
761  * gtk_tree_model_iter_next:
762  * @tree_model: A #GtkTreeModel.
763  * @iter: The #GtkTreeIter.
764  *
765  * Sets @iter to point to the node following it at the current level.  If there
766  * is no next @iter, FALSE is returned and @iter is set to be invalid.
767  *
768  * Return value: TRUE if @iter has been changed to the next node.
769  **/
770 gboolean
771 gtk_tree_model_iter_next (GtkTreeModel  *tree_model,
772                           GtkTreeIter   *iter)
773 {
774   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
775   g_return_val_if_fail (iter != NULL, FALSE);
776   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_next != NULL, FALSE);
777
778   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_next) (tree_model, iter);
779 }
780
781 /**
782  * gtk_tree_model_iter_children:
783  * @tree_model: A #GtkTreeModel.
784  * @iter: The new #GtkTreeIter to be set to the child.
785  * @parent: The #GtkTreeIter.
786  *
787  * Sets @iter to point to the first child of @parent.  If @parent has no children,
788  * FALSE is returned and @iter is set to be invalid.  @parent will remain a valid
789  * node after this function has been called.
790  *
791  * Return value: TRUE, if @child has been set to the first child.
792  **/
793 gboolean
794 gtk_tree_model_iter_children (GtkTreeModel *tree_model,
795                               GtkTreeIter  *iter,
796                               GtkTreeIter  *parent)
797 {
798   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
799   g_return_val_if_fail (iter != NULL, FALSE);
800   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_children != NULL, FALSE);
801
802   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_children) (tree_model, iter, parent);
803 }
804
805 /**
806  * gtk_tree_model_iter_has_child:
807  * @tree_model: A #GtkTreeModel.
808  * @iter: The #GtkTreeIter to test for children.
809  *
810  * Returns TRUE if @iter has children, FALSE otherwise.
811  *
812  * Return value: TRUE if @iter has children.
813  **/
814 gboolean
815 gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
816                                GtkTreeIter  *iter)
817 {
818   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
819   g_return_val_if_fail (iter != NULL, FALSE);
820   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_has_child != NULL, FALSE);
821
822   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_has_child) (tree_model, iter);
823 }
824
825 /**
826  * gtk_tree_model_iter_n_children:
827  * @tree_model: A #GtkTreeModel.
828  * @iter: The #GtkTreeIter, or NULL.
829  *
830  * Returns the number of children that @iter has.  As a special case, if @iter
831  * is NULL, then the number of toplevel nodes is returned.
832  *
833  * Return value: The number of children of @iter.
834  **/
835 gint
836 gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
837                                 GtkTreeIter  *iter)
838 {
839   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
840   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children != NULL, 0);
841
842   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children) (tree_model, iter);
843 }
844
845 /**
846  * gtk_tree_model_iter_nth_child:
847  * @tree_model: A #GtkTreeModel.
848  * @iter: The #GtkTreeIter to set to the nth child.
849  * @parent: The #GtkTreeIter to get the child from, or NULL.
850  * @n: Then index of the desired child.
851  *
852  * Sets @iter to be the child of @parent, using the given index.  The first
853  * index is 0.  If @index is too big, or @parent has no children, @iter is set
854  * to an invalid iterator and FALSE is returned.  @parent will remain a valid
855  * node after this function has been called.  As a special case, if @parent is
856  * NULL, then the nth root node is set.
857  *
858  * Return value: TRUE, if @parent has an nth child.
859  **/
860 gboolean
861 gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
862                                GtkTreeIter  *iter,
863                                GtkTreeIter  *parent,
864                                gint          n)
865 {
866   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
867   g_return_val_if_fail (iter != NULL, FALSE);
868   g_return_val_if_fail (n >= 0, FALSE);
869   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_nth_child != NULL, FALSE);
870
871   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_nth_child) (tree_model, iter, parent, n);
872 }
873
874 /**
875  * gtk_tree_model_iter_parent:
876  * @tree_model: A #GtkTreeModel
877  * @iter: The new #GtkTreeIter to set to the parent.
878  * @child: The #GtkTreeIter.
879  *
880  * Sets @iter to be the parent of @child.  If @child is at the toplevel, and
881  * doesn't have a parent, then @iter is set to an invalid iterator and FALSE
882  * is returned.  @child will remain a valid node after this function has been
883  * called.
884  *
885  * Return value: TRUE, if @iter is set to the parent of @child.
886  **/
887 gboolean
888 gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
889                             GtkTreeIter  *iter,
890                             GtkTreeIter  *child)
891 {
892   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
893   g_return_val_if_fail (iter != NULL, FALSE);
894   g_return_val_if_fail (child != NULL, FALSE);
895   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent != NULL, FALSE);
896
897   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent) (tree_model, iter, child);
898 }
899
900 /**
901  * gtk_tree_model_ref_node:
902  * @tree_model: A #GtkTreeModel.
903  * @iter: The #GtkTreeIter.
904  *
905  * Lets the tree ref the node.  This is an optional method for models to
906  * implement.  To be more specific, models may ignore this call as it exists
907  * primarily for performance reasons.
908  * 
909  * This function is primarily meant as a way for views to let caching model know
910  * when nodes are being displayed (and hence, whether or not to cache that
911  * node.)  For example, a file-system based model would not want to keep the
912  * entire file-heirarchy in memory, just the sections that are currently being
913  * displayed by every current view.
914  *
915  * A model should be expected to be able to get an iter independent of it's
916  * reffed state.
917  **/
918 void
919 gtk_tree_model_ref_node (GtkTreeModel *tree_model,
920                          GtkTreeIter  *iter)
921 {
922   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
923
924   if (GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_node)
925     (* GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_node) (tree_model, iter);
926 }
927
928 /**
929  * gtk_tree_model_unref_node:
930  * @tree_model: A #GtkTreeModel.
931  * @iter: The #GtkTreeIter.
932  *
933  * Lets the tree unref the node.  This is an optional method for models to
934  * implement.  To be more specific, models may ignore this call as it exists
935  * primarily for performance reasons.
936  *
937  * For more information on what this means, please see #gtk_tree_model_ref_node.
938  * Please note that nodes that are deleted are not unreffed.
939  **/
940 void
941 gtk_tree_model_unref_node (GtkTreeModel *tree_model,
942                            GtkTreeIter  *iter)
943 {
944   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
945   g_return_if_fail (iter != NULL);
946
947   if (GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_node)
948     (* GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_node) (tree_model, iter);
949 }
950
951 /**
952  * gtk_tree_model_get:
953  * @tree_model: a #GtkTreeModel
954  * @iter: a row in @tree_model
955  * @Varargs: pairs of column number and value return locations, terminated by -1
956  *
957  * Gets the value of one or more cells in the row referenced by @iter.
958  * The variable argument list should contain integer column numbers,
959  * each column number followed by a place to store the value being
960  * retrieved.  The list is terminated by a -1. For example, to get a
961  * value from column 0 with type %G_TYPE_STRING, you would
962  * write: gtk_tree_model_set (model, iter, 0, &place_string_here, -1),
963  * where place_string_here is a gchar* to be filled with the string.
964  * If appropriate, the returned values have to be freed or unreferenced.
965  *
966  **/
967 void
968 gtk_tree_model_get (GtkTreeModel *tree_model,
969                     GtkTreeIter  *iter,
970                     ...)
971 {
972   va_list var_args;
973
974   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
975   g_return_if_fail (iter != NULL);
976
977   va_start (var_args, iter);
978   gtk_tree_model_get_valist (tree_model, iter, var_args);
979   va_end (var_args);
980 }
981
982 /**
983  * gtk_tree_model_get_valist:
984  * @tree_model: a #GtkTreeModel
985  * @iter: a row in @tree_model
986  * @var_args: va_list of column/return location pairs
987  *
988  * See gtk_tree_model_get(), this version takes a va_list for language bindings
989  * to use.
990  **/
991 void
992 gtk_tree_model_get_valist (GtkTreeModel *tree_model,
993                            GtkTreeIter  *iter,
994                            va_list      var_args)
995 {
996   gint column;
997
998   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
999   g_return_if_fail (iter != NULL);
1000
1001   column = va_arg (var_args, gint);
1002
1003   while (column != -1)
1004     {
1005       GValue value = { 0, };
1006       gchar *error = NULL;
1007
1008       if (column >= gtk_tree_model_get_n_columns (tree_model))
1009         {
1010           g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC, column);
1011           break;
1012         }
1013
1014       gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, column, &value);
1015
1016       G_VALUE_LCOPY (&value, var_args, 0, &error);
1017       if (error)
1018         {
1019           g_warning ("%s: %s", G_STRLOC, error);
1020           g_free (error);
1021
1022           /* we purposely leak the value here, it might not be
1023            * in a sane state if an error condition occoured
1024            */
1025           break;
1026         }
1027
1028       g_value_unset (&value);
1029
1030       column = va_arg (var_args, gint);
1031     }
1032 }
1033
1034 /**
1035  * gtk_tree_model_row_changed:
1036  * @tree_model: A #GtkTreeModel
1037  * @path: A #GtkTreePath pointing to the changed row
1038  * @iter: A valid #GtkTreeIter pointing to the changed row
1039  * 
1040  * Emits the "row_changed" signal on @tree_model.
1041  **/
1042 void
1043 gtk_tree_model_row_changed (GtkTreeModel *tree_model,
1044                             GtkTreePath  *path,
1045                             GtkTreeIter  *iter)
1046 {
1047   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1048   g_return_if_fail (path != NULL);
1049   g_return_if_fail (iter != NULL);
1050
1051   g_signal_emit_by_name (tree_model, "row_changed", path, iter);
1052 }
1053
1054 /**
1055  * gtk_tree_model_row_inserted:
1056  * @tree_model: A #GtkTreeModel
1057  * @path: A #GtkTreePath pointing to the inserted row
1058  * @iter: A valid #GtkTreeIter pointing to the inserted row
1059  * 
1060  * Emits the "row_inserted" signal on @tree_model
1061  **/
1062 void
1063 gtk_tree_model_row_inserted (GtkTreeModel *tree_model,
1064                              GtkTreePath  *path,
1065                              GtkTreeIter  *iter)
1066 {
1067   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1068   g_return_if_fail (path != NULL);
1069   g_return_if_fail (iter != NULL);
1070
1071   g_signal_emit_by_name (tree_model, "row_inserted", path, iter);
1072 }
1073
1074 /**
1075  * gtk_tree_model_row_has_child_toggled:
1076  * @tree_model: A #GtkTreeModel
1077  * @path: A #GtkTreePath pointing to the changed row
1078  * @iter: A valid #GtkTreeIter pointing to the changed row
1079  * 
1080  * Emits the "row_has_child_toggled" signal on @tree_model.  This should be
1081  * called by models after the child state of a node changes.
1082  **/
1083 void
1084 gtk_tree_model_row_has_child_toggled (GtkTreeModel *tree_model,
1085                                       GtkTreePath  *path,
1086                                       GtkTreeIter  *iter)
1087 {
1088   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1089   g_return_if_fail (path != NULL);
1090   g_return_if_fail (iter != NULL);
1091
1092   g_signal_emit_by_name (tree_model, "row_has_child_toggled", path, iter);
1093 }
1094
1095 void
1096 gtk_tree_model_row_deleted (GtkTreeModel *tree_model,
1097                             GtkTreePath  *path)
1098 {
1099   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1100   g_return_if_fail (path != NULL);
1101
1102   g_signal_emit_by_name (tree_model, "row_deleted", path);
1103 }
1104
1105 void
1106 gtk_tree_model_rows_reordered (GtkTreeModel *tree_model,
1107                                GtkTreePath  *path,
1108                                GtkTreeIter  *iter,
1109                                gint         *new_order)
1110 {
1111   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1112   g_return_if_fail (new_order != NULL);
1113
1114   g_signal_emit_by_name (tree_model, "rows_reordered", path, iter, new_order);
1115 }
1116
1117
1118 static gboolean
1119 gtk_tree_model_foreach_helper (GtkTreeModel            *model,
1120                                GtkTreeIter             *iter,
1121                                GtkTreePath             *path,
1122                                GtkTreeModelForeachFunc  func,
1123                                gpointer                 user_data)
1124 {
1125   gtk_tree_path_append_index (path, 0);
1126
1127   do
1128     {
1129       GtkTreeIter child;
1130
1131       if (gtk_tree_model_iter_children (model, &child, iter))
1132         {
1133           if (gtk_tree_model_foreach_helper (model, &child, path, func, user_data))
1134             return TRUE;
1135         }
1136
1137       if ((* func) (model, path, iter, user_data))
1138         return TRUE;
1139
1140       gtk_tree_path_next (path);
1141     }
1142   while (gtk_tree_model_iter_next (model, iter));
1143
1144   gtk_tree_path_up (path);
1145   return FALSE;
1146 }
1147
1148 /**
1149  * gtk_tree_model_foreach:
1150  * @model: A #GtkTreeModel
1151  * @func: A function to be called on each row
1152  * @user_data: User data to passed to func.
1153  * 
1154  * Calls func on each node in model in a depth-first fashion.  If func returns
1155  * %TRUE, then the tree ceases to be walked, and gtk_tree_model_foreach returns.
1156  **/
1157
1158 void
1159 gtk_tree_model_foreach (GtkTreeModel            *model,
1160                         GtkTreeModelForeachFunc  func,
1161                         gpointer                 user_data)
1162 {
1163   GtkTreePath *path;
1164   GtkTreeIter iter;
1165
1166   g_return_if_fail (GTK_IS_TREE_MODEL (model));
1167   g_return_if_fail (func != NULL);
1168
1169   path = gtk_tree_path_new_root ();
1170   if (gtk_tree_model_get_iter (model, &iter, path) == FALSE)
1171     return;
1172
1173   gtk_tree_model_foreach_helper (model, &iter, path, func, user_data);
1174   gtk_tree_path_free (path);
1175 }
1176
1177
1178 /*
1179  * GtkTreeRowReference
1180  */
1181
1182 static void gtk_tree_row_reference_unref_path (GtkTreePath  *path,
1183                                                GtkTreeModel *model,
1184                                                gboolean      free_last);
1185
1186 #define ROW_REF_DATA_STRING "gtk-tree-row-refs"
1187
1188 struct _GtkTreeRowReference
1189 {
1190   GObject *proxy;
1191   GtkTreeModel *model;
1192   GtkTreePath *path;
1193 };
1194
1195 typedef struct
1196 {
1197   GSList *list;
1198 } RowRefList;
1199
1200
1201 static void
1202 release_row_references (gpointer data)
1203 {
1204   RowRefList *refs = data;
1205   GSList *tmp_list = NULL;
1206
1207   tmp_list = refs->list;
1208   while (tmp_list != NULL)
1209     {
1210       GtkTreeRowReference *reference = tmp_list->data;
1211
1212       if (reference->proxy == (GObject *)reference->model)
1213         reference->model = NULL;
1214       reference->proxy = NULL;
1215
1216       /* we don't free the reference, users are responsible for that. */
1217
1218       tmp_list = g_slist_next (tmp_list);
1219     }
1220
1221   g_slist_free (refs->list);
1222   g_free (refs);
1223 }
1224
1225 static void
1226 gtk_tree_row_ref_inserted_callback (GObject     *object,
1227                                     GtkTreePath *path,
1228                                     GtkTreeIter *iter,
1229                                     gpointer     data)
1230 {
1231   RowRefList *refs = g_object_get_data (data, ROW_REF_DATA_STRING);
1232
1233   GSList *tmp_list;
1234
1235   if (refs == NULL)
1236     return;
1237
1238   /* This function corrects the path stored in the reference to
1239    * account for an insertion. Note that it's called _after_ the insertion
1240    * with the path to the newly-inserted row. Which means that
1241    * the inserted path is in a different "coordinate system" than
1242    * the old path (e.g. if the inserted path was just before the old path,
1243    * then inserted path and old path will be the same, and old path must be
1244    * moved down one).
1245    */
1246
1247   tmp_list = refs->list;
1248
1249   while (tmp_list != NULL)
1250     {
1251       GtkTreeRowReference *reference = tmp_list->data;
1252
1253       if (reference->path == NULL)
1254         goto done;
1255
1256       if (reference->path->depth >= path->depth)
1257         {
1258           gint i;
1259           gboolean ancestor = TRUE;
1260
1261           for (i = 0; i < path->depth - 1; i ++)
1262             {
1263               if (path->indices[i] != reference->path->indices[i])
1264                 {
1265                   ancestor = FALSE;
1266                   break;
1267                 }
1268             }
1269           if (ancestor == FALSE)
1270             goto done;
1271
1272           if (path->indices[path->depth-1] <= reference->path->indices[path->depth-1])
1273             reference->path->indices[path->depth-1] += 1;
1274         }
1275     done:
1276       tmp_list = g_slist_next (tmp_list);
1277     }
1278 }
1279
1280 static void
1281 gtk_tree_row_ref_deleted_callback (GObject     *object,
1282                                    GtkTreePath *path,
1283                                    gpointer     data)
1284 {
1285   RowRefList *refs = g_object_get_data (data, ROW_REF_DATA_STRING);
1286   GSList *tmp_list;
1287
1288   if (refs == NULL)
1289     return;
1290
1291   /* This function corrects the path stored in the reference to
1292    * account for an deletion. Note that it's called _after_ the
1293    * deletion with the old path of the just-deleted row. Which means
1294    * that the deleted path is the same now-defunct "coordinate system"
1295    * as the path saved in the reference, which is what we want to fix.
1296    */
1297
1298   tmp_list = refs->list;
1299
1300   while (tmp_list != NULL)
1301     {
1302       GtkTreeRowReference *reference = tmp_list->data;
1303
1304       if (reference->path)
1305         {
1306           if (gtk_tree_path_is_ancestor (path, reference->path))
1307             {
1308               reference->path->indices[path->depth-1]-=1;
1309             }
1310           else if (gtk_tree_path_compare (path, reference->path) == 0)
1311             {
1312               gtk_tree_row_reference_unref_path (reference->path, reference->model, FALSE);
1313               gtk_tree_path_free (reference->path);
1314               reference->path = NULL;
1315             }
1316         }
1317       tmp_list = g_slist_next (tmp_list);
1318     }
1319 }
1320
1321 static void
1322 gtk_tree_row_ref_reordered_callback (GObject     *object,
1323                                      GtkTreePath *path,
1324                                      GtkTreeIter *iter,
1325                                      gint        *new_order,
1326                                      gpointer     data)
1327 {
1328   RowRefList *refs = g_object_get_data (data, ROW_REF_DATA_STRING);
1329   GSList *tmp_list;
1330   gint length;
1331
1332   if (refs == NULL)
1333     return;
1334
1335   tmp_list = refs->list;
1336
1337   while (tmp_list != NULL)
1338     {
1339       GtkTreeRowReference *reference = tmp_list->data;
1340
1341       length = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (reference->model), iter);
1342
1343       if (length < 2)
1344         return;
1345
1346       if ((reference->path) &&
1347           (gtk_tree_path_is_ancestor (path, reference->path)))
1348         {
1349           gint ref_depth = gtk_tree_path_get_depth (reference->path);
1350           gint depth = gtk_tree_path_get_depth (path);
1351
1352           if (ref_depth > depth)
1353             {
1354               gint i;
1355               gint *indices = gtk_tree_path_get_indices (reference->path);
1356
1357               for (i = 0; i < length; i++)
1358                 {
1359                   if (new_order[i] == indices[depth])
1360                     {
1361                       indices[depth] = i;
1362                       return;
1363                     }
1364                 }
1365             }
1366         }
1367
1368       tmp_list = g_slist_next (tmp_list);
1369     }
1370   
1371 }
1372      
1373 static void
1374 connect_ref_callbacks (GtkTreeModel *model)
1375 {
1376   g_signal_connect (G_OBJECT (model),
1377                     "row_inserted",
1378                     (GCallback) gtk_tree_row_ref_inserted_callback,
1379                     model);
1380   g_signal_connect (G_OBJECT (model),
1381                     "row_deleted",
1382                     (GCallback) gtk_tree_row_ref_deleted_callback,
1383                     model);
1384   g_signal_connect (G_OBJECT (model),
1385                     "rows_reordered",
1386                     (GCallback) gtk_tree_row_ref_reordered_callback,
1387                     model);
1388 }
1389
1390
1391 /* We do this recursively so that we can unref children nodes before their parent */
1392 static void
1393 gtk_tree_row_reference_unref_path_helper (GtkTreePath  *path,
1394                                           GtkTreeModel *model,
1395                                           GtkTreeIter  *parent_iter,
1396                                           gint          depth,
1397                                           gboolean      free_last)
1398 {
1399   GtkTreeIter iter;
1400
1401   if (free_last == FALSE && path->depth - 1 == depth)
1402     return;
1403   if (path->depth == depth)
1404     return;
1405
1406   gtk_tree_model_iter_nth_child (model, &iter, parent_iter, path->indices[depth]);
1407   gtk_tree_row_reference_unref_path_helper (path, model, &iter, depth + 1, free_last);
1408   gtk_tree_model_unref_node (model, &iter);
1409 }
1410
1411 static void
1412 gtk_tree_row_reference_unref_path (GtkTreePath  *path,
1413                                    GtkTreeModel *model,
1414                                    gboolean      free_last)
1415 {
1416   GtkTreeIter iter;
1417
1418   if (free_last == FALSE && path->depth == 1)
1419     return;
1420       
1421   gtk_tree_model_iter_nth_child (model, &iter, NULL, path->indices[0]);
1422   gtk_tree_row_reference_unref_path_helper (path, model, &iter, 1, free_last);
1423   gtk_tree_model_unref_node (model, &iter);
1424 }
1425
1426 static void
1427 disconnect_ref_callbacks (GtkTreeModel *model)
1428 {
1429   g_signal_handlers_disconnect_matched (G_OBJECT (model),
1430                                         G_SIGNAL_MATCH_FUNC,
1431                                         0, 0, NULL,
1432                                         gtk_tree_row_ref_inserted_callback,
1433                                         NULL);
1434   g_signal_handlers_disconnect_matched (G_OBJECT (model),
1435                                         G_SIGNAL_MATCH_FUNC,
1436                                         0, 0, NULL,
1437                                         gtk_tree_row_ref_deleted_callback,
1438                                         NULL);
1439   g_signal_handlers_disconnect_matched (G_OBJECT (model),
1440                                         G_SIGNAL_MATCH_FUNC,
1441                                         0, 0, NULL,
1442                                         gtk_tree_row_ref_reordered_callback,
1443                                         NULL);
1444 }
1445
1446 /**
1447  * gtk_tree_row_reference_new:
1448  * @model: A #GtkTreeModel
1449  * @path: A valid #GtkTreePath
1450  * 
1451  * Creates a row reference based on @path.  This reference will keep pointing to
1452  * the node pointed to by @path, so long as it exists.  It listens to all
1453  * signals on model, and updates it's path appropriately.  If @path isn't a
1454  * valid path in @model, then %NULL is returned.
1455  * 
1456  * Return value: A newly allocated #GtkTreeRowReference, or %NULL
1457  **/
1458 GtkTreeRowReference *
1459 gtk_tree_row_reference_new (GtkTreeModel *model,
1460                             GtkTreePath  *path)
1461 {
1462   g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1463   g_return_val_if_fail (path != NULL, NULL);
1464
1465   return gtk_tree_row_reference_new_proxy (G_OBJECT (model), model, path);
1466 }
1467
1468 GtkTreeRowReference *
1469 gtk_tree_row_reference_new_proxy (GObject      *proxy,
1470                                   GtkTreeModel *model,
1471                                   GtkTreePath  *path)
1472 {
1473   GtkTreeRowReference *reference;
1474   RowRefList *refs;
1475   GtkTreeIter parent_iter;
1476   gint i;
1477
1478   g_return_val_if_fail (G_IS_OBJECT (proxy), NULL);
1479   g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL);
1480   g_return_val_if_fail (path != NULL, NULL);
1481   g_return_val_if_fail (path->depth > 0, NULL);
1482
1483   /* check that the path is valid */
1484   if (gtk_tree_model_get_iter (model, &parent_iter, path) == FALSE)
1485     return NULL;
1486
1487   /* Now we want to ref every node */
1488   gtk_tree_model_iter_nth_child (model, &parent_iter, NULL, path->indices[0]);
1489   gtk_tree_model_ref_node (model, &parent_iter);
1490
1491   for (i = 1; i < path->depth; i++)
1492     {
1493       GtkTreeIter iter;
1494       gtk_tree_model_iter_nth_child (model, &iter, &parent_iter, path->indices[i]);
1495       gtk_tree_model_ref_node (model, &iter);
1496       parent_iter = iter;
1497     }
1498
1499   /* Make ther row reference */
1500   reference = g_new (GtkTreeRowReference, 1);
1501
1502   g_object_ref (proxy);
1503   g_object_ref (model);
1504   reference->proxy = proxy;
1505   reference->model = model;
1506   reference->path = gtk_tree_path_copy (path);
1507
1508   refs = g_object_get_data (G_OBJECT (proxy), ROW_REF_DATA_STRING);
1509
1510   if (refs == NULL)
1511     {
1512       refs = g_new (RowRefList, 1);
1513       refs->list = NULL;
1514
1515       if (G_OBJECT (model) == proxy)
1516         connect_ref_callbacks (model);
1517
1518       g_object_set_data_full (G_OBJECT (proxy),
1519                               ROW_REF_DATA_STRING,
1520                               refs, release_row_references);
1521     }
1522
1523   refs->list = g_slist_prepend (refs->list, reference);
1524
1525   return reference;
1526 }
1527
1528 /**
1529  * gtk_tree_row_reference_get_path:
1530  * @reference: A #GtkTreeRowReference
1531  * 
1532  * Returns a path that the row reference currently points to, or NULL if the
1533  * path pointed to is no longer valid.
1534  * 
1535  * Return value: A current path, or NULL.
1536  **/
1537 GtkTreePath *
1538 gtk_tree_row_reference_get_path (GtkTreeRowReference *reference)
1539 {
1540   g_return_val_if_fail (reference != NULL, NULL);
1541
1542   if (reference->proxy == NULL)
1543     return NULL;
1544
1545   if (reference->path == NULL)
1546     return NULL;
1547
1548   return gtk_tree_path_copy (reference->path);
1549 }
1550
1551 /**
1552  * gtk_tree_row_reference_valid:
1553  * @reference: A #GtkTreeRowReference, or NULL
1554  * 
1555  * Returns TRUE if the %reference is non-NULL and refers to a current valid
1556  * path.
1557  * 
1558  * Return value: TRUE if %reference points to a valid path.
1559  **/
1560 gboolean
1561 gtk_tree_row_reference_valid (GtkTreeRowReference *reference)
1562 {
1563   if (reference == NULL || reference->path == NULL)
1564     return FALSE;
1565
1566   return TRUE;
1567 }
1568
1569 /**
1570  * gtk_tree_row_reference_free:
1571  * @reference: A #GtkTreeRowReference, or NULL
1572  * 
1573  * Free's %reference.  %reference may be NULL.
1574  **/
1575 void
1576 gtk_tree_row_reference_free (GtkTreeRowReference *reference)
1577 {
1578   RowRefList *refs;
1579
1580   if (reference == NULL)
1581     return;
1582
1583   refs = g_object_get_data (G_OBJECT (reference->proxy), ROW_REF_DATA_STRING);
1584
1585   if (refs == NULL)
1586     {
1587       g_warning (G_STRLOC": bad row reference, proxy has no outstanding row references");
1588       return;
1589     }
1590
1591   refs->list = g_slist_remove (refs->list, reference);
1592
1593   if (refs->list == NULL)
1594     {
1595       disconnect_ref_callbacks (reference->model);
1596       g_object_set_data (G_OBJECT (reference->proxy),
1597                          ROW_REF_DATA_STRING,
1598                          NULL);
1599     }
1600   g_object_unref (reference->proxy);
1601   g_object_unref (reference->model);
1602
1603   if (reference->path)
1604     {
1605       gtk_tree_row_reference_unref_path (reference->path, reference->model, TRUE);
1606       gtk_tree_path_free (reference->path);
1607     }
1608
1609   g_free (reference);
1610 }
1611
1612 void
1613 gtk_tree_row_reference_inserted (GObject     *proxy,
1614                                  GtkTreePath *path)
1615 {
1616   g_return_if_fail (G_IS_OBJECT (proxy));
1617
1618   gtk_tree_row_ref_inserted_callback (NULL, path, NULL, proxy);
1619   
1620 }
1621
1622 void
1623 gtk_tree_row_reference_deleted (GObject     *proxy,
1624                                 GtkTreePath *path)
1625 {
1626   g_return_if_fail (G_IS_OBJECT (proxy));
1627
1628   gtk_tree_row_ref_deleted_callback (NULL, path, proxy);
1629 }
1630
1631 void
1632 gtk_tree_row_reference_reordered (GObject     *proxy,
1633                                   GtkTreePath *path,
1634                                   GtkTreeIter *iter,
1635                                   gint        *new_order)
1636 {
1637   g_return_if_fail (G_IS_OBJECT (proxy));
1638
1639   gtk_tree_row_ref_reordered_callback (NULL, path, iter, new_order, proxy);
1640 }
1641   
1642