]> Pileus Git - ~andy/gtk/blob - gtk/gtktreestore.c
Forgot to namespace this.
[~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 "gtktreednd.h"
24 #include <string.h>
25 #include <gobject/gvaluecollector.h>
26
27 #define G_NODE(node) ((GNode *)node)
28
29 static void         gtk_tree_store_init            (GtkTreeStore      *tree_store);
30 static void         gtk_tree_store_class_init      (GtkTreeStoreClass *tree_store_class);
31 static void         gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
32 static void         gtk_tree_store_drag_source_init(GtkTreeDragSourceIface *iface);
33 static void         gtk_tree_store_drag_dest_init  (GtkTreeDragDestIface   *iface);
34 static void         gtk_tree_store_sortable_init   (GtkTreeSortableIface   *iface);
35 static guint        gtk_tree_store_get_flags       (GtkTreeModel      *tree_model);
36 static gint         gtk_tree_store_get_n_columns   (GtkTreeModel      *tree_model);
37 static GType        gtk_tree_store_get_column_type (GtkTreeModel      *tree_model,
38                                                     gint               index);
39 static GtkTreePath *gtk_tree_store_get_path        (GtkTreeModel      *tree_model,
40                                                     GtkTreeIter       *iter);
41 static void         gtk_tree_store_get_value       (GtkTreeModel      *tree_model,
42                                                     GtkTreeIter       *iter,
43                                                     gint               column,
44                                                     GValue            *value);
45 static gboolean     gtk_tree_store_iter_next       (GtkTreeModel      *tree_model,
46                                                     GtkTreeIter       *iter);
47 static gboolean     gtk_tree_store_iter_children   (GtkTreeModel      *tree_model,
48                                                     GtkTreeIter       *iter,
49                                                     GtkTreeIter       *parent);
50 static gboolean     gtk_tree_store_iter_has_child  (GtkTreeModel      *tree_model,
51                                                     GtkTreeIter       *iter);
52 static gint         gtk_tree_store_iter_n_children (GtkTreeModel      *tree_model,
53                                                     GtkTreeIter       *iter);
54 static gboolean     gtk_tree_store_iter_nth_child  (GtkTreeModel      *tree_model,
55                                                     GtkTreeIter       *iter,
56                                                     GtkTreeIter       *parent,
57                                                     gint               n);
58 static gboolean     gtk_tree_store_iter_parent     (GtkTreeModel      *tree_model,
59                                                     GtkTreeIter       *iter,
60                                                     GtkTreeIter       *child);
61
62
63 /* DND interfaces */
64 static gboolean gtk_tree_store_drag_data_delete   (GtkTreeDragSource *drag_source,
65                                                    GtkTreePath       *path);
66 static gboolean gtk_tree_store_drag_data_get      (GtkTreeDragSource *drag_source,
67                                                    GtkTreePath       *path,
68                                                    GtkSelectionData  *selection_data);
69 static gboolean gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
70                                                    GtkTreePath       *dest,
71                                                    GtkSelectionData  *selection_data);
72 static gboolean gtk_tree_store_row_drop_possible  (GtkTreeDragDest   *drag_dest,
73                                                    GtkTreeModel      *src_model,
74                                                    GtkTreePath       *src_path,
75                                                    GtkTreePath       *dest_path);
76
77 /* Sortable Interfaces */
78
79 static void gtk_tree_store_get_sort_column_id      (GtkTreeSortable        *sortable,
80                                                     gint                   *sort_column_id,
81                                                     GtkTreeSortOrder       *order);
82 static void gtk_tree_store_set_sort_column_id      (GtkTreeSortable        *sortable,
83                                                     gint                    sort_column_id,
84                                                     GtkTreeSortOrder        order);
85 static void gtk_tree_store_sort_column_id_set_func (GtkTreeSortable        *sortable,
86                                                     gint                    sort_column_id,
87                                                     GtkTreeIterCompareFunc  func,
88                                                     gpointer                data,
89                                                     GtkDestroyNotify        destroy);
90
91
92
93 static void     validate_gnode                    (GNode *node);
94
95 static inline void
96 validate_tree (GtkTreeStore *tree_store)
97 {
98   if (gtk_debug_flags & GTK_DEBUG_TREE)
99     {
100       g_assert (G_NODE (tree_store->root)->parent == NULL);
101
102       validate_gnode (G_NODE (tree_store->root));
103     }
104 }
105
106 GtkType
107 gtk_tree_store_get_type (void)
108 {
109   static GType tree_store_type = 0;
110
111   if (!tree_store_type)
112     {
113       static const GTypeInfo tree_store_info =
114       {
115         sizeof (GtkTreeStoreClass),
116         NULL,           /* base_init */
117         NULL,           /* base_finalize */
118         (GClassInitFunc) gtk_tree_store_class_init,
119         NULL,           /* class_finalize */
120         NULL,           /* class_data */
121         sizeof (GtkTreeStore),
122         0,              /* n_preallocs */
123         (GInstanceInitFunc) gtk_tree_store_init
124       };
125
126       static const GInterfaceInfo tree_model_info =
127       {
128         (GInterfaceInitFunc) gtk_tree_store_tree_model_init,
129         NULL,
130         NULL
131       };
132
133       static const GInterfaceInfo drag_source_info =
134       {
135         (GInterfaceInitFunc) gtk_tree_store_drag_source_init,
136         NULL,
137         NULL
138       };
139
140       static const GInterfaceInfo drag_dest_info =
141       {
142         (GInterfaceInitFunc) gtk_tree_store_drag_dest_init,
143         NULL,
144         NULL
145       };
146
147       static const GInterfaceInfo sortable_info =
148       {
149         (GInterfaceInitFunc) gtk_tree_store_sortable_init,
150         NULL,
151         NULL
152       };
153
154       tree_store_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeStore", &tree_store_info, 0);
155
156       g_type_add_interface_static (tree_store_type,
157                                    GTK_TYPE_TREE_MODEL,
158                                    &tree_model_info);
159       g_type_add_interface_static (tree_store_type,
160                                    GTK_TYPE_TREE_DRAG_SOURCE,
161                                    &drag_source_info);
162       g_type_add_interface_static (tree_store_type,
163                                    GTK_TYPE_TREE_DRAG_DEST,
164                                    &drag_dest_info);
165       g_type_add_interface_static (tree_store_type,
166                                    GTK_TYPE_TREE_SORTABLE,
167                                    &sortable_info);
168
169     }
170
171   return tree_store_type;
172 }
173
174 static void
175 gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class)
176 {
177   GObjectClass *object_class;
178
179   object_class = (GObjectClass *) tree_store_class;
180
181 }
182
183 static void
184 gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
185 {
186   iface->get_flags = gtk_tree_store_get_flags;
187   iface->get_n_columns = gtk_tree_store_get_n_columns;
188   iface->get_column_type = gtk_tree_store_get_column_type;
189   iface->get_path = gtk_tree_store_get_path;
190   iface->get_value = gtk_tree_store_get_value;
191   iface->iter_next = gtk_tree_store_iter_next;
192   iface->iter_children = gtk_tree_store_iter_children;
193   iface->iter_has_child = gtk_tree_store_iter_has_child;
194   iface->iter_n_children = gtk_tree_store_iter_n_children;
195   iface->iter_nth_child = gtk_tree_store_iter_nth_child;
196   iface->iter_parent = gtk_tree_store_iter_parent;
197 }
198
199 static void
200 gtk_tree_store_drag_source_init (GtkTreeDragSourceIface *iface)
201 {
202   iface->drag_data_delete = gtk_tree_store_drag_data_delete;
203   iface->drag_data_get = gtk_tree_store_drag_data_get;
204 }
205
206 static void
207 gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface)
208 {
209   iface->drag_data_received = gtk_tree_store_drag_data_received;
210   iface->row_drop_possible = gtk_tree_store_row_drop_possible;
211 }
212
213 static void
214 gtk_tree_store_sortable_init (GtkTreeSortableIface *iface)
215 {
216   iface->get_sort_column_id = NULL;
217   iface->set_sort_column_id = NULL;
218   iface->sort_column_id_set_func = NULL;
219 }
220
221 static void
222 gtk_tree_store_init (GtkTreeStore *tree_store)
223 {
224   tree_store->root = g_node_new (NULL);
225   tree_store->stamp = g_random_int ();
226   tree_store->sort_list = NULL;
227 }
228
229 GtkTreeStore *
230 gtk_tree_store_new (void)
231 {
232   return GTK_TREE_STORE (g_object_new (gtk_tree_store_get_type (), NULL));
233 }
234
235 GtkTreeStore *
236 gtk_tree_store_new_with_types (gint n_columns,
237                                ...)
238 {
239   GtkTreeStore *retval;
240   va_list args;
241   gint i;
242
243   g_return_val_if_fail (n_columns > 0, NULL);
244
245   retval = gtk_tree_store_new ();
246   gtk_tree_store_set_n_columns (retval, n_columns);
247
248   va_start (args, n_columns);
249
250   for (i = 0; i < n_columns; i++)
251     {
252       GType type = va_arg (args, GType);
253       if (! _gtk_tree_data_list_check_type (type))
254         {
255           g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (type));
256           g_object_unref (G_OBJECT (retval));
257           return NULL;
258         }
259       gtk_tree_store_set_column_type (retval, i, type);
260     }
261   va_end (args);
262
263   return retval;
264 }
265
266 /**
267  * gtk_tree_store_set_n_columns:
268  * @tree_store: 
269  * @n_columns: 
270  * 
271  * As a side effect of calling this function, all sort columns that overlap with
272  * the current number of columns will be removed.
273  **/
274 void
275 gtk_tree_store_set_n_columns (GtkTreeStore *tree_store,
276                               gint          n_columns)
277 {
278   GType *new_columns;
279
280   g_return_if_fail (tree_store != NULL);
281   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
282
283   if (tree_store->n_columns == n_columns)
284     return;
285
286   new_columns = g_new0 (GType, n_columns);
287   if (tree_store->column_headers)
288     {
289       /* copy the old header orders over */
290       if (n_columns >= tree_store->n_columns)
291         memcpy (new_columns, tree_store->column_headers, tree_store->n_columns * sizeof (gchar *));
292       else
293         memcpy (new_columns, tree_store->column_headers, n_columns * sizeof (GType));
294
295       g_free (tree_store->column_headers);
296     }
297
298   if (tree_store->sort_list)
299     _gtk_tree_data_list_header_free (tree_store->sort_list);
300
301   tree_store->sort_list = _gtk_tree_data_list_header_new (n_columns, tree_store->column_headers);
302
303   tree_store->column_headers = new_columns;
304   tree_store->n_columns = n_columns;
305 }
306
307 /**
308  * gtk_tree_store_set_column_type:
309  * @tree_store: a #GtkTreeStore
310  * @column: column number
311  * @type: type of the data to be stored in @column
312  *
313  * Supported types include: %G_TYPE_UINT, %G_TYPE_INT, %G_TYPE_UCHAR,
314  * %G_TYPE_CHAR, %G_TYPE_BOOLEAN, %G_TYPE_POINTER, %G_TYPE_FLOAT,
315  * %G_TYPE_DOUBLE, %G_TYPE_STRING, %G_TYPE_OBJECT, and %G_TYPE_BOXED, along with
316  * subclasses of those types such as %GDK_TYPE_PIXBUF.
317  *
318  **/
319 void
320 gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
321                                 gint          column,
322                                 GType         type)
323 {
324   g_return_if_fail (tree_store != NULL);
325   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
326   g_return_if_fail (column >=0 && column < tree_store->n_columns);
327   if (!_gtk_tree_data_list_check_type (type))
328     {
329       g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (type));
330       return;
331     }
332   tree_store->column_headers[column] = type;
333 }
334
335 /* fulfill the GtkTreeModel requirements */
336 /* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node.  However,
337  * it is not visible to the tree or to the user., and the path "0" refers to the
338  * first child of GtkTreeStore::root.
339  */
340
341
342 static guint
343 gtk_tree_store_get_flags (GtkTreeModel *tree_model)
344 {
345   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
346
347   return GTK_TREE_MODEL_ITERS_PERSIST;
348 }
349
350 static gint
351 gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
352 {
353   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
354
355   return GTK_TREE_STORE (tree_model)->n_columns;
356 }
357
358 static GType
359 gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
360                                 gint          index)
361 {
362   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), G_TYPE_INVALID);
363   g_return_val_if_fail (index < GTK_TREE_STORE (tree_model)->n_columns &&
364                         index >= 0, G_TYPE_INVALID);
365
366   return GTK_TREE_STORE (tree_model)->column_headers[index];
367 }
368
369 static GtkTreePath *
370 gtk_tree_store_get_path (GtkTreeModel *tree_model,
371                          GtkTreeIter  *iter)
372 {
373   GtkTreePath *retval;
374   GNode *tmp_node;
375   gint i = 0;
376
377   g_return_val_if_fail (tree_model != NULL, NULL);
378   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL);
379   g_return_val_if_fail (iter != NULL, NULL);
380   g_return_val_if_fail (iter->user_data != NULL, NULL);
381
382   validate_tree ((GtkTreeStore*)tree_model);
383
384   g_assert (G_NODE (iter->user_data)->parent != NULL);
385
386   if (G_NODE (iter->user_data)->parent == G_NODE (GTK_TREE_STORE (tree_model)->root))
387     {
388       retval = gtk_tree_path_new ();
389       tmp_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
390     }
391   else
392     {
393       GtkTreeIter tmp_iter = *iter;
394
395       tmp_iter.user_data = G_NODE (iter->user_data)->parent;
396
397       retval = gtk_tree_store_get_path (tree_model,
398                                         &tmp_iter);
399       tmp_node = G_NODE (iter->user_data)->parent->children;
400     }
401
402   if (retval == NULL)
403     return NULL;
404
405   if (tmp_node == NULL)
406     {
407       gtk_tree_path_free (retval);
408       return NULL;
409     }
410
411   for (; tmp_node; tmp_node = tmp_node->next)
412     {
413       if (tmp_node == G_NODE (iter->user_data))
414         break;
415       i++;
416     }
417
418   if (tmp_node == NULL)
419     {
420       /* We couldn't find node, meaning it's prolly not ours */
421       /* Perhaps I should do a g_return_if_fail here. */
422       gtk_tree_path_free (retval);
423       return NULL;
424     }
425
426   gtk_tree_path_append_index (retval, i);
427
428   return retval;
429 }
430
431
432 static void
433 gtk_tree_store_get_value (GtkTreeModel *tree_model,
434                           GtkTreeIter  *iter,
435                           gint          column,
436                           GValue       *value)
437 {
438   GtkTreeDataList *list;
439   gint tmp_column = column;
440
441   g_return_if_fail (tree_model != NULL);
442   g_return_if_fail (GTK_IS_TREE_STORE (tree_model));
443   g_return_if_fail (iter != NULL);
444   g_return_if_fail (column < GTK_TREE_STORE (tree_model)->n_columns);
445
446   list = G_NODE (iter->user_data)->data;
447
448   while (tmp_column-- > 0 && list)
449     list = list->next;
450
451   if (list)
452     {
453       _gtk_tree_data_list_node_to_value (list,
454                                          GTK_TREE_STORE (tree_model)->column_headers[column],
455                                          value);
456     }
457   else
458     {
459       /* We want to return an initialized but empty (default) value */
460       g_value_init (value, GTK_TREE_STORE (tree_model)->column_headers[column]);
461     }
462 }
463
464 static gboolean
465 gtk_tree_store_iter_next (GtkTreeModel  *tree_model,
466                           GtkTreeIter   *iter)
467 {
468   g_return_val_if_fail (iter->user_data != NULL, FALSE);
469
470   if (G_NODE (iter->user_data)->next)
471     {
472       iter->user_data = G_NODE (iter->user_data)->next;
473       return TRUE;
474     }
475   else
476     return FALSE;
477 }
478
479 static gboolean
480 gtk_tree_store_iter_children (GtkTreeModel *tree_model,
481                               GtkTreeIter  *iter,
482                               GtkTreeIter  *parent)
483 {
484   GNode *children;
485
486   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
487
488   if (parent)
489     children = G_NODE (parent->user_data)->children;
490   else
491     children = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
492
493   if (children)
494     {
495       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
496       iter->user_data = children;
497       return TRUE;
498     }
499   else
500     return FALSE;
501 }
502
503 static gboolean
504 gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
505                                GtkTreeIter  *iter)
506 {
507   g_return_val_if_fail (tree_model != NULL, FALSE);
508   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
509   g_return_val_if_fail (iter != NULL, FALSE);
510   g_return_val_if_fail (iter->user_data != NULL, FALSE);
511
512   return G_NODE (iter->user_data)->children != NULL;
513 }
514
515 static gint
516 gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
517                                 GtkTreeIter  *iter)
518 {
519   GNode *node;
520   gint i = 0;
521
522   g_return_val_if_fail (tree_model != NULL, 0);
523   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
524   g_return_val_if_fail (iter != NULL, FALSE);
525   g_return_val_if_fail (iter->user_data != NULL, FALSE);
526
527   if (iter == NULL)
528     node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
529   else
530     node = G_NODE (iter->user_data)->children;
531
532   while (node)
533     {
534       i++;
535       node = node->next;
536     }
537
538   return i;
539 }
540
541 static gboolean
542 gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
543                                GtkTreeIter  *iter,
544                                GtkTreeIter  *parent,
545                                gint          n)
546 {
547   GNode *parent_node;
548   GNode *child;
549
550   g_return_val_if_fail (tree_model != NULL, FALSE);
551   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
552   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
553
554   if (parent == NULL)
555     parent_node = GTK_TREE_STORE (tree_model)->root;
556   else
557     parent_node = parent->user_data;
558
559   child = g_node_nth_child (parent_node, n);
560
561   if (child)
562     {
563       iter->user_data = child;
564       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
565       return TRUE;
566     }
567   else
568     return FALSE;
569 }
570
571 static gboolean
572 gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
573                             GtkTreeIter  *iter,
574                             GtkTreeIter  *child)
575 {
576   GNode *parent;
577
578   g_return_val_if_fail (iter != NULL, FALSE);
579   g_return_val_if_fail (iter->user_data != NULL, FALSE);
580
581   parent = G_NODE (child->user_data)->parent;
582
583   g_assert (parent != NULL);
584
585   if (parent != GTK_TREE_STORE (tree_model)->root)
586     {
587       iter->user_data = parent;
588       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
589       return TRUE;
590     }
591   else
592     return FALSE;
593 }
594
595 /*
596  * This is a somewhat inelegant function that does a lot of list
597  * manipulations on it's own.
598  */
599 void
600 gtk_tree_store_set_value (GtkTreeStore *tree_store,
601                           GtkTreeIter  *iter,
602                           gint          column,
603                           GValue       *value)
604 {
605   GtkTreeDataList *list;
606   GtkTreeDataList *prev;
607   GtkTreePath *path = NULL;
608   GValue real_value = {0, };
609   gboolean converted = FALSE;
610
611   g_return_if_fail (tree_store != NULL);
612   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
613   g_return_if_fail (column >= 0 && column < tree_store->n_columns);
614   g_return_if_fail (G_IS_VALUE (value));
615
616   if (! g_type_is_a (G_VALUE_TYPE (value), tree_store->column_headers[column]))
617     {
618       if (! (g_value_type_compatible (G_VALUE_TYPE (value), tree_store->column_headers[column]) &&
619              g_value_type_compatible (tree_store->column_headers[column], G_VALUE_TYPE (value))))
620         {
621           g_warning ("%s: Unable to convert from %s to %s\n",
622                      G_STRLOC,
623                      g_type_name (G_VALUE_TYPE (value)),
624                      g_type_name (tree_store->column_headers[column]));
625           return;
626         }
627       if (!g_value_transform (value, &real_value))
628         {
629           g_warning ("%s: Unable to make conversion from %s to %s\n",
630                      G_STRLOC,
631                      g_type_name (G_VALUE_TYPE (value)),
632                      g_type_name (tree_store->column_headers[column]));
633           g_value_unset (&real_value);
634           return;
635         }
636       converted = TRUE;
637     }
638
639   prev = list = G_NODE (iter->user_data)->data;
640
641   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
642
643   while (list != NULL)
644     {
645       if (column == 0)
646         {
647           if (converted)
648             _gtk_tree_data_list_value_to_node (list, &real_value);
649           else
650             _gtk_tree_data_list_value_to_node (list, value);
651           gtk_tree_model_changed (GTK_TREE_MODEL (tree_store), path, iter);
652           gtk_tree_path_free (path);
653           if (converted)
654             g_value_unset (&real_value);
655           return;
656         }
657
658       column--;
659       prev = list;
660       list = list->next;
661     }
662
663   if (G_NODE (iter->user_data)->data == NULL)
664     {
665       G_NODE (iter->user_data)->data = list = _gtk_tree_data_list_alloc ();
666       list->next = NULL;
667     }
668   else
669     {
670       list = prev->next = _gtk_tree_data_list_alloc ();
671       list->next = NULL;
672     }
673
674   while (column != 0)
675     {
676       list->next = _gtk_tree_data_list_alloc ();
677       list = list->next;
678       list->next = NULL;
679       column --;
680     }
681   if (converted)
682     _gtk_tree_data_list_value_to_node (list, &real_value);
683   else
684     _gtk_tree_data_list_value_to_node (list, value);
685   gtk_tree_model_changed (GTK_TREE_MODEL (tree_store), path, iter);
686   gtk_tree_path_free (path);
687   if (converted)
688     g_value_unset (&real_value);
689 }
690
691 /**
692  * gtk_tree_store_set_valist:
693  * @tree_store: a #GtkTreeStore
694  * @iter: row to set data for
695  * @var_args: va_list of column/value pairs
696  *
697  * See gtk_tree_store_set(); this version takes a va_list for
698  * use by language bindings.
699  *
700  **/
701 void
702 gtk_tree_store_set_valist (GtkTreeStore *tree_store,
703                            GtkTreeIter  *iter,
704                            va_list      var_args)
705 {
706   gint column;
707
708   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
709
710   column = va_arg (var_args, gint);
711
712   while (column != -1)
713     {
714       GValue value = { 0, };
715       gchar *error = NULL;
716
717       if (column >= tree_store->n_columns)
718         {
719           g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
720           break;
721         }
722       g_value_init (&value, tree_store->column_headers[column]);
723
724       G_VALUE_COLLECT (&value, var_args, 0, &error);
725       if (error)
726         {
727           g_warning ("%s: %s", G_STRLOC, error);
728           g_free (error);
729
730           /* we purposely leak the value here, it might not be
731            * in a sane state if an error condition occoured
732            */
733           break;
734         }
735
736       gtk_tree_store_set_value (tree_store,
737                                 iter,
738                                 column,
739                                 &value);
740
741       g_value_unset (&value);
742
743       column = va_arg (var_args, gint);
744     }
745 }
746
747 /**
748  * gtk_tree_store_set:
749  * @tree_store: a #GtkTreeStore
750  * @iter: row iterator
751  * @Varargs: pairs of column number and value, terminated with -1
752  *
753  * Sets the value of one or more cells in the row referenced by @iter.
754  * The variable argument list should contain integer column numbers,
755  * each column number followed by the value to be set. For example,
756  * The list is terminated by a -1. For example, to set column 0 with type
757  * %G_TYPE_STRING to "Foo", you would write gtk_tree_store_set (store, iter,
758  * 0, "Foo", -1).
759  **/
760 void
761 gtk_tree_store_set (GtkTreeStore *tree_store,
762                     GtkTreeIter  *iter,
763                     ...)
764 {
765   va_list var_args;
766
767   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
768
769   va_start (var_args, iter);
770   gtk_tree_store_set_valist (tree_store, iter, var_args);
771   va_end (var_args);
772 }
773
774 void
775 gtk_tree_store_remove (GtkTreeStore *model,
776                        GtkTreeIter  *iter)
777 {
778   GtkTreePath *path;
779   GtkTreeIter new_iter = {0,};
780   GNode *parent;
781
782   g_return_if_fail (model != NULL);
783   g_return_if_fail (GTK_IS_TREE_STORE (model));
784
785   parent = G_NODE (iter->user_data)->parent;
786
787   g_assert (parent != NULL);
788
789   if (G_NODE (iter->user_data)->data)
790     _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data,
791                               model->column_headers);
792
793   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
794   g_node_destroy (G_NODE (iter->user_data));
795
796   model->stamp++;
797   gtk_tree_model_deleted (GTK_TREE_MODEL (model), path);
798
799   if (parent != G_NODE (model->root) && parent->children == NULL)
800     {
801       gtk_tree_path_up (path);
802
803       new_iter.stamp = model->stamp;
804       new_iter.user_data = parent;
805       gtk_tree_model_has_child_toggled (GTK_TREE_MODEL (model), path, &new_iter);
806     }
807   gtk_tree_path_free (path);
808 }
809
810 void
811 gtk_tree_store_insert (GtkTreeStore *model,
812                        GtkTreeIter  *iter,
813                        GtkTreeIter  *parent,
814                        gint          position)
815 {
816   GtkTreePath *path;
817   GNode *parent_node;
818
819   g_return_if_fail (model != NULL);
820   g_return_if_fail (GTK_IS_TREE_STORE (model));
821
822   if (parent)
823     parent_node = parent->user_data;
824   else
825     parent_node = model->root;
826
827   iter->stamp = model->stamp;
828   iter->user_data = g_node_new (NULL);
829   g_node_insert (parent_node, position, G_NODE (iter->user_data));
830
831   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
832   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
833
834   gtk_tree_path_free (path);
835
836   validate_tree ((GtkTreeStore*)model);
837 }
838
839 void
840 gtk_tree_store_insert_before (GtkTreeStore *model,
841                               GtkTreeIter  *iter,
842                               GtkTreeIter  *parent,
843                               GtkTreeIter  *sibling)
844 {
845   GtkTreePath *path;
846   GNode *parent_node = NULL;
847   GNode *new_node;
848
849   g_return_if_fail (model != NULL);
850   g_return_if_fail (GTK_IS_TREE_STORE (model));
851   g_return_if_fail (iter != NULL);
852
853   new_node = g_node_new (NULL);
854
855   if (parent == NULL && sibling == NULL)
856     parent_node = model->root;
857   else if (parent == NULL)
858     parent_node = G_NODE (sibling->user_data)->parent;
859   else if (sibling == NULL)
860     parent_node = G_NODE (parent->user_data);
861   else
862     {
863       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
864                         G_NODE (parent->user_data));
865       parent_node = G_NODE (parent->user_data);
866     }
867
868   g_node_insert_before (parent_node,
869                         sibling ? G_NODE (sibling->user_data) : NULL,
870                         new_node);
871
872   iter->stamp = model->stamp;
873   iter->user_data = new_node;
874
875   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
876   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
877
878   gtk_tree_path_free (path);
879
880   validate_tree ((GtkTreeStore*)model);
881 }
882
883 void
884 gtk_tree_store_insert_after (GtkTreeStore *model,
885                              GtkTreeIter  *iter,
886                              GtkTreeIter  *parent,
887                              GtkTreeIter  *sibling)
888 {
889   GtkTreePath *path;
890   GNode *parent_node;
891   GNode *new_node;
892
893   g_return_if_fail (model != NULL);
894   g_return_if_fail (GTK_IS_TREE_STORE (model));
895   g_return_if_fail (iter != NULL);
896
897   new_node = g_node_new (NULL);
898
899   if (parent == NULL && sibling == NULL)
900     parent_node = model->root;
901   else if (parent == NULL)
902     parent_node = G_NODE (sibling->user_data)->parent;
903   else if (sibling == NULL)
904     parent_node = G_NODE (parent->user_data);
905   else
906     {
907       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
908                         G_NODE (parent->user_data));
909       parent_node = G_NODE (parent->user_data);
910     }
911
912
913   g_node_insert_after (parent_node,
914                        sibling ? G_NODE (sibling->user_data) : NULL,
915                        new_node);
916
917   iter->stamp = model->stamp;
918   iter->user_data = new_node;
919
920   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
921   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
922
923   gtk_tree_path_free (path);
924
925   validate_tree ((GtkTreeStore*)model);
926 }
927
928 void
929 gtk_tree_store_prepend (GtkTreeStore *model,
930                         GtkTreeIter  *iter,
931                         GtkTreeIter  *parent)
932 {
933   GNode *parent_node;
934
935   g_return_if_fail (model != NULL);
936   g_return_if_fail (GTK_IS_TREE_STORE (model));
937   g_return_if_fail (iter != NULL);
938
939   if (parent == NULL)
940     parent_node = model->root;
941   else
942     parent_node = parent->user_data;
943
944   if (parent_node->children == NULL)
945     {
946       GtkTreePath *path;
947
948       iter->stamp = model->stamp;
949       iter->user_data = g_node_new (NULL);
950
951       g_node_prepend (parent_node, iter->user_data);
952
953       if (parent_node != model->root)
954         {
955           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
956           gtk_tree_model_has_child_toggled (GTK_TREE_MODEL (model), path, parent);
957           gtk_tree_path_append_index (path, 0);
958         }
959       else
960         {
961           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
962         }
963       gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
964       gtk_tree_path_free (path);
965     }
966   else
967     {
968       gtk_tree_store_insert_after (model, iter, parent, NULL);
969     }
970
971   validate_tree ((GtkTreeStore*)model);
972 }
973
974 void
975 gtk_tree_store_append (GtkTreeStore *model,
976                        GtkTreeIter  *iter,
977                        GtkTreeIter  *parent)
978 {
979   GNode *parent_node;
980
981   g_return_if_fail (model != NULL);
982   g_return_if_fail (GTK_IS_TREE_STORE (model));
983   g_return_if_fail (iter != NULL);
984
985   if (parent == NULL)
986     parent_node = model->root;
987   else
988     parent_node = parent->user_data;
989
990   if (parent_node->children == NULL)
991     {
992       GtkTreePath *path;
993
994       iter->stamp = model->stamp;
995       iter->user_data = g_node_new (NULL);
996
997       g_node_append (parent_node, G_NODE (iter->user_data));
998
999       if (parent_node != model->root)
1000         {
1001           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
1002           gtk_tree_model_has_child_toggled (GTK_TREE_MODEL (model), path, parent);
1003           gtk_tree_path_append_index (path, 0);
1004         }
1005       else
1006         {
1007           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
1008         }
1009
1010       gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
1011       gtk_tree_path_free (path);
1012     }
1013   else
1014     {
1015       gtk_tree_store_insert_before (model, iter, parent, NULL);
1016     }
1017
1018   validate_tree ((GtkTreeStore*)model);
1019 }
1020
1021 gboolean
1022 gtk_tree_store_is_ancestor (GtkTreeStore *model,
1023                             GtkTreeIter  *iter,
1024                             GtkTreeIter  *descendant)
1025 {
1026   g_return_val_if_fail (model != NULL, FALSE);
1027   g_return_val_if_fail (GTK_IS_TREE_STORE (model), FALSE);
1028   g_return_val_if_fail (iter != NULL, FALSE);
1029   g_return_val_if_fail (descendant != NULL, FALSE);
1030
1031   return g_node_is_ancestor (G_NODE (iter->user_data),
1032                              G_NODE (descendant->user_data));
1033 }
1034
1035
1036 gint
1037 gtk_tree_store_iter_depth (GtkTreeStore *model,
1038                            GtkTreeIter  *iter)
1039 {
1040   g_return_val_if_fail (model != NULL, 0);
1041   g_return_val_if_fail (GTK_IS_TREE_STORE (model), 0);
1042   g_return_val_if_fail (iter != NULL, 0);
1043
1044   return g_node_depth (G_NODE (iter->user_data)) - 1;
1045 }
1046
1047 /* DND */
1048
1049
1050
1051 static gboolean
1052 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
1053                                  GtkTreePath       *path)
1054 {
1055   GtkTreeIter iter;
1056
1057   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1058
1059   if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
1060                                &iter,
1061                                path))
1062     {
1063       gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
1064                              &iter);
1065       return TRUE;
1066     }
1067   else
1068     {
1069       return FALSE;
1070     }
1071 }
1072
1073 static gboolean
1074 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
1075                               GtkTreePath       *path,
1076                               GtkSelectionData  *selection_data)
1077 {
1078   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1079
1080   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1081    * target, because the default handler does it for us, but
1082    * we do anyway for the convenience of someone maybe overriding the
1083    * default handler.
1084    */
1085
1086   if (gtk_selection_data_set_tree_row (selection_data,
1087                                        GTK_TREE_MODEL (drag_source),
1088                                        path))
1089     {
1090       return TRUE;
1091     }
1092   else
1093     {
1094       /* FIXME handle text targets at least. */
1095     }
1096
1097   return FALSE;
1098 }
1099
1100 static void
1101 copy_node_data (GtkTreeStore *tree_store,
1102                 GtkTreeIter  *src_iter,
1103                 GtkTreeIter  *dest_iter)
1104 {
1105   GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
1106   GtkTreeDataList *copy_head = NULL;
1107   GtkTreeDataList *copy_prev = NULL;
1108   GtkTreeDataList *copy_iter = NULL;
1109   GtkTreePath *path;
1110   gint col;
1111
1112   col = 0;
1113   while (dl)
1114     {
1115       copy_iter = _gtk_tree_data_list_node_copy (dl, tree_store->column_headers[col]);
1116
1117       if (copy_head == NULL)
1118         copy_head = copy_iter;
1119
1120       if (copy_prev)
1121         copy_prev->next = copy_iter;
1122
1123       copy_prev = copy_iter;
1124
1125       dl = dl->next;
1126       ++col;
1127     }
1128
1129   G_NODE (dest_iter->user_data)->data = copy_head;
1130
1131   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), dest_iter);
1132   gtk_tree_model_changed (GTK_TREE_MODEL (tree_store), path, dest_iter);
1133   gtk_tree_path_free (path);
1134 }
1135
1136 static void
1137 recursive_node_copy (GtkTreeStore *tree_store,
1138                      GtkTreeIter  *src_iter,
1139                      GtkTreeIter  *dest_iter)
1140 {
1141   GtkTreeIter child;
1142   GtkTreeModel *model;
1143
1144   model = GTK_TREE_MODEL (tree_store);
1145
1146   copy_node_data (tree_store, src_iter, dest_iter);
1147
1148   if (gtk_tree_model_iter_children (model,
1149                                     &child,
1150                                     src_iter))
1151     {
1152       /* Need to create children and recurse. Note our
1153        * dependence on persistent iterators here.
1154        */
1155       do
1156         {
1157           GtkTreeIter copy;
1158
1159           /* Gee, a really slow algorithm... ;-) FIXME */
1160           gtk_tree_store_append (tree_store,
1161                                  &copy,
1162                                  dest_iter);
1163
1164           recursive_node_copy (tree_store, &child, &copy);
1165         }
1166       while (gtk_tree_model_iter_next (model, &child));
1167     }
1168 }
1169
1170 static gboolean
1171 gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
1172                                    GtkTreePath       *dest,
1173                                    GtkSelectionData  *selection_data)
1174 {
1175   GtkTreeModel *tree_model;
1176   GtkTreeStore *tree_store;
1177   GtkTreeModel *src_model = NULL;
1178   GtkTreePath *src_path = NULL;
1179   gboolean retval = FALSE;
1180
1181   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE);
1182
1183   tree_model = GTK_TREE_MODEL (drag_dest);
1184   tree_store = GTK_TREE_STORE (drag_dest);
1185
1186   validate_tree (tree_store);
1187
1188   if (gtk_selection_data_get_tree_row (selection_data,
1189                                        &src_model,
1190                                        &src_path) &&
1191       src_model == tree_model)
1192     {
1193       /* Copy the given row to a new position */
1194       GtkTreeIter src_iter;
1195       GtkTreeIter dest_iter;
1196       GtkTreePath *prev;
1197
1198       if (!gtk_tree_model_get_iter (src_model,
1199                                     &src_iter,
1200                                     src_path))
1201         {
1202           goto out;
1203         }
1204
1205       /* Get the path to insert _after_ (dest is the path to insert _before_) */
1206       prev = gtk_tree_path_copy (dest);
1207
1208       if (!gtk_tree_path_prev (prev))
1209         {
1210           GtkTreeIter dest_parent;
1211           GtkTreePath *parent;
1212           GtkTreeIter *dest_parent_p;
1213
1214           /* dest was the first spot at the current depth; which means
1215            * we are supposed to prepend.
1216            */
1217
1218           /* Get the parent, NULL if parent is the root */
1219           dest_parent_p = NULL;
1220           parent = gtk_tree_path_copy (dest);
1221           if (gtk_tree_path_up (parent))
1222             {
1223               gtk_tree_model_get_iter (tree_model,
1224                                        &dest_parent,
1225                                        parent);
1226               dest_parent_p = &dest_parent;
1227             }
1228           gtk_tree_path_free (parent);
1229           parent = NULL;
1230
1231           gtk_tree_store_prepend (GTK_TREE_STORE (tree_model),
1232                                   &dest_iter,
1233                                   dest_parent_p);
1234
1235           retval = TRUE;
1236         }
1237       else
1238         {
1239           if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
1240                                        &dest_iter,
1241                                        prev))
1242             {
1243               GtkTreeIter tmp_iter = dest_iter;
1244               gtk_tree_store_insert_after (GTK_TREE_STORE (tree_model),
1245                                            &dest_iter,
1246                                            NULL,
1247                                            &tmp_iter);
1248               retval = TRUE;
1249
1250             }
1251         }
1252
1253       gtk_tree_path_free (prev);
1254
1255       /* If we succeeded in creating dest_iter, walk src_iter tree branch,
1256        * duplicating it below dest_iter.
1257        */
1258
1259       if (retval)
1260         {
1261           recursive_node_copy (tree_store,
1262                                &src_iter,
1263                                &dest_iter);
1264         }
1265     }
1266   else
1267     {
1268       /* FIXME maybe add some data targets eventually, or handle text
1269        * targets in the simple case.
1270        */
1271
1272     }
1273
1274  out:
1275
1276   if (src_path)
1277     gtk_tree_path_free (src_path);
1278
1279   return retval;
1280 }
1281
1282 static gboolean
1283 gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
1284                                   GtkTreeModel    *src_model,
1285                                   GtkTreePath     *src_path,
1286                                   GtkTreePath     *dest_path)
1287 {
1288   /* can only drag to ourselves */
1289   if (src_model != GTK_TREE_MODEL (drag_dest))
1290     return FALSE;
1291
1292   /* Can't drop into ourself. */
1293   if (gtk_tree_path_is_ancestor (src_path,
1294                                  dest_path))
1295     return FALSE;
1296
1297   /* Can't drop if dest_path's parent doesn't exist */
1298   {
1299     GtkTreeIter iter;
1300     GtkTreePath *tmp = gtk_tree_path_copy (dest_path);
1301
1302     /* if we can't go up, we know the parent exists, the root
1303      * always exists.
1304      */
1305     if (gtk_tree_path_up (tmp))
1306       {
1307         if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
1308                                       &iter, tmp))
1309           {
1310             if (tmp)
1311               gtk_tree_path_free (tmp);
1312             return FALSE;
1313           }
1314       }
1315
1316     if (tmp)
1317       gtk_tree_path_free (tmp);
1318   }
1319
1320   /* Can otherwise drop anywhere. */
1321   return TRUE;
1322 }
1323
1324
1325 static void
1326 gtk_tree_store_get_sort_column_id (GtkTreeSortable  *sortable,
1327                                    gint             *sort_column_id,
1328                                    GtkTreeSortOrder *order)
1329 {
1330
1331 }
1332
1333 static void
1334 gtk_tree_store_set_sort_column_id (GtkTreeSortable  *sortable,
1335                                    gint              sort_column_id,
1336                                    GtkTreeSortOrder  order)
1337 {
1338
1339 }
1340
1341 static void
1342 gtk_tree_store_sort_column_id_set_func (GtkTreeSortable        *sortable,
1343                                         gint                    sort_column_id,
1344                                         GtkTreeIterCompareFunc  func,
1345                                         gpointer                data,
1346                                         GtkDestroyNotify        destroy)
1347 {
1348
1349 }
1350
1351 static void
1352 validate_gnode (GNode* node)
1353 {
1354   GNode *iter;
1355
1356   iter = node->children;
1357   while (iter != NULL)
1358     {
1359       g_assert (iter->parent == node);
1360       if (iter->prev)
1361         g_assert (iter->prev->next == iter);
1362       validate_gnode (iter);
1363       iter = iter->next;
1364     }
1365 }
1366
1367