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