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