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