]> Pileus Git - ~andy/gtk/blob - gtk/gtktreestore.c
Add "getters" for all the non-deprecated set_foo functions. Added missing
[~andy/gtk] / gtk / gtktreestore.c
1 /* gtktreestore.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 "gtktreemodel.h"
21 #include "gtktreestore.h"
22 #include "gtktreedatalist.h"
23 #include "gtksignal.h"
24 #include <string.h>
25 #include <gobject/gvaluecollector.h>
26
27 #define G_NODE(node) ((GNode *)node)
28
29 enum {
30   CHANGED,
31   INSERTED,
32   CHILD_TOGGLED,
33   DELETED,
34   LAST_SIGNAL
35 };
36
37 static guint tree_store_signals[LAST_SIGNAL] = { 0 };
38
39
40 static void         gtk_tree_store_init            (GtkTreeStore      *tree_store);
41 static void         gtk_tree_store_class_init      (GtkTreeStoreClass *tree_store_class);
42 static void         gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
43 static guint        gtk_tree_store_get_flags       (GtkTreeModel      *tree_model);
44 static gint         gtk_tree_store_get_n_columns   (GtkTreeModel      *tree_model);
45 static GType        gtk_tree_store_get_column_type (GtkTreeModel      *tree_model,
46                                                     gint               index);
47 static GtkTreePath *gtk_tree_store_get_path        (GtkTreeModel      *tree_model,
48                                                     GtkTreeIter       *iter);
49 static void         gtk_tree_store_get_value       (GtkTreeModel      *tree_model,
50                                                     GtkTreeIter       *iter,
51                                                     gint               column,
52                                                     GValue            *value);
53 static gboolean     gtk_tree_store_iter_next       (GtkTreeModel      *tree_model,
54                                                     GtkTreeIter       *iter);
55 static gboolean     gtk_tree_store_iter_children   (GtkTreeModel      *tree_model,
56                                                     GtkTreeIter       *iter,
57                                                     GtkTreeIter       *parent);
58 static gboolean     gtk_tree_store_iter_has_child  (GtkTreeModel      *tree_model,
59                                                     GtkTreeIter       *iter);
60 static gint         gtk_tree_store_iter_n_children (GtkTreeModel      *tree_model,
61                                                     GtkTreeIter       *iter);
62 static gboolean     gtk_tree_store_iter_nth_child  (GtkTreeModel      *tree_model,
63                                                     GtkTreeIter       *iter,
64                                                     GtkTreeIter       *parent,
65                                                     gint               n);
66 static gboolean     gtk_tree_store_iter_parent     (GtkTreeModel      *tree_model,
67                                                     GtkTreeIter       *iter,
68                                                     GtkTreeIter       *child);
69
70
71 GtkType
72 gtk_tree_store_get_type (void)
73 {
74   static GtkType tree_store_type = 0;
75
76   if (!tree_store_type)
77     {
78       static const GTypeInfo tree_store_info =
79       {
80         sizeof (GtkTreeStoreClass),
81         NULL,           /* base_init */
82         NULL,           /* base_finalize */
83         (GClassInitFunc) gtk_tree_store_class_init,
84         NULL,           /* class_finalize */
85         NULL,           /* class_data */
86         sizeof (GtkTreeStore),
87         0,              /* n_preallocs */
88         (GInstanceInitFunc) gtk_tree_store_init
89       };
90
91       static const GInterfaceInfo tree_model_info =
92       {
93         (GInterfaceInitFunc) gtk_tree_store_tree_model_init,
94         NULL,
95         NULL
96       };
97
98       tree_store_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeStore", &tree_store_info, 0);
99       g_type_add_interface_static (tree_store_type,
100                                    GTK_TYPE_TREE_MODEL,
101                                    &tree_model_info);
102     }
103
104   return tree_store_type;
105 }
106
107 static void
108 gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class)
109 {
110   GtkObjectClass *object_class;
111
112   object_class = (GtkObjectClass *) tree_store_class;
113
114   tree_store_signals[CHANGED] =
115     gtk_signal_new ("changed",
116                     GTK_RUN_FIRST,
117                     GTK_CLASS_TYPE (object_class),
118                     GTK_SIGNAL_OFFSET (GtkTreeStoreClass, changed),
119                     gtk_marshal_VOID__BOXED_BOXED,
120                     G_TYPE_NONE, 2,
121                     GTK_TYPE_TREE_PATH,
122                     GTK_TYPE_TREE_ITER);
123   tree_store_signals[INSERTED] =
124     gtk_signal_new ("inserted",
125                     GTK_RUN_FIRST,
126                     GTK_CLASS_TYPE (object_class),
127                     GTK_SIGNAL_OFFSET (GtkTreeStoreClass, inserted),
128                     gtk_marshal_VOID__BOXED_BOXED,
129                     G_TYPE_NONE, 2,
130                     GTK_TYPE_TREE_PATH,
131                     GTK_TYPE_TREE_ITER);
132   tree_store_signals[CHILD_TOGGLED] =
133     gtk_signal_new ("child_toggled",
134                     GTK_RUN_FIRST,
135                     GTK_CLASS_TYPE (object_class),
136                     GTK_SIGNAL_OFFSET (GtkTreeStoreClass, child_toggled),
137                     gtk_marshal_VOID__BOXED_BOXED,
138                     G_TYPE_NONE, 2,
139                     GTK_TYPE_TREE_PATH,
140                     GTK_TYPE_TREE_ITER);
141   tree_store_signals[DELETED] =
142     gtk_signal_new ("deleted",
143                     GTK_RUN_FIRST,
144                     GTK_CLASS_TYPE (object_class),
145                     GTK_SIGNAL_OFFSET (GtkTreeStoreClass, deleted),
146                     gtk_marshal_VOID__BOXED,
147                     G_TYPE_NONE, 1,
148                     GTK_TYPE_TREE_PATH);
149 }
150
151 static void
152 gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
153 {
154   iface->get_flags = gtk_tree_store_get_flags;
155   iface->get_n_columns = gtk_tree_store_get_n_columns;
156   iface->get_column_type = gtk_tree_store_get_column_type;
157   iface->get_path = gtk_tree_store_get_path;
158   iface->get_value = gtk_tree_store_get_value;
159   iface->iter_next = gtk_tree_store_iter_next;
160   iface->iter_children = gtk_tree_store_iter_children;
161   iface->iter_has_child = gtk_tree_store_iter_has_child;
162   iface->iter_n_children = gtk_tree_store_iter_n_children;
163   iface->iter_nth_child = gtk_tree_store_iter_nth_child;
164   iface->iter_parent = gtk_tree_store_iter_parent;
165 }
166
167 static void
168 gtk_tree_store_init (GtkTreeStore *tree_store)
169 {
170   tree_store->root = g_node_new (NULL);
171   tree_store->stamp = g_random_int ();
172 }
173
174 GtkTreeStore *
175 gtk_tree_store_new (void)
176 {
177   return GTK_TREE_STORE (gtk_type_new (gtk_tree_store_get_type ()));
178 }
179
180 GtkTreeStore *
181 gtk_tree_store_new_with_types (gint n_columns,
182                                ...)
183 {
184   GtkTreeStore *retval;
185   va_list args;
186   gint i;
187
188   g_return_val_if_fail (n_columns > 0, NULL);
189
190   retval = gtk_tree_store_new ();
191   gtk_tree_store_set_n_columns (retval, n_columns);
192
193   va_start (args, n_columns);
194
195   for (i = 0; i < n_columns; i++)
196     gtk_tree_store_set_column_type (retval, i, va_arg (args, GType));
197
198   va_end (args);
199
200   return retval;
201 }
202
203 void
204 gtk_tree_store_set_n_columns (GtkTreeStore *tree_store,
205                               gint          n_columns)
206 {
207   GType *new_columns;
208
209   g_return_if_fail (tree_store != NULL);
210   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
211
212   if (tree_store->n_columns == n_columns)
213     return;
214
215   new_columns = g_new0 (GType, n_columns);
216   if (tree_store->column_headers)
217     {
218       /* copy the old header orders over */
219       if (n_columns >= tree_store->n_columns)
220         memcpy (new_columns, tree_store->column_headers, tree_store->n_columns * sizeof (gchar *));
221       else
222         memcpy (new_columns, tree_store->column_headers, n_columns * sizeof (GType));
223
224       g_free (tree_store->column_headers);
225     }
226
227   tree_store->column_headers = new_columns;
228   tree_store->n_columns = n_columns;
229 }
230
231 void
232 gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
233                                 gint          column,
234                                 GType         type)
235 {
236   g_return_if_fail (tree_store != NULL);
237   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
238   g_return_if_fail (column >=0 && column < tree_store->n_columns);
239
240   tree_store->column_headers[column] = type;
241 }
242
243 /* fulfill the GtkTreeModel requirements */
244 /* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node.  However,
245  * it is not visible to the tree or to the user., and the path "1" refers to the
246  * first child of GtkTreeStore::root.
247  */
248
249
250 static guint
251 gtk_tree_store_get_flags (GtkTreeModel *tree_model)
252 {
253   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
254
255   return GTK_TREE_MODEL_ITERS_PERSIST;
256 }
257
258 static gint
259 gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
260 {
261   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
262
263   return GTK_TREE_STORE (tree_model)->n_columns;
264 }
265
266 static GType
267 gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
268                                 gint          index)
269 {
270   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), G_TYPE_INVALID);
271   g_return_val_if_fail (index < GTK_TREE_STORE (tree_model)->n_columns &&
272                         index >= 0, G_TYPE_INVALID);
273
274   return GTK_TREE_STORE (tree_model)->column_headers[index];
275 }
276
277 static GtkTreePath *
278 gtk_tree_store_get_path (GtkTreeModel *tree_model,
279                          GtkTreeIter  *iter)
280 {
281   GtkTreePath *retval;
282   GNode *tmp_node;
283   gint i = 0;
284
285   g_return_val_if_fail (tree_model != NULL, NULL);
286   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL);
287   g_return_val_if_fail (iter != NULL, NULL);
288
289   if (iter->user_data == NULL)
290     return NULL;
291
292   g_assert (G_NODE (iter->user_data)->parent != NULL);
293   
294   if (G_NODE (iter->user_data)->parent == G_NODE (GTK_TREE_STORE (tree_model)->root))
295     {
296       retval = gtk_tree_path_new ();
297       tmp_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
298     }
299   else
300     {
301       GtkTreeIter tmp_iter = *iter;
302       tmp_iter.user_data = G_NODE (tmp_iter.user_data)->parent;
303
304       retval = gtk_tree_store_get_path (tree_model,
305                                         &tmp_iter);
306       tmp_node = G_NODE (iter->user_data)->parent->children;
307     }
308
309   if (retval == NULL)
310     return NULL;
311
312   if (tmp_node == NULL)
313     {
314       gtk_tree_path_free (retval);
315       return NULL;
316     }
317
318   for (; tmp_node; tmp_node = tmp_node->next)
319     {
320       if (tmp_node == G_NODE (iter->user_data))
321         break;
322       i++;
323     }
324
325   if (tmp_node == NULL)
326     {
327       /* We couldn't find node, meaning it's prolly not ours */
328       /* Perhaps I should do a g_return_if_fail here. */
329       gtk_tree_path_free (retval);
330       return NULL;
331     }
332
333   gtk_tree_path_append_index (retval, i);
334
335   return retval;
336 }
337
338
339 static void
340 gtk_tree_store_get_value (GtkTreeModel *tree_model,
341                           GtkTreeIter  *iter,
342                           gint          column,
343                           GValue       *value)
344 {
345   GtkTreeDataList *list;
346   gint tmp_column = column;
347
348   g_return_if_fail (tree_model != NULL);
349   g_return_if_fail (GTK_IS_TREE_STORE (tree_model));
350   g_return_if_fail (iter != NULL);
351   g_return_if_fail (column < GTK_TREE_STORE (tree_model)->n_columns);
352
353   list = G_NODE (iter->user_data)->data;
354
355   while (tmp_column-- > 0 && list)
356     list = list->next;
357
358   if (list)
359     {
360       _gtk_tree_data_list_node_to_value (list,
361                                          GTK_TREE_STORE (tree_model)->column_headers[column],
362                                          value);
363     }
364   else
365     {
366       /* We want to return an initialized but empty (default) value */
367       g_value_init (value, GTK_TREE_STORE (tree_model)->column_headers[column]);
368     }
369 }
370
371 static gboolean
372 gtk_tree_store_iter_next (GtkTreeModel  *tree_model,
373                           GtkTreeIter   *iter)
374 {
375   if (iter->user_data == NULL)
376     return FALSE;
377
378   iter->user_data = G_NODE (iter->user_data)->next;
379
380   return (iter->user_data != NULL);
381 }
382
383 static gboolean
384 gtk_tree_store_iter_children (GtkTreeModel *tree_model,
385                               GtkTreeIter  *iter,
386                               GtkTreeIter  *parent)
387 {
388   iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
389   if (parent)
390     iter->user_data = G_NODE (parent->user_data)->children;
391   else
392     iter->user_data = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
393
394   return iter->user_data != NULL;
395 }
396
397 static gboolean
398 gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
399                                GtkTreeIter  *iter)
400 {
401   g_return_val_if_fail (tree_model != NULL, FALSE);
402   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
403   g_return_val_if_fail (iter != NULL, FALSE);
404
405   return G_NODE (iter->user_data)->children != NULL;
406 }
407
408 static gint
409 gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
410                                 GtkTreeIter  *iter)
411 {
412   GNode *node;
413   gint i = 0;
414
415   g_return_val_if_fail (tree_model != NULL, 0);
416   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
417
418   if (iter == NULL)
419     node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
420   else
421     node = G_NODE (iter->user_data)->children;
422   while (node)
423     {
424       i++;
425       node = node->next;
426     }
427
428   return i;
429 }
430
431 static gboolean
432 gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
433                                GtkTreeIter  *iter,
434                                GtkTreeIter  *parent,
435                                gint          n)
436 {
437   GNode *parent_node;
438
439   g_return_val_if_fail (tree_model != NULL, FALSE);
440   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
441   g_return_val_if_fail (iter != NULL, FALSE);
442
443   if (parent == NULL)
444     parent_node = GTK_TREE_STORE (tree_model)->root;
445   else
446     parent_node = parent->user_data;
447
448   iter->user_data = g_node_nth_child (parent_node, n);
449
450   if (iter->user_data == NULL)
451     iter->stamp = 0;
452   else
453     iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
454
455   return (iter->user_data != NULL);
456 }
457
458 static gboolean
459 gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
460                             GtkTreeIter  *iter,
461                             GtkTreeIter  *child)
462 {
463   g_assert (G_NODE (child->user_data)->parent != NULL);
464   
465   iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
466   iter->user_data = G_NODE (child->user_data)->parent;
467
468   if (iter->user_data == GTK_TREE_STORE (tree_model)->root)
469     {
470       iter->stamp = 0;
471       iter->user_data = NULL;
472       return FALSE;
473     }
474
475   return TRUE;
476 }
477
478 /*
479  * This is a somewhat inelegant function that does a lot of list
480  * manipulations on it's own.
481  */
482 void
483 gtk_tree_store_set_cell (GtkTreeStore *tree_store,
484                          GtkTreeIter  *iter,
485                          gint          column,
486                          GValue       *value)
487 {
488   GtkTreeDataList *list;
489   GtkTreeDataList *prev;
490
491   g_return_if_fail (tree_store != NULL);
492   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
493   g_return_if_fail (column >= 0 && column < tree_store->n_columns);
494
495   prev = list = G_NODE (iter->user_data)->data;
496
497   while (list != NULL)
498     {
499       if (column == 0)
500         {
501           _gtk_tree_data_list_value_to_node (list, value);
502           gtk_signal_emit_by_name (GTK_OBJECT (tree_store),
503                                    "changed",
504                                    NULL, iter);
505           return;
506         }
507
508       column--;
509       prev = list;
510       list = list->next;
511     }
512
513   if (G_NODE (iter->user_data)->data == NULL)
514     {
515       G_NODE (iter->user_data)->data = list = _gtk_tree_data_list_alloc ();
516       list->next = NULL;
517     }
518   else
519     {
520       list = prev->next = _gtk_tree_data_list_alloc ();
521       list->next = NULL;
522     }
523
524   while (column != 0)
525     {
526       list->next = _gtk_tree_data_list_alloc ();
527       list = list->next;
528       list->next = NULL;
529       column --;
530     }
531   _gtk_tree_data_list_value_to_node (list, value);
532   gtk_signal_emit_by_name (GTK_OBJECT (tree_store),
533                            "changed",
534                            NULL, iter);
535 }
536
537 void
538 gtk_tree_store_set_valist (GtkTreeStore *tree_store,
539                            GtkTreeIter  *iter,
540                            va_list      var_args)
541 {
542   gint column;
543
544   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
545
546   column = va_arg (var_args, gint);
547
548   while (column != -1)
549     {
550       GValue value = { 0, };
551       gchar *error = NULL;
552
553       if (column >= tree_store->n_columns)
554         {
555           g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
556           break;
557         }
558       g_value_init (&value, tree_store->column_headers[column]);
559
560       G_VALUE_COLLECT (&value, var_args, &error);
561       if (error)
562         {
563           g_warning ("%s: %s", G_STRLOC, error);
564           g_free (error);
565
566           /* we purposely leak the value here, it might not be
567            * in a sane state if an error condition occoured
568            */
569           break;
570         }
571
572       gtk_tree_store_set_cell (tree_store,
573                                iter,
574                                column,
575                                &value);
576
577       g_value_unset (&value);
578
579       column = va_arg (var_args, gint);
580     }
581 }
582
583 /**
584  * gtk_tree_store_set:
585  * @tree_store: a #GtkTreeStore
586  * @iter: row iterator
587  * @Varargs: pairs of column number and value, terminated with -1
588  * 
589  * Sets the value of one or more cells in the row referenced by @iter.
590  * The variable argument list should contain integer column numbers,
591  * each column number followed by the value to be set. For example,
592  * The list is terminated by a -1. For example, to set column 0 with type
593  * %G_TYPE_STRING to "Foo", you would write gtk_tree_store_set (store, iter,
594  * 0, "Foo", -1).
595  **/
596 void
597 gtk_tree_store_set (GtkTreeStore *tree_store,
598                     GtkTreeIter  *iter,
599                     ...)
600 {
601   va_list var_args;
602
603   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
604
605   va_start (var_args, iter);
606   gtk_tree_store_set_valist (tree_store, iter, var_args);
607   va_end (var_args);
608 }
609
610 void
611 gtk_tree_store_get_valist (GtkTreeStore *tree_store,
612                            GtkTreeIter  *iter,
613                            va_list      var_args)
614 {
615   gint column;
616
617   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
618
619   column = va_arg (var_args, gint);
620
621   while (column != -1)
622     {
623       GValue value = { 0, };
624       gchar *error = NULL;
625
626       if (column >= tree_store->n_columns)
627         {
628           g_warning ("%s: Invalid column number %d accessed (remember to end your list of columns with a -1)", G_STRLOC, column);
629           break;
630         }
631
632       gtk_tree_store_get_value (GTK_TREE_MODEL (tree_store), iter, column, &value);
633
634       G_VALUE_LCOPY (&value, var_args, &error);
635       if (error)
636         {
637           g_warning ("%s: %s", G_STRLOC, error);
638           g_free (error);
639
640           /* we purposely leak the value here, it might not be
641            * in a sane state if an error condition occoured
642            */
643           break;
644         }
645
646       g_value_unset (&value);
647
648       column = va_arg (var_args, gint);
649     }
650 }
651
652 void
653 gtk_tree_store_get (GtkTreeStore *tree_store,
654                     GtkTreeIter  *iter,
655                     ...)
656 {
657   va_list var_args;
658
659   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
660
661   va_start (var_args, iter);
662   gtk_tree_store_get_valist (tree_store, iter, var_args);
663   va_end (var_args);
664 }
665
666 void
667 gtk_tree_store_remove (GtkTreeStore *model,
668                        GtkTreeIter  *iter)
669 {
670   GtkTreePath *path;
671
672   GNode *parent;
673
674   g_return_if_fail (model != NULL);
675   g_return_if_fail (GTK_IS_TREE_STORE (model));
676
677   parent = G_NODE (iter->user_data)->parent;
678
679   g_assert (parent != NULL);
680   
681   if (G_NODE (iter->user_data)->data)
682     _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data,
683                               model->column_headers);
684
685   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
686   g_node_destroy (G_NODE (iter->user_data));
687
688   model->stamp++;
689   gtk_signal_emit_by_name (GTK_OBJECT (model),
690                            "deleted",
691                            path);
692   if (parent != G_NODE (model->root) && parent->children == NULL)
693     {
694       gtk_tree_path_up (path);
695       
696       gtk_signal_emit_by_name (GTK_OBJECT (model),
697                                "child_toggled",
698                                path,
699                                parent);
700     }
701   gtk_tree_path_free (path);
702 }
703
704 void
705 gtk_tree_store_insert (GtkTreeStore *model,
706                        GtkTreeIter  *iter,
707                        GtkTreeIter  *parent,
708                        gint          position)
709 {
710   GtkTreePath *path;
711   
712   g_return_if_fail (model != NULL);
713   g_return_if_fail (GTK_IS_TREE_STORE (model));
714
715   if (parent->user_data == NULL)
716     parent->user_data = model->root;
717
718   iter->stamp = model->stamp;
719   iter->user_data = g_node_new (NULL);
720   g_node_insert (G_NODE (parent->user_data), position, G_NODE (iter->user_data));
721   
722   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
723   gtk_signal_emit_by_name (GTK_OBJECT (model),
724                            "inserted",
725                            path, iter);
726   gtk_tree_path_free (path);
727 }
728
729 void
730 gtk_tree_store_insert_before (GtkTreeStore *model,
731                               GtkTreeIter  *iter,
732                               GtkTreeIter  *parent,
733                               GtkTreeIter  *sibling)
734 {
735   GtkTreePath *path;
736   GNode *parent_node = NULL;  
737   GNode *new_node;
738   
739   g_return_if_fail (model != NULL);
740   g_return_if_fail (GTK_IS_TREE_STORE (model));
741   g_return_if_fail (iter != NULL);
742
743   new_node = g_node_new (NULL);  
744
745   if (parent == NULL && sibling == NULL)
746     parent_node = model->root;
747   else if (parent == NULL)
748     parent_node = G_NODE (sibling->user_data)->parent;
749   else if (sibling == NULL)
750     parent_node = G_NODE (parent->user_data);
751   else
752     {
753       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
754                         G_NODE (parent->user_data));
755       parent_node = G_NODE (parent->user_data);
756     }
757
758   g_node_insert_before (parent_node,
759                         sibling ? G_NODE (sibling->user_data) : NULL,
760                         new_node);
761
762   iter->stamp = model->stamp;
763   iter->user_data = new_node;
764   
765   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
766   gtk_signal_emit_by_name (GTK_OBJECT (model),
767                            "inserted",
768                            path, iter);
769   gtk_tree_path_free (path);
770 }
771
772 void
773 gtk_tree_store_insert_after (GtkTreeStore *model,
774                              GtkTreeIter  *iter,
775                              GtkTreeIter  *parent,
776                              GtkTreeIter  *sibling)
777 {
778   GtkTreePath *path;
779   GNode *parent_node;
780   GNode *new_node;
781   
782   g_return_if_fail (model != NULL);
783   g_return_if_fail (GTK_IS_TREE_STORE (model));
784   g_return_if_fail (iter != NULL);
785
786   new_node = g_node_new (NULL);
787
788   if (parent == NULL && sibling == NULL)
789     parent_node = model->root;
790   else if (parent == NULL)
791     parent_node = G_NODE (sibling->user_data)->parent;
792   else if (sibling == NULL)
793     parent_node = G_NODE (parent->user_data);
794   else
795     {
796       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
797                         G_NODE (parent->user_data));
798       parent_node = G_NODE (parent->user_data);
799     }
800
801   
802   g_node_insert_after (parent_node,
803                        sibling ? G_NODE (sibling->user_data) : NULL,
804                        new_node);
805   
806   iter->stamp = model->stamp;
807   iter->user_data = new_node;
808   
809   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
810   gtk_signal_emit_by_name (GTK_OBJECT (model),
811                            "inserted",
812                            path, iter);
813   gtk_tree_path_free (path);
814 }
815
816 void
817 gtk_tree_store_prepend (GtkTreeStore *model,
818                         GtkTreeIter  *iter,
819                         GtkTreeIter  *parent)
820 {
821   GNode *parent_node;
822   
823   g_return_if_fail (model != NULL);
824   g_return_if_fail (GTK_IS_TREE_STORE (model));
825   g_return_if_fail (iter != NULL);
826
827   if (parent == NULL)
828     parent_node = model->root;
829   else
830     parent_node = parent->user_data;
831   
832   if (parent_node->children == NULL)
833     {
834       GtkTreePath *path;
835       
836       iter->stamp = model->stamp;
837       iter->user_data = g_node_new (NULL);
838       
839       g_node_prepend (parent_node, iter->user_data);
840       
841       if (parent_node != model->root)
842         {
843           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
844           gtk_signal_emit_by_name (GTK_OBJECT (model),
845                                    "child_toggled",
846                                    path,
847                                    parent);
848           gtk_tree_path_append_index (path, 0);
849         }
850       else
851         {
852           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
853         }
854       gtk_signal_emit_by_name (GTK_OBJECT (model),
855                                "inserted",
856                                path,
857                                iter);
858       gtk_tree_path_free (path);
859     }
860   else
861     {
862       gtk_tree_store_insert_after (model, iter, parent, NULL);
863     }
864 }
865
866 void
867 gtk_tree_store_append (GtkTreeStore *model,
868                        GtkTreeIter  *iter,
869                        GtkTreeIter  *parent)
870 {
871   GNode *parent_node;
872
873   g_return_if_fail (model != NULL);
874   g_return_if_fail (GTK_IS_TREE_STORE (model));
875   g_return_if_fail (iter != NULL);
876
877   if (parent == NULL)
878     parent_node = model->root;
879   else
880     parent_node = parent->user_data;
881
882   iter->stamp = model->stamp;
883   iter->user_data = g_node_new (NULL);
884
885   if (parent_node->children == NULL)
886     {
887       GtkTreePath *path;
888
889       g_node_append (parent_node, G_NODE (iter->user_data));
890
891       if (parent_node != model->root)
892         {
893           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
894           gtk_signal_emit_by_name (GTK_OBJECT (model),
895                                    "child_toggled",
896                                    path,
897                                    parent);
898           gtk_tree_path_append_index (path, 0);
899         }
900       else
901         {
902           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
903         }
904       gtk_signal_emit_by_name (GTK_OBJECT (model),
905                                "inserted",
906                                path,
907                                iter);
908       gtk_tree_path_free (path);
909     }
910   else
911     {
912       gtk_tree_store_insert_before (model, iter, parent, NULL);
913     }
914 }
915
916 gboolean
917 gtk_tree_store_is_ancestor (GtkTreeStore *model,
918                             GtkTreeIter  *iter,
919                             GtkTreeIter  *descendant)
920 {
921   g_return_val_if_fail (model != NULL, FALSE);
922   g_return_val_if_fail (GTK_IS_TREE_STORE (model), FALSE);
923   g_return_val_if_fail (iter != NULL, FALSE);
924   g_return_val_if_fail (descendant != NULL, FALSE);
925
926   return g_node_is_ancestor (G_NODE (iter->user_data),
927                              G_NODE (descendant->user_data));
928 }
929
930
931 gint
932 gtk_tree_store_iter_depth (GtkTreeStore *model,
933                            GtkTreeIter  *iter)
934 {
935   g_return_val_if_fail (model != NULL, 0);
936   g_return_val_if_fail (GTK_IS_TREE_STORE (model), 0);
937   g_return_val_if_fail (iter != NULL, 0);
938
939   return g_node_depth (G_NODE (iter->user_data)) - 1;
940 }