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