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