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