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