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