2 * Copyright (C) 2000 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
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.
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.
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.
20 /* NOTE: There is a potential for confusion in this code as to whether an iter,
21 * path or value refers to the GtkTreeModelSort model, or the child model being
22 * sorted. As a convention, variables referencing the child model will have an
23 * s_ prefix before them (ie. s_iter, s_value, s_path);
26 #include "gtktreemodelsort.h"
27 #include "gtktreesortable.h"
28 #include "gtktreestore.h"
29 #include "gtksignal.h"
30 #include "gtktreedatalist.h"
34 typedef struct _SortElt SortElt;
44 typedef struct _SortData SortData;
47 GtkTreeModelSort *tree_model_sort;
48 GtkTreePath *parent_a;
49 GtkTreePath *parent_b;
52 typedef struct _SortTuple SortTuple;
60 #define get_array(e,t) ((GArray *)((e)->parent?(e)->parent->children:GTK_TREE_MODEL_SORT(t)->root))
62 /* object init and signal handlers */
63 static void gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort);
64 static void gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class);
65 static void gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface);
66 static void gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface);
67 static void gtk_tree_model_sort_finalize (GObject *object);
68 static void gtk_tree_model_sort_row_changed (GtkTreeModel *model,
69 GtkTreePath *start_path,
70 GtkTreeIter *start_iter,
72 static void gtk_tree_model_sort_row_inserted (GtkTreeModel *model,
76 static void gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *model,
80 static void gtk_tree_model_sort_row_deleted (GtkTreeModel *model,
83 static void gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
90 /* TreeModel interface */
91 static gint gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model);
92 static GType gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
94 static gboolean gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
97 static GtkTreePath *gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
99 static void gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
103 static gboolean gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
105 static gboolean gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
107 GtkTreeIter *parent);
108 static gboolean gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
110 static gint gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
112 static gboolean gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
116 static gboolean gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
121 static void gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
123 static void gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
127 /* TreeSortable interface */
128 static gboolean gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
129 gint *sort_column_id,
131 static void gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
134 static void gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
136 GtkTreeIterCompareFunc func,
138 GtkDestroyNotify destroy);
139 static void gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
140 GtkTreeIterCompareFunc func,
142 GtkDestroyNotify destroy);
143 static gboolean gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable);
145 /* internal functions */
146 static gboolean gtk_tree_model_sort_get_iter_helper (GtkTreeModelSort *tree_model_sort,
151 static gint gtk_tree_model_sort_compare_func (gconstpointer a,
154 static gint gtk_tree_model_sort_offset_compare_func (gconstpointer a,
157 static void gtk_tree_model_sort_sort_helper (GtkTreeModelSort *tree_model_sort,
160 gboolean emit_reordered);
161 static void gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort);
162 static gint gtk_tree_model_sort_array_find_insert (GtkTreeModelSort *tree_model_sort,
165 gboolean skip_sort_elt);
166 static GtkTreePath *gtk_tree_model_sort_generate_path_index(SortElt *item,
167 GtkTreeModelSort *tree_model_sort);
168 static GtkTreePath *gtk_tree_model_sort_generate_path (SortElt *item);
169 static GtkTreePath *gtk_tree_model_sort_convert_path_real (GtkTreeModelSort *tree_model_sort,
170 GtkTreePath *child_path,
171 gboolean build_children);
172 static void gtk_tree_model_sort_convert_iter_real (GtkTreeModelSort *tree_model_sort,
173 GtkTreeIter *sort_iter,
174 GtkTreeIter *child_iter,
175 gboolean build_children);
176 static void gtk_tree_model_sort_build_level_sort (GtkTreeModelSort *tree_model_sort,
178 static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
180 static void gtk_tree_model_sort_free_level (GArray *array);
181 static void sort_elt_get_iter (GtkTreeModelSort *tree_model_sort,
183 GtkTreeIter *child_iter);
188 gtk_tree_model_sort_get_type (void)
190 static GType tree_model_sort_type = 0;
192 if (!tree_model_sort_type)
194 static const GTypeInfo tree_model_sort_info =
196 sizeof (GtkTreeModelSortClass),
197 NULL, /* base_init */
198 NULL, /* base_finalize */
199 (GClassInitFunc) gtk_tree_model_sort_class_init,
200 NULL, /* class_finalize */
201 NULL, /* class_data */
202 sizeof (GtkTreeModelSort),
204 (GInstanceInitFunc) gtk_tree_model_sort_init
207 static const GInterfaceInfo tree_model_info =
209 (GInterfaceInitFunc) gtk_tree_model_sort_tree_model_init,
214 static const GInterfaceInfo sortable_info =
216 (GInterfaceInitFunc) gtk_tree_model_sort_tree_sortable_init,
221 tree_model_sort_type = g_type_register_static (G_TYPE_OBJECT,
223 &tree_model_sort_info, 0);
224 g_type_add_interface_static (tree_model_sort_type,
228 g_type_add_interface_static (tree_model_sort_type,
229 GTK_TYPE_TREE_SORTABLE,
233 return tree_model_sort_type;
237 gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class)
239 GObjectClass *object_class;
241 object_class = (GObjectClass *) tree_model_sort_class;
243 object_class->finalize = gtk_tree_model_sort_finalize;
247 gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
249 iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
250 iface->get_column_type = gtk_tree_model_sort_get_column_type;
251 iface->get_iter = gtk_tree_model_sort_get_iter;
252 iface->get_path = gtk_tree_model_sort_get_path;
253 iface->get_value = gtk_tree_model_sort_get_value;
254 iface->iter_next = gtk_tree_model_sort_iter_next;
255 iface->iter_children = gtk_tree_model_sort_iter_children;
256 iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
257 iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
258 iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
259 iface->iter_parent = gtk_tree_model_sort_iter_parent;
260 iface->ref_node = gtk_tree_model_sort_ref_node;
261 iface->unref_node = gtk_tree_model_sort_unref_node;
265 gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface)
267 iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id;
268 iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id;
269 iface->set_sort_func = gtk_tree_model_sort_set_sort_func;
270 iface->set_default_sort_func = gtk_tree_model_sort_set_default_sort_func;
271 iface->has_default_sort_func = gtk_tree_model_sort_has_default_sort_func;
275 gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
277 tree_model_sort->sort_column_id = -1;
278 tree_model_sort->stamp = g_random_int ();
279 tree_model_sort->cache_child_iters = FALSE;
281 tree_model_sort->root = NULL;
282 tree_model_sort->sort_list = NULL;
286 * gtk_tree_model_sort_new:
288 * Creates a new #GtkTreeModel without child_model.
290 * Returns: A new #GtkTreeModel.
293 gtk_tree_model_sort_new (void)
295 return GTK_TREE_MODEL (g_object_new (gtk_tree_model_sort_get_type (), NULL));
299 * gtk_tree_model_sort_new_with_model:
300 * @child_model: A #GtkTreeModel
302 * Creates a new #GtkTreeModel, with @child_model as the child_model.
304 * Return value: A new #GtkTreeModel.
307 gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model)
309 GtkTreeModel *retval;
311 retval = gtk_tree_model_sort_new ();
312 gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model);
318 * gtk_tree_model_sort_set_model:
319 * @tree_model_sort: The #GtkTreeModelSort.
320 * @child_model: A #GtkTreeModel, or NULL.
322 * Sets the model of @tree_model_sort to be @model. If @model is NULL, then the * old model is unset.
325 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
326 GtkTreeModel *child_model)
328 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
331 g_object_ref (G_OBJECT (child_model));
333 if (tree_model_sort->child_model)
335 g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
336 tree_model_sort->changed_id);
337 g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
338 tree_model_sort->inserted_id);
339 g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
340 tree_model_sort->has_child_toggled_id);
341 g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
342 tree_model_sort->deleted_id);
343 g_signal_handler_disconnect (G_OBJECT (tree_model_sort->child_model),
344 tree_model_sort->reordered_id);
346 gtk_tree_model_sort_free_level (tree_model_sort->root);
347 g_object_unref (G_OBJECT (tree_model_sort->child_model));
350 if (tree_model_sort->root)
352 gtk_tree_model_sort_free_level (tree_model_sort->root);
353 tree_model_sort->root = NULL;
356 if (tree_model_sort->sort_list)
358 _gtk_tree_data_list_header_free (tree_model_sort->sort_list);
359 tree_model_sort->sort_list = NULL;
362 tree_model_sort->child_model = child_model;
368 tree_model_sort->changed_id =
369 g_signal_connect (child_model,
371 G_CALLBACK (gtk_tree_model_sort_row_changed),
373 tree_model_sort->inserted_id =
374 g_signal_connect (child_model,
376 G_CALLBACK (gtk_tree_model_sort_row_inserted),
378 tree_model_sort->has_child_toggled_id =
379 g_signal_connect (child_model,
380 "row_has_child_toggled",
381 G_CALLBACK (gtk_tree_model_sort_row_has_child_toggled),
383 tree_model_sort->deleted_id =
384 g_signal_connect (child_model,
386 G_CALLBACK (gtk_tree_model_sort_row_deleted),
388 tree_model_sort->reordered_id =
389 g_signal_connect (child_model,
391 G_CALLBACK (gtk_tree_model_sort_rows_reordered),
394 tree_model_sort->flags = gtk_tree_model_get_flags (child_model);
395 n_columns = gtk_tree_model_get_n_columns (child_model);
397 types = g_new (GType, n_columns);
398 for (i = 0; i < n_columns; i++)
399 types[i] = gtk_tree_model_get_column_type (child_model, i);
401 tree_model_sort->sort_list = _gtk_tree_data_list_header_new (n_columns,
405 if (tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST)
406 tree_model_sort->cache_child_iters = TRUE;
408 tree_model_sort->cache_child_iters = FALSE;
410 /* ugly hack - ugly ugly ugly (do not try at home) */
411 tree_model_sort->default_sort_func =
412 (GtkTreeIterCompareFunc)0x1;
417 * gtk_tree_model_sort_get_model:
418 * @tree_model: a #GtkTreeModelSort
420 * Returns the model the #GtkTreeModelSort is sorting.
422 * Return value: the "child model" being sorted
425 gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model)
427 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
429 return tree_model->child_model;
433 * gtk_tree_model_sort_convert_path:
434 * @tree_model_sort: The #GtkTreeModelSort.
435 * @child_path: A #GtkTreePath, relative to the child model.
437 * Converts the @child_path to a new path, relative to the sorted position. In other
438 * words, the value found in the @tree_model_sort ->child_model at the @child_path, is
439 * identical to that found in the @tree_model_sort and the return value.
441 * Return value: A new path, or NULL if @child_path does not exist in @tree_model_sort
445 gtk_tree_model_sort_convert_path (GtkTreeModelSort *tree_model_sort,
446 GtkTreePath *child_path)
448 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
449 g_return_val_if_fail (child_path != NULL, NULL);
451 return gtk_tree_model_sort_convert_path_real (tree_model_sort, child_path, TRUE);
455 * gtk_tree_model_sort_convert_iter:
456 * @tree_model_sort: The #GtkTreeModelSort
457 * @sort_iter: A pointer to a #GtkTreeIter
458 * @child_iter: A #GtkTreeIter, relative to the child model
460 * Converts the @child_iter to a new iter, relative to the sorted position. In other
461 * words, the value found in the @tree_model_sort ->child_model at the @child_iter, is
462 * identical to that found in @tree_model_sort at the @sort_iter. The @sort_iter will be
466 gtk_tree_model_sort_convert_iter (GtkTreeModelSort *tree_model_sort,
467 GtkTreeIter *sort_iter,
468 GtkTreeIter *child_iter)
470 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
471 g_return_if_fail (sort_iter != NULL);
472 g_return_if_fail (child_iter != NULL);
474 gtk_tree_model_sort_convert_iter_real (tree_model_sort,
481 gtk_tree_model_sort_finalize (GObject *object)
483 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
485 if (tree_model_sort->root)
486 gtk_tree_model_sort_free_level (tree_model_sort->root);
488 if (tree_model_sort->child_model)
490 g_object_unref (G_OBJECT (tree_model_sort->child_model));
491 tree_model_sort->child_model = NULL;
493 if (tree_model_sort->sort_list)
495 _gtk_tree_data_list_header_free (tree_model_sort->sort_list);
496 tree_model_sort->sort_list = NULL;
501 gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
506 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
512 gboolean free_s_path = FALSE;
518 g_return_if_fail (s_path != NULL || s_iter != NULL);
523 s_path = gtk_tree_model_get_path (s_model, s_iter);
526 path = gtk_tree_model_sort_convert_path_real (tree_model_sort, s_path, FALSE);
530 gtk_tree_path_free (s_path);
534 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
535 elt = iter.user_data;
536 array = get_array (elt, tree_model_sort);
541 gtk_tree_path_free (s_path);
543 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
545 gtk_tree_path_free (path);
549 if (tree_model_sort->cache_child_iters)
550 sort_elt_get_iter (tree_model_sort, elt, &tmpiter);
552 offset = elt->offset;
554 for (i = 0; i < array->len; i++)
555 if (elt->offset == g_array_index (array, SortElt, i).offset)
560 memcpy (&tmp, elt, sizeof (SortElt));
561 g_array_remove_index (array, index);
563 /* _kris_: don't know if this FIXME was originally at this position...
564 * FIXME: as an optimization for when the column other then the one we're
565 * sorting is changed, we can check the prev and next element to see if
569 /* now we need to resort things */
570 if (tree_model_sort->cache_child_iters)
571 index = gtk_tree_model_sort_array_find_insert (tree_model_sort,
576 index = gtk_tree_model_sort_array_find_insert (tree_model_sort,
581 g_array_insert_val (array, index, tmp);
583 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
584 /* FIXME: emit row_reordered here */
586 gtk_tree_path_free (path);
588 gtk_tree_path_free (s_path);
591 /* Returns FALSE if the value was inserted, TRUE otherwise */
593 gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
597 GtkTreePath *tmp_path;
598 GArray *array = NULL;
606 offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];
608 if (tree_model_sort->cache_child_iters)
614 tmp_path = gtk_tree_path_copy (s_path);
616 if (gtk_tree_path_up (tmp_path))
618 GtkTreePath *parent_path;
620 parent_path = gtk_tree_model_sort_convert_path_real (tree_model_sort,
626 gtk_tree_path_free (tmp_path);
630 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort), &iter,
633 gtk_tree_path_free (tmp_path);
637 elt.parent = iter.user_data;
638 array = elt.parent->children;
639 gtk_tree_path_free (parent_path);
643 gtk_tree_path_free (tmp_path);
649 if (!tree_model_sort->root)
650 tree_model_sort->root =
651 g_array_sized_new (FALSE, FALSE, sizeof (SortElt), 1);
652 array = tree_model_sort->root;
655 gtk_tree_path_free (tmp_path);
657 if (tree_model_sort->cache_child_iters)
658 index = gtk_tree_model_sort_array_find_insert (tree_model_sort,
665 sort_elt_get_iter (tree_model_sort, &elt, &tmpiter);
666 index = gtk_tree_model_sort_array_find_insert (tree_model_sort,
672 g_array_insert_vals (array, index, &elt, 1);
674 /* update all the larger offsets */
675 tmp_elt = (SortElt *)array->data;
676 for (j = 0; j < array->len; j++, tmp_elt++)
678 if ((tmp_elt->offset >= offset) && j != index)
686 gtk_tree_model_sort_row_inserted (GtkTreeModel *s_model,
691 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
695 g_return_if_fail (s_path != NULL || s_iter != NULL);
698 s_path = gtk_tree_model_get_path (s_model, s_iter);
700 if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST))
702 gtk_tree_model_sort_free_level ((GArray *) tree_model_sort->root);
703 tree_model_sort->root = NULL;
707 GtkTreeIter real_s_iter;
710 gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
712 real_s_iter = (* s_iter);
714 if (!gtk_tree_model_sort_insert_value (tree_model_sort,
715 s_path, &real_s_iter))
719 if (!tree_model_sort->root)
720 path = gtk_tree_model_sort_convert_path_real (tree_model_sort,
723 path = gtk_tree_model_sort_convert_path_real (tree_model_sort,
729 tree_model_sort->stamp++;
730 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
731 gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
732 gtk_tree_path_free (path);
736 gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *s_model,
741 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
744 gboolean free_s_path = FALSE;
746 g_return_if_fail (s_path != NULL || s_iter != NULL);
748 if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST))
750 gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
751 tree_model_sort->root = NULL;
756 s_path = gtk_tree_model_get_path (s_model, s_iter);
760 path = gtk_tree_model_sort_convert_path_real (tree_model_sort, s_path, FALSE); if (path == NULL)
762 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
763 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
764 gtk_tree_path_free (path);
766 gtk_tree_path_free (s_path);
770 gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
774 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
777 g_return_if_fail (s_path != NULL);
778 path = gtk_tree_model_sort_convert_path (tree_model_sort, s_path);
779 g_return_if_fail (path != NULL);
781 if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST))
783 gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
784 tree_model_sort->root = NULL;
794 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort), &iter, path);
795 elt = iter.user_data;
796 offset = elt->offset;
797 array = get_array (elt, tree_model_sort);
801 if (((SortElt *)array->data)->parent == NULL)
802 tree_model_sort->root = NULL;
804 (((SortElt *)array->data)->parent)->children = NULL;
805 gtk_tree_model_sort_free_level (array);
809 for (i = 0; i < array->len; i++)
810 if (elt->offset == g_array_index (array, SortElt, i).offset)
813 g_array_remove_index (array, i);
815 /* update all offsets */
816 for (i = 0; i < array->len; i++)
818 elt = & (g_array_index (array, SortElt, i));
819 if (elt->offset > offset)
825 gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
826 tree_model_sort->stamp++;
827 gtk_tree_path_free (path);
831 gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
838 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
845 gboolean listen_to_reorder = TRUE;
849 g_return_if_fail (s_path != NULL || s_iter != NULL);
850 g_return_if_fail (new_order != NULL);
853 s_path = gtk_tree_model_get_path (s_model, s_iter);
855 if (!gtk_tree_path_get_indices (s_path))
856 len = gtk_tree_model_iter_n_children (s_model, NULL);
858 len = gtk_tree_model_iter_n_children (s_model, s_iter);
863 if (!gtk_tree_path_get_indices (s_path))
865 array = (GArray *)tree_model_sort->root;
869 gtk_tree_model_sort_build_level (tree_model_sort, NULL);
870 array = (GArray *)tree_model_sort->root;
872 if (tree_model_sort->sort_column_id != -1)
873 gtk_tree_model_sort_sort_helper (tree_model_sort,
881 if (!tree_model_sort->cache_child_iters
882 && tree_model_sort->sort_column_id != -1)
885 gtk_tree_model_sort_free_level (tree_model_sort->root);
886 tree_model_sort->root = NULL;
887 gtk_tree_model_sort_build_level (tree_model_sort, NULL);
889 gtk_tree_model_sort_sort_helper (tree_model_sort,
890 tree_model_sort->root,
894 array = tree_model_sort->root;
896 listen_to_reorder = FALSE;
898 else if (tree_model_sort->cache_child_iters
899 && tree_model_sort->sort_column_id == -1)
902 gtk_tree_model_sort_free_level (tree_model_sort->root);
904 tree_model_sort->root = NULL;
905 gtk_tree_model_sort_build_level (tree_model_sort, NULL);
907 array = tree_model_sort->root;
909 listen_to_reorder = FALSE;
914 path = gtk_tree_model_sort_convert_path_real (tree_model_sort,
921 if (!gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path))
924 elt = iter.user_data;
925 gtk_tree_path_free (path);
928 gtk_tree_model_get_iter (s_model, s_iter, s_path);
933 array = elt->children;
935 if (!tree_model_sort->cache_child_iters
936 && tree_model_sort->sort_column_id != -1)
939 gtk_tree_model_sort_free_level (elt->children);
940 elt->children = NULL;
941 gtk_tree_model_sort_build_level (tree_model_sort, elt);
943 gtk_tree_model_sort_sort_helper (tree_model_sort,
948 array = elt->children;
950 listen_to_reorder = FALSE;
952 else if (tree_model_sort->cache_child_iters
953 && tree_model_sort->sort_column_id == -1)
956 gtk_tree_model_sort_free_level (elt->children);
958 elt->children = NULL;
959 gtk_tree_model_sort_build_level (tree_model_sort, elt);
961 array = elt->children;
963 listen_to_reorder = FALSE;
967 if (listen_to_reorder
968 && tree_model_sort->default_sort_func != (GtkTreeIterCompareFunc) 0x1)
970 if (len != array->len)
971 /* length mismatch, pretty bad, shouldn't happen */
974 for (i = 0; i < array->len; i++)
975 g_array_index (array, SortElt, i).offset = new_order[i];
978 my_new_order = g_new (gint, array->len);
979 for (i = 0; i < array->len; i++)
982 tree_model_sort->stamp++;
984 path = gtk_tree_model_sort_convert_path_real (tree_model_sort,
987 if (gtk_tree_path_get_depth (path))
989 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort), &iter, path);
990 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
991 &iter, my_new_order);
994 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
997 g_free (my_new_order);
998 gtk_tree_path_free (path);
1002 gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
1004 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1006 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
1008 if (tree_model_sort->child_model == 0)
1011 return gtk_tree_model_get_n_columns (GTK_TREE_MODEL_SORT (tree_model)->child_model);
1015 gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
1018 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), G_TYPE_INVALID);
1019 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, G_TYPE_INVALID);
1021 return gtk_tree_model_get_column_type (GTK_TREE_MODEL_SORT (tree_model)->child_model, index);
1025 gtk_tree_model_sort_get_iter_helper (GtkTreeModelSort *tree_model_sort,
1031 SortElt *elt = NULL;
1032 GtkTreeIter child_iter;
1037 if (gtk_tree_path_get_indices (path)[depth] >= array->len)
1040 elt = &g_array_index (array, SortElt, gtk_tree_path_get_indices (path)[depth]);
1045 if (depth == gtk_tree_path_get_depth (path) - 1)
1047 iter->stamp = tree_model_sort->stamp;
1048 iter->user_data = elt;
1053 if (elt->children != NULL)
1054 return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
1060 sort_elt_get_iter (tree_model_sort, elt, &child_iter);
1061 if (gtk_tree_model_iter_has_child (tree_model_sort->child_model, &child_iter))
1062 gtk_tree_model_sort_build_level_sort (tree_model_sort, elt);
1064 return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
1072 gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
1076 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
1077 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
1079 if (GTK_TREE_MODEL_SORT (tree_model)->root == NULL)
1080 gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), NULL);
1082 return gtk_tree_model_sort_get_iter_helper (GTK_TREE_MODEL_SORT (tree_model),
1083 GTK_TREE_MODEL_SORT (tree_model)->root,
1087 static GtkTreePath *
1088 gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
1091 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
1092 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, NULL);
1094 if (iter->stamp == GTK_TREE_MODEL_SORT (tree_model)->stamp)
1099 elt = iter->user_data;
1100 path = gtk_tree_model_sort_generate_path_index
1101 (elt, GTK_TREE_MODEL_SORT (tree_model));
1105 return gtk_tree_model_get_path (GTK_TREE_MODEL_SORT (tree_model)->child_model, iter);
1109 gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
1115 GtkTreeIter child_iter;
1117 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
1118 g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
1119 g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
1121 elt = iter->user_data;
1123 sort_elt_get_iter (GTK_TREE_MODEL_SORT (tree_model), elt, &child_iter);
1124 gtk_tree_model_get_value (GTK_TREE_MODEL_SORT (tree_model)->child_model,
1125 &child_iter, column, value);
1129 gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
1135 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
1136 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
1137 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
1139 elt = iter->user_data;
1140 array = get_array (elt, GTK_TREE_MODEL_SORT (tree_model));
1148 if ((elt - ((SortElt *)array->data)) >= array->len - 1)
1154 iter->user_data = elt + 1;
1160 gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
1162 GtkTreeIter *parent)
1166 GtkTreeIter child_iter;
1168 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
1169 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
1172 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
1174 if (GTK_TREE_MODEL_SORT (tree_model)->root == NULL)
1175 gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), NULL);
1178 elt = parent->user_data;
1181 if (!GTK_TREE_MODEL_SORT (tree_model)->root)
1185 array = GTK_TREE_MODEL_SORT (tree_model)->root;
1187 iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
1188 iter->user_data = &g_array_index (array, SortElt, 0);
1197 sort_elt_get_iter (GTK_TREE_MODEL_SORT (tree_model), elt, &child_iter);
1199 if (!elt->children &&
1200 gtk_tree_model_iter_has_child
1201 (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter))
1202 gtk_tree_model_sort_build_level_sort (GTK_TREE_MODEL_SORT (tree_model),
1208 array = elt->children;
1210 iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
1211 iter->user_data = &g_array_index (array, SortElt, 0);
1217 gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
1221 GtkTreeIter child_iter;
1223 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
1224 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
1225 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
1227 elt = iter->user_data;
1232 sort_elt_get_iter (GTK_TREE_MODEL_SORT (tree_model), elt, &child_iter);
1234 return gtk_tree_model_iter_has_child
1235 (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter);
1239 gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
1243 GtkTreeIter child_iter;
1245 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
1246 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, 0);
1249 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, 0);
1251 if (GTK_TREE_MODEL_SORT (tree_model)->root == NULL)
1252 gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), NULL);
1255 elt = iter->user_data;
1258 if (!GTK_TREE_MODEL_SORT (tree_model)->root)
1261 return ((GArray *)GTK_TREE_MODEL_SORT (tree_model)->root)->len;
1264 g_return_val_if_fail (elt != NULL, 0);
1267 return elt->children->len;
1269 sort_elt_get_iter (GTK_TREE_MODEL_SORT (tree_model), elt, &child_iter);
1271 return gtk_tree_model_iter_n_children
1272 (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter);
1276 gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
1278 GtkTreeIter *parent,
1284 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
1285 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
1287 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
1289 if (GTK_TREE_MODEL_SORT (tree_model)->root == NULL)
1290 gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), NULL);
1293 elt = parent->user_data;
1296 if (!GTK_TREE_MODEL_SORT (tree_model)->root)
1302 array = GTK_TREE_MODEL_SORT (tree_model)->root;
1304 elt = &g_array_index (array, SortElt, n);
1313 GtkTreeIter child_iter;
1315 sort_elt_get_iter (GTK_TREE_MODEL_SORT (tree_model), elt, &child_iter);
1317 if (gtk_tree_model_iter_has_child
1318 (GTK_TREE_MODEL_SORT (tree_model)->child_model, &child_iter))
1319 gtk_tree_model_sort_build_level_sort
1320 (GTK_TREE_MODEL_SORT (tree_model), elt);
1328 if (n >= elt->children->len)
1331 array = elt->children;
1333 iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
1334 iter->user_data = &g_array_index (array, SortElt, n);
1340 gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
1346 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
1347 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL, FALSE);
1348 g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == child->stamp, FALSE);
1350 elt = child->user_data;
1354 iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
1355 iter->user_data = elt->parent;
1364 gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
1369 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
1370 g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
1371 g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
1373 elt = iter->user_data;
1379 gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
1384 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
1385 g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->child_model != NULL);
1386 g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
1388 elt = iter->user_data;
1393 if (elt->parent->ref == 0)
1395 SortElt *parent = elt->parent;
1397 gtk_tree_model_sort_free_level (parent->children);
1398 parent->children = NULL;
1403 /* sortable interface */
1405 gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
1406 gint *sort_column_id,
1409 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1411 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (sortable), FALSE);
1413 if (tree_model_sort->sort_column_id == -1)
1417 *sort_column_id = tree_model_sort->sort_column_id;
1419 *order = tree_model_sort->order;
1425 gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
1426 gint sort_column_id,
1429 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1432 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
1434 if (sort_column_id != -1)
1436 GtkTreeDataSortHeader *header = NULL;
1438 header = _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1441 /* we want to make sure that we have a function */
1442 g_return_if_fail (header != NULL);
1443 g_return_if_fail (header->func != NULL);
1447 g_return_if_fail (tree_model_sort->default_sort_func != NULL);
1450 for (list = tree_model_sort->sort_list; list; list = list->next)
1452 GtkTreeDataSortHeader *header = (GtkTreeDataSortHeader*) list->data;
1453 if (header->sort_column_id == sort_column_id)
1457 g_return_if_fail (list != NULL);
1459 if ((tree_model_sort->sort_column_id == sort_column_id) &&
1460 (tree_model_sort->order == order))
1463 tree_model_sort->sort_column_id = sort_column_id;
1464 tree_model_sort->order = order;
1466 if (tree_model_sort->sort_column_id >= 0)
1467 gtk_tree_model_sort_sort (tree_model_sort);
1469 gtk_tree_sortable_sort_column_changed (sortable);
1473 gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
1474 gint sort_column_id,
1475 GtkTreeIterCompareFunc func,
1477 GtkDestroyNotify destroy)
1479 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1480 GtkTreeDataSortHeader *header = NULL;
1483 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
1484 g_return_if_fail (func != NULL);
1486 for (list = tree_model_sort->sort_list; list; list = list->next)
1488 header = (GtkTreeDataSortHeader*) list->data;
1489 if (header->sort_column_id == sort_column_id)
1495 header = g_new0 (GtkTreeDataSortHeader, 1);
1496 header->sort_column_id = sort_column_id;
1497 tree_model_sort->sort_list = g_list_append (tree_model_sort->sort_list,
1501 if (header->destroy)
1502 (* header->destroy) (header->data);
1504 header->func = func;
1505 header->data = data;
1506 header->destroy = destroy;
1510 gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
1511 GtkTreeIterCompareFunc func,
1513 GtkDestroyNotify destroy)
1515 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1517 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (sortable));
1519 if (tree_model_sort->default_sort_destroy)
1520 (* tree_model_sort->default_sort_destroy)
1521 (tree_model_sort->default_sort_data);
1523 tree_model_sort->default_sort_func = func;
1524 tree_model_sort->default_sort_data = data;
1525 tree_model_sort->default_sort_destroy = destroy;
1529 gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable)
1531 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1533 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (sortable), FALSE);
1535 return (tree_model_sort->default_sort_func != NULL);
1540 gtk_tree_model_sort_compare_func (gconstpointer a,
1546 SortElt *sa = ((SortTuple *)a)->elt;
1547 SortElt *sb = ((SortTuple *)b)->elt;
1552 SortData *data = (SortData *)user_data;
1553 GtkTreeModelSort *tree_model_sort = data->tree_model_sort;
1555 GtkTreeIterCompareFunc func;
1558 if (tree_model_sort->sort_column_id != -1)
1560 GtkTreeDataSortHeader *header = NULL;
1563 _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1564 tree_model_sort->sort_column_id);
1566 g_return_val_if_fail (header != NULL, 0);
1567 g_return_val_if_fail (header->func != NULL, 0);
1569 func = header->func;
1570 f_data = header->data;
1574 /* absolutely SHOULD NOT happen: */
1575 g_return_val_if_fail (tree_model_sort->default_sort_func
1576 != (GtkTreeIterCompareFunc)0x1, 0);
1578 g_return_val_if_fail (tree_model_sort->default_sort_func != NULL, 0);
1580 func = tree_model_sort->default_sort_func;
1581 f_data = tree_model_sort->default_sort_data;
1584 /* sortcut, if we've the same offsets here, they should be equal */
1585 if (sa->offset == sb->offset)
1588 sort_elt_get_iter (tree_model_sort, sa, &iter_a);
1589 sort_elt_get_iter (tree_model_sort, sb, &iter_b);
1591 retval = (* func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1592 &iter_a, &iter_b, f_data);
1594 if (tree_model_sort->order == GTK_SORT_DESCENDING)
1598 else if (retval < 0)
1606 gtk_tree_model_sort_offset_compare_func (gconstpointer a,
1612 SortElt *sa = ((SortTuple *)a)->elt;
1613 SortElt *sb = ((SortTuple *)b)->elt;
1615 SortData *data = (SortData *)user_data;
1617 if (sa->offset < sb->offset)
1619 else if (sa->offset > sb->offset)
1624 if (data->tree_model_sort->order == GTK_SORT_DESCENDING)
1628 else if (retval < 0)
1636 gtk_tree_model_sort_sort_helper (GtkTreeModelSort *tree_model_sort,
1639 gboolean emit_reordered)
1648 SortData *data = NULL;
1650 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1651 g_return_if_fail (parent != NULL);
1653 if (parent->len < 1 && !((SortElt *)parent->data)->children)
1656 data = g_new (SortData, 1);
1658 if (((SortElt *)parent->data)->parent)
1660 data->parent_a = gtk_tree_model_sort_generate_path
1661 (((SortElt *)parent->data)->parent);
1662 data->parent_b = gtk_tree_path_copy (data->parent_a);
1666 data->parent_a = gtk_tree_path_new ();
1667 data->parent_b = gtk_tree_path_new ();
1670 data->tree_model_sort = tree_model_sort;
1672 sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple),
1674 for (i = 0; i < parent->len; i++)
1678 tuple.elt = &g_array_index (parent, SortElt, i);
1679 tuple.children = tuple.elt->children;
1680 tuple.offset = tuple.elt->offset;
1682 g_array_append_val (sort_array, tuple);
1685 if (tree_model_sort->sort_column_id == -1 &&
1686 tree_model_sort->default_sort_func == (GtkTreeIterCompareFunc)0x1)
1687 g_array_sort_with_data (sort_array,
1688 gtk_tree_model_sort_offset_compare_func,
1691 g_array_sort_with_data (sort_array, gtk_tree_model_sort_compare_func,
1695 gtk_tree_path_free (data->parent_a);
1696 gtk_tree_path_free (data->parent_b);
1699 /* let the world know about our absolutely great new order */
1700 new_array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), parent->len);
1701 g_array_set_size (new_array, parent->len);
1702 new_order = g_new (gint, parent->len);
1704 for (i = 0; i < parent->len; i++)
1711 elt1 = &g_array_index (parent, SortElt, i);
1713 for (j = 0; j < sort_array->len; j++)
1714 if (elt1->offset == g_array_index (sort_array, SortTuple, j).offset)
1717 if (j >= parent->len)
1718 /* isn't supposed to happen */
1723 /* copy (hackety hack, or not? ;-) */
1724 memcpy (&g_array_index (new_array, SortElt, j), elt1, sizeof (SortElt));
1725 elt2 = &g_array_index (new_array, SortElt, j);
1727 /* point children to correct parent */
1733 for (k = 0; k < c->len; k++)
1734 g_array_index (c, SortElt, k).parent = elt2;
1739 /* a bit hackish ? */
1741 SortElt *p = g_array_index (new_array, SortElt, 0).parent;
1743 if (!p && parent == tree_model_sort->root)
1745 g_array_free (tree_model_sort->root, TRUE);
1746 tree_model_sort->root = parent = new_array;
1748 else if (p && parent == p->children)
1750 g_array_free (p->children, TRUE);
1751 p->children = parent = new_array;
1755 g_array_free (sort_array, TRUE);
1759 tree_model_sort->stamp++;
1761 iter.stamp = tree_model_sort->stamp;
1762 iter.user_data = ((SortElt *)parent->data)->parent;
1765 path = gtk_tree_model_sort_generate_path (iter.user_data);
1767 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1774 path = gtk_tree_path_new ();
1775 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
1776 path, NULL, new_order);
1779 gtk_tree_path_free (path);
1784 /* recurse, check if possible */
1787 for (i = 0; i < parent->len; i++)
1789 SortElt *elt = (SortElt *)&g_array_index (parent, SortElt, i);
1793 gtk_tree_model_sort_sort_helper (tree_model_sort,
1795 TRUE, emit_reordered);
1802 gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort)
1804 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
1806 if (!tree_model_sort->root)
1809 if (tree_model_sort->sort_column_id != -1)
1811 GtkTreeDataSortHeader *header = NULL;
1813 header = _gtk_tree_data_list_get_header
1814 (tree_model_sort->sort_list, tree_model_sort->sort_column_id);
1816 /* we want to make sure that we have a function */
1817 g_return_if_fail (header != NULL);
1818 g_return_if_fail (header->func != NULL);
1822 g_return_if_fail (tree_model_sort->default_sort_func != NULL);
1825 gtk_tree_model_sort_sort_helper (tree_model_sort, tree_model_sort->root,
1830 gtk_tree_model_sort_array_find_insert (GtkTreeModelSort *tree_model_sort,
1833 gboolean skip_sort_elt)
1838 GtkTreeIter tmp_iter;
1840 GtkTreeIterCompareFunc func;
1843 if (tree_model_sort->sort_column_id < 0)
1847 if (tree_model_sort->sort_column_id == -1 &&
1848 tree_model_sort->default_sort_func == (GtkTreeIterCompareFunc)0x1)
1851 if (tree_model_sort->sort_column_id != -1)
1853 GtkTreeDataSortHeader *header;
1855 header = _gtk_tree_data_list_get_header
1856 (tree_model_sort->sort_list, tree_model_sort->sort_column_id);
1858 g_return_val_if_fail (header != NULL, 0);
1859 g_return_val_if_fail (header->func != NULL, 0);
1861 func = header->func;
1862 data = header->data;
1866 /* absolutely SHOULD NOT HAPPEN */
1867 g_return_val_if_fail (tree_model_sort->default_sort_func
1868 != (GtkTreeIterCompareFunc)0x1, 0);
1870 g_return_val_if_fail (tree_model_sort->default_sort_func != NULL, 0);
1872 func = tree_model_sort->default_sort_func;
1873 data = tree_model_sort->default_sort_data;
1876 for (middle = 0; middle < array->len; middle++)
1878 tmp_elt = &(g_array_index (array, SortElt, middle));
1879 if (!skip_sort_elt && (SortElt *) iter == tmp_elt)
1882 sort_elt_get_iter (tree_model_sort, tmp_elt, &tmp_iter);
1884 if (tree_model_sort->order == GTK_SORT_ASCENDING)
1885 cmp = (* func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1886 &tmp_iter, iter, data);
1888 cmp = (* func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1889 iter, &tmp_iter, data);
1898 /* sort_elt helpers */
1900 sort_elt_get_iter (GtkTreeModelSort *tree_model_sort,
1902 GtkTreeIter *child_iter)
1904 if (tree_model_sort->cache_child_iters)
1905 *child_iter = elt->iter;
1908 GtkTreePath *path = gtk_tree_model_sort_generate_path (elt);
1909 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort->child_model),
1911 gtk_tree_path_free (path);
1915 /* another helper */
1918 static GtkTreePath *
1919 gtk_tree_model_sort_generate_path_index (SortElt *item,
1920 GtkTreeModelSort *tree_model_sort)
1924 GList *offsets = NULL;
1925 SortElt *walker = item;
1928 g_return_val_if_fail (item != NULL, NULL);
1934 GArray *array = get_array (walker, tree_model_sort);
1935 for (j = 0; j < array->len; j++)
1936 if (walker == &g_array_index (array, SortElt, j))
1939 if (j >= array->len)
1941 g_assert_not_reached ();
1945 offsets = g_list_prepend (offsets,
1946 g_strdup_printf ("%d", j));
1947 walker = walker->parent;
1950 g_return_val_if_fail (g_list_length (offsets) > 0, NULL);
1952 for (i = offsets; i; i = i->next)
1957 str = g_strconcat (copy, ":", i->data, NULL);
1959 str = g_strdup (i->data);
1967 g_list_free (offsets);
1969 path = gtk_tree_path_new_from_string (str);
1976 static GtkTreePath *
1977 gtk_tree_model_sort_generate_path (SortElt *item)
1981 GList *offsets = NULL;
1982 SortElt *walker = item;
1985 g_return_val_if_fail (item != NULL, NULL);
1989 offsets = g_list_prepend (offsets,
1990 g_strdup_printf ("%d", walker->offset));
1991 walker = walker->parent;
1994 g_return_val_if_fail (g_list_length (offsets) > 0, NULL);
1996 for (i = offsets; i; i = i->next)
2001 str = g_strconcat (copy, ":", i->data, NULL);
2003 str = g_strdup (i->data);
2011 g_list_free (offsets);
2013 path = gtk_tree_path_new_from_string (str);
2019 /* model cache/child model conversion and cache management */
2020 static GtkTreePath *
2021 gtk_tree_model_sort_convert_path_real (GtkTreeModelSort *tree_model_sort,
2022 GtkTreePath *child_path,
2023 gboolean build_children)
2025 GtkTreePath *retval;
2030 if (tree_model_sort->root == NULL)
2033 gtk_tree_model_sort_build_level (tree_model_sort, NULL);
2038 retval = gtk_tree_path_new ();
2039 array = (GArray *) tree_model_sort->root;
2040 indices = gtk_tree_path_get_indices (child_path);
2042 if (!indices && !gtk_tree_path_get_depth (child_path))
2043 /* just a new path */
2049 gboolean found = FALSE;
2052 if ((array->len < indices[i]) || (array == NULL))
2054 gtk_tree_path_free (retval);
2058 elt = (SortElt *) array->data;
2059 for (j = 0; j < array->len; j++, elt++)
2060 if (elt->offset == indices[i])
2068 gtk_tree_path_free (retval);
2072 gtk_tree_path_append_index (retval, j);
2076 if (i == gtk_tree_path_get_depth (child_path))
2079 if (elt->children == NULL)
2082 gtk_tree_model_sort_build_level_sort (tree_model_sort,
2086 gtk_tree_path_free (retval);
2092 array = elt->children;
2095 /* shouldn't happen... */
2096 gtk_tree_path_free (retval);
2106 gtk_tree_model_sort_convert_iter_real (GtkTreeModelSort *tree_model_sort,
2107 GtkTreeIter *sort_iter,
2108 GtkTreeIter *child_iter,
2109 gboolean build_children)
2111 GtkTreePath *sort_path;
2112 GtkTreePath *child_path;
2114 child_path = gtk_tree_model_get_path (tree_model_sort->child_model,
2116 sort_path = gtk_tree_model_sort_convert_path_real (tree_model_sort,
2120 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
2121 sort_iter, sort_path);
2123 gtk_tree_path_free (sort_path);
2124 gtk_tree_path_free (child_path);
2128 gtk_tree_model_sort_build_level_sort (GtkTreeModelSort *tree_model_sort,
2131 gtk_tree_model_sort_build_level (tree_model_sort, place);
2134 && tree_model_sort->default_sort_func != (GtkTreeIterCompareFunc) 0x1)
2136 gtk_tree_model_sort_sort_helper (tree_model_sort,
2143 gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
2148 GtkTreeIter *parent_iter = NULL;
2152 if (place && place->children)
2157 parent_iter = g_new (GtkTreeIter, 1);
2159 sort_elt_get_iter (tree_model_sort, place, parent_iter);
2162 n = gtk_tree_model_iter_n_children (tree_model_sort->child_model,
2168 gtk_tree_iter_free (parent_iter);
2172 children = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), n);
2175 place->children = children;
2177 tree_model_sort->root = children;
2179 gtk_tree_model_iter_children (tree_model_sort->child_model,
2185 if (tree_model_sort->cache_child_iters)
2188 elt.children = NULL;
2192 g_array_append_vals (children, &elt, 1);
2196 while (gtk_tree_model_iter_next (tree_model_sort->child_model, &iter));
2199 gtk_tree_iter_free (parent_iter);
2203 gtk_tree_model_sort_free_level (GArray *array)
2210 for (i = 0; i < array->len; i++)
2214 elt = &g_array_index (array, SortElt, i);
2216 gtk_tree_model_sort_free_level (elt->children);
2219 g_array_free (array, TRUE);
2222 /* USEFUL DEBUGGING CODE */
2226 _dump_tree (GtkTreeModelSort *tree_model_sort, const char *tag)
2231 g_return_if_fail (tree_model_sort != NULL);
2233 g_print ("-----------%s-----------------\n", tag);
2235 a = (GArray *)tree_model_sort->root;
2236 for (i = 0; i < a->len; i++)
2238 GValue value = {0,};
2241 sort_elt_get_iter (tree_model_sort, &g_array_index (a, SortElt, i),
2243 gtk_tree_model_get_value (tree_model_sort->child_model,
2245 g_print ("I/O=%d/%d --- %s\n", i, g_array_index (a, SortElt, i).offset,
2246 g_value_get_string (&value));
2247 g_value_unset (&value);
2250 g_print ("-------------------------\n");
2257 /* FIXME: we can, as we are an array, do binary search to find the correct
2258 * location to insert the element. However, I'd rather get it working. The
2259 * below is quite wrong, but a step in the right direction.
2263 middle = (low + high)/2;
2265 /* Insert the value into the array */
2269 tmp_elt = &(g_array_index (array, SortElt, middle));
2270 gtk_tree_model_get_value (sort->child_model,
2271 (GtkTreeIter *) tmp_elt,
2272 sort->sort_column_id,
2275 cmp = ((func) (&tmp_value, &s_value));
2276 g_value_unset (&tmp_value);
2284 middle = (low + high)/2;