]> Pileus Git - ~andy/gtk/blob - gtk/gtktreemodel.c
Changed name to be set_cell_data_func to make it clear what the functino
[~andy/gtk] / gtk / gtktreemodel.c
1 /* gtktreemodel.c
2  * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <string.h>
23 #include <glib.h>
24 #include <gobject/gobject.h>
25 #include <gobject/gvaluecollector.h>
26 #include "gtkmarshal.h"
27 #include "gtktreemodel.h"
28
29 struct _GtkTreePath
30 {
31   gint depth;
32   gint *indices;
33 };
34
35 static void gtk_tree_model_base_init (gpointer g_class);
36
37
38 GtkType
39 gtk_tree_model_get_type (void)
40 {
41   static GtkType tree_model_type = 0;
42
43   if (!tree_model_type)
44     {
45       static const GTypeInfo tree_model_info =
46       {
47         sizeof (GtkTreeModelIface), /* class_size */
48         gtk_tree_model_base_init,   /* base_init */
49         NULL,           /* base_finalize */
50         NULL,
51         NULL,           /* class_finalize */
52         NULL,           /* class_data */
53         0,
54         0,              /* n_preallocs */
55         NULL
56       };
57
58       tree_model_type = g_type_register_static (G_TYPE_INTERFACE, "GtkTreeModel", &tree_model_info, 0);
59     }
60
61   return tree_model_type;
62 }
63
64
65 static void
66 gtk_tree_model_base_init (gpointer g_class)
67 {
68   static gboolean initted = FALSE;
69 #if 0
70   if (! initted)
71     {
72       g_signal_newc ("changed",
73                      GTK_TYPE_TREE_MODEL,
74                      G_SIGNAL_RUN_FIRST,
75                      G_STRUCT_OFFSET (GtkTreeModelIface, changed),
76                      NULL,
77                      gtk_marshal_VOID__BOXED_BOXED,
78                      G_TYPE_NONE, 2,
79                      GTK_TYPE_TREE_PATH,
80                      GTK_TYPE_TREE_ITER);
81
82       g_signal_newc ("inserted",
83                      GTK_TYPE_TREE_MODEL,
84                      G_SIGNAL_RUN_FIRST,
85                      G_STRUCT_OFFSET (GtkTreeModelIface, inserted),
86                      NULL,
87                      gtk_marshal_VOID__BOXED_BOXED,
88                      G_TYPE_NONE, 2,
89                      GTK_TYPE_TREE_PATH,
90                      GTK_TYPE_TREE_ITER);
91       g_signal_newc ("child_toggled",
92                      GTK_TYPE_TREE_MODEL,
93                      G_SIGNAL_RUN_FIRST,
94                      G_STRUCT_OFFSET (GtkTreeModelIface, child_toggled),
95                      NULL,
96                      gtk_marshal_VOID__BOXED_BOXED,
97                      G_TYPE_NONE, 2,
98                      GTK_TYPE_TREE_PATH,
99                      GTK_TYPE_TREE_ITER);
100       g_signal_newc ("deleted",
101                      GTK_TYPE_TREE_MODEL,
102                      G_SIGNAL_RUN_FIRST,
103                      G_STRUCT_OFFSET (GtkTreeModelIface, deleted),
104                      NULL,
105                      gtk_marshal_VOID__BOXED_BOXED,
106                      G_TYPE_NONE, 1,
107                      GTK_TYPE_TREE_PATH);
108
109       initted = TRUE;
110     }
111 #endif
112 }
113
114 /**
115  * gtk_tree_path_new:
116  * 
117  * Creates a new #GtkTreePath.
118  * 
119  * Return value: A newly created #GtkTreePath.
120  **/
121 /* GtkTreePath Operations */
122 GtkTreePath *
123 gtk_tree_path_new (void)
124 {
125   GtkTreePath *retval;
126   retval = (GtkTreePath *) g_new (GtkTreePath, 1);
127   retval->depth = 0;
128   retval->indices = NULL;
129
130   return retval;
131 }
132
133 /**
134  * gtk_tree_path_new_from_string:
135  * @path: The string representation of a path.
136  * 
137  * Creates a new #GtkTreePath initialized to @path.  @path is expected
138  * to be a colon separated list of numbers.  For example, the string
139  * "10:4:0" would create a path of depth 3 pointing to the 11th child
140  * of the root node, the 5th child of that 11th child, and the 1st
141  * child of that 5th child.
142  * 
143  * Return value: A newly created #GtkTreePath.
144  **/
145 GtkTreePath *
146 gtk_tree_path_new_from_string (gchar *path)
147 {
148   GtkTreePath *retval;
149   gchar *ptr;
150   gint i;
151
152   g_return_val_if_fail (path != NULL, gtk_tree_path_new ());
153
154   retval = gtk_tree_path_new ();
155
156   while (1)
157     {
158       i = strtol (path, &ptr, 10);
159       gtk_tree_path_append_index (retval, i);
160
161       if (*ptr == '\000')
162         break;
163       /* FIXME: should we error out if this is not a ':', or should we be tolerant? */
164       path = ptr + 1;
165     }
166
167   return retval;
168 }
169
170 /**
171  * gtk_tree_path_to_string:
172  * @path: A #GtkTreePath
173  * 
174  * Generates a string representation of the path.  This string is a ':'
175  * separated list of numbers.  For example, "4:10:0:3" would be an acceptable return value for this string.
176  * 
177  * Return value: A newly allocated string.  Must be freed with #g_free.
178  **/
179 gchar *
180 gtk_tree_path_to_string (GtkTreePath *path)
181 {
182   gchar *retval, *ptr;
183   gint i;
184
185   if (path->depth == 0)
186     return NULL;
187
188   ptr = retval = (gchar *) g_new0 (char *, path->depth*8);
189   sprintf (retval, "%d", path->indices[0]);
190   while (*ptr != '\000')
191     ptr++;
192
193   for (i = 1; i < path->depth; i++)
194     {
195       sprintf (ptr, ":%d", path->indices[i]);
196       while (*ptr != '\000')
197         ptr++;
198     }
199
200   return retval;
201 }
202
203 /**
204  * gtk_tree_path_new_root:
205  * 
206  * Creates a new root #GtkTreePath.  The string representation of this path is
207  * "0"
208  * 
209  * Return value: A new #GtkTreePath.
210  **/
211 GtkTreePath *
212 gtk_tree_path_new_root (void)
213 {
214   GtkTreePath *retval;
215
216   retval = gtk_tree_path_new ();
217   gtk_tree_path_append_index (retval, 0);
218
219   return retval;
220 }
221
222 /**
223  * gtk_tree_path_append_index:
224  * @path: A #GtkTreePath.
225  * @index: The index.
226  * 
227  * Appends a new index to a path.  As a result, the depth of the path is
228  * increased.
229  **/
230 void
231 gtk_tree_path_append_index (GtkTreePath *path,
232                             gint         index)
233 {
234   g_return_if_fail (path != NULL);
235   g_return_if_fail (index >= 0);
236
237   path->depth += 1;
238   path->indices = g_realloc (path->indices, path->depth * sizeof(gint));
239   path->indices[path->depth - 1] = index;
240 }
241
242 /**
243  * gtk_tree_path_prepend_index:
244  * @path: A #GtkTreePath.
245  * @index: The index.
246  * 
247  * Prepends a new index to a path.  As a result, the depth of the path is
248  * increased.
249  **/
250 void
251 gtk_tree_path_prepend_index (GtkTreePath *path,
252                              gint       index)
253 {
254   gint *new_indices = g_new (gint, ++path->depth);
255   if (path->indices == NULL)
256     {
257       path->indices = new_indices;
258       path->indices[0] = index;
259       return;
260     }
261   memcpy (new_indices + 1, path->indices, (path->depth - 1)*sizeof (gint));
262   g_free (path->indices);
263   path->indices = new_indices;
264   path->indices[0] = index;
265 }
266
267 /**
268  * gtk_tree_path_get_depth:
269  * @path: A #GtkTreePath.
270  * 
271  * Returns the current depth of @path.
272  * 
273  * Return value: The depth of @path
274  **/
275 gint
276 gtk_tree_path_get_depth (GtkTreePath *path)
277 {
278   g_return_val_if_fail (path != NULL, 0);
279
280   return path->depth;
281 }
282
283 /**
284  * gtk_tree_path_get_indices:
285  * @path: A #GtkTreePath.
286  * 
287  * Returns the current indices of @path.  This is an array of integers, each
288  * representing a node in a tree.
289  * 
290  * Return value: The current indices, or NULL.
291  **/
292 gint *
293 gtk_tree_path_get_indices (GtkTreePath *path)
294 {
295   g_return_val_if_fail (path != NULL, NULL);
296
297   return path->indices;
298 }
299
300 /**
301  * gtk_tree_path_free:
302  * @path: A #GtkTreePath.
303  * 
304  * Frees @path.
305  **/
306 void
307 gtk_tree_path_free (GtkTreePath *path)
308 {
309   g_return_if_fail (path != NULL);
310
311   g_free (path->indices);
312   g_free (path);
313 }
314
315 /**
316  * gtk_tree_path_copy:
317  * @path: A #GtkTreePath.
318  * 
319  * Creates a new #GtkTreePath as a copy of @path.
320  * 
321  * Return value: A new #GtkTreePath.
322  **/
323 GtkTreePath *
324 gtk_tree_path_copy (GtkTreePath *path)
325 {
326   GtkTreePath *retval;
327
328   g_return_val_if_fail (path != NULL, NULL);
329
330   retval = g_new (GtkTreePath, 1);
331   retval->depth = path->depth;
332   retval->indices = g_new (gint, path->depth);
333   memcpy (retval->indices, path->indices, path->depth * sizeof (gint));
334   return retval;
335 }
336
337 /**
338  * gtk_tree_path_compare:
339  * @a: A #GtkTreePath.
340  * @b: A #GtkTreePath to compare with.
341  * 
342  * Compares two paths.  If @a appears before @b in a tree, then 1, is returned.
343  * If @b appears before @a, then -1 is returned.  If the two nodes are equal,
344  * then 0 is returned.
345  * 
346  * Return value: The relative positions of @a and @b
347  **/
348 gint
349 gtk_tree_path_compare (const GtkTreePath *a,
350                        const GtkTreePath *b)
351 {
352   gint p = 0, q = 0;
353
354   g_return_val_if_fail (a != NULL, 0);
355   g_return_val_if_fail (b != NULL, 0);
356   g_return_val_if_fail (a->depth > 0, 0);
357   g_return_val_if_fail (b->depth > 0, 0);
358
359   do
360     {
361       if (a->indices[p] == b->indices[q])
362         continue;
363       return (a->indices[p] < b->indices[q]?1:-1);
364     }
365   while (++p < a->depth && ++q < b->depth);
366   if (a->depth == b->depth)
367     return 0;
368   return (a->depth < b->depth?1:-1);
369 }
370
371 /**
372  * gtk_tree_path_is_ancestor:
373  * @path: a #GtkTreePath
374  * @descendant: another #GtkTreePath
375  * 
376  * 
377  * 
378  * Return value: %TRUE if @descendant is contained inside @path
379  **/
380 gboolean
381 gtk_tree_path_is_ancestor (GtkTreePath *path,
382                            GtkTreePath *descendant)
383 {
384   gint i;
385   
386   g_return_val_if_fail (path != NULL, FALSE);
387   g_return_val_if_fail (descendant != NULL, FALSE);
388
389   /* can't be an ancestor if we're deeper */
390   if (path->depth >= descendant->depth)
391     return FALSE;
392   
393   i = 0;
394   while (i < path->depth)
395     {
396       if (path->indices[i] != descendant->indices[i])
397         return FALSE;
398       ++i;
399     }
400
401   return TRUE;
402 }
403
404 /**
405  * gtk_tree_path_is_descendant:
406  * @path: a #GtkTreePath
407  * @ancestor: another #GtkTreePath
408  * 
409  * 
410  * 
411  * Return value: %TRUE if @ancestor contains @path somewhere below it
412  **/
413 gboolean
414 gtk_tree_path_is_descendant (GtkTreePath *path,
415                              GtkTreePath *ancestor)
416 {
417   gint i;
418   
419   g_return_val_if_fail (path != NULL, FALSE);
420   g_return_val_if_fail (ancestor != NULL, FALSE);
421   
422   /* can't be a descendant if we're shallower in the tree */
423   if (path->depth <= ancestor->depth)
424     return FALSE;
425   
426   i = 0;
427   while (i < ancestor->depth)
428     {
429       if (path->indices[i] != ancestor->indices[i])
430         return FALSE;
431       ++i;
432     }
433
434   return TRUE;
435 }
436
437
438 /**
439  * gtk_tree_path_next:
440  * @path: A #GtkTreePath.
441  * 
442  * Moves the @path to point to the next node at the current depth.
443  **/
444 void
445 gtk_tree_path_next (GtkTreePath *path)
446 {
447   g_return_if_fail (path != NULL);
448   g_return_if_fail (path->depth > 0);
449
450   path->indices[path->depth - 1] ++;
451 }
452
453 /**
454  * gtk_tree_path_prev:
455  * @path: A #GtkTreePath.
456  * 
457  * Moves the @path to point to the previous node at the current depth, if it exists.
458  * 
459  * Return value: TRUE if @path has a previous node, and the move was made.
460  **/
461 gboolean
462 gtk_tree_path_prev (GtkTreePath *path)
463 {
464   g_return_val_if_fail (path != NULL, FALSE);
465
466   if (path->indices[path->depth - 1] == 0)
467     return FALSE;
468
469   path->indices[path->depth - 1] -= 1;
470
471   return TRUE;
472 }
473
474 /**
475  * gtk_tree_path_up:
476  * @path: A #GtkTreePath.
477  * 
478  * Moves the @path to point to it's parent node, if it has a parent.
479  * 
480  * Return value: TRUE if @path has a parent, and the move was made.
481  **/
482 gboolean
483 gtk_tree_path_up (GtkTreePath *path)
484 {
485   g_return_val_if_fail (path != NULL, FALSE);
486
487   if (path->depth == 1)
488     return FALSE;
489
490   path->depth--;
491
492   return TRUE;
493 }
494
495 /**
496  * gtk_tree_path_down:
497  * @path: A #GtkTreePath.
498  * 
499  * Moves @path to point to the first child of the current path.
500  **/
501 void
502 gtk_tree_path_down (GtkTreePath *path)
503 {
504   g_return_if_fail (path != NULL);
505
506   gtk_tree_path_append_index (path, 0);
507 }
508
509 struct _GtkTreeRowReference
510 {
511   GtkTreeModel *model;
512   GtkTreePath *path;
513 };
514
515 typedef struct _RowRefList RowRefList;
516
517 struct _RowRefList
518 {
519   GSList *list;
520 };
521
522 static void
523 release_row_references (gpointer data)
524 {
525   RowRefList *refs = data;
526   GSList *tmp_list = NULL;
527   
528   tmp_list = refs->list;
529   while (tmp_list != NULL)
530     {
531       GtkTreeRowReference *reference = tmp_list->data;
532
533       reference->model = NULL;
534
535       /* we don't free the reference, users are responsible for that. */
536
537       tmp_list = g_slist_next (tmp_list);
538     }
539
540   g_slist_free (refs->list);
541   g_free (refs);
542 }
543
544 static void
545 inserted_callback (GtkTreeModel *tree_model,
546                    GtkTreePath  *path,
547                    GtkTreeIter  *iter,
548                    gpointer      data)
549 {
550   RowRefList *refs = data;
551   GSList *tmp_list;
552
553   /* This function corrects the path stored in the reference to
554    * account for an insertion. Note that it's called _after_ the insertion
555    * with the path to the newly-inserted row. Which means that
556    * the inserted path is in a different "coordinate system" than
557    * the old path (e.g. if the inserted path was just before the old path,
558    * then inserted path and old path will be the same, and old path must be
559    * moved down one).
560    */
561   
562   tmp_list = refs->list;
563
564   while (tmp_list != NULL)
565     {
566       GtkTreeRowReference *reference = tmp_list->data;
567
568       /* if reference->path == NULL then the reference was already
569        * deleted.
570        */
571       
572       if (reference->path)
573         {
574           gint depth = gtk_tree_path_get_depth (path);
575           gint ref_depth = gtk_tree_path_get_depth (reference->path);
576           
577           if (ref_depth >= depth)
578             {
579               gint *indices = gtk_tree_path_get_indices (path);
580               gint *ref_indices = gtk_tree_path_get_indices (reference->path);
581               gint i;
582
583               /* This is the depth that might affect us. */
584               i = depth - 1;
585               
586               if (indices[i] <= ref_indices[i])
587                 ref_indices[i] += 1;
588             }
589         }
590
591       tmp_list = g_slist_next (tmp_list);
592     }
593 }
594
595 static void
596 deleted_callback (GtkTreeModel *tree_model,
597                   GtkTreePath  *path,
598                   gpointer      data)
599 {
600   RowRefList *refs = data;
601   GSList *tmp_list;
602
603   /* This function corrects the path stored in the reference to
604    * account for an deletion. Note that it's called _after_ the
605    * deletion with the old path of the just-deleted row. Which means
606    * that the deleted path is the same now-defunct "coordinate system"
607    * as the path saved in the reference, which is what we want to fix.
608    *
609    * Note that this is different from the situation in "inserted," so
610    * while you might think you can cut-and-paste between these
611    * functions, it's not going to work. ;-)
612    */
613   
614   tmp_list = refs->list;
615
616   while (tmp_list != NULL)
617     {
618       GtkTreeRowReference *reference = tmp_list->data;
619
620       /* if reference->path == NULL then the reference was already
621        * deleted.
622        */
623       
624       if (reference->path)
625         {
626           gint depth = gtk_tree_path_get_depth (path);
627           gint ref_depth = gtk_tree_path_get_depth (reference->path);
628
629           if (ref_depth >= depth)
630             {
631               /* Need to adjust path upward */
632               gint *indices = gtk_tree_path_get_indices (path);
633               gint *ref_indices = gtk_tree_path_get_indices (reference->path);
634               gint i;
635
636               i = depth - 1;
637               if (indices[i] < ref_indices[i])
638                 ref_indices[i] -= 1;
639               else if (indices[i] == ref_indices[i])
640                 {
641                   /* the referenced node itself, or its parent, was
642                    * deleted, mark invalid
643                    */
644
645                   gtk_tree_path_free (reference->path);
646                   reference->path = NULL;
647                 }
648             }
649         }
650
651       tmp_list = g_slist_next (tmp_list);
652     }
653 }
654
655 static void
656 connect_ref_callbacks (GtkTreeModel *model,
657                        RowRefList   *refs)
658 {
659   g_signal_connect_data (G_OBJECT (model),
660                          "inserted",
661                          (GCallback) inserted_callback,
662                          refs,
663                          NULL,
664                          FALSE,
665                          FALSE);
666
667   g_signal_connect_data (G_OBJECT (model),
668                          "deleted",
669                          (GCallback) deleted_callback,
670                          refs,
671                          NULL,
672                          FALSE,
673                          FALSE);
674
675 #if 0
676   /* FIXME */
677   g_signal_connect_data (G_OBJECT (model),
678                          "reordered",
679                          (GCallback) reorderedc_allback,
680                          refs,
681                          NULL,
682                          FALSE,
683                          FALSE);
684 #endif
685 }
686
687 static void
688 disconnect_ref_callbacks (GtkTreeModel *model,
689                           RowRefList   *refs)
690 {
691   g_signal_handlers_disconnect_matched (G_OBJECT (model),
692                                         G_SIGNAL_MATCH_DATA,
693                                         0,
694                                         0,
695                                         NULL,
696                                         NULL,
697                                         refs);
698 }
699
700 GtkTreeRowReference*
701 gtk_tree_row_reference_new (GtkTreeModel *model,
702                             GtkTreePath  *path)
703 {
704   GtkTreeRowReference *reference;
705   RowRefList *refs;
706   
707   reference = g_new (GtkTreeRowReference, 1);
708
709   reference->model = model;
710   reference->path = gtk_tree_path_copy (path);
711
712   refs = g_object_get_data (G_OBJECT (model),
713                             "gtk-tree-row-refs");
714
715   if (refs == NULL)
716     {
717       refs = g_new (RowRefList, 1);
718       refs->list = NULL;
719       connect_ref_callbacks (model, refs);
720       g_object_set_data_full (G_OBJECT (model),
721                               "gtk-tree-row-refs",
722                               refs,
723                               release_row_references);  
724     }
725   
726   refs->list = g_slist_prepend (refs->list, reference);
727   
728   return reference;
729 }
730
731 GtkTreePath*
732 gtk_tree_row_reference_get_path (GtkTreeRowReference *reference)
733 {
734   g_return_val_if_fail (reference != NULL, NULL);
735
736   if (reference->model == NULL)
737     return NULL;
738
739   if (reference->path == NULL)
740     return NULL;
741
742   return gtk_tree_path_copy (reference->path);
743 }
744
745 void
746 gtk_tree_row_reference_free (GtkTreeRowReference *reference)
747 {
748   RowRefList *refs;
749
750   g_return_if_fail (reference != NULL);
751   
752   if (reference->model)
753     {
754       refs = g_object_get_data (G_OBJECT (reference->model),
755                                 "gtk-tree-row-refs");
756
757       if (refs == NULL)
758         {
759           g_warning (G_STRLOC": bad row reference, model has no outstanding row references");
760           return;
761         }
762           
763       refs->list = g_slist_remove (refs->list, reference);
764
765       if (refs->list == NULL)
766         {
767           disconnect_ref_callbacks (reference->model, refs);
768           g_object_set_data (G_OBJECT (reference->model),
769                              "gtk-tree-row-refs",
770                              NULL);
771         }
772     }
773   
774   if (reference->path)
775     gtk_tree_path_free (reference->path);
776
777   g_free (reference);
778 }
779
780 /**
781  * gtk_tree_iter_copy:
782  * @iter: A #GtkTreeIter.
783  * 
784  * Creates a dynamically allocated tree iterator as a copy of @iter.  This
785  * function is not intended for use in applications, because you can just copy
786  * the structs by value (GtkTreeIter new_iter = iter;).  You
787  * must free this iter with gtk_tree_iter_free ().
788  * 
789  * Return value: a newly allocated copy of @iter.
790  **/
791 GtkTreeIter *
792 gtk_tree_iter_copy (GtkTreeIter *iter)
793 {
794   GtkTreeIter *retval;
795
796   g_return_val_if_fail (iter != NULL, NULL);
797
798   retval = g_new (GtkTreeIter, 1);
799   *retval = *iter;
800
801   return retval;
802 }
803
804 /**
805  * gtk_tree_iter_free:
806  * @iter: A dynamically allocated tree iterator.
807  * 
808  * Free an iterator that has been allocated on the heap.  This function is
809  * mainly used for language bindings.
810  **/
811 void
812 gtk_tree_iter_free (GtkTreeIter *iter)
813 {
814   g_return_if_fail (iter != NULL);
815
816   g_free (iter);
817 }
818
819 /**
820  * gtk_tree_model_get_flags:
821  * @tree_model: A #GtkTreeModel.
822  * 
823  * Returns a set of flags supported by this interface.  The flags are a bitwise
824  * combination of #GtkTreeModelFlags.  It is expected that the flags supported
825  * do not change for an interface.
826  * 
827  * Return value: The flags supported by this interface.
828  **/
829 GtkTreeModelFlags
830 gtk_tree_model_get_flags (GtkTreeModel *tree_model)
831 {
832   g_return_val_if_fail (tree_model != NULL, 0);
833   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
834
835   if (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags)
836     return (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags) (tree_model);
837
838   return 0;
839 }
840
841 /**
842  * gtk_tree_model_get_n_columns:
843  * @tree_model: A #GtkTreeModel.
844  * 
845  * Returns the number of columns supported by the #tree_model
846  * 
847  * Return value: The number of columns.
848  **/
849 gint
850 gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
851 {
852   g_return_val_if_fail (tree_model != NULL, 0);
853   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
854   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_n_columns != NULL, 0);
855
856   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_n_columns) (tree_model);
857 }
858
859 /**
860  * gtk_tree_model_get_column_type:
861  * @tree_model: A #GtkTreeModel.
862  * @index: The column index.
863  * 
864  * Returns the type of the column.
865  * 
866  * Return value: The type of the column.
867  **/
868 GType
869 gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
870                                 gint          index)
871 {
872   g_return_val_if_fail (tree_model != NULL, G_TYPE_INVALID);
873   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
874   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type != NULL, G_TYPE_INVALID);
875   g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
876
877   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type) (tree_model, index);
878 }
879
880 /**
881  * gtk_tree_model_get_iter:
882  * @tree_model: A #GtkTreeModel.
883  * @iter: The uninitialized #GtkTreeIter.
884  * @path: The #GtkTreePath.
885  * 
886  * Sets @iter to a valid iterator pointing to @path.  If the model does not
887  * provide an implementation of this function, it is implemented in terms of
888  * @gtk_tree_model_iter_nth_child.
889  * 
890  * Return value: TRUE, if @iter was set.
891  **/
892 gboolean
893 gtk_tree_model_get_iter (GtkTreeModel *tree_model,
894                          GtkTreeIter  *iter,
895                          GtkTreePath  *path)
896 {
897   GtkTreeIter parent;
898   gint *indices;
899   gint depth, i;
900
901   g_return_val_if_fail (tree_model != NULL, FALSE);
902   g_return_val_if_fail (iter != NULL, FALSE);
903   g_return_val_if_fail (path != NULL, FALSE);
904   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
905
906   if (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_iter != NULL)
907     return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_iter) (tree_model, iter, path);
908
909   indices = gtk_tree_path_get_indices (path);
910   depth = gtk_tree_path_get_depth (path);
911
912   g_return_val_if_fail (depth > 0, FALSE);
913
914   if (! gtk_tree_model_iter_nth_child (tree_model, iter, NULL, indices[0]))
915     return FALSE;
916
917   for (i = 1; i < depth; i++)
918     {
919       parent = *iter;
920       if (! gtk_tree_model_iter_nth_child (tree_model, iter, &parent, indices[i]))
921         return FALSE;
922     }
923
924   return TRUE;
925 }
926
927 /**
928  * gtk_tree_model_get_first:
929  * @tree_model: a #GtkTreeModel
930  * @iter: iterator to initialize
931  * 
932  * Initialized @iter with the first iterator in the tree (the one at the
933  * root path) and returns %TRUE, or returns %FALSE if there are no
934  * iterable locations in the model (i.e. the tree is empty).
935  * 
936  * Return value: %TRUE if @iter was initialized
937  **/
938 gboolean
939 gtk_tree_model_get_first (GtkTreeModel *tree_model,
940                           GtkTreeIter  *iter)
941 {
942   gboolean retval;
943   GtkTreePath *path;
944   
945   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
946   g_return_val_if_fail (iter != NULL, FALSE);
947
948   path = gtk_tree_path_new_root ();
949
950   retval = gtk_tree_model_get_iter (tree_model, iter, path);
951
952   gtk_tree_path_free (path);
953
954   return retval;
955 }
956
957 /**
958  * gtk_tree_model_get_path:
959  * @tree_model: A #GtkTreeModel.
960  * @iter: The #GtkTreeIter.
961  * 
962  * Returns a newly created #GtkTreePath referenced by @iter.  This path should
963  * be freed with #gtk_tree_path_free.
964  * 
965  * Return value: a newly created #GtkTreePath.
966  **/
967 GtkTreePath *
968 gtk_tree_model_get_path (GtkTreeModel *tree_model,
969                          GtkTreeIter  *iter)
970 {
971   g_return_val_if_fail (tree_model != NULL, NULL);
972   g_return_val_if_fail (iter != NULL, NULL);
973   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), NULL);
974   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_path != NULL, NULL);
975
976   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_path) (tree_model, iter);
977 }
978
979 /**
980  * gtk_tree_model_get_value:
981  * @tree_model: A #GtkTreeModel.
982  * @iter: The #GtkTreeIter.
983  * @column: The column to lookup the value at.
984  * @value: An empty #GValue to set.
985  * 
986  * Sets initializes and sets @value to that at @column.  When done with value,
987  * #g_value_unset needs to be called on it.
988  **/
989 void
990 gtk_tree_model_get_value (GtkTreeModel *tree_model,
991                           GtkTreeIter  *iter,
992                           gint          column,
993                           GValue       *value)
994 {
995   g_return_if_fail (tree_model != NULL);
996   g_return_if_fail (iter != NULL);
997   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
998   g_return_if_fail (value != NULL);
999   g_return_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_value != NULL);
1000
1001   (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_value) (tree_model, iter, column, value);
1002 }
1003
1004 /**
1005  * gtk_tree_model_iter_next:
1006  * @tree_model: A #GtkTreeModel.
1007  * @iter: The #GtkTreeIter.
1008  * 
1009  * Sets @iter to point to the node following it at the current level.  If there
1010  * is no next @iter, FALSE is returned and @iter is set to be invalid.
1011  * 
1012  * Return value: TRUE if @iter has been changed to the next node.
1013  **/
1014 gboolean
1015 gtk_tree_model_iter_next (GtkTreeModel  *tree_model,
1016                           GtkTreeIter   *iter)
1017 {
1018   g_return_val_if_fail (tree_model != NULL, FALSE);
1019   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1020   g_return_val_if_fail (iter != NULL, FALSE);
1021   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_next != NULL, FALSE);
1022
1023   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_next) (tree_model, iter);
1024 }
1025
1026 /**
1027  * gtk_tree_model_iter_children:
1028  * @tree_model: A #GtkTreeModel.
1029  * @iter: The new #GtkTreeIter to be set to the child.
1030  * @parent: The #GtkTreeIter.
1031  * 
1032  * Sets @iter to point to the first child of @parent.  If @parent has no children,
1033  * FALSE is returned and @iter is set to be invalid.  @parent will remain a valid
1034  * node after this function has been called.
1035  * 
1036  * Return value: TRUE, if @child has been set to the first child.
1037  **/
1038 gboolean
1039 gtk_tree_model_iter_children (GtkTreeModel *tree_model,
1040                               GtkTreeIter  *iter,
1041                               GtkTreeIter  *parent)
1042 {
1043   g_return_val_if_fail (tree_model != NULL, FALSE);
1044   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1045   g_return_val_if_fail (iter != NULL, FALSE);
1046   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_children != NULL, FALSE);
1047
1048   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_children) (tree_model, iter, parent);
1049 }
1050
1051 /**
1052  * gtk_tree_model_iter_has_child:
1053  * @tree_model: A #GtkTreeModel.
1054  * @iter: The #GtkTreeIter to test for children.
1055  * 
1056  * Returns TRUE if @iter has children, FALSE otherwise.
1057  * 
1058  * Return value: TRUE if @iter has children.
1059  **/
1060 gboolean
1061 gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
1062                                GtkTreeIter  *iter)
1063 {
1064   g_return_val_if_fail (tree_model != NULL, FALSE);
1065   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1066   g_return_val_if_fail (iter != NULL, FALSE);
1067   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_has_child != NULL, FALSE);
1068
1069   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_has_child) (tree_model, iter);
1070 }
1071
1072 /**
1073  * gtk_tree_model_iter_n_children:
1074  * @tree_model: A #GtkTreeModel.
1075  * @iter: The #GtkTreeIter, or NULL.
1076  * 
1077  * Returns the number of children that @iter has.  If @iter is NULL, then the
1078  * number of toplevel nodes is returned.
1079  * 
1080  * Return value: The number of children of @iter.
1081  **/
1082 gint
1083 gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
1084                                 GtkTreeIter  *iter)
1085 {
1086   g_return_val_if_fail (tree_model != NULL, 0);
1087   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
1088   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children != NULL, 0);
1089
1090   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children) (tree_model, iter);
1091 }
1092
1093 /**
1094  * gtk_tree_model_iter_nth_child:
1095  * @tree_model: A #GtkTreeModel.
1096  * @iter: The #GtkTreeIter to set to the nth child.
1097  * @parent: The #GtkTreeIter to get the child from, or NULL.
1098  * @n: Then index of the desired child.
1099  * 
1100  * Sets @iter to be the child of @parent, using the given index.  The first
1101  * index is 0.  If the index is too big, or @parent has no children, @iter is
1102  * set to an invalid iterator and FALSE is returned.  @parent will remain a
1103  * valid node after this function has been called.  If @parent is NULL, then the
1104  * root node is assumed.
1105  * 
1106  * Return value: TRUE, if @parent has an nth child.
1107  **/
1108 gboolean
1109 gtk_tree_model_iter_nth_child (GtkTreeModel *tree_model,
1110                                GtkTreeIter  *iter,
1111                                GtkTreeIter  *parent,
1112                                gint          n)
1113 {
1114   g_return_val_if_fail (tree_model != NULL, FALSE);
1115   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1116   g_return_val_if_fail (iter != NULL, FALSE);
1117   g_return_val_if_fail (n >= 0, FALSE);
1118   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_nth_child != NULL, FALSE);
1119
1120   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_nth_child) (tree_model, iter, parent, n);
1121 }
1122
1123 /**
1124  * gtk_tree_model_iter_parent:
1125  * @tree_model: A #GtkTreeModel
1126  * @iter: The new #GtkTreeIter to set to the parent.
1127  * @child: The #GtkTreeIter.
1128  * 
1129  * Sets @iter to be the parent of @child.  If @child is at the toplevel, and
1130  * doesn't have a parent, then @iter is set to an invalid iterator and FALSE
1131  * is returned.  @child will remain a valid node after this function has been
1132  * called.
1133  * 
1134  * Return value: TRUE, if @iter is set to the parent of @child.
1135  **/
1136 gboolean
1137 gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
1138                             GtkTreeIter  *iter,
1139                             GtkTreeIter  *child)
1140 {
1141   g_return_val_if_fail (tree_model != NULL, FALSE);
1142   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
1143   g_return_val_if_fail (iter != NULL, FALSE);
1144   g_return_val_if_fail (child != NULL, FALSE);
1145   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent != NULL, FALSE);
1146
1147   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent) (tree_model, iter, child);
1148 }
1149
1150 /* FIXME explain what the method is supposed to do! */
1151 /**
1152  * gtk_tree_model_ref_iter:
1153  * @tree_model: A #GtkTreeModel.
1154  * @iter: The #GtkTreeIter.
1155  * 
1156  * Ref's the iter.  This is an optional method for models to implement.  To be
1157  * more specific, models may ignore this call as it exists primarily for
1158  * performance reasons.
1159  **/
1160 void
1161 gtk_tree_model_ref_iter (GtkTreeModel *tree_model,
1162                          GtkTreeIter  *iter)
1163 {
1164   g_return_if_fail (tree_model != NULL);
1165   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1166
1167   if (GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_iter)
1168     (* GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_iter) (tree_model, iter);
1169 }
1170
1171 /* FIXME explain what the method is supposed to do! */
1172 /**
1173  * gtk_tree_model_unref_iter:
1174  * @tree_model: A #GtkTreeModel.
1175  * @iter: The #GtkTreeIter.
1176  * 
1177  * Unref's the iter.  This is an optional method for models to implement.  To be
1178  * more specific, models may ignore this call as it exists primarily for
1179  * performance reasons.
1180  **/
1181 void
1182 gtk_tree_model_unref_iter (GtkTreeModel *tree_model,
1183                            GtkTreeIter  *iter)
1184 {
1185   g_return_if_fail (tree_model != NULL);
1186   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1187
1188   if (GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_iter)
1189     (* GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_iter) (tree_model, iter);
1190 }
1191
1192 /**
1193  * gtk_tree_model_get:
1194  * @tree_model: a #GtkTreeModel
1195  * @iter: a row in @tree_model
1196  * @Varargs: pairs of column number and value return locations, terminated by -1
1197  *
1198  * Gets the value of one or more cells in the row referenced by @iter.
1199  * The variable argument list should contain integer column numbers,
1200  * each column number followed by a place to store the value being
1201  * retrieved.  The list is terminated by a -1. For example, to get a
1202  * value from column 0 with type %G_TYPE_STRING, you would
1203  * write: gtk_tree_model_set (model, iter, 0, &place_string_here, -1),
1204  * where place_string_here is a gchar* to be filled with the string.
1205  * If appropriate, the returned values have to be freed or unreferenced.
1206  * 
1207  **/
1208 void
1209 gtk_tree_model_get (GtkTreeModel *tree_model,
1210                     GtkTreeIter  *iter,
1211                     ...)
1212 {
1213   va_list var_args;
1214
1215   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1216
1217   va_start (var_args, iter);
1218   gtk_tree_model_get_valist (tree_model, iter, var_args);
1219   va_end (var_args);
1220 }
1221
1222 /**
1223  * gtk_tree_model_get_valist:
1224  * @tree_model: a #GtkTreeModel
1225  * @iter: a row in @tree_model
1226  * @var_args: va_list of column/return location pairs
1227  *
1228  * See gtk_tree_model_get(), this version takes a va_list for
1229  * language bindings to use.
1230  * 
1231  **/
1232 void
1233 gtk_tree_model_get_valist (GtkTreeModel *tree_model,
1234                            GtkTreeIter  *iter,
1235                            va_list      var_args)
1236 {
1237   gint column;
1238
1239   g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
1240
1241   column = va_arg (var_args, gint);
1242
1243   while (column != -1)
1244     {
1245       GValue value = { 0, };
1246       gchar *error = NULL;
1247
1248       if (column >= gtk_tree_model_get_n_columns (tree_model))
1249         {
1250           g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC, column);
1251           break;
1252         }
1253
1254       gtk_tree_model_get_value (GTK_TREE_MODEL (tree_model), iter, column, &value);
1255
1256       G_VALUE_LCOPY (&value, var_args, 0, &error);
1257       if (error)
1258         {
1259           g_warning ("%s: %s", G_STRLOC, error);
1260           g_free (error);
1261
1262           /* we purposely leak the value here, it might not be
1263            * in a sane state if an error condition occoured
1264            */
1265           break;
1266         }
1267
1268       g_value_unset (&value);
1269
1270       column = va_arg (var_args, gint);
1271     }
1272 }