]> Pileus Git - ~andy/gtk/blob - gtk/gtktreestore.c
c0376b6921f496869280ede2b710a109748def04
[~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 #define GTK_TREE_STORE_IS_SORTED(tree) (GTK_TREE_STORE (tree)->sort_column_id != -1)
29 #define VALID_ITER(iter, tree_store) (iter!= NULL && iter->user_data != NULL && tree_store->stamp == iter->stamp)
30
31 static void         gtk_tree_store_init            (GtkTreeStore      *tree_store);
32 static void         gtk_tree_store_class_init      (GtkTreeStoreClass *tree_store_class);
33 static void         gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
34 static void         gtk_tree_store_drag_source_init(GtkTreeDragSourceIface *iface);
35 static void         gtk_tree_store_drag_dest_init  (GtkTreeDragDestIface   *iface);
36 static void         gtk_tree_store_sortable_init   (GtkTreeSortableIface   *iface);
37 static guint        gtk_tree_store_get_flags       (GtkTreeModel      *tree_model);
38 static gint         gtk_tree_store_get_n_columns   (GtkTreeModel      *tree_model);
39 static GType        gtk_tree_store_get_column_type (GtkTreeModel      *tree_model,
40                                                     gint               index);
41 static gboolean     gtk_tree_store_get_iter        (GtkTreeModel      *tree_model,
42                                                     GtkTreeIter       *iter,
43                                                     GtkTreePath       *path);
44 static GtkTreePath *gtk_tree_store_get_path        (GtkTreeModel      *tree_model,
45                                                     GtkTreeIter       *iter);
46 static void         gtk_tree_store_get_value       (GtkTreeModel      *tree_model,
47                                                     GtkTreeIter       *iter,
48                                                     gint               column,
49                                                     GValue            *value);
50 static gboolean     gtk_tree_store_iter_next       (GtkTreeModel      *tree_model,
51                                                     GtkTreeIter       *iter);
52 static gboolean     gtk_tree_store_iter_children   (GtkTreeModel      *tree_model,
53                                                     GtkTreeIter       *iter,
54                                                     GtkTreeIter       *parent);
55 static gboolean     gtk_tree_store_iter_has_child  (GtkTreeModel      *tree_model,
56                                                     GtkTreeIter       *iter);
57 static gint         gtk_tree_store_iter_n_children (GtkTreeModel      *tree_model,
58                                                     GtkTreeIter       *iter);
59 static gboolean     gtk_tree_store_iter_nth_child  (GtkTreeModel      *tree_model,
60                                                     GtkTreeIter       *iter,
61                                                     GtkTreeIter       *parent,
62                                                     gint               n);
63 static gboolean     gtk_tree_store_iter_parent     (GtkTreeModel      *tree_model,
64                                                     GtkTreeIter       *iter,
65                                                     GtkTreeIter       *child);
66
67
68 static void gtk_tree_store_set_n_columns   (GtkTreeStore *tree_store,
69                                             gint          n_columns);
70 static void gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
71                                             gint          column,
72                                             GType         type);
73
74
75 /* DND interfaces */
76 static gboolean gtk_tree_store_drag_data_delete   (GtkTreeDragSource *drag_source,
77                                                    GtkTreePath       *path);
78 static gboolean gtk_tree_store_drag_data_get      (GtkTreeDragSource *drag_source,
79                                                    GtkTreePath       *path,
80                                                    GtkSelectionData  *selection_data);
81 static gboolean gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
82                                                    GtkTreePath       *dest,
83                                                    GtkSelectionData  *selection_data);
84 static gboolean gtk_tree_store_row_drop_possible  (GtkTreeDragDest   *drag_dest,
85                                                    GtkTreeModel      *src_model,
86                                                    GtkTreePath       *src_path,
87                                                    GtkTreePath       *dest_path);
88
89 /* Sortable Interfaces */
90
91 static void     gtk_tree_store_sort                    (GtkTreeStore           *tree_store);
92 static void     gtk_tree_store_sort_iter_changed       (GtkTreeStore           *tree_store,
93                                                         GtkTreeIter            *iter,
94                                                         gint                    column);
95 static gboolean gtk_tree_store_get_sort_column_id      (GtkTreeSortable        *sortable,
96                                                         gint                   *sort_column_id,
97                                                         GtkTreeSortOrder       *order);
98 static void     gtk_tree_store_set_sort_column_id      (GtkTreeSortable        *sortable,
99                                                         gint                    sort_column_id,
100                                                         GtkTreeSortOrder        order);
101 static void     gtk_tree_store_set_sort_func (GtkTreeSortable        *sortable,
102                                                         gint                    sort_column_id,
103                                                         GtkTreeIterCompareFunc  func,
104                                                         gpointer                data,
105                                                         GtkDestroyNotify        destroy);
106
107
108 static void     validate_gnode                    (GNode *node);
109
110 static inline void
111 validate_tree (GtkTreeStore *tree_store)
112 {
113   if (gtk_debug_flags & GTK_DEBUG_TREE)
114     {
115       g_assert (G_NODE (tree_store->root)->parent == NULL);
116
117       validate_gnode (G_NODE (tree_store->root));
118     }
119 }
120
121 GtkType
122 gtk_tree_store_get_type (void)
123 {
124   static GType tree_store_type = 0;
125
126   if (!tree_store_type)
127     {
128       static const GTypeInfo tree_store_info =
129       {
130         sizeof (GtkTreeStoreClass),
131         NULL,           /* base_init */
132         NULL,           /* base_finalize */
133         (GClassInitFunc) gtk_tree_store_class_init,
134         NULL,           /* class_finalize */
135         NULL,           /* class_data */
136         sizeof (GtkTreeStore),
137         0,              /* n_preallocs */
138         (GInstanceInitFunc) gtk_tree_store_init
139       };
140
141       static const GInterfaceInfo tree_model_info =
142       {
143         (GInterfaceInitFunc) gtk_tree_store_tree_model_init,
144         NULL,
145         NULL
146       };
147
148       static const GInterfaceInfo drag_source_info =
149       {
150         (GInterfaceInitFunc) gtk_tree_store_drag_source_init,
151         NULL,
152         NULL
153       };
154
155       static const GInterfaceInfo drag_dest_info =
156       {
157         (GInterfaceInitFunc) gtk_tree_store_drag_dest_init,
158         NULL,
159         NULL
160       };
161
162       static const GInterfaceInfo sortable_info =
163       {
164         (GInterfaceInitFunc) gtk_tree_store_sortable_init,
165         NULL,
166         NULL
167       };
168
169       tree_store_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeStore", &tree_store_info, 0);
170
171       g_type_add_interface_static (tree_store_type,
172                                    GTK_TYPE_TREE_MODEL,
173                                    &tree_model_info);
174       g_type_add_interface_static (tree_store_type,
175                                    GTK_TYPE_TREE_DRAG_SOURCE,
176                                    &drag_source_info);
177       g_type_add_interface_static (tree_store_type,
178                                    GTK_TYPE_TREE_DRAG_DEST,
179                                    &drag_dest_info);
180       g_type_add_interface_static (tree_store_type,
181                                    GTK_TYPE_TREE_SORTABLE,
182                                    &sortable_info);
183
184     }
185
186   return tree_store_type;
187 }
188
189 static void
190 gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class)
191 {
192   GObjectClass *object_class;
193
194   object_class = (GObjectClass *) tree_store_class;
195
196 }
197
198 static void
199 gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
200 {
201   iface->get_flags = gtk_tree_store_get_flags;
202   iface->get_n_columns = gtk_tree_store_get_n_columns;
203   iface->get_column_type = gtk_tree_store_get_column_type;
204   iface->get_iter = gtk_tree_store_get_iter;
205   iface->get_path = gtk_tree_store_get_path;
206   iface->get_value = gtk_tree_store_get_value;
207   iface->iter_next = gtk_tree_store_iter_next;
208   iface->iter_children = gtk_tree_store_iter_children;
209   iface->iter_has_child = gtk_tree_store_iter_has_child;
210   iface->iter_n_children = gtk_tree_store_iter_n_children;
211   iface->iter_nth_child = gtk_tree_store_iter_nth_child;
212   iface->iter_parent = gtk_tree_store_iter_parent;
213 }
214
215 static void
216 gtk_tree_store_drag_source_init (GtkTreeDragSourceIface *iface)
217 {
218   iface->drag_data_delete = gtk_tree_store_drag_data_delete;
219   iface->drag_data_get = gtk_tree_store_drag_data_get;
220 }
221
222 static void
223 gtk_tree_store_drag_dest_init (GtkTreeDragDestIface *iface)
224 {
225   iface->drag_data_received = gtk_tree_store_drag_data_received;
226   iface->row_drop_possible = gtk_tree_store_row_drop_possible;
227 }
228
229 static void
230 gtk_tree_store_sortable_init (GtkTreeSortableIface *iface)
231 {
232   iface->get_sort_column_id = gtk_tree_store_get_sort_column_id;
233   iface->set_sort_column_id = gtk_tree_store_set_sort_column_id;
234   iface->set_sort_func = gtk_tree_store_set_sort_func;
235 }
236
237 static void
238 gtk_tree_store_init (GtkTreeStore *tree_store)
239 {
240   tree_store->root = g_node_new (NULL);
241   tree_store->stamp = g_random_int ();
242   tree_store->sort_list = NULL;
243   tree_store->sort_column_id = -1;
244 }
245
246 /**
247  * gtk_tree_store_new:
248  * @n_columns: number of columns in the tree store
249  * @Varargs: all #GType types for the columns, from first to last
250  *
251  * Creates a new tree store as with @n_columns columns each of the types passed
252  * in.  As an example, gtk_tree_store_new (3, G_TYPE_INT, G_TYPE_STRING,
253  * GDK_TYPE_PIXBUF); will create a new GtkTreeStore with three columns, of type
254  * int, string and GDkPixbuf respectively.
255  *
256  * Return value: a new #GtkTreeStore
257  **/
258 GtkTreeStore *
259 gtk_tree_store_new (gint n_columns,
260                                ...)
261 {
262   GtkTreeStore *retval;
263   va_list args;
264   gint i;
265
266   g_return_val_if_fail (n_columns > 0, NULL);
267
268   retval = GTK_TREE_STORE (g_object_new (GTK_TYPE_TREE_STORE, NULL));
269   gtk_tree_store_set_n_columns (retval, n_columns);
270
271   va_start (args, n_columns);
272
273   for (i = 0; i < n_columns; i++)
274     {
275       GType type = va_arg (args, GType);
276       if (! _gtk_tree_data_list_check_type (type))
277         {
278           g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (type));
279           g_object_unref (G_OBJECT (retval));
280           return NULL;
281         }
282       gtk_tree_store_set_column_type (retval, i, type);
283     }
284   va_end (args);
285
286   return retval;
287 }
288 /**
289  * gtk_tree_store_newv:
290  * @n_columns: number of columns in the tree store
291  * @types: an array of #GType types for the columns, from first to last
292  *
293  * Non vararg creation function.  Used primarily by language bindings.
294  *
295  * Return value: a new #GtkTreeStore
296  **/
297 GtkTreeStore *
298 gtk_tree_store_newv (gint   n_columns,
299                      GType *types)
300 {
301   GtkTreeStore *retval;
302   gint i;
303
304   g_return_val_if_fail (n_columns > 0, NULL);
305
306   retval = GTK_TREE_STORE (g_object_new (GTK_TYPE_TREE_STORE, NULL));
307   gtk_tree_store_set_n_columns (retval, n_columns);
308
309    for (i = 0; i < n_columns; i++)
310     {
311       if (! _gtk_tree_data_list_check_type (types[i]))
312         {
313           g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (types[i]));
314           g_object_unref (G_OBJECT (retval));
315           return NULL;
316         }
317       gtk_tree_store_set_column_type (retval, i, types[i]);
318     }
319
320   return retval;
321 }
322
323 /**
324  * gtk_tree_store_set_n_columns:
325  * @tree_store:
326  * @n_columns:
327  *
328  * As a side effect of calling this function, all sort columns that overlap with
329  * the current number of columns will be removed.
330  **/
331 static void
332 gtk_tree_store_set_n_columns (GtkTreeStore *tree_store,
333                               gint          n_columns)
334 {
335   GType *new_columns;
336
337   g_return_if_fail (tree_store != NULL);
338   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
339
340   if (tree_store->n_columns == n_columns)
341     return;
342
343   new_columns = g_new0 (GType, n_columns);
344   if (tree_store->column_headers)
345     {
346       /* copy the old header orders over */
347       if (n_columns >= tree_store->n_columns)
348         memcpy (new_columns, tree_store->column_headers, tree_store->n_columns * sizeof (gchar *));
349       else
350         memcpy (new_columns, tree_store->column_headers, n_columns * sizeof (GType));
351
352       g_free (tree_store->column_headers);
353     }
354
355   if (tree_store->sort_list)
356     _gtk_tree_data_list_header_free (tree_store->sort_list);
357
358   tree_store->sort_list = _gtk_tree_data_list_header_new (n_columns, tree_store->column_headers);
359
360   tree_store->column_headers = new_columns;
361   tree_store->n_columns = n_columns;
362 }
363
364 /**
365  * gtk_tree_store_set_column_type:
366  * @tree_store: a #GtkTreeStore
367  * @column: column number
368  * @type: type of the data to be stored in @column
369  *
370  * Supported types include: %G_TYPE_UINT, %G_TYPE_INT, %G_TYPE_UCHAR,
371  * %G_TYPE_CHAR, %G_TYPE_BOOLEAN, %G_TYPE_POINTER, %G_TYPE_FLOAT,
372  * %G_TYPE_DOUBLE, %G_TYPE_STRING, %G_TYPE_OBJECT, and %G_TYPE_BOXED, along with
373  * subclasses of those types such as %GDK_TYPE_PIXBUF.
374  *
375  **/
376 static void
377 gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
378                                 gint          column,
379                                 GType         type)
380 {
381   g_return_if_fail (tree_store != NULL);
382   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
383   g_return_if_fail (column >=0 && column < tree_store->n_columns);
384   if (!_gtk_tree_data_list_check_type (type))
385     {
386       g_warning ("%s: Invalid type %s passed to gtk_tree_store_new_with_types\n", G_STRLOC, g_type_name (type));
387       return;
388     }
389   tree_store->column_headers[column] = type;
390 }
391
392 /* fulfill the GtkTreeModel requirements */
393 /* NOTE: GtkTreeStore::root is a GNode, that acts as the parent node.  However,
394  * it is not visible to the tree or to the user., and the path "0" refers to the
395  * first child of GtkTreeStore::root.
396  */
397
398
399 static guint
400 gtk_tree_store_get_flags (GtkTreeModel *tree_model)
401 {
402   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
403
404   return GTK_TREE_MODEL_ITERS_PERSIST;
405 }
406
407 static gint
408 gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
409 {
410   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
411
412   return GTK_TREE_STORE (tree_model)->n_columns;
413 }
414
415 static GType
416 gtk_tree_store_get_column_type (GtkTreeModel *tree_model,
417                                 gint          index)
418 {
419   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), G_TYPE_INVALID);
420   g_return_val_if_fail (index < GTK_TREE_STORE (tree_model)->n_columns &&
421                         index >= 0, G_TYPE_INVALID);
422
423   return GTK_TREE_STORE (tree_model)->column_headers[index];
424 }
425
426 static gboolean
427 gtk_tree_store_get_iter (GtkTreeModel *tree_model,
428                          GtkTreeIter  *iter,
429                          GtkTreePath  *path)
430 {
431   GtkTreeStore *tree_store = (GtkTreeStore *) tree_model;
432   GtkTreeIter parent;
433   gint *indices;
434   gint depth, i;
435
436   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_store), FALSE);
437   
438   indices = gtk_tree_path_get_indices (path);
439   depth = gtk_tree_path_get_depth (path);
440
441   g_return_val_if_fail (depth > 0, FALSE);
442
443   parent.stamp = tree_store->stamp;
444   parent.user_data = tree_store->root;
445
446   if (! gtk_tree_model_iter_nth_child (tree_model, iter, &parent, indices[0]))
447     return FALSE;
448
449   for (i = 1; i < depth; i++)
450     {
451       parent = *iter;
452       if (! gtk_tree_model_iter_nth_child (tree_model, iter, &parent, indices[i]))
453         return FALSE;
454     }
455
456   return TRUE;
457 }
458
459 static GtkTreePath *
460 gtk_tree_store_get_path (GtkTreeModel *tree_model,
461                          GtkTreeIter  *iter)
462 {
463   GtkTreePath *retval;
464   GNode *tmp_node;
465   gint i = 0;
466
467   g_return_val_if_fail (tree_model != NULL, NULL);
468   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL);
469   g_return_val_if_fail (iter != NULL, NULL);
470   g_return_val_if_fail (iter->user_data != NULL, NULL);
471   g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, NULL);
472
473   validate_tree ((GtkTreeStore*)tree_model);
474
475   if (G_NODE (iter->user_data)->parent == NULL &&
476       G_NODE (iter->user_data) == GTK_TREE_STORE (tree_model)->root)
477     return gtk_tree_path_new ();
478   g_assert (G_NODE (iter->user_data)->parent != NULL);
479
480   if (G_NODE (iter->user_data)->parent == G_NODE (GTK_TREE_STORE (tree_model)->root))
481     {
482       retval = gtk_tree_path_new ();
483       tmp_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
484     }
485   else
486     {
487       GtkTreeIter tmp_iter = *iter;
488
489       tmp_iter.user_data = G_NODE (iter->user_data)->parent;
490
491       retval = gtk_tree_store_get_path (tree_model,
492                                         &tmp_iter);
493       tmp_node = G_NODE (iter->user_data)->parent->children;
494     }
495
496   if (retval == NULL)
497     return NULL;
498
499   if (tmp_node == NULL)
500     {
501       gtk_tree_path_free (retval);
502       return NULL;
503     }
504
505   for (; tmp_node; tmp_node = tmp_node->next)
506     {
507       if (tmp_node == G_NODE (iter->user_data))
508         break;
509       i++;
510     }
511
512   if (tmp_node == NULL)
513     {
514       /* We couldn't find node, meaning it's prolly not ours */
515       /* Perhaps I should do a g_return_if_fail here. */
516       gtk_tree_path_free (retval);
517       return NULL;
518     }
519
520   gtk_tree_path_append_index (retval, i);
521
522   return retval;
523 }
524
525
526 static void
527 gtk_tree_store_get_value (GtkTreeModel *tree_model,
528                           GtkTreeIter  *iter,
529                           gint          column,
530                           GValue       *value)
531 {
532   GtkTreeDataList *list;
533   gint tmp_column = column;
534
535   g_return_if_fail (tree_model != NULL);
536   g_return_if_fail (GTK_IS_TREE_STORE (tree_model));
537   g_return_if_fail (iter != NULL);
538   g_return_if_fail (column < GTK_TREE_STORE (tree_model)->n_columns);
539
540   list = G_NODE (iter->user_data)->data;
541
542   while (tmp_column-- > 0 && list)
543     list = list->next;
544
545   if (list)
546     {
547       _gtk_tree_data_list_node_to_value (list,
548                                          GTK_TREE_STORE (tree_model)->column_headers[column],
549                                          value);
550     }
551   else
552     {
553       /* We want to return an initialized but empty (default) value */
554       g_value_init (value, GTK_TREE_STORE (tree_model)->column_headers[column]);
555     }
556 }
557
558 static gboolean
559 gtk_tree_store_iter_next (GtkTreeModel  *tree_model,
560                           GtkTreeIter   *iter)
561 {
562   g_return_val_if_fail (iter->user_data != NULL, FALSE);
563
564   if (G_NODE (iter->user_data)->next)
565     {
566       iter->user_data = G_NODE (iter->user_data)->next;
567       return TRUE;
568     }
569   else
570     return FALSE;
571 }
572
573 static gboolean
574 gtk_tree_store_iter_children (GtkTreeModel *tree_model,
575                               GtkTreeIter  *iter,
576                               GtkTreeIter  *parent)
577 {
578   GNode *children;
579
580   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
581
582   if (parent)
583     children = G_NODE (parent->user_data)->children;
584   else
585     children = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
586
587   if (children)
588     {
589       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
590       iter->user_data = children;
591       return TRUE;
592     }
593   else
594     return FALSE;
595 }
596
597 static gboolean
598 gtk_tree_store_iter_has_child (GtkTreeModel *tree_model,
599                                GtkTreeIter  *iter)
600 {
601   g_return_val_if_fail (tree_model != NULL, FALSE);
602   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
603   g_return_val_if_fail (iter != NULL, FALSE);
604   g_return_val_if_fail (iter->user_data != NULL, FALSE);
605
606   return G_NODE (iter->user_data)->children != NULL;
607 }
608
609 static gint
610 gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
611                                 GtkTreeIter  *iter)
612 {
613   GNode *node;
614   gint i = 0;
615
616   g_return_val_if_fail (tree_model != NULL, 0);
617   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
618   g_return_val_if_fail (iter != NULL, FALSE);
619   g_return_val_if_fail (iter->user_data != NULL, FALSE);
620
621   if (iter == NULL)
622     node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
623   else
624     node = G_NODE (iter->user_data)->children;
625
626   while (node)
627     {
628       i++;
629       node = node->next;
630     }
631
632   return i;
633 }
634
635 static gboolean
636 gtk_tree_store_iter_nth_child (GtkTreeModel *tree_model,
637                                GtkTreeIter  *iter,
638                                GtkTreeIter  *parent,
639                                gint          n)
640 {
641   GNode *parent_node;
642   GNode *child;
643
644   g_return_val_if_fail (tree_model != NULL, FALSE);
645   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
646   g_return_val_if_fail (parent == NULL || parent->user_data != NULL, FALSE);
647
648   if (parent == NULL)
649     parent_node = GTK_TREE_STORE (tree_model)->root;
650   else
651     parent_node = parent->user_data;
652
653   child = g_node_nth_child (parent_node, n);
654
655   if (child)
656     {
657       iter->user_data = child;
658       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
659       return TRUE;
660     }
661   else
662     return FALSE;
663 }
664
665 static gboolean
666 gtk_tree_store_iter_parent (GtkTreeModel *tree_model,
667                             GtkTreeIter  *iter,
668                             GtkTreeIter  *child)
669 {
670   GNode *parent;
671
672   g_return_val_if_fail (iter != NULL, FALSE);
673   g_return_val_if_fail (iter->user_data != NULL, FALSE);
674
675   parent = G_NODE (child->user_data)->parent;
676
677   g_assert (parent != NULL);
678
679   if (parent != GTK_TREE_STORE (tree_model)->root)
680     {
681       iter->user_data = parent;
682       iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
683       return TRUE;
684     }
685   else
686     return FALSE;
687 }
688
689 /*
690  * This is a somewhat inelegant function that does a lot of list
691  * manipulations on it's own.
692  */
693 void
694 gtk_tree_store_set_value (GtkTreeStore *tree_store,
695                           GtkTreeIter  *iter,
696                           gint          column,
697                           GValue       *value)
698 {
699   GtkTreeDataList *list;
700   GtkTreeDataList *prev;
701   GtkTreePath *path = NULL;
702   GValue real_value = {0, };
703   gboolean converted = FALSE;
704   gint orig_column = column;
705
706   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
707   g_return_if_fail (VALID_ITER (iter, tree_store));
708   g_return_if_fail (column >= 0 && column < tree_store->n_columns);
709   g_return_if_fail (G_IS_VALUE (value));
710
711   if (! g_type_is_a (G_VALUE_TYPE (value), tree_store->column_headers[column]))
712     {
713       if (! (g_value_type_compatible (G_VALUE_TYPE (value), tree_store->column_headers[column]) &&
714              g_value_type_compatible (tree_store->column_headers[column], G_VALUE_TYPE (value))))
715         {
716           g_warning ("%s: Unable to convert from %s to %s\n",
717                      G_STRLOC,
718                      g_type_name (G_VALUE_TYPE (value)),
719                      g_type_name (tree_store->column_headers[column]));
720           return;
721         }
722       if (!g_value_transform (value, &real_value))
723         {
724           g_warning ("%s: Unable to make conversion from %s to %s\n",
725                      G_STRLOC,
726                      g_type_name (G_VALUE_TYPE (value)),
727                      g_type_name (tree_store->column_headers[column]));
728           g_value_unset (&real_value);
729           return;
730         }
731       converted = TRUE;
732     }
733
734   prev = list = G_NODE (iter->user_data)->data;
735
736   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), iter);
737
738   while (list != NULL)
739     {
740       if (column == 0)
741         {
742           if (converted)
743             _gtk_tree_data_list_value_to_node (list, &real_value);
744           else
745             _gtk_tree_data_list_value_to_node (list, value);
746           gtk_tree_model_range_changed (GTK_TREE_MODEL (tree_store), path, iter, path, iter);
747           gtk_tree_path_free (path);
748           if (converted)
749             g_value_unset (&real_value);
750           return;
751         }
752
753       column--;
754       prev = list;
755       list = list->next;
756     }
757
758   if (G_NODE (iter->user_data)->data == NULL)
759     {
760       G_NODE (iter->user_data)->data = list = _gtk_tree_data_list_alloc ();
761       list->next = NULL;
762     }
763   else
764     {
765       list = prev->next = _gtk_tree_data_list_alloc ();
766       list->next = NULL;
767     }
768
769   while (column != 0)
770     {
771       list->next = _gtk_tree_data_list_alloc ();
772       list = list->next;
773       list->next = NULL;
774       column --;
775     }
776   if (converted)
777     _gtk_tree_data_list_value_to_node (list, &real_value);
778   else
779     _gtk_tree_data_list_value_to_node (list, value);
780   gtk_tree_model_range_changed (GTK_TREE_MODEL (tree_store), path, iter, path, iter);
781   gtk_tree_path_free (path);
782   if (converted)
783     g_value_unset (&real_value);
784
785   if (GTK_TREE_STORE_IS_SORTED (tree_store))
786     gtk_tree_store_sort_iter_changed (tree_store, iter, orig_column);
787 }
788
789 /**
790  * gtk_tree_store_set_valist:
791  * @tree_store: a #GtkTreeStore
792  * @iter: row to set data for
793  * @var_args: va_list of column/value pairs
794  *
795  * See gtk_tree_store_set(); this version takes a va_list for
796  * use by language bindings.
797  *
798  **/
799 void
800 gtk_tree_store_set_valist (GtkTreeStore *tree_store,
801                            GtkTreeIter  *iter,
802                            va_list      var_args)
803 {
804   gint column;
805
806   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
807   g_return_if_fail (VALID_ITER (iter, tree_store));
808
809   column = va_arg (var_args, gint);
810
811   while (column != -1)
812     {
813       GValue value = { 0, };
814       gchar *error = NULL;
815
816       if (column >= tree_store->n_columns)
817         {
818           g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
819           break;
820         }
821       g_value_init (&value, tree_store->column_headers[column]);
822
823       G_VALUE_COLLECT (&value, var_args, 0, &error);
824       if (error)
825         {
826           g_warning ("%s: %s", G_STRLOC, error);
827           g_free (error);
828
829           /* we purposely leak the value here, it might not be
830            * in a sane state if an error condition occoured
831            */
832           break;
833         }
834
835       /* FIXME: instead of calling this n times, refactor with above */
836       gtk_tree_store_set_value (tree_store,
837                                 iter,
838                                 column,
839                                 &value);
840
841       g_value_unset (&value);
842
843       column = va_arg (var_args, gint);
844     }
845 }
846
847 /**
848  * gtk_tree_store_set:
849  * @tree_store: a #GtkTreeStore
850  * @iter: row iterator
851  * @Varargs: pairs of column number and value, terminated with -1
852  *
853  * Sets the value of one or more cells in the row referenced by @iter.
854  * The variable argument list should contain integer column numbers,
855  * each column number followed by the value to be set. For example,
856  * The list is terminated by a -1. For example, to set column 0 with type
857  * %G_TYPE_STRING to "Foo", you would write gtk_tree_store_set (store, iter,
858  * 0, "Foo", -1).
859  **/
860 void
861 gtk_tree_store_set (GtkTreeStore *tree_store,
862                     GtkTreeIter  *iter,
863                     ...)
864 {
865   va_list var_args;
866
867   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
868   g_return_if_fail (VALID_ITER (iter, tree_store));
869
870   va_start (var_args, iter);
871   gtk_tree_store_set_valist (tree_store, iter, var_args);
872   va_end (var_args);
873 }
874
875 void
876 gtk_tree_store_remove (GtkTreeStore *model,
877                        GtkTreeIter  *iter)
878 {
879   GtkTreePath *path;
880   GtkTreeIter new_iter = {0,};
881   GNode *parent;
882
883   g_return_if_fail (GTK_IS_TREE_STORE (model));
884   g_return_if_fail (VALID_ITER (iter, model));
885
886   parent = G_NODE (iter->user_data)->parent;
887
888   g_assert (parent != NULL);
889
890   if (G_NODE (iter->user_data)->data)
891     _gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data,
892                               model->column_headers);
893
894   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
895   g_node_destroy (G_NODE (iter->user_data));
896
897   model->stamp++;
898   gtk_tree_model_deleted (GTK_TREE_MODEL (model), path);
899
900   if (parent != G_NODE (model->root))
901     {
902       /* child_toggled */
903       if (parent->children == NULL)
904         {
905           gtk_tree_path_up (path);
906
907           new_iter.stamp = model->stamp;
908           new_iter.user_data = parent;
909           gtk_tree_model_has_child_toggled (GTK_TREE_MODEL (model), path, &new_iter);
910         }
911
912       /* revalidate iter */
913       while (parent != G_NODE (model->root))
914         {
915           if (parent->next != NULL)
916             {
917               iter->stamp = model->stamp;
918               iter->user_data = parent->next;
919               break;
920             }
921           parent = parent->parent;
922         }
923     }
924   gtk_tree_path_free (path);
925 }
926
927 void
928 gtk_tree_store_insert (GtkTreeStore *model,
929                        GtkTreeIter  *iter,
930                        GtkTreeIter  *parent,
931                        gint          position)
932 {
933   GtkTreePath *path;
934   GNode *parent_node;
935
936   g_return_if_fail (GTK_IS_TREE_STORE (model));
937   if (parent)
938     g_return_if_fail (VALID_ITER (parent, model));
939
940   if (parent)
941     parent_node = parent->user_data;
942   else
943     parent_node = model->root;
944
945   iter->stamp = model->stamp;
946   iter->user_data = g_node_new (NULL);
947   g_node_insert (parent_node, position, G_NODE (iter->user_data));
948
949   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
950   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
951
952   gtk_tree_path_free (path);
953
954   validate_tree ((GtkTreeStore*)model);
955 }
956
957 void
958 gtk_tree_store_insert_before (GtkTreeStore *model,
959                               GtkTreeIter  *iter,
960                               GtkTreeIter  *parent,
961                               GtkTreeIter  *sibling)
962 {
963   GtkTreePath *path;
964   GNode *parent_node = NULL;
965   GNode *new_node;
966
967   g_return_if_fail (GTK_IS_TREE_STORE (model));
968   g_return_if_fail (iter != NULL);
969   if (parent != NULL)
970     g_return_if_fail (VALID_ITER (parent, model));
971   if (sibling != NULL)
972     g_return_if_fail (VALID_ITER (sibling, model));
973
974   new_node = g_node_new (NULL);
975
976   if (parent == NULL && sibling == NULL)
977     parent_node = model->root;
978   else if (parent == NULL)
979     parent_node = G_NODE (sibling->user_data)->parent;
980   else if (sibling == NULL)
981     parent_node = G_NODE (parent->user_data);
982   else
983     {
984       g_return_if_fail (G_NODE (sibling->user_data)->parent == G_NODE (parent->user_data));
985       parent_node = G_NODE (parent->user_data);
986     }
987
988   g_node_insert_before (parent_node,
989                         sibling ? G_NODE (sibling->user_data) : NULL,
990                         new_node);
991
992   iter->stamp = model->stamp;
993   iter->user_data = new_node;
994
995   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
996   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
997
998   gtk_tree_path_free (path);
999
1000   validate_tree ((GtkTreeStore*)model);
1001 }
1002
1003 void
1004 gtk_tree_store_insert_after (GtkTreeStore *model,
1005                              GtkTreeIter  *iter,
1006                              GtkTreeIter  *parent,
1007                              GtkTreeIter  *sibling)
1008 {
1009   GtkTreePath *path;
1010   GNode *parent_node;
1011   GNode *new_node;
1012
1013   g_return_if_fail (GTK_IS_TREE_STORE (model));
1014   g_return_if_fail (iter != NULL);
1015   if (parent != NULL)
1016     g_return_if_fail (VALID_ITER (parent, model));
1017   if (sibling != NULL)
1018     g_return_if_fail (VALID_ITER (sibling, model));
1019
1020   new_node = g_node_new (NULL);
1021
1022   if (parent == NULL && sibling == NULL)
1023     parent_node = model->root;
1024   else if (parent == NULL)
1025     parent_node = G_NODE (sibling->user_data)->parent;
1026   else if (sibling == NULL)
1027     parent_node = G_NODE (parent->user_data);
1028   else
1029     {
1030       g_return_if_fail (G_NODE (sibling->user_data)->parent ==
1031                         G_NODE (parent->user_data));
1032       parent_node = G_NODE (parent->user_data);
1033     }
1034
1035
1036   g_node_insert_after (parent_node,
1037                        sibling ? G_NODE (sibling->user_data) : NULL,
1038                        new_node);
1039
1040   iter->stamp = model->stamp;
1041   iter->user_data = new_node;
1042
1043   path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
1044   gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
1045
1046   gtk_tree_path_free (path);
1047
1048   validate_tree ((GtkTreeStore*)model);
1049 }
1050
1051 void
1052 gtk_tree_store_prepend (GtkTreeStore *model,
1053                         GtkTreeIter  *iter,
1054                         GtkTreeIter  *parent)
1055 {
1056   GNode *parent_node;
1057
1058   g_return_if_fail (GTK_IS_TREE_STORE (model));
1059   g_return_if_fail (iter != NULL);
1060   if (parent != NULL)
1061     g_return_if_fail (VALID_ITER (parent, model));
1062
1063   if (parent == NULL)
1064     parent_node = model->root;
1065   else
1066     parent_node = parent->user_data;
1067
1068   if (parent_node->children == NULL)
1069     {
1070       GtkTreePath *path;
1071
1072       iter->stamp = model->stamp;
1073       iter->user_data = g_node_new (NULL);
1074
1075       g_node_prepend (parent_node, iter->user_data);
1076
1077       if (parent_node != model->root)
1078         {
1079           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
1080           gtk_tree_model_has_child_toggled (GTK_TREE_MODEL (model), path, parent);
1081           gtk_tree_path_append_index (path, 0);
1082         }
1083       else
1084         {
1085           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
1086         }
1087       gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
1088       gtk_tree_path_free (path);
1089     }
1090   else
1091     {
1092       gtk_tree_store_insert_after (model, iter, parent, NULL);
1093     }
1094
1095   validate_tree ((GtkTreeStore*)model);
1096 }
1097
1098 void
1099 gtk_tree_store_append (GtkTreeStore *model,
1100                        GtkTreeIter  *iter,
1101                        GtkTreeIter  *parent)
1102 {
1103   GNode *parent_node;
1104
1105   g_return_if_fail (GTK_IS_TREE_STORE (model));
1106   g_return_if_fail (iter != NULL);
1107   if (parent != NULL)
1108     g_return_if_fail (VALID_ITER (parent, model));
1109
1110   if (parent == NULL)
1111     parent_node = model->root;
1112   else
1113     parent_node = parent->user_data;
1114
1115   if (parent_node->children == NULL)
1116     {
1117       GtkTreePath *path;
1118
1119       iter->stamp = model->stamp;
1120       iter->user_data = g_node_new (NULL);
1121
1122       g_node_append (parent_node, G_NODE (iter->user_data));
1123
1124       if (parent_node != model->root)
1125         {
1126           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
1127           gtk_tree_model_has_child_toggled (GTK_TREE_MODEL (model), path, parent);
1128           gtk_tree_path_append_index (path, 0);
1129         }
1130       else
1131         {
1132           path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
1133         }
1134
1135       gtk_tree_model_inserted (GTK_TREE_MODEL (model), path, iter);
1136       gtk_tree_path_free (path);
1137     }
1138   else
1139     {
1140       gtk_tree_store_insert_before (model, iter, parent, NULL);
1141     }
1142
1143   validate_tree ((GtkTreeStore*)model);
1144 }
1145
1146 gboolean
1147 gtk_tree_store_is_ancestor (GtkTreeStore *model,
1148                             GtkTreeIter  *iter,
1149                             GtkTreeIter  *descendant)
1150 {
1151   g_return_val_if_fail (GTK_IS_TREE_STORE (model), FALSE);
1152   g_return_val_if_fail (VALID_ITER (iter, model), FALSE);
1153   g_return_val_if_fail (VALID_ITER (descendant, model), FALSE);
1154
1155   return g_node_is_ancestor (G_NODE (iter->user_data),
1156                              G_NODE (descendant->user_data));
1157 }
1158
1159
1160 gint
1161 gtk_tree_store_iter_depth (GtkTreeStore *model,
1162                            GtkTreeIter  *iter)
1163 {
1164   g_return_val_if_fail (GTK_IS_TREE_STORE (model), 0);
1165   g_return_val_if_fail (VALID_ITER (iter, model), 0);
1166
1167   return g_node_depth (G_NODE (iter->user_data)) - 1;
1168 }
1169
1170
1171 void
1172 gtk_tree_store_clear (GtkTreeStore *tree_store)
1173 {
1174   GtkTreeIter iter;
1175
1176   g_return_if_fail (GTK_IS_TREE_STORE (tree_store));
1177
1178   while (G_NODE (tree_store->root)->children)
1179     {
1180       iter.stamp = tree_store->stamp;
1181       iter.user_data = G_NODE (tree_store->root)->children;
1182       gtk_tree_store_remove (tree_store, &iter);
1183     }
1184 }
1185
1186 /* DND */
1187
1188
1189 static gboolean
1190 gtk_tree_store_drag_data_delete (GtkTreeDragSource *drag_source,
1191                                  GtkTreePath       *path)
1192 {
1193   GtkTreeIter iter;
1194
1195   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1196
1197   if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
1198                                &iter,
1199                                path))
1200     {
1201       gtk_tree_store_remove (GTK_TREE_STORE (drag_source),
1202                              &iter);
1203       return TRUE;
1204     }
1205   else
1206     {
1207       return FALSE;
1208     }
1209 }
1210
1211 static gboolean
1212 gtk_tree_store_drag_data_get (GtkTreeDragSource *drag_source,
1213                               GtkTreePath       *path,
1214                               GtkSelectionData  *selection_data)
1215 {
1216   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_source), FALSE);
1217
1218   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1219    * target, because the default handler does it for us, but
1220    * we do anyway for the convenience of someone maybe overriding the
1221    * default handler.
1222    */
1223
1224   if (gtk_selection_data_set_tree_row (selection_data,
1225                                        GTK_TREE_MODEL (drag_source),
1226                                        path))
1227     {
1228       return TRUE;
1229     }
1230   else
1231     {
1232       /* FIXME handle text targets at least. */
1233     }
1234
1235   return FALSE;
1236 }
1237
1238 static void
1239 copy_node_data (GtkTreeStore *tree_store,
1240                 GtkTreeIter  *src_iter,
1241                 GtkTreeIter  *dest_iter)
1242 {
1243   GtkTreeDataList *dl = G_NODE (src_iter->user_data)->data;
1244   GtkTreeDataList *copy_head = NULL;
1245   GtkTreeDataList *copy_prev = NULL;
1246   GtkTreeDataList *copy_iter = NULL;
1247   GtkTreePath *path;
1248   gint col;
1249
1250   col = 0;
1251   while (dl)
1252     {
1253       copy_iter = _gtk_tree_data_list_node_copy (dl, tree_store->column_headers[col]);
1254
1255       if (copy_head == NULL)
1256         copy_head = copy_iter;
1257
1258       if (copy_prev)
1259         copy_prev->next = copy_iter;
1260
1261       copy_prev = copy_iter;
1262
1263       dl = dl->next;
1264       ++col;
1265     }
1266
1267   G_NODE (dest_iter->user_data)->data = copy_head;
1268
1269   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), dest_iter);
1270   gtk_tree_model_range_changed (GTK_TREE_MODEL (tree_store), path, dest_iter, path, dest_iter);
1271   gtk_tree_path_free (path);
1272 }
1273
1274 static void
1275 recursive_node_copy (GtkTreeStore *tree_store,
1276                      GtkTreeIter  *src_iter,
1277                      GtkTreeIter  *dest_iter)
1278 {
1279   GtkTreeIter child;
1280   GtkTreeModel *model;
1281
1282   model = GTK_TREE_MODEL (tree_store);
1283
1284   copy_node_data (tree_store, src_iter, dest_iter);
1285
1286   if (gtk_tree_model_iter_children (model,
1287                                     &child,
1288                                     src_iter))
1289     {
1290       /* Need to create children and recurse. Note our
1291        * dependence on persistent iterators here.
1292        */
1293       do
1294         {
1295           GtkTreeIter copy;
1296
1297           /* Gee, a really slow algorithm... ;-) FIXME */
1298           gtk_tree_store_append (tree_store,
1299                                  &copy,
1300                                  dest_iter);
1301
1302           recursive_node_copy (tree_store, &child, &copy);
1303         }
1304       while (gtk_tree_model_iter_next (model, &child));
1305     }
1306 }
1307
1308 static gboolean
1309 gtk_tree_store_drag_data_received (GtkTreeDragDest   *drag_dest,
1310                                    GtkTreePath       *dest,
1311                                    GtkSelectionData  *selection_data)
1312 {
1313   GtkTreeModel *tree_model;
1314   GtkTreeStore *tree_store;
1315   GtkTreeModel *src_model = NULL;
1316   GtkTreePath *src_path = NULL;
1317   gboolean retval = FALSE;
1318
1319   g_return_val_if_fail (GTK_IS_TREE_STORE (drag_dest), FALSE);
1320
1321   tree_model = GTK_TREE_MODEL (drag_dest);
1322   tree_store = GTK_TREE_STORE (drag_dest);
1323
1324   validate_tree (tree_store);
1325
1326   if (gtk_selection_data_get_tree_row (selection_data,
1327                                        &src_model,
1328                                        &src_path) &&
1329       src_model == tree_model)
1330     {
1331       /* Copy the given row to a new position */
1332       GtkTreeIter src_iter;
1333       GtkTreeIter dest_iter;
1334       GtkTreePath *prev;
1335
1336       if (!gtk_tree_model_get_iter (src_model,
1337                                     &src_iter,
1338                                     src_path))
1339         {
1340           goto out;
1341         }
1342
1343       /* Get the path to insert _after_ (dest is the path to insert _before_) */
1344       prev = gtk_tree_path_copy (dest);
1345
1346       if (!gtk_tree_path_prev (prev))
1347         {
1348           GtkTreeIter dest_parent;
1349           GtkTreePath *parent;
1350           GtkTreeIter *dest_parent_p;
1351
1352           /* dest was the first spot at the current depth; which means
1353            * we are supposed to prepend.
1354            */
1355
1356           /* Get the parent, NULL if parent is the root */
1357           dest_parent_p = NULL;
1358           parent = gtk_tree_path_copy (dest);
1359           if (gtk_tree_path_up (parent))
1360             {
1361               gtk_tree_model_get_iter (tree_model,
1362                                        &dest_parent,
1363                                        parent);
1364               dest_parent_p = &dest_parent;
1365             }
1366           gtk_tree_path_free (parent);
1367           parent = NULL;
1368
1369           gtk_tree_store_prepend (GTK_TREE_STORE (tree_model),
1370                                   &dest_iter,
1371                                   dest_parent_p);
1372
1373           retval = TRUE;
1374         }
1375       else
1376         {
1377           if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
1378                                        &dest_iter,
1379                                        prev))
1380             {
1381               GtkTreeIter tmp_iter = dest_iter;
1382               gtk_tree_store_insert_after (GTK_TREE_STORE (tree_model),
1383                                            &dest_iter,
1384                                            NULL,
1385                                            &tmp_iter);
1386               retval = TRUE;
1387
1388             }
1389         }
1390
1391       gtk_tree_path_free (prev);
1392
1393       /* If we succeeded in creating dest_iter, walk src_iter tree branch,
1394        * duplicating it below dest_iter.
1395        */
1396
1397       if (retval)
1398         {
1399           recursive_node_copy (tree_store,
1400                                &src_iter,
1401                                &dest_iter);
1402         }
1403     }
1404   else
1405     {
1406       /* FIXME maybe add some data targets eventually, or handle text
1407        * targets in the simple case.
1408        */
1409
1410     }
1411
1412  out:
1413
1414   if (src_path)
1415     gtk_tree_path_free (src_path);
1416
1417   return retval;
1418 }
1419
1420 static gboolean
1421 gtk_tree_store_row_drop_possible (GtkTreeDragDest *drag_dest,
1422                                   GtkTreeModel    *src_model,
1423                                   GtkTreePath     *src_path,
1424                                   GtkTreePath     *dest_path)
1425 {
1426   /* can only drag to ourselves */
1427   if (src_model != GTK_TREE_MODEL (drag_dest))
1428     return FALSE;
1429
1430   /* Can't drop into ourself. */
1431   if (gtk_tree_path_is_ancestor (src_path,
1432                                  dest_path))
1433     return FALSE;
1434
1435   /* Can't drop if dest_path's parent doesn't exist */
1436   {
1437     GtkTreeIter iter;
1438     GtkTreePath *tmp = gtk_tree_path_copy (dest_path);
1439
1440     /* if we can't go up, we know the parent exists, the root
1441      * always exists.
1442      */
1443     if (gtk_tree_path_up (tmp))
1444       {
1445         if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_dest),
1446                                       &iter, tmp))
1447           {
1448             if (tmp)
1449               gtk_tree_path_free (tmp);
1450             return FALSE;
1451           }
1452       }
1453
1454     if (tmp)
1455       gtk_tree_path_free (tmp);
1456   }
1457
1458   /* Can otherwise drop anywhere. */
1459   return TRUE;
1460 }
1461
1462 /* Sorting */
1463 typedef struct _SortTuple
1464 {
1465   gint offset;
1466   GNode *node;
1467 } SortTuple;
1468
1469 static gint
1470 gtk_tree_store_compare_func (gconstpointer a,
1471                              gconstpointer b,
1472                              gpointer      user_data)
1473 {
1474   GtkTreeStore *tree_store = user_data;
1475   GtkTreeDataSortHeader *header = NULL;
1476   GNode *node_a;
1477   GNode *node_b;
1478   GtkTreeIter iter_a;
1479   GtkTreeIter iter_b;
1480   gint retval;
1481
1482   header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1483                                            tree_store->sort_column_id);
1484
1485   g_return_val_if_fail (header != NULL, 0);
1486   g_return_val_if_fail (header->func != NULL, 0);
1487
1488   node_a = ((SortTuple *) a)->node;
1489   node_b = ((SortTuple *) b)->node;
1490
1491   iter_a.stamp = tree_store->stamp;
1492   iter_a.user_data = node_a;
1493   iter_b.stamp = tree_store->stamp;
1494   iter_b.user_data = node_b;
1495
1496   retval = (* header->func) (GTK_TREE_MODEL (user_data),
1497                              &iter_a, &iter_b,
1498                              header->data);
1499
1500   if (tree_store->order == GTK_TREE_SORT_DESCENDING)
1501     {
1502       if (retval > 0)
1503         retval = -1;
1504       else if (retval < 0)
1505         retval = 1;
1506     }
1507   return retval;
1508 }
1509
1510 static void
1511 gtk_tree_store_sort_helper (GtkTreeStore *tree_store,
1512                             GNode        *parent,
1513                             gboolean      recurse)
1514 {
1515   GtkTreeDataSortHeader *header = NULL;
1516   GtkTreeIter iter;
1517   GArray *sort_array;
1518   GNode *node;
1519   GNode *tmp_node;
1520   gint list_length;
1521   gint i;
1522   gint *new_order;
1523   GtkTreePath *path;
1524
1525   node = parent->children;
1526   if (node->next == NULL)
1527     return;
1528
1529   g_assert (GTK_TREE_STORE_IS_SORTED (tree_store));
1530
1531   header = _gtk_tree_data_list_get_header (tree_store->sort_list, tree_store->sort_column_id);
1532
1533   /* We want to make sure that we have a function */
1534   g_return_if_fail (header != NULL);
1535   g_return_if_fail (header->func != NULL);
1536
1537   list_length = 0;
1538   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1539     list_length++;
1540
1541   sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), list_length);
1542
1543   i = 0;
1544   for (tmp_node = node; tmp_node; tmp_node = tmp_node->next)
1545     {
1546       SortTuple tuple;
1547
1548       tuple.offset = i;
1549       tuple.node = tmp_node;
1550       g_array_append_val (sort_array, tuple);
1551       i++;
1552     }
1553
1554   g_array_sort_with_data (sort_array, gtk_tree_store_compare_func, tree_store);
1555
1556   for (i = 0; i < list_length - 1; i++)
1557     {
1558       g_array_index (sort_array, SortTuple, i).node->next =
1559         g_array_index (sort_array, SortTuple, i + 1).node;
1560       g_array_index (sort_array, SortTuple, i + 1).node->prev =
1561         g_array_index (sort_array, SortTuple, i).node;
1562     }
1563   g_array_index (sort_array, SortTuple, list_length - 1).node->next = NULL;
1564   g_array_index (sort_array, SortTuple, 0).node->prev = NULL;
1565   parent->children = g_array_index (sort_array, SortTuple, 0).node;
1566
1567   /* Let the world know about our new order */
1568   new_order = g_new (gint, list_length);
1569   for (i = 0; i < list_length; i++)
1570     new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1571
1572   iter.stamp = tree_store->stamp;
1573   iter.user_data = parent;
1574   path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &iter);
1575   gtk_tree_model_reordered (GTK_TREE_MODEL (tree_store),
1576                             path, &iter, new_order);
1577   gtk_tree_path_free (path);
1578   g_free (new_order);
1579   g_array_free (sort_array, TRUE);
1580
1581   if (recurse)
1582     {
1583       for (tmp_node = parent->children; tmp_node; tmp_node = tmp_node->next)
1584         {
1585           if (tmp_node->children)
1586             gtk_tree_store_sort_helper (tree_store, tmp_node, TRUE);
1587         }
1588     }
1589 }
1590
1591 static void
1592 gtk_tree_store_sort (GtkTreeStore *tree_store)
1593 {
1594   gtk_tree_store_sort_helper (tree_store, G_NODE (tree_store->root), TRUE);
1595 }
1596
1597 static void
1598 gtk_tree_store_sort_iter_changed (GtkTreeStore *tree_store,
1599                                   GtkTreeIter  *iter,
1600                                   gint          column)
1601 {
1602   GtkTreeDataSortHeader *header;
1603   GNode *prev = NULL;
1604   GNode *next = NULL;
1605   GNode *node;
1606   GtkTreePath *tmp_path;
1607   GtkTreeIter tmp_iter;
1608   gint cmp_a = 0;
1609   gint cmp_b = 0;
1610   gint i;
1611   gint old_location;
1612   gint new_location;
1613   gint *new_order;
1614   gint length;
1615
1616   g_return_if_fail (G_NODE (iter->user_data)->parent != NULL);
1617
1618
1619   tmp_iter.stamp = tree_store->stamp;
1620   header = _gtk_tree_data_list_get_header (tree_store->sort_list,
1621                                            tree_store->sort_column_id);
1622   g_return_if_fail (header != NULL);
1623   g_return_if_fail (header->func != NULL);
1624
1625   /* If it's the built in function, we don't sort. */
1626   if (header->func == gtk_tree_data_list_compare_func &&
1627       tree_store->sort_column_id != column)
1628     return;
1629
1630   old_location = 0;
1631   node = G_NODE (iter->user_data)->parent->children;
1632   /* First we find the iter, its prev, and its next */
1633   while (node)
1634     {
1635       if (node == G_NODE (iter->user_data))
1636         break;
1637       old_location++;
1638       node = node->next;
1639     }
1640   g_assert (node != NULL);
1641
1642   prev = node->prev;
1643   next = node->next;
1644
1645   /* Check the common case, where we don't need to sort it moved. */
1646   if (prev != NULL)
1647     {
1648       tmp_iter.user_data = prev;
1649       cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1650                                 &tmp_iter, iter,
1651                                 header->data);
1652     }
1653
1654   if (next != NULL)
1655     {
1656       tmp_iter.user_data = next;
1657       cmp_b = (* header->func) (GTK_TREE_MODEL (tree_store),
1658                                 iter, &tmp_iter,
1659                                 header->data);
1660     }
1661
1662
1663   if (tree_store->order == GTK_TREE_SORT_DESCENDING)
1664     {
1665       if (cmp_a < 0)
1666         cmp_a = 1;
1667       else if (cmp_a > 0)
1668         cmp_a = -1;
1669
1670       if (cmp_b < 0)
1671         cmp_b = 1;
1672       else if (cmp_b > 0)
1673         cmp_b = -1;
1674     }
1675
1676   if (prev == NULL && cmp_b <= 0)
1677     return;
1678   else if (next == NULL && cmp_a <= 0)
1679     return;
1680   else if (prev != NULL && next != NULL &&
1681            cmp_a <= 0 && cmp_b <= 0)
1682     return;
1683
1684   /* We actually need to sort it */
1685   /* First, remove the old link. */
1686
1687   if (prev)
1688     prev->next = next;
1689   else
1690     node->parent->children = next;
1691   if (next)
1692     next->prev = prev;
1693
1694   node->prev = NULL;
1695   node->next = NULL;
1696
1697   /* FIXME: as an optimization, we can potentially start at next */
1698   prev = NULL;
1699   node = node->parent->children;
1700   new_location = 0;
1701   tmp_iter.user_data = node;
1702   if (tree_store->order == GTK_TREE_SORT_DESCENDING)
1703     cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1704                               &tmp_iter, iter, header->data);
1705   else
1706     cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1707                               iter, &tmp_iter, header->data);
1708
1709   while ((node->next) && (cmp_a > 0))
1710     {
1711       prev = node;
1712       node = node->next;
1713       new_location++;
1714       tmp_iter.user_data = node;
1715       if (tree_store->order == GTK_TREE_SORT_DESCENDING)
1716         cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1717                                   &tmp_iter, iter, header->data);
1718       else
1719         cmp_a = (* header->func) (GTK_TREE_MODEL (tree_store),
1720                                   iter, &tmp_iter, header->data);
1721     }
1722
1723   if ((!node->next) && (cmp_a > 0))
1724     {
1725       node->next = G_NODE (iter->user_data);
1726       node->next->prev = node;
1727     }
1728   else if (prev)
1729     {
1730       prev->next = G_NODE (iter->user_data);
1731       prev->next->prev = prev;
1732       G_NODE (iter->user_data)->next = node;
1733       G_NODE (iter->user_data)->next->prev = G_NODE (iter->user_data);
1734     }
1735   else
1736     {
1737       G_NODE (iter->user_data)->next = G_NODE (iter->user_data)->parent->children;
1738       G_NODE (iter->user_data)->parent->children = G_NODE (iter->user_data);
1739     }
1740
1741   /* Emit the reordered signal. */
1742   length = g_node_n_children (node->parent);
1743   new_order = g_new (int, length);
1744   if (old_location < new_location)
1745     for (i = 0; i < length; i++)
1746       {
1747         if (i < old_location ||
1748             i > new_location)
1749           new_order[i] = i;
1750         else if (i >= old_location &&
1751                  i < new_location)
1752           new_order[i] = i + 1;
1753         else if (i == new_location)
1754           new_order[i] = old_location;
1755       }
1756   else
1757     for (i = 0; i < length; i++)
1758       {
1759         if (i < new_location ||
1760             i > old_location)
1761           new_order[i] = i;
1762         else if (i > new_location &&
1763                  i <= old_location)
1764           new_order[i] = i - 1;
1765         else if (i == new_location)
1766           new_order[i] = old_location;
1767       }
1768
1769   tmp_iter.user_data = node->parent;
1770   tmp_path = gtk_tree_store_get_path (GTK_TREE_MODEL (tree_store), &tmp_iter);
1771
1772   gtk_tree_model_reordered (GTK_TREE_MODEL (tree_store),
1773                             tmp_path, &tmp_iter,
1774                             new_order);
1775
1776   gtk_tree_path_free (tmp_path);
1777   g_free (new_order);
1778 }
1779
1780
1781 static gboolean
1782 gtk_tree_store_get_sort_column_id (GtkTreeSortable  *sortable,
1783                                    gint             *sort_column_id,
1784                                    GtkTreeSortOrder *order)
1785 {
1786   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
1787
1788   g_return_val_if_fail (sortable != NULL, FALSE);
1789   g_return_val_if_fail (GTK_IS_TREE_STORE (sortable), FALSE);
1790
1791   if (tree_store->sort_column_id == -1)
1792     return FALSE;
1793
1794   if (sort_column_id)
1795     * sort_column_id = tree_store->sort_column_id;
1796   if (order)
1797     * order = tree_store->order;
1798   return TRUE;
1799
1800 }
1801
1802 static void
1803 gtk_tree_store_set_sort_column_id (GtkTreeSortable  *sortable,
1804                                    gint              sort_column_id,
1805                                    GtkTreeSortOrder  order)
1806 {
1807   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
1808   GList *list;
1809
1810   g_return_if_fail (sortable != NULL);
1811   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
1812
1813   for (list = tree_store->sort_list; list; list = list->next)
1814     {
1815       GtkTreeDataSortHeader *header = (GtkTreeDataSortHeader*) list->data;
1816       if (header->sort_column_id == sort_column_id)
1817         break;
1818     }
1819   g_return_if_fail (list != NULL);
1820
1821   if ((tree_store->sort_column_id == sort_column_id) &&
1822       (tree_store->order == order))
1823     return;
1824
1825   tree_store->sort_column_id = sort_column_id;
1826   tree_store->order = order;
1827
1828   if (tree_store->sort_column_id >= 0)
1829     gtk_tree_store_sort (tree_store);
1830
1831   gtk_tree_sortable_sort_column_changed (sortable);
1832 }
1833
1834 static void
1835 gtk_tree_store_set_sort_func (GtkTreeSortable        *sortable,
1836                               gint                    sort_column_id,
1837                               GtkTreeIterCompareFunc  func,
1838                               gpointer                data,
1839                               GtkDestroyNotify        destroy)
1840 {
1841   GtkTreeStore *tree_store = (GtkTreeStore *) sortable;
1842   GtkTreeDataSortHeader *header = NULL;
1843   GList *list;
1844
1845   g_return_if_fail (sortable != NULL);
1846   g_return_if_fail (GTK_IS_TREE_STORE (sortable));
1847   g_return_if_fail (func != NULL);
1848
1849   for (list = tree_store->sort_list; list; list = list->next)
1850     {
1851       header = (GtkTreeDataSortHeader*) list->data;
1852       if (header->sort_column_id == sort_column_id)
1853         break;
1854     }
1855
1856   if (header == NULL)
1857     {
1858       header = g_new0 (GtkTreeDataSortHeader, 1);
1859       header->sort_column_id = sort_column_id;
1860       tree_store->sort_list = g_list_append (tree_store->sort_list, header);
1861     }
1862
1863   if (header->destroy)
1864     (* header->destroy) (header->data);
1865
1866   header->func = func;
1867   header->data = data;
1868   header->destroy = destroy;
1869
1870 }
1871
1872 static void
1873 validate_gnode (GNode* node)
1874 {
1875   GNode *iter;
1876
1877   iter = node->children;
1878   while (iter != NULL)
1879     {
1880       g_assert (iter->parent == node);
1881       if (iter->prev)
1882         g_assert (iter->prev->next == iter);
1883       validate_gnode (iter);
1884       iter = iter->next;
1885     }
1886 }
1887
1888
1889