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