]> Pileus Git - ~andy/gtk/blob - gtk/gtkliststore.c
Make GtkTreeRowReference a boxed type.
[~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_slist_foreach (list_store->root, (GFunc) _gtk_tree_data_list_free, list_store->column_headers);
428   g_slist_free (list_store->root);
429
430   _gtk_tree_data_list_header_free (list_store->sort_list);
431   g_free (list_store->column_headers);
432   
433   if (list_store->default_sort_destroy)
434     {
435       GtkDestroyNotify d = list_store->default_sort_destroy;
436
437       list_store->default_sort_destroy = NULL;
438       d (list_store->default_sort_data);
439       list_store->default_sort_data = NULL;
440     }
441
442   /* must chain up */
443   (* parent_class->finalize) (object);
444 }
445
446 /* Fulfill the GtkTreeModel requirements */
447 static guint
448 gtk_list_store_get_flags (GtkTreeModel *tree_model)
449 {
450   g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), 0);
451
452   return GTK_TREE_MODEL_ITERS_PERSIST | GTK_TREE_MODEL_LIST_ONLY;
453 }
454
455 static gint
456 gtk_list_store_get_n_columns (GtkTreeModel *tree_model)
457 {
458   GtkListStore *list_store = (GtkListStore *) tree_model;
459
460   g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), 0);
461
462   list_store->columns_dirty = TRUE;
463
464   return list_store->n_columns;
465 }
466
467 static GType
468 gtk_list_store_get_column_type (GtkTreeModel *tree_model,
469                                 gint          index)
470 {
471   GtkListStore *list_store = (GtkListStore *) tree_model;
472
473   g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), G_TYPE_INVALID);
474   g_return_val_if_fail (index < GTK_LIST_STORE (tree_model)->n_columns &&
475                         index >= 0, G_TYPE_INVALID);
476
477   list_store->columns_dirty = TRUE;
478
479   return list_store->column_headers[index];
480 }
481
482 static gboolean
483 gtk_list_store_get_iter (GtkTreeModel *tree_model,
484                          GtkTreeIter  *iter,
485                          GtkTreePath  *path)
486 {
487   GtkListStore *list_store = (GtkListStore *) tree_model;
488   GSList *list;
489   gint i;
490
491   g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
492   g_return_val_if_fail (gtk_tree_path_get_depth (path) > 0, FALSE);
493
494   list_store->columns_dirty = TRUE;
495
496   i = gtk_tree_path_get_indices (path)[0];
497
498   if (i >= list_store->length)
499     return FALSE;
500
501   list = g_slist_nth (G_SLIST (list_store->root), i);
502
503   /* If this fails, list_store->length has gotten mangled. */
504   g_assert (list);
505
506   iter->stamp = list_store->stamp;
507   iter->user_data = list;
508
509   return TRUE;
510 }
511
512 static GtkTreePath *
513 gtk_list_store_get_path (GtkTreeModel *tree_model,
514                          GtkTreeIter  *iter)
515 {
516   GtkTreePath *retval;
517   GSList *list;
518   gint i = 0;
519
520   g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), NULL);
521   g_return_val_if_fail (iter->stamp == GTK_LIST_STORE (tree_model)->stamp, NULL);
522   if (G_SLIST (iter->user_data) == G_SLIST (GTK_LIST_STORE (tree_model)->tail))
523     {
524       retval = gtk_tree_path_new ();
525       gtk_tree_path_append_index (retval, GTK_LIST_STORE (tree_model)->length - 1);
526       return retval;
527     }
528
529   for (list = G_SLIST (GTK_LIST_STORE (tree_model)->root); list; list = list->next)
530     {
531       if (list == G_SLIST (iter->user_data))
532         break;
533       i++;
534     }
535   if (list == NULL)
536     return NULL;
537
538   retval = gtk_tree_path_new ();
539   gtk_tree_path_append_index (retval, i);
540   return retval;
541 }
542
543 static void
544 gtk_list_store_get_value (GtkTreeModel *tree_model,
545                           GtkTreeIter  *iter,
546                           gint          column,
547                           GValue       *value)
548 {
549   GtkTreeDataList *list;
550   gint tmp_column = column;
551
552   g_return_if_fail (GTK_IS_LIST_STORE (tree_model));
553   g_return_if_fail (column < GTK_LIST_STORE (tree_model)->n_columns);
554   g_return_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp);
555
556   list = G_SLIST (iter->user_data)->data;
557
558   while (tmp_column-- > 0 && list)
559     list = list->next;
560
561   if (list == NULL)
562     g_value_init (value, GTK_LIST_STORE (tree_model)->column_headers[column]);
563   else
564     _gtk_tree_data_list_node_to_value (list,
565                                        GTK_LIST_STORE (tree_model)->column_headers[column],
566                                        value);
567 }
568
569 static gboolean
570 gtk_list_store_iter_next (GtkTreeModel  *tree_model,
571                           GtkTreeIter   *iter)
572 {
573   g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
574   g_return_val_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp, FALSE);
575
576   iter->user_data = G_SLIST (iter->user_data)->next;
577
578   return (iter->user_data != NULL);
579 }
580
581 static gboolean
582 gtk_list_store_iter_children (GtkTreeModel *tree_model,
583                               GtkTreeIter  *iter,
584                               GtkTreeIter  *parent)
585 {
586   /* this is a list, nodes have no children */
587   if (parent)
588     return FALSE;
589
590   /* but if parent == NULL we return the list itself as children of the
591    * "root"
592    */
593
594   if (GTK_LIST_STORE (tree_model)->root)
595     {
596       iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
597       iter->user_data = GTK_LIST_STORE (tree_model)->root;
598       return TRUE;
599     }
600   else
601     return FALSE;
602 }
603
604 static gboolean
605 gtk_list_store_iter_has_child (GtkTreeModel *tree_model,
606                                GtkTreeIter  *iter)
607 {
608   return FALSE;
609 }
610
611 static gint
612 gtk_list_store_iter_n_children (GtkTreeModel *tree_model,
613                                 GtkTreeIter  *iter)
614 {
615   g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), -1);
616   if (iter == NULL)
617     return GTK_LIST_STORE (tree_model)->length;
618
619   g_return_val_if_fail (GTK_LIST_STORE (tree_model)->stamp == iter->stamp, -1);
620   return 0;
621 }
622
623 static gboolean
624 gtk_list_store_iter_nth_child (GtkTreeModel *tree_model,
625                                GtkTreeIter  *iter,
626                                GtkTreeIter  *parent,
627                                gint          n)
628 {
629   GSList *child;
630
631   g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), FALSE);
632
633   if (parent)
634     return FALSE;
635
636   child = g_slist_nth (G_SLIST (GTK_LIST_STORE (tree_model)->root), n);
637
638   if (child)
639     {
640       iter->stamp = GTK_LIST_STORE (tree_model)->stamp;
641       iter->user_data = child;
642       return TRUE;
643     }
644   else
645     return FALSE;
646 }
647
648 static gboolean
649 gtk_list_store_iter_parent (GtkTreeModel *tree_model,
650                             GtkTreeIter  *iter,
651                             GtkTreeIter  *child)
652 {
653   return FALSE;
654 }
655
656 static gboolean
657 gtk_list_store_real_set_value (GtkListStore *list_store,
658                                GtkTreeIter  *iter,
659                                gint          column,
660                                GValue       *value,
661                                gboolean      sort)
662 {
663   GtkTreeDataList *list;
664   GtkTreeDataList *prev;
665   gint old_column = column;
666   GValue real_value = {0, };
667   gboolean converted = FALSE;
668   gboolean retval = FALSE;
669
670   g_return_val_if_fail (GTK_IS_LIST_STORE (list_store), FALSE);
671   g_return_val_if_fail (VALID_ITER (iter, list_store), FALSE);
672   g_return_val_if_fail (column >= 0 && column < list_store->n_columns, FALSE);
673   g_return_val_if_fail (G_IS_VALUE (value), FALSE);
674
675   if (! g_type_is_a (G_VALUE_TYPE (value), list_store->column_headers[column]))
676     {
677       if (! (g_value_type_compatible (G_VALUE_TYPE (value), list_store->column_headers[column]) &&
678              g_value_type_compatible (list_store->column_headers[column], G_VALUE_TYPE (value))))
679         {
680           g_warning ("%s: Unable to convert from %s to %s\n",
681                      G_STRLOC,
682                      g_type_name (G_VALUE_TYPE (value)),
683                      g_type_name (list_store->column_headers[column]));
684           return retval;
685         }
686       if (!g_value_transform (value, &real_value))
687         {
688           g_warning ("%s: Unable to make conversion from %s to %s\n",
689                      G_STRLOC,
690                      g_type_name (G_VALUE_TYPE (value)),
691                      g_type_name (list_store->column_headers[column]));
692           g_value_unset (&real_value);
693           return retval;
694         }
695       converted = TRUE;
696     }
697
698   prev = list = G_SLIST (iter->user_data)->data;
699
700   while (list != NULL)
701     {
702       if (column == 0)
703         {
704           if (converted)
705             _gtk_tree_data_list_value_to_node (list, &real_value);
706           else
707             _gtk_tree_data_list_value_to_node (list, value);
708           retval = TRUE;
709           if (converted)
710             g_value_unset (&real_value);
711           return retval;
712         }
713
714       column--;
715       prev = list;
716       list = list->next;
717     }
718
719   if (G_SLIST (iter->user_data)->data == NULL)
720     {
721       G_SLIST (iter->user_data)->data = list = _gtk_tree_data_list_alloc ();
722       list->next = NULL;
723     }
724   else
725     {
726       list = prev->next = _gtk_tree_data_list_alloc ();
727       list->next = NULL;
728     }
729
730   while (column != 0)
731     {
732       list->next = _gtk_tree_data_list_alloc ();
733       list = list->next;
734       list->next = NULL;
735       column --;
736     }
737
738   if (converted)
739     _gtk_tree_data_list_value_to_node (list, &real_value);
740   else
741     _gtk_tree_data_list_value_to_node (list, value);
742
743   retval = TRUE;
744   if (converted)
745     g_value_unset (&real_value);
746
747   if (sort && GTK_LIST_STORE_IS_SORTED (list_store))
748     gtk_list_store_sort_iter_changed (list_store, iter, old_column);
749
750   return retval;
751 }
752
753
754 /**
755  * gtk_list_store_set_value:
756  * @list_store: A #GtkListStore
757  * @iter: A valid #GtkTreeIter for the row being modified
758  * @column: column number to modify
759  * @value: new value for the cell
760  *
761  * Sets the data in the cell specified by @iter and @column.
762  * The type of @value must be convertible to the type of the
763  * column.
764  *
765  **/
766 void
767 gtk_list_store_set_value (GtkListStore *list_store,
768                           GtkTreeIter  *iter,
769                           gint          column,
770                           GValue       *value)
771 {
772   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
773   g_return_if_fail (VALID_ITER (iter, list_store));
774   g_return_if_fail (column >= 0 && column < list_store->n_columns);
775   g_return_if_fail (G_IS_VALUE (value));
776
777   if (gtk_list_store_real_set_value (list_store, iter, column, value, TRUE))
778     {
779       GtkTreePath *path;
780
781       path = gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), iter);
782       gtk_tree_model_row_changed (GTK_TREE_MODEL (list_store), path, iter);
783       gtk_tree_path_free (path);
784     }
785 }
786
787 /**
788  * gtk_list_store_set_valist:
789  * @list_store: A #GtkListStore
790  * @iter: A valid #GtkTreeIter for the row being modified
791  * @var_args: va_list of column/value pairs
792  *
793  * See gtk_list_store_set(); this version takes a va_list for use by language
794  * bindings.
795  *
796  **/
797 void
798 gtk_list_store_set_valist (GtkListStore *list_store,
799                            GtkTreeIter  *iter,
800                            va_list       var_args)
801 {
802   gint column;
803   gboolean emit_signal = FALSE;
804   gboolean maybe_need_sort = FALSE;
805   GtkTreeIterCompareFunc func = NULL;
806
807   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
808   g_return_if_fail (VALID_ITER (iter, list_store));
809
810   column = va_arg (var_args, gint);
811
812   if (GTK_LIST_STORE_IS_SORTED (list_store))
813     {
814       if (list_store->sort_column_id != -1)
815         {
816           GtkTreeDataSortHeader *header;
817           header = _gtk_tree_data_list_get_header (list_store->sort_list,
818                                                    list_store->sort_column_id);
819           g_return_if_fail (header != NULL);
820           g_return_if_fail (header->func != NULL);
821           func = header->func;
822         }
823       else
824         {
825           func = list_store->default_sort_func;
826         }
827     }
828
829   if (func != gtk_tree_data_list_compare_func)
830     maybe_need_sort = TRUE;
831
832   while (column != -1)
833     {
834       GValue value = { 0, };
835       gchar *error = NULL;
836
837       if (column >= list_store->n_columns)
838         {
839           g_warning ("%s: Invalid column number %d added to iter (remember to end your list of columns with a -1)", G_STRLOC, column);
840           break;
841         }
842       g_value_init (&value, list_store->column_headers[column]);
843
844       G_VALUE_COLLECT (&value, var_args, 0, &error);
845       if (error)
846         {
847           g_warning ("%s: %s", G_STRLOC, error);
848           g_free (error);
849
850           /* we purposely leak the value here, it might not be
851            * in a sane state if an error condition occoured
852            */
853           break;
854         }
855
856       /* FIXME: instead of calling this n times, refactor with above */
857       emit_signal = gtk_list_store_real_set_value (list_store,
858                                                    iter,
859                                                    column,
860                                                    &value,
861                                                    FALSE) || emit_signal;
862
863       if (func == gtk_tree_data_list_compare_func &&
864           column == list_store->sort_column_id)
865         maybe_need_sort = TRUE;
866
867       g_value_unset (&value);
868
869       column = va_arg (var_args, gint);
870     }
871
872   if (maybe_need_sort && GTK_LIST_STORE_IS_SORTED (list_store))
873     gtk_list_store_sort_iter_changed (list_store, iter, list_store->sort_column_id);
874
875   if (emit_signal)
876     {
877       GtkTreePath *path;
878
879       path = gtk_tree_model_get_path (GTK_TREE_MODEL (list_store), iter);
880       gtk_tree_model_row_changed (GTK_TREE_MODEL (list_store), path, iter);
881       gtk_tree_path_free (path);
882     }
883 }
884
885 /**
886  * gtk_list_store_set:
887  * @list_store: a #GtkListStore
888  * @iter: row iterator
889  * @Varargs: pairs of column number and value, terminated with -1
890  *
891  * Sets the value of one or more cells in the row referenced by @iter.
892  * The variable argument list should contain integer column numbers,
893  * each column number followed by the value to be set.
894  * The list is terminated by a -1. For example, to set column 0 with type
895  * %G_TYPE_STRING to "Foo", you would write <literal>gtk_list_store_set (store, iter,
896  * 0, "Foo", -1)</literal>.
897  **/
898 void
899 gtk_list_store_set (GtkListStore *list_store,
900                     GtkTreeIter  *iter,
901                     ...)
902 {
903   va_list var_args;
904
905   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
906   g_return_if_fail (iter != NULL);
907   g_return_if_fail (iter->stamp == list_store->stamp);
908
909   va_start (var_args, iter);
910   gtk_list_store_set_valist (list_store, iter, var_args);
911   va_end (var_args);
912 }
913
914 static GSList*
915 remove_link_saving_prev (GSList  *list,
916                          GSList  *link,
917                          GSList **prevp)
918 {
919   GSList *tmp;
920   GSList *prev;
921
922   prev = NULL;
923   tmp = list;
924
925   while (tmp)
926     {
927       if (tmp == link)
928         {
929           if (prev)
930             prev->next = link->next;
931
932           if (list == link)
933             list = list->next;
934
935           link->next = NULL;
936           break;
937         }
938
939       prev = tmp;
940       tmp = tmp->next;
941     }
942
943   *prevp = prev;
944
945   return list;
946 }
947
948 static void
949 gtk_list_store_remove_silently (GtkListStore *list_store,
950                                 GtkTreeIter  *iter,
951                                 GtkTreePath  *path)
952 {
953   if (G_SLIST (iter->user_data)->data)
954     {
955       _gtk_tree_data_list_free ((GtkTreeDataList *) G_SLIST (iter->user_data)->data,
956                                 list_store->column_headers);
957       G_SLIST (iter->user_data)->data = NULL;
958     }
959
960   {
961     GSList *prev = NULL;
962
963     list_store->root = remove_link_saving_prev (G_SLIST (list_store->root),
964                                                 G_SLIST (iter->user_data),
965                                                 &prev);
966
967     list_store->length -= 1;
968
969     if (iter->user_data == list_store->tail)
970       list_store->tail = prev;
971   }
972 }
973
974 /**
975  * gtk_list_store_remove:
976  * @list_store: A #GtkListStore
977  * @iter: A valid #GtkTreeIter
978  *
979  * Removes the given row from the list store.  After being removed, 
980  * @iter is set to be the next valid row, or invalidated if it pointed 
981  * to the last row in @list_store.
982  *
983  * Return value: %TRUE if @iter is valid, %FALSE if not.
984  **/
985 gboolean
986 gtk_list_store_remove (GtkListStore *list_store,
987                        GtkTreeIter  *iter)
988 {
989   GtkTreePath *path;
990   GSList *next;
991
992   g_return_val_if_fail (GTK_IS_LIST_STORE (list_store), FALSE);
993   g_return_val_if_fail (VALID_ITER (iter, list_store), FALSE);
994
995   next = G_SLIST (iter->user_data)->next;
996   path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
997
998   validate_list_store (list_store);
999
1000   gtk_list_store_remove_silently (list_store, iter, path);
1001
1002   validate_list_store (list_store);
1003
1004   gtk_tree_model_row_deleted (GTK_TREE_MODEL (list_store), path);
1005   gtk_tree_path_free (path);
1006
1007   if (next)
1008     {
1009       iter->stamp = list_store->stamp;
1010       iter->user_data = next;
1011       return TRUE;
1012     }
1013   else
1014     {
1015       iter->stamp = 0;
1016     }
1017
1018   return FALSE;
1019 }
1020
1021 static void
1022 insert_after (GtkListStore *list_store,
1023               GSList       *sibling,
1024               GSList       *new_list)
1025 {
1026   g_return_if_fail (sibling != NULL);
1027   g_return_if_fail (new_list != NULL);
1028
1029   /* insert new node after list */
1030   new_list->next = sibling->next;
1031   sibling->next = new_list;
1032
1033   /* if list was the tail, the new node is the new tail */
1034   if (sibling == ((GSList *) list_store->tail))
1035     list_store->tail = new_list;
1036
1037   list_store->length += 1;
1038 }
1039
1040 /**
1041  * gtk_list_store_insert:
1042  * @list_store: A #GtkListStore
1043  * @iter: An unset #GtkTreeIter to set to the new row
1044  * @position: position to insert the new row
1045  *
1046  * Creates a new row at @position.  @iter will be changed to point to this new
1047  * row.  If @position is larger than the number of rows on the list, then the
1048  * new row will be appended to the list.  The row will be empty before this
1049  * function is called.  To fill in values, you need to call gtk_list_store_set()
1050  * or gtk_list_store_set_value().
1051  *
1052  **/
1053 void
1054 gtk_list_store_insert (GtkListStore *list_store,
1055                        GtkTreeIter  *iter,
1056                        gint          position)
1057 {
1058   GSList *list;
1059   GtkTreePath *path;
1060   GSList *new_list;
1061
1062   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
1063   g_return_if_fail (iter != NULL);
1064   g_return_if_fail (position >= 0);
1065
1066   list_store->columns_dirty = TRUE;
1067
1068   if (position == 0 ||
1069       GTK_LIST_STORE_IS_SORTED (list_store))
1070     {
1071       gtk_list_store_prepend (list_store, iter);
1072       return;
1073     }
1074
1075   new_list = g_slist_alloc ();
1076
1077   list = g_slist_nth (G_SLIST (list_store->root), position - 1);
1078
1079   if (list == NULL)
1080     {
1081       /* position if off the end of the list, append it */
1082       gtk_list_store_append (list_store, iter);
1083
1084       return;
1085     }
1086
1087   insert_after (list_store, list, new_list);
1088
1089   iter->stamp = list_store->stamp;
1090   iter->user_data = new_list;
1091
1092   validate_list_store (list_store);
1093
1094   path = gtk_tree_path_new ();
1095   gtk_tree_path_append_index (path, position);
1096   gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter);
1097   gtk_tree_path_free (path);
1098 }
1099
1100 /**
1101  * gtk_list_store_insert_before:
1102  * @list_store: A #GtkListStore
1103  * @iter: An unset #GtkTreeIter to set to the new row
1104  * @sibling: A valid #GtkTreeIter, or %NULL
1105  *
1106  * Inserts a new row before @sibling. If @sibling is %NULL, then the row will be
1107  * appended to the end of the list. @iter will be changed to point to this new 
1108  * row. The row will be empty before this function is called. To fill in values,
1109  * you need to call gtk_list_store_set() or gtk_list_store_set_value().
1110  *
1111  **/
1112 void
1113 gtk_list_store_insert_before (GtkListStore *list_store,
1114                               GtkTreeIter  *iter,
1115                               GtkTreeIter  *sibling)
1116 {
1117   GtkTreePath *path;
1118   GSList *list, *prev, *new_list;
1119   gint i = 0;
1120
1121   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
1122   g_return_if_fail (iter != NULL);
1123   if (sibling)
1124     g_return_if_fail (VALID_ITER (sibling, list_store));
1125
1126   list_store->columns_dirty = TRUE;
1127
1128   if (GTK_LIST_STORE_IS_SORTED (list_store))
1129     {
1130       gtk_list_store_prepend (list_store, iter);
1131       return;
1132     }
1133
1134   if (sibling == NULL)
1135     {
1136       gtk_list_store_append (list_store, iter);
1137       return;
1138     }
1139
1140   new_list = g_slist_alloc ();
1141
1142   prev = NULL;
1143   list = list_store->root;
1144   while (list && list != sibling->user_data)
1145     {
1146       prev = list;
1147       list = list->next;
1148       i++;
1149     }
1150
1151   if (list != sibling->user_data)
1152     {
1153       g_warning ("%s: sibling iterator invalid? not found in the list", G_STRLOC);
1154       return;
1155     }
1156
1157   /* if there are no nodes, we become the list tail, otherwise we
1158    * are inserting before any existing nodes so we can't change
1159    * the tail
1160    */
1161
1162   if (list_store->root == NULL)
1163     list_store->tail = new_list;
1164
1165   if (prev)
1166     {
1167       new_list->next = prev->next;
1168       prev->next = new_list;
1169     }
1170   else
1171     {
1172       new_list->next = list_store->root;
1173       list_store->root = new_list;
1174     }
1175
1176   iter->stamp = list_store->stamp;
1177   iter->user_data = new_list;
1178
1179   list_store->length += 1;
1180
1181   validate_list_store (list_store);
1182
1183   path = gtk_tree_path_new ();
1184   gtk_tree_path_append_index (path, i);
1185   gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter);
1186   gtk_tree_path_free (path);
1187 }
1188
1189 /**
1190  * gtk_list_store_insert_after:
1191  * @list_store: A #GtkListStore
1192  * @iter: An unset #GtkTreeIter to set to the new row
1193  * @sibling: A valid #GtkTreeIter, or %NULL
1194  *
1195  * Inserts a new row after @sibling. If @sibling is %NULL, then the row will be
1196  * prepended to the beginning of the list. @iter will be changed to point to
1197  * this new row. The row will be empty after this function is called. To fill
1198  * in values, you need to call gtk_list_store_set() or gtk_list_store_set_value().
1199  *
1200  **/
1201 void
1202 gtk_list_store_insert_after (GtkListStore *list_store,
1203                              GtkTreeIter  *iter,
1204                              GtkTreeIter  *sibling)
1205 {
1206   GtkTreePath *path;
1207   GSList *list, *new_list;
1208   gint i = 0;
1209
1210   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
1211   g_return_if_fail (iter != NULL);
1212   if (sibling)
1213     g_return_if_fail (VALID_ITER (sibling, list_store));
1214
1215   list_store->columns_dirty = TRUE;
1216
1217   if (sibling == NULL ||
1218       GTK_LIST_STORE_IS_SORTED (list_store))
1219     {
1220       gtk_list_store_prepend (list_store, iter);
1221       return;
1222     }
1223
1224   for (list = list_store->root; list && list != sibling->user_data; list = list->next)
1225     i++;
1226
1227   g_return_if_fail (list == sibling->user_data);
1228
1229   new_list = g_slist_alloc ();
1230
1231   insert_after (list_store, list, new_list);
1232
1233   iter->stamp = list_store->stamp;
1234   iter->user_data = new_list;
1235
1236   validate_list_store (list_store);
1237
1238   path = gtk_tree_path_new ();
1239   gtk_tree_path_append_index (path, i + 1);
1240   gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter);
1241   gtk_tree_path_free (path);
1242 }
1243
1244 /**
1245  * gtk_list_store_prepend:
1246  * @list_store: A #GtkListStore
1247  * @iter: An unset #GtkTreeIter to set to the prepend row
1248  *
1249  * Prepends a new row to @list_store. @iter will be changed to point to this new
1250  * row. The row will be empty after this function is called. To fill in
1251  * values, you need to call gtk_list_store_set() or gtk_list_store_set_value().
1252  *
1253  **/
1254 void
1255 gtk_list_store_prepend (GtkListStore *list_store,
1256                         GtkTreeIter  *iter)
1257 {
1258   GtkTreePath *path;
1259
1260   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
1261   g_return_if_fail (iter != NULL);
1262
1263   iter->stamp = list_store->stamp;
1264   iter->user_data = g_slist_alloc ();
1265
1266   list_store->columns_dirty = TRUE;
1267
1268   if (list_store->root == NULL)
1269     list_store->tail = iter->user_data;
1270
1271   G_SLIST (iter->user_data)->next = G_SLIST (list_store->root);
1272   list_store->root = iter->user_data;
1273
1274   list_store->length += 1;
1275
1276   validate_list_store (list_store);
1277
1278   path = gtk_tree_path_new ();
1279   gtk_tree_path_append_index (path, 0);
1280   gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter);
1281   gtk_tree_path_free (path);
1282 }
1283
1284 /**
1285  * gtk_list_store_append:
1286  * @list_store: A #GtkListStore
1287  * @iter: An unset #GtkTreeIter to set to the appended row
1288  *
1289  * Appends a new row to @list_store.  @iter will be changed to point to this new
1290  * row.  The row will be empty after this function is called.  To fill in
1291  * values, you need to call gtk_list_store_set() or gtk_list_store_set_value().
1292  *
1293  **/
1294 void
1295 gtk_list_store_append (GtkListStore *list_store,
1296                        GtkTreeIter  *iter)
1297 {
1298   GtkTreePath *path;
1299
1300   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
1301   g_return_if_fail (iter != NULL);
1302
1303   list_store->columns_dirty = TRUE;
1304
1305   if (GTK_LIST_STORE_IS_SORTED (list_store))
1306     {
1307       gtk_list_store_prepend (list_store, iter);
1308       return;
1309     }
1310
1311   iter->stamp = list_store->stamp;
1312   iter->user_data = g_slist_alloc ();
1313
1314   if (list_store->tail)
1315     ((GSList *)list_store->tail)->next = iter->user_data;
1316   else
1317     list_store->root = iter->user_data;
1318
1319   list_store->tail = iter->user_data;
1320
1321   list_store->length += 1;
1322
1323   validate_list_store (list_store);
1324
1325   path = gtk_tree_path_new ();
1326   gtk_tree_path_append_index (path, list_store->length - 1);
1327   gtk_tree_model_row_inserted (GTK_TREE_MODEL (list_store), path, iter);
1328   gtk_tree_path_free (path);
1329 }
1330
1331 /**
1332  * gtk_list_store_clear:
1333  * @list_store: a #GtkListStore.
1334  *
1335  * Removes all rows from the list store.  
1336  *
1337  **/
1338 void
1339 gtk_list_store_clear (GtkListStore *list_store)
1340 {
1341   GtkTreeIter iter;
1342   g_return_if_fail (GTK_IS_LIST_STORE (list_store));
1343
1344   while (list_store->root)
1345     {
1346       iter.stamp = list_store->stamp;
1347       iter.user_data = list_store->root;
1348       gtk_list_store_remove (list_store, &iter);
1349     }
1350 }
1351
1352 /**
1353  * gtk_list_store_iter_is_valid:
1354  * @list_store: A #GtkListStore.
1355  * @iter: A #GtkTreeIter.
1356  *
1357  * WARNING: This function is slow. Only use it for debugging and/or testing
1358  * purposes.
1359  *
1360  * Checks if the given iter is a valid iter for this #GtkListStore.
1361  *
1362  * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
1363  **/
1364 gboolean
1365 gtk_list_store_iter_is_valid (GtkListStore *list_store,
1366                               GtkTreeIter  *iter)
1367 {
1368   GList *list;
1369
1370   g_return_val_if_fail (GTK_IS_LIST_STORE (list_store), FALSE);
1371   g_return_val_if_fail (iter != NULL, FALSE);
1372
1373   if (!VALID_ITER (iter, list_store))
1374     return FALSE;
1375
1376   if (iter->user_data == list_store->root)
1377     return TRUE;
1378   if (iter->user_data == list_store->tail)
1379     return TRUE;
1380
1381   for (list = ((GList *)list_store->root)->next; list; list = list->next)
1382     if (list == iter->user_data)
1383       return TRUE;
1384
1385   return FALSE;
1386 }
1387
1388 static gboolean
1389 gtk_list_store_drag_data_delete (GtkTreeDragSource *drag_source,
1390                                  GtkTreePath       *path)
1391 {
1392   GtkTreeIter iter;
1393   g_return_val_if_fail (GTK_IS_LIST_STORE (drag_source), FALSE);
1394
1395   if (gtk_tree_model_get_iter (GTK_TREE_MODEL (drag_source),
1396                                &iter,
1397                                path))
1398     {
1399       gtk_list_store_remove (GTK_LIST_STORE (drag_source), &iter);
1400       return TRUE;
1401     }
1402   return FALSE;
1403 }
1404
1405 static gboolean
1406 gtk_list_store_drag_data_get (GtkTreeDragSource *drag_source,
1407                               GtkTreePath       *path,
1408                               GtkSelectionData  *selection_data)
1409 {
1410   g_return_val_if_fail (GTK_IS_LIST_STORE (drag_source), FALSE);
1411
1412   /* Note that we don't need to handle the GTK_TREE_MODEL_ROW
1413    * target, because the default handler does it for us, but
1414    * we do anyway for the convenience of someone maybe overriding the
1415    * default handler.
1416    */
1417
1418   if (gtk_tree_set_row_drag_data (selection_data,
1419                                   GTK_TREE_MODEL (drag_source),
1420                                   path))
1421     {
1422       return TRUE;
1423     }
1424   else
1425     {
1426       /* FIXME handle text targets at least. */
1427     }
1428
1429   return FALSE;
1430 }
1431
1432 static gboolean
1433 gtk_list_store_drag_data_received (GtkTreeDragDest   *drag_dest,
1434                                    GtkTreePath       *dest,
1435                                    GtkSelectionData  *selection_data)
1436 {
1437   GtkTreeModel *tree_model;
1438   GtkListStore *list_store;
1439   GtkTreeModel *src_model = NULL;
1440   GtkTreePath *src_path = NULL;
1441   gboolean retval = FALSE;
1442
1443   g_return_val_if_fail (GTK_IS_LIST_STORE (drag_dest), FALSE);
1444
1445   tree_model = GTK_TREE_MODEL (drag_dest);
1446   list_store = GTK_LIST_STORE (drag_dest);
1447
1448   if (gtk_tree_get_row_drag_data (selection_data,
1449                                   &src_model,
1450                                   &src_path) &&
1451       src_model == tree_model)
1452     {
1453       /* Copy the given row to a new position */
1454       GtkTreeIter src_iter;
1455       GtkTreeIter dest_iter;
1456       GtkTreePath *prev;
1457
1458       if (!gtk_tree_model_get_iter (src_model,
1459                                     &src_iter,
1460                                     src_path))
1461         {
1462           goto out;
1463         }
1464
1465       /* Get the path to insert _after_ (dest is the path to insert _before_) */
1466       prev = gtk_tree_path_copy (dest);
1467
1468       if (!gtk_tree_path_prev (prev))
1469         {
1470           /* dest was the first spot in the list; which means we are supposed
1471            * to prepend.
1472            */
1473           gtk_list_store_prepend (GTK_LIST_STORE (tree_model),
1474                                   &dest_iter);
1475
1476           retval = TRUE;
1477         }
1478       else
1479         {
1480           if (gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model),
1481                                        &dest_iter,
1482                                        prev))
1483             {
1484               GtkTreeIter tmp_iter = dest_iter;
1485
1486               if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (tree_model), "gtk-tree-model-drop-append")))
1487                 gtk_list_store_append (GTK_LIST_STORE (tree_model), &dest_iter);
1488               else
1489                 gtk_list_store_insert_after (GTK_LIST_STORE (tree_model),
1490                                              &dest_iter, &tmp_iter);
1491
1492               retval = TRUE;
1493             }
1494         }
1495
1496       g_object_set_data (G_OBJECT (tree_model), "gtk-tree-model-drop-append",
1497                          NULL);
1498
1499       gtk_tree_path_free (prev);
1500
1501       /* If we succeeded in creating dest_iter, copy data from src
1502        */
1503       if (retval)
1504         {
1505           GtkTreeDataList *dl = G_SLIST (src_iter.user_data)->data;
1506           GtkTreeDataList *copy_head = NULL;
1507           GtkTreeDataList *copy_prev = NULL;
1508           GtkTreeDataList *copy_iter = NULL;
1509           GtkTreePath *path;
1510           gint col;
1511
1512           col = 0;
1513           while (dl)
1514             {
1515               copy_iter = _gtk_tree_data_list_node_copy (dl,
1516                                                          list_store->column_headers[col]);
1517
1518               if (copy_head == NULL)
1519                 copy_head = copy_iter;
1520
1521               if (copy_prev)
1522                 copy_prev->next = copy_iter;
1523
1524               copy_prev = copy_iter;
1525
1526               dl = dl->next;
1527               ++col;
1528             }
1529
1530           dest_iter.stamp = GTK_LIST_STORE (tree_model)->stamp;
1531           G_SLIST (dest_iter.user_data)->data = copy_head;
1532
1533           path = gtk_list_store_get_path (GTK_TREE_MODEL (tree_model), &dest_iter);
1534           gtk_tree_model_row_changed (GTK_TREE_MODEL (tree_model), path, &dest_iter);
1535           gtk_tree_path_free (path);
1536         }
1537     }
1538   else
1539     {
1540       /* FIXME maybe add some data targets eventually, or handle text
1541        * targets in the simple case.
1542        */
1543     }
1544
1545  out:
1546
1547   if (src_path)
1548     gtk_tree_path_free (src_path);
1549
1550   return retval;
1551 }
1552
1553 static gboolean
1554 gtk_list_store_row_drop_possible (GtkTreeDragDest  *drag_dest,
1555                                   GtkTreePath      *dest_path,
1556                                   GtkSelectionData *selection_data)
1557 {
1558   gint *indices;
1559   GtkTreeModel *src_model = NULL;
1560   GtkTreePath *src_path = NULL;
1561   gboolean retval = FALSE;
1562
1563   g_return_val_if_fail (GTK_IS_LIST_STORE (drag_dest), FALSE);
1564
1565   if (!gtk_tree_get_row_drag_data (selection_data,
1566                                    &src_model,
1567                                    &src_path))
1568     goto out;
1569     
1570   if (src_model != GTK_TREE_MODEL (drag_dest))
1571     goto out;
1572
1573   if (gtk_tree_path_get_depth (dest_path) != 1)
1574     goto out;
1575
1576   /* can drop before any existing node, or before one past any existing. */
1577
1578   indices = gtk_tree_path_get_indices (dest_path);
1579
1580   if (indices[0] <= GTK_LIST_STORE (drag_dest)->length)
1581     retval = TRUE;
1582
1583  out:
1584   gtk_tree_path_free (src_path);
1585   
1586   return retval;
1587 }
1588
1589 /* Sorting and reordering */
1590 typedef struct _SortTuple
1591 {
1592   gint offset;
1593   GSList *el;
1594 } SortTuple;
1595
1596 /* Reordering */
1597 static gint
1598 gtk_list_store_reorder_func (gconstpointer a,
1599                              gconstpointer b,
1600                              gpointer      user_data)
1601 {
1602   SortTuple *a_reorder;
1603   SortTuple *b_reorder;
1604
1605   a_reorder = (SortTuple *)a;
1606   b_reorder = (SortTuple *)b;
1607
1608   if (a_reorder->offset < b_reorder->offset)
1609     return -1;
1610   if (a_reorder->offset > b_reorder->offset)
1611     return 1;
1612
1613   return 0;
1614 }
1615
1616 /**
1617  * gtk_list_store_reorder:
1618  * @store: A #GtkTreeStore.
1619  * @new_order: An integer array indicating the new order for the list.
1620  *
1621  * Reorders @store to follow the order indicated by @new_order. Note that
1622  * this function only works with unsorted stores.
1623  **/
1624 void
1625 gtk_list_store_reorder (GtkListStore *store,
1626                         gint         *new_order)
1627 {
1628   gint i;
1629   GSList *current_list;
1630   GtkTreePath *path;
1631   SortTuple *sort_array;
1632
1633   g_return_if_fail (GTK_IS_LIST_STORE (store));
1634   g_return_if_fail (!GTK_LIST_STORE_IS_SORTED (store));
1635   g_return_if_fail (new_order != NULL);
1636
1637   sort_array = g_new (SortTuple, store->length);
1638
1639   current_list = store->root;
1640
1641   for (i = 0; i < store->length; i++)
1642     {
1643       sort_array[i].offset = new_order[i];
1644       sort_array[i].el = current_list;
1645
1646       current_list = current_list->next;
1647     }
1648
1649   g_qsort_with_data (sort_array,
1650                      store->length,
1651                      sizeof (SortTuple),
1652                      gtk_list_store_reorder_func,
1653                      NULL);
1654
1655   for (i = 0; i < store->length - 1; i++)
1656     G_SLIST (sort_array[i].el)->next = G_SLIST (sort_array[i+1].el);
1657
1658   store->root = G_SLIST (sort_array[0].el);
1659   store->tail = G_SLIST (sort_array[store->length-1].el);
1660   G_SLIST (store->tail)->next = NULL;
1661
1662   /* emit signal */
1663   path = gtk_tree_path_new ();
1664   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (store),
1665                                  path, NULL, new_order);
1666   gtk_tree_path_free (path);
1667   g_free (sort_array);
1668 }
1669
1670 /**
1671  * gtk_list_store_swap:
1672  * @store: A #GtkListStore.
1673  * @a: A #GtkTreeIter.
1674  * @b: Another #GtkTreeIter.
1675  *
1676  * Swaps @a and @b in @store. Note that this function only works with
1677  * unsorted stores.
1678  **/
1679 void
1680 gtk_list_store_swap (GtkListStore *store,
1681                      GtkTreeIter  *a,
1682                      GtkTreeIter  *b)
1683 {
1684   GSList *i, *prev_a = NULL, *prev_b = NULL;
1685   gint j, a_count = 0, b_count = 0, *order;
1686   GtkTreePath *path;
1687
1688   g_return_if_fail (GTK_IS_LIST_STORE (store));
1689   g_return_if_fail (!GTK_LIST_STORE_IS_SORTED (store));
1690   g_return_if_fail (VALID_ITER (a, store));
1691   g_return_if_fail (VALID_ITER (b, store));
1692
1693   if (a->user_data == b->user_data)
1694     return;
1695
1696   if (a->user_data == store->root)
1697     prev_a = NULL;
1698   else
1699     {
1700       for (i = store->root; i; i = i->next, a_count++)
1701         if (i->next == a->user_data)
1702           {
1703             prev_a = i;
1704             break;
1705           }
1706
1707       a_count++;
1708     }
1709
1710   if (a->user_data == store->root)
1711     prev_b = NULL;
1712   else
1713     {
1714       for (i = store->root; i; i = i->next, b_count++)
1715         if (i->next == b->user_data)
1716           {
1717             prev_b = i;
1718             break;
1719           }
1720
1721       b_count++;
1722     }
1723
1724   if (!prev_a)
1725     store->root = b->user_data;
1726   else
1727     prev_a->next = b->user_data;
1728
1729   if (!prev_b)
1730     store->root = a->user_data;
1731   else
1732     prev_b->next = a->user_data;
1733
1734   /* think a_next inspead of a_prev here ... */
1735   prev_a = G_SLIST (a->user_data)->next;
1736   prev_b = G_SLIST (b->user_data)->next;
1737
1738   G_SLIST (a->user_data)->next = prev_b;
1739   G_SLIST (b->user_data)->next = prev_a;
1740
1741   /* emit signal */
1742   order = g_new (gint, store->length);
1743   for (j = 0; j < store->length; j++)
1744     if (j == a_count)
1745       order[j] = b_count;
1746     else if (j == b_count)
1747       order[j] = a_count;
1748     else
1749       order[j] = j;
1750
1751   path = gtk_tree_path_new ();
1752   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (store),
1753                                  path, NULL, order);
1754   gtk_tree_path_free (path);
1755   g_free (order);
1756 }
1757
1758 /**
1759  * gtk_list_store_move:
1760  * @store: A #GtkTreeStore.
1761  * @iter: A #GtkTreeIter.
1762  * @position: A #GtkTreePath.
1763  *
1764  * Moves @iter in @store to the position before @position. Note that this
1765  * function only works with unsorted stores.
1766  **/
1767 void
1768 gtk_list_store_move (GtkListStore *store,
1769                      GtkTreeIter  *iter,
1770                      GtkTreePath  *position)
1771 {
1772   GSList *i, *prev = NULL, *new_prev = NULL;
1773   gint old_pos = 0, j = 0, *order;
1774   GtkTreePath *path;
1775
1776   g_return_if_fail (GTK_IS_LIST_STORE (store));
1777   g_return_if_fail (!GTK_LIST_STORE_IS_SORTED (store));
1778   g_return_if_fail (VALID_ITER (iter, store));
1779   g_return_if_fail (position != NULL);
1780
1781   if (gtk_tree_path_get_depth (position) != 1)
1782     return;
1783
1784   if (iter->user_data == store->root)
1785     prev = NULL;
1786   else
1787     {
1788       for (i = store->root; i; i = i->next, old_pos++)
1789         if (i->next == iter->user_data)
1790           {
1791             prev = i;
1792             break;
1793           }
1794
1795       old_pos++;
1796     }
1797
1798   if (old_pos == gtk_tree_path_get_indices (position)[0])
1799     return;
1800
1801   if (gtk_tree_path_get_indices (position)[0] == 0)
1802     new_prev = NULL;
1803   else
1804     {
1805       for (i = store->root; i; i = i->next, j++)
1806         if (j == gtk_tree_path_get_indices (position)[0] - 1)
1807           {
1808             new_prev = i;
1809             break;
1810           }
1811     }
1812
1813   if (!prev)
1814     store->root = G_SLIST (iter->user_data)->next;
1815   else
1816     prev->next = G_SLIST (iter->user_data)->next;
1817
1818   if (!new_prev)
1819     {
1820       G_SLIST (iter->user_data)->next = store->root;
1821       store->root = G_SLIST (iter->user_data);
1822     }
1823   else
1824     {
1825       G_SLIST (iter->user_data)->next = new_prev->next;
1826       new_prev->next = G_SLIST (iter->user_data);
1827     }
1828
1829   /* emit signal */
1830   order = g_new (gint, store->length);
1831   for (j = 0; j < store->length; j++)
1832     if (j < old_pos)
1833       order[j] = j;
1834     else if (j >= old_pos && j < gtk_tree_path_get_indices (position)[0])
1835       order[j] = j + 1;
1836     else if (j == gtk_tree_path_get_indices (position)[0])
1837       order[j] = old_pos;
1838     else
1839       order[j] = j;
1840
1841   path = gtk_tree_path_new ();
1842   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (store),
1843                                  path, NULL, order);
1844   gtk_tree_path_free (path);
1845   g_free (order);
1846 }
1847
1848 /* Sorting */
1849 static gint
1850 gtk_list_store_compare_func (gconstpointer a,
1851                              gconstpointer b,
1852                              gpointer      user_data)
1853 {
1854   GtkListStore *list_store = user_data;
1855   GSList *el_a; /* Los Angeles? */
1856   GSList *el_b;
1857   GtkTreeIter iter_a;
1858   GtkTreeIter iter_b;
1859   gint retval;
1860   GtkTreeIterCompareFunc func;
1861   gpointer data;
1862
1863
1864   if (list_store->sort_column_id != -1)
1865     {
1866       GtkTreeDataSortHeader *header;
1867
1868       header = _gtk_tree_data_list_get_header (list_store->sort_list,
1869                                                list_store->sort_column_id);
1870       g_return_val_if_fail (header != NULL, 0);
1871       g_return_val_if_fail (header->func != NULL, 0);
1872
1873       func = header->func;
1874       data = header->data;
1875     }
1876   else
1877     {
1878       g_return_val_if_fail (list_store->default_sort_func != NULL, 0);
1879       func = list_store->default_sort_func;
1880       data = list_store->default_sort_data;
1881     }
1882
1883   el_a = ((SortTuple *) a)->el;
1884   el_b = ((SortTuple *) b)->el;
1885
1886   iter_a.stamp = list_store->stamp;
1887   iter_a.user_data = el_a;
1888   iter_b.stamp = list_store->stamp;
1889   iter_b.user_data = el_b;
1890
1891   retval = (* func) (GTK_TREE_MODEL (list_store), &iter_a, &iter_b, data);
1892
1893   if (list_store->order == GTK_SORT_DESCENDING)
1894     {
1895       if (retval > 0)
1896         retval = -1;
1897       else if (retval < 0)
1898         retval = 1;
1899     }
1900   return retval;
1901 }
1902
1903 static void
1904 gtk_list_store_sort (GtkListStore *list_store)
1905 {
1906   GArray *sort_array;
1907   gint i;
1908   gint *new_order;
1909   GSList *list;
1910   GtkTreePath *path;
1911
1912   if (list_store->length <= 1)
1913     return;
1914
1915   g_assert (GTK_LIST_STORE_IS_SORTED (list_store));
1916
1917   list = G_SLIST (list_store->root);
1918
1919   sort_array = g_array_sized_new (FALSE, FALSE,
1920                                   sizeof (SortTuple),
1921                                   list_store->length);
1922
1923   for (i = 0; i < list_store->length; i++)
1924     {
1925       SortTuple tuple;
1926
1927       /* If this fails, we are in an inconsistent state.  Bad */
1928       g_return_if_fail (list != NULL);
1929
1930       tuple.offset = i;
1931       tuple.el = list;
1932       g_array_append_val (sort_array, tuple);
1933
1934       list = list->next;
1935     }
1936
1937   g_array_sort_with_data (sort_array, gtk_list_store_compare_func, list_store);
1938
1939   for (i = 0; i < list_store->length - 1; i++)
1940       g_array_index (sort_array, SortTuple, i).el->next =
1941         g_array_index (sort_array, SortTuple, i + 1).el;
1942   g_array_index (sort_array, SortTuple, list_store->length - 1).el->next = NULL;
1943   list_store->root = g_array_index (sort_array, SortTuple, 0).el;
1944   list_store->tail = g_array_index (sort_array, SortTuple, list_store->length - 1).el;
1945
1946   /* Let the world know about our new order */
1947   new_order = g_new (gint, list_store->length);
1948   for (i = 0; i < list_store->length; i++)
1949     new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1950
1951   path = gtk_tree_path_new ();
1952   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (list_store),
1953                                  path, NULL, new_order);
1954   gtk_tree_path_free (path);
1955   g_free (new_order);
1956   g_array_free (sort_array, TRUE);
1957 }
1958
1959 static void
1960 gtk_list_store_sort_iter_changed (GtkListStore *list_store,
1961                                   GtkTreeIter  *iter,
1962                                   gint          column)
1963
1964 {
1965   GSList *prev = NULL;
1966   GSList *next = NULL;
1967   GSList *list = G_SLIST (list_store->root);
1968   GtkTreePath *tmp_path;
1969   GtkTreeIter tmp_iter;
1970   gint cmp_a = 0;
1971   gint cmp_b = 0;
1972   gint i;
1973   gint old_location;
1974   gint new_location;
1975   gint *new_order;
1976   GtkTreeIterCompareFunc func;
1977   gpointer data;
1978
1979   if (list_store->length < 2)
1980     return;
1981
1982   tmp_iter.stamp = list_store->stamp;
1983
1984   if (list_store->sort_column_id != -1)
1985     {
1986       GtkTreeDataSortHeader *header;
1987       header = _gtk_tree_data_list_get_header (list_store->sort_list,
1988                                                list_store->sort_column_id);
1989       g_return_if_fail (header != NULL);
1990       g_return_if_fail (header->func != NULL);
1991       func = header->func;
1992       data = header->data;
1993     }
1994   else
1995     {
1996       g_return_if_fail (list_store->default_sort_func != NULL);
1997       func = list_store->default_sort_func;
1998       data = list_store->default_sort_data;
1999     }
2000
2001   /* If it's the built in function, we don't sort. */
2002   if (func == gtk_tree_data_list_compare_func &&
2003       list_store->sort_column_id != column)
2004     return;
2005
2006   old_location = 0;
2007   /* First we find the iter, its prev, and its next */
2008   while (list)
2009     {
2010       if (list == G_SLIST (iter->user_data))
2011         break;
2012       prev = list;
2013       list = list->next;
2014       old_location++;
2015     }
2016   g_assert (list != NULL);
2017
2018   next = list->next;
2019
2020   /* Check the common case, where we don't need to sort it moved. */
2021   if (prev != NULL)
2022     {
2023       tmp_iter.user_data = prev;
2024       cmp_a = (* func) (GTK_TREE_MODEL (list_store), &tmp_iter, iter, data);
2025     }
2026
2027   if (next != NULL)
2028     {
2029       tmp_iter.user_data = next;
2030       cmp_b = (* func) (GTK_TREE_MODEL (list_store), iter, &tmp_iter, data);
2031     }
2032
2033   if (list_store->order == GTK_SORT_DESCENDING)
2034     {
2035       if (cmp_a < 0)
2036         cmp_a = 1;
2037       else if (cmp_a > 0)
2038         cmp_a = -1;
2039
2040       if (cmp_b < 0)
2041         cmp_b = 1;
2042       else if (cmp_b > 0)
2043         cmp_b = -1;
2044     }
2045
2046   if (prev == NULL && cmp_b <= 0)
2047     return;
2048   else if (next == NULL && cmp_a <= 0)
2049     return;
2050   else if (prev != NULL && next != NULL &&
2051            cmp_a <= 0 && cmp_b <= 0)
2052     return;
2053
2054   /* We actually need to sort it */
2055   /* First, remove the old link. */
2056
2057   if (prev == NULL)
2058     list_store->root = next;
2059   else
2060     prev->next = next;
2061   if (next == NULL)
2062     list_store->tail = prev;
2063   list->next = NULL;
2064   
2065   /* FIXME: as an optimization, we can potentially start at next */
2066   prev = NULL;
2067   list = G_SLIST (list_store->root);
2068   new_location = 0;
2069   tmp_iter.user_data = list;
2070   if (list_store->order == GTK_SORT_DESCENDING)
2071     cmp_a = (* func) (GTK_TREE_MODEL (list_store), &tmp_iter, iter, data);
2072   else
2073     cmp_a = (* func) (GTK_TREE_MODEL (list_store), iter, &tmp_iter, data);
2074
2075   while ((list->next) && (cmp_a > 0))
2076     {
2077       prev = list;
2078       list = list->next;
2079       new_location++;
2080       tmp_iter.user_data = list;
2081       if (list_store->order == GTK_SORT_DESCENDING)
2082         cmp_a = (* func) (GTK_TREE_MODEL (list_store), &tmp_iter, iter, data);
2083       else
2084         cmp_a = (* func) (GTK_TREE_MODEL (list_store), iter, &tmp_iter, data);
2085     }
2086
2087   if ((!list->next) && (cmp_a > 0))
2088     {
2089       new_location++;
2090       list->next = G_SLIST (iter->user_data);
2091       list_store->tail = list->next;
2092     }
2093   else if (prev)
2094     {
2095       prev->next = G_SLIST (iter->user_data);
2096       G_SLIST (iter->user_data)->next = list;
2097     }
2098   else
2099     {
2100       G_SLIST (iter->user_data)->next = G_SLIST (list_store->root);
2101       list_store->root = G_SLIST (iter->user_data);
2102     }
2103
2104   /* Emit the reordered signal. */
2105   new_order = g_new (int, list_store->length);
2106   if (old_location < new_location)
2107     for (i = 0; i < list_store->length; i++)
2108       {
2109         if (i < old_location ||
2110             i > new_location)
2111           new_order[i] = i;
2112         else if (i >= old_location &&
2113                  i < new_location)
2114           new_order[i] = i + 1;
2115         else if (i == new_location)
2116           new_order[i] = old_location;
2117       }
2118   else
2119     for (i = 0; i < list_store->length; i++)
2120       {
2121         if (i < new_location ||
2122             i > old_location)
2123           new_order[i] = i;
2124         else if (i > new_location &&
2125                  i <= old_location)
2126           new_order[i] = i - 1;
2127         else if (i == new_location)
2128           new_order[i] = old_location;
2129       }
2130
2131   tmp_path = gtk_tree_path_new ();
2132   tmp_iter.user_data = NULL;
2133
2134   gtk_tree_model_rows_reordered (GTK_TREE_MODEL (list_store),
2135                                  tmp_path, NULL,
2136                                  new_order);
2137
2138   gtk_tree_path_free (tmp_path);
2139   g_free (new_order);
2140 }
2141
2142 static gboolean
2143 gtk_list_store_get_sort_column_id (GtkTreeSortable  *sortable,
2144                                    gint             *sort_column_id,
2145                                    GtkSortType      *order)
2146 {
2147   GtkListStore *list_store = (GtkListStore *) sortable;
2148
2149   g_return_val_if_fail (GTK_IS_LIST_STORE (sortable), FALSE);
2150
2151   if (list_store->sort_column_id == -1)
2152     return FALSE;
2153
2154   if (sort_column_id)
2155     * sort_column_id = list_store->sort_column_id;
2156   if (order)
2157     * order = list_store->order;
2158   return TRUE;
2159 }
2160
2161 static void
2162 gtk_list_store_set_sort_column_id (GtkTreeSortable  *sortable,
2163                                    gint              sort_column_id,
2164                                    GtkSortType       order)
2165 {
2166   GtkListStore *list_store = (GtkListStore *) sortable;
2167
2168   g_return_if_fail (GTK_IS_LIST_STORE (sortable));
2169
2170   if ((list_store->sort_column_id == sort_column_id) &&
2171       (list_store->order == order))
2172     return;
2173
2174   if (sort_column_id != -1)
2175     {
2176       GtkTreeDataSortHeader *header = NULL;
2177
2178       header = _gtk_tree_data_list_get_header (list_store->sort_list, sort_column_id);
2179
2180       /* We want to make sure that we have a function */
2181       g_return_if_fail (header != NULL);
2182       g_return_if_fail (header->func != NULL);
2183     }
2184   else
2185     {
2186       g_return_if_fail (list_store->default_sort_func != NULL);
2187     }
2188
2189
2190   list_store->sort_column_id = sort_column_id;
2191   list_store->order = order;
2192
2193   gtk_list_store_sort (list_store);
2194
2195   gtk_tree_sortable_sort_column_changed (sortable);
2196 }
2197
2198 static void
2199 gtk_list_store_set_sort_func (GtkTreeSortable        *sortable,
2200                               gint                    sort_column_id,
2201                               GtkTreeIterCompareFunc  func,
2202                               gpointer                data,
2203                               GtkDestroyNotify        destroy)
2204 {
2205   GtkListStore *list_store = (GtkListStore *) sortable;
2206   GtkTreeDataSortHeader *header = NULL;
2207   GList *list;
2208
2209   g_return_if_fail (GTK_IS_LIST_STORE (sortable));
2210   g_return_if_fail (func != NULL);
2211
2212   for (list = list_store->sort_list; list; list = list->next)
2213     {
2214       GtkTreeDataSortHeader *list_header;
2215
2216       list_header = (GtkTreeDataSortHeader*) list->data;
2217       if (list_header->sort_column_id == sort_column_id)
2218         {
2219           header = list_header;
2220           break;
2221         }
2222     }
2223
2224   if (header == NULL)
2225     {
2226       header = g_new0 (GtkTreeDataSortHeader, 1);
2227       header->sort_column_id = sort_column_id;
2228       list_store->sort_list = g_list_append (list_store->sort_list, header);
2229     }
2230
2231   if (header->destroy)
2232     {
2233       GtkDestroyNotify d = header->destroy;
2234
2235       header->destroy = NULL;
2236       d (header->data);
2237     }
2238
2239   header->func = func;
2240   header->data = data;
2241   header->destroy = destroy;
2242 }
2243
2244
2245 static void
2246 gtk_list_store_set_default_sort_func (GtkTreeSortable        *sortable,
2247                                       GtkTreeIterCompareFunc  func,
2248                                       gpointer                data,
2249                                       GtkDestroyNotify        destroy)
2250 {
2251   GtkListStore *list_store = (GtkListStore *) sortable;
2252
2253   g_return_if_fail (GTK_IS_LIST_STORE (sortable));
2254
2255   if (list_store->default_sort_destroy)
2256     {
2257       GtkDestroyNotify d = list_store->default_sort_destroy;
2258
2259       list_store->default_sort_destroy = NULL;
2260       d (list_store->default_sort_data);
2261     }
2262
2263   list_store->default_sort_func = func;
2264   list_store->default_sort_data = data;
2265   list_store->default_sort_destroy = destroy;
2266 }
2267
2268 static gboolean
2269 gtk_list_store_has_default_sort_func (GtkTreeSortable *sortable)
2270 {
2271   GtkListStore *list_store = (GtkListStore *) sortable;
2272
2273   g_return_val_if_fail (GTK_IS_LIST_STORE (sortable), FALSE);
2274
2275   return (list_store->default_sort_func != NULL);
2276 }