2 * Copyright (C) 2000,2001 Red Hat, Inc., Jonathan Blandford <jrb@redhat.com>
3 * Copyright (C) 2001,2002 Kristian Rietveld <kris@gtk.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Library General Public License for more details.
15 * You should have received a copy of the GNU Library General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
21 /* NOTE: There is a potential for confusion in this code as to whether an iter,
22 * path or value refers to the GtkTreeModelSort model, or the child model being
23 * sorted. As a convention, variables referencing the child model will have an
24 * s_ prefix before them (ie. s_iter, s_value, s_path);
29 * iter->stamp = tree_model_sort->stamp
30 * iter->user_data = SortLevel
31 * iter->user_data2 = SortElt
37 #include "gtktreemodelsort.h"
38 #include "gtktreesortable.h"
39 #include "gtktreestore.h"
40 #include "gtktreedatalist.h"
42 #include "gtkprivate.h"
43 #include "gtktreednd.h"
47 * SECTION:gtktreemodelsort
48 * @Short_description: A GtkTreeModel which makes an underlying tree model sortable
49 * @Title: GtkTreeModelSort
50 * @See_also: #GtkTreeModel, #GtkListStore, #GtkTreeStore, #GtkTreeSortable, #GtkTreeModelFilter
52 * The #GtkTreeModelSort is a model which implements the #GtkTreeSortable
53 * interface. It does not hold any data itself, but rather is created with
54 * a child model and proxies its data. It has identical column types to
55 * this child model, and the changes in the child are propagated. The
56 * primary purpose of this model is to provide a way to sort a different
57 * model without modifying it. Note that the sort function used by
58 * #GtkTreeModelSort is not guaranteed to be stable.
60 * The use of this is best demonstrated through an example. In the
61 * following sample code we create two #GtkTreeView widgets each with a
62 * view of the same data. As the model is wrapped here by a
63 * #GtkTreeModelSort, the two #GtkTreeView<!-- -->s can each sort their
64 * view of the data without affecting the other. By contrast, if we
65 * simply put the same model in each widget, then sorting the first would
69 * <title>Using a <structname>GtkTreeModelSort</structname></title>
72 * GtkTreeView *tree_view1;
73 * GtkTreeView *tree_view2;
74 * GtkTreeModel *sort_model1;
75 * GtkTreeModel *sort_model2;
76 * GtkTreeModel *child_model;
78 * // get the child model
79 * child_model = get_my_model ();
81 * // Create the first tree
82 * sort_model1 = gtk_tree_model_sort_new_with_model (child_model);
83 * tree_view1 = gtk_tree_view_new_with_model (sort_model1);
85 * // Create the second tree
86 * sort_model2 = gtk_tree_model_sort_new_with_model (child_model);
87 * tree_view2 = gtk_tree_view_new_with_model (sort_model2);
89 * // Now we can sort the two models independently
90 * gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model1),
91 * COLUMN_1, GTK_SORT_ASCENDING);
92 * gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model2),
93 * COLUMN_1, GTK_SORT_DESCENDING);
98 * To demonstrate how to access the underlying child model from the sort
99 * model, the next example will be a callback for the #GtkTreeSelection
100 * #GtkTreeSelection::changed signal. In this callback, we get a string
101 * from COLUMN_1 of the model. We then modify the string, find the same
102 * selected row on the child model, and change the row there.
105 * <title>Accessing the child model of in a selection changed callback</title>
108 * selection_changed (GtkTreeSelection *selection, gpointer data)
110 * GtkTreeModel *sort_model = NULL;
111 * GtkTreeModel *child_model;
112 * GtkTreeIter sort_iter;
113 * GtkTreeIter child_iter;
114 * char *some_data = NULL;
115 * char *modified_data;
117 * // Get the current selected row and the model.
118 * if (! gtk_tree_selection_get_selected (selection,
123 * /<!---->* Look up the current value on the selected row and get a new value
126 * gtk_tree_model_get (GTK_TREE_MODEL (sort_model), &sort_iter,
127 * COLUMN_1, &some_data,
130 * modified_data = change_the_data (some_data);
131 * g_free (some_data);
133 * // Get an iterator on the child model, instead of the sort model.
134 * gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (sort_model),
138 * /<!---->* Get the child model and change the value of the row. In this
139 * * example, the child model is a GtkListStore. It could be any other
140 * * type of model, though.
142 * child_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
143 * gtk_list_store_set (GTK_LIST_STORE (child_model), &child_iter,
144 * COLUMN_1, &modified_data,
146 * g_free (modified_data);
153 typedef struct _SortElt SortElt;
154 typedef struct _SortLevel SortLevel;
155 typedef struct _SortData SortData;
156 typedef struct _SortTuple SortTuple;
172 SortLevel *parent_level;
177 GtkTreeModelSort *tree_model_sort;
178 GtkTreePath *parent_path;
179 gint parent_path_depth;
180 gint *parent_path_indices;
181 GtkTreeIterCompareFunc sort_func;
199 struct _GtkTreeModelSortPrivate
204 GtkTreeModel *child_model;
207 /* sort information */
213 GtkTreeIterCompareFunc default_sort_func;
214 gpointer default_sort_data;
215 GDestroyNotify default_sort_destroy;
220 gulong has_child_toggled_id;
225 /* Set this to 0 to disable caching of child iterators. This
226 * allows for more stringent testing. It is recommended to set this
227 * to one when refactoring this code and running the unit tests to
231 # define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) \
232 (((GtkTreeModelSort *)tree_model_sort)->priv->child_flags>K_TREE_MODEL_ITERS_PERSIST)
234 # define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) (FALSE)
237 #define SORT_ELT(sort_elt) ((SortElt *)sort_elt)
238 #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level)
241 #define GET_CHILD_ITER(tree_model_sort,ch_iter,so_iter) gtk_tree_model_sort_convert_iter_to_child_iter((GtkTreeModelSort*)(tree_model_sort), (ch_iter), (so_iter));
243 #define NO_SORT_FUNC ((GtkTreeIterCompareFunc) 0x1)
245 #define VALID_ITER(iter, tree_model_sort) ((iter) != NULL && (iter)->user_data != NULL && (iter)->user_data2 != NULL && (tree_model_sort)->priv->stamp == (iter)->stamp)
247 /* general (object/interface init, etc) */
248 static void gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface);
249 static void gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface);
250 static void gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface*iface);
251 static void gtk_tree_model_sort_finalize (GObject *object);
252 static void gtk_tree_model_sort_set_property (GObject *object,
256 static void gtk_tree_model_sort_get_property (GObject *object,
261 /* our signal handlers */
262 static void gtk_tree_model_sort_row_changed (GtkTreeModel *model,
263 GtkTreePath *start_path,
264 GtkTreeIter *start_iter,
266 static void gtk_tree_model_sort_row_inserted (GtkTreeModel *model,
270 static void gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *model,
274 static void gtk_tree_model_sort_row_deleted (GtkTreeModel *model,
277 static void gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
283 /* TreeModel interface */
284 static GtkTreeModelFlags gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model);
285 static gint gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model);
286 static GType gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
288 static gboolean gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
291 static GtkTreePath *gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
293 static void gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
297 static gboolean gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
299 static gboolean gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
301 static gboolean gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
303 GtkTreeIter *parent);
304 static gboolean gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
306 static gint gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
308 static gboolean gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
312 static gboolean gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
315 static void gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
317 static void gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
319 gboolean propagate_unref);
320 static void gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
323 /* TreeDragSource interface */
324 static gboolean gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
326 static gboolean gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
328 GtkSelectionData *selection_data);
329 static gboolean gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
332 /* TreeSortable interface */
333 static gboolean gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
334 gint *sort_column_id,
336 static void gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
339 static void gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
341 GtkTreeIterCompareFunc func,
343 GDestroyNotify destroy);
344 static void gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
345 GtkTreeIterCompareFunc func,
347 GDestroyNotify destroy);
348 static gboolean gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable);
350 /* Private functions (sort funcs, level handling and other utils) */
351 static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
352 SortLevel *parent_level,
353 SortElt *parent_elt);
354 static void gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
355 SortLevel *sort_level,
357 static void gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort);
358 static void gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
361 gboolean emit_reordered);
362 static void gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort);
363 static gint gtk_tree_model_sort_level_find_insert (GtkTreeModelSort *tree_model_sort,
367 static gboolean gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
370 GtkTreeIter *s_iter);
371 static GtkTreePath *gtk_tree_model_sort_elt_get_path (SortLevel *level,
373 static void gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
374 GtkTreeModel *child_model);
375 static GtkTreePath *gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
376 GtkTreePath *child_path,
377 gboolean build_levels);
380 G_DEFINE_TYPE_WITH_CODE (GtkTreeModelSort, gtk_tree_model_sort, G_TYPE_OBJECT,
381 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
382 gtk_tree_model_sort_tree_model_init)
383 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
384 gtk_tree_model_sort_tree_sortable_init)
385 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
386 gtk_tree_model_sort_drag_source_init))
389 gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
391 GtkTreeModelSortPrivate *priv;
393 priv = G_TYPE_INSTANCE_GET_PRIVATE (tree_model_sort,
394 GTK_TYPE_TREE_MODEL_SORT,
395 GtkTreeModelSortPrivate);
396 tree_model_sort->priv = priv;
397 priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
399 priv->zero_ref_count = 0;
401 priv->sort_list = NULL;
405 gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
407 GObjectClass *object_class;
409 object_class = (GObjectClass *) class;
411 object_class->set_property = gtk_tree_model_sort_set_property;
412 object_class->get_property = gtk_tree_model_sort_get_property;
414 object_class->finalize = gtk_tree_model_sort_finalize;
417 g_object_class_install_property (object_class,
419 g_param_spec_object ("model",
420 P_("TreeModelSort Model"),
421 P_("The model for the TreeModelSort to sort"),
423 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
425 g_type_class_add_private (class, sizeof (GtkTreeModelSortPrivate));
429 gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
431 iface->get_flags = gtk_tree_model_sort_get_flags;
432 iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
433 iface->get_column_type = gtk_tree_model_sort_get_column_type;
434 iface->get_iter = gtk_tree_model_sort_get_iter;
435 iface->get_path = gtk_tree_model_sort_get_path;
436 iface->get_value = gtk_tree_model_sort_get_value;
437 iface->iter_next = gtk_tree_model_sort_iter_next;
438 iface->iter_previous = gtk_tree_model_sort_iter_previous;
439 iface->iter_children = gtk_tree_model_sort_iter_children;
440 iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
441 iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
442 iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
443 iface->iter_parent = gtk_tree_model_sort_iter_parent;
444 iface->ref_node = gtk_tree_model_sort_ref_node;
445 iface->unref_node = gtk_tree_model_sort_unref_node;
449 gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface)
451 iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id;
452 iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id;
453 iface->set_sort_func = gtk_tree_model_sort_set_sort_func;
454 iface->set_default_sort_func = gtk_tree_model_sort_set_default_sort_func;
455 iface->has_default_sort_func = gtk_tree_model_sort_has_default_sort_func;
459 gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface *iface)
461 iface->row_draggable = gtk_tree_model_sort_row_draggable;
462 iface->drag_data_delete = gtk_tree_model_sort_drag_data_delete;
463 iface->drag_data_get = gtk_tree_model_sort_drag_data_get;
467 * gtk_tree_model_sort_new_with_model:
468 * @child_model: A #GtkTreeModel
470 * Creates a new #GtkTreeModel, with @child_model as the child model.
472 * Return value: (transfer full): A new #GtkTreeModel.
475 gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model)
477 GtkTreeModel *retval;
479 g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
481 retval = g_object_new (gtk_tree_model_sort_get_type (), NULL);
483 gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model);
488 /* GObject callbacks */
490 gtk_tree_model_sort_finalize (GObject *object)
492 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
493 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
495 gtk_tree_model_sort_set_model (tree_model_sort, NULL);
498 gtk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE);
502 _gtk_tree_data_list_header_free (priv->sort_list);
503 priv->sort_list = NULL;
506 if (priv->default_sort_destroy)
508 priv->default_sort_destroy (priv->default_sort_data);
509 priv->default_sort_destroy = NULL;
510 priv->default_sort_data = NULL;
515 G_OBJECT_CLASS (gtk_tree_model_sort_parent_class)->finalize (object);
519 gtk_tree_model_sort_set_property (GObject *object,
524 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
529 gtk_tree_model_sort_set_model (tree_model_sort, g_value_get_object (value));
532 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
538 gtk_tree_model_sort_get_property (GObject *object,
543 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
548 g_value_set_object (value, gtk_tree_model_sort_get_model (tree_model_sort));
551 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
557 gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
558 GtkTreePath *start_s_path,
559 GtkTreeIter *start_s_iter,
562 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
563 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
564 GtkTreePath *path = NULL;
572 gboolean free_s_path = FALSE;
574 gint index = 0, old_index, i;
576 g_return_if_fail (start_s_path != NULL || start_s_iter != NULL);
581 start_s_path = gtk_tree_model_get_path (s_model, start_s_iter);
584 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
590 gtk_tree_path_free (start_s_path);
594 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
595 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (data), &iter);
597 level = iter.user_data;
598 elt = iter.user_data2;
600 if (level->array->len < 2 ||
601 (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
602 priv->default_sort_func == NO_SORT_FUNC))
605 gtk_tree_path_free (start_s_path);
607 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
608 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
610 gtk_tree_path_free (path);
615 if (!GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
617 gtk_tree_model_get_iter (priv->child_model,
618 &tmpiter, start_s_path);
621 old_index = elt - SORT_ELT (level->array->data);
623 memcpy (&tmp, elt, sizeof (SortElt));
625 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
626 index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
631 index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
636 if (index < old_index)
638 g_memmove (level->array->data + ((index + 1)*sizeof (SortElt)),
639 level->array->data + ((index)*sizeof (SortElt)),
640 (old_index - index)* sizeof(SortElt));
642 else if (index > old_index)
644 g_memmove (level->array->data + ((old_index)*sizeof (SortElt)),
645 level->array->data + ((old_index + 1)*sizeof (SortElt)),
646 (index - old_index)* sizeof(SortElt));
648 memcpy (level->array->data + ((index)*sizeof (SortElt)),
649 &tmp, sizeof (SortElt));
651 for (i = 0; i < level->array->len; i++)
652 if (g_array_index (level->array, SortElt, i).children)
653 g_array_index (level->array, SortElt, i).children->parent_elt = &g_array_index (level->array, SortElt, i);
655 gtk_tree_path_up (path);
656 gtk_tree_path_append_index (path, index);
658 gtk_tree_model_sort_increment_stamp (tree_model_sort);
660 /* if the item moved, then emit rows_reordered */
661 if (old_index != index)
666 GtkTreePath *tmppath;
668 new_order = g_new (gint, level->array->len);
670 for (j = 0; j < level->array->len; j++)
672 if (index > old_index)
675 new_order[j] = old_index;
676 else if (j >= old_index && j < index)
677 new_order[j] = j + 1;
681 else if (index < old_index)
684 new_order[j] = old_index;
685 else if (j > index && j <= old_index)
686 new_order[j] = j - 1;
690 /* else? shouldn't really happen */
693 if (level->parent_elt)
695 iter.stamp = priv->stamp;
696 iter.user_data = level->parent_level;
697 iter.user_data2 = level->parent_elt;
699 tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter);
701 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
702 tmppath, &iter, new_order);
707 tmppath = gtk_tree_path_new ();
709 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), tmppath,
713 gtk_tree_path_free (tmppath);
717 /* emit row_changed signal (at new location) */
718 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
719 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
720 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
722 gtk_tree_path_free (path);
724 gtk_tree_path_free (start_s_path);
728 gtk_tree_model_sort_row_inserted (GtkTreeModel *s_model,
733 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
734 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
737 GtkTreeIter real_s_iter;
741 gboolean free_s_path = FALSE;
745 SortLevel *parent_level = NULL;
747 parent_level = level = SORT_LEVEL (priv->root);
749 g_return_if_fail (s_path != NULL || s_iter != NULL);
753 s_path = gtk_tree_model_get_path (s_model, s_iter);
758 gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
760 real_s_iter = *s_iter;
764 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
766 /* the build level already put the inserted iter in the level,
767 so no need to handle this signal anymore */
769 goto done_and_submit;
772 /* find the parent level */
773 while (i < gtk_tree_path_get_depth (s_path) - 1)
779 /* level not yet build, we won't cover this signal */
783 if (level->array->len < gtk_tree_path_get_indices (s_path)[i])
785 g_warning ("%s: A node was inserted with a parent that's not in the tree.\n"
786 "This possibly means that a GtkTreeModel inserted a child node\n"
787 "before the parent was inserted.",
793 for (j = 0; j < level->array->len; j++)
794 if (g_array_index (level->array, SortElt, j).offset == gtk_tree_path_get_indices (s_path)[i])
796 elt = &g_array_index (level->array, SortElt, j);
800 g_return_if_fail (elt != NULL);
804 /* not covering this signal */
808 level = elt->children;
809 parent_level = level;
816 if (level->ref_count == 0 && level != priv->root)
818 gtk_tree_model_sort_free_level (tree_model_sort, level, TRUE);
822 if (!gtk_tree_model_sort_insert_value (tree_model_sort,
829 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
836 gtk_tree_model_sort_increment_stamp (tree_model_sort);
838 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
839 gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
840 gtk_tree_path_free (path);
844 gtk_tree_path_free (s_path);
850 gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *s_model,
855 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
859 g_return_if_fail (s_path != NULL && s_iter != NULL);
861 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
865 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
866 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
868 gtk_tree_path_free (path);
872 gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
876 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
877 GtkTreePath *path = NULL;
884 g_return_if_fail (s_path != NULL);
886 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
890 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
892 level = SORT_LEVEL (iter.user_data);
893 elt = SORT_ELT (iter.user_data2);
894 offset = elt->offset;
896 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
898 while (elt->ref_count > 0)
899 gtk_tree_model_sort_real_unref_node (GTK_TREE_MODEL (data), &iter, FALSE);
901 /* If this node has children, we free the level (recursively) here
902 * and specify that unref may not be used, because parent and its
903 * children have been removed by now.
906 gtk_tree_model_sort_free_level (tree_model_sort,
907 elt->children, FALSE);
909 if (level->ref_count == 0)
911 gtk_tree_model_sort_increment_stamp (tree_model_sort);
912 gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
913 gtk_tree_path_free (path);
915 if (level == tree_model_sort->priv->root)
917 gtk_tree_model_sort_free_level (tree_model_sort,
918 tree_model_sort->priv->root,
920 tree_model_sort->priv->root = NULL;
926 for (i = 0; i < level->array->len; i++)
927 if (elt->offset == g_array_index (level->array, SortElt, i).offset)
930 g_array_remove_index (level->array, i);
932 /* update all offsets */
933 for (i = 0; i < level->array->len; i++)
935 elt = & (g_array_index (level->array, SortElt, i));
936 if (elt->offset > offset)
939 elt->children->parent_elt = elt;
942 gtk_tree_model_sort_increment_stamp (tree_model_sort);
943 gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
945 gtk_tree_path_free (path);
949 gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
961 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
962 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
964 g_return_if_fail (new_order != NULL);
966 if (s_path == NULL || gtk_tree_path_get_depth (s_path) == 0)
968 if (priv->root == NULL)
970 path = gtk_tree_path_new ();
971 level = SORT_LEVEL (priv->root);
975 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
978 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
980 level = SORT_LEVEL (iter.user_data);
981 elt = SORT_ELT (iter.user_data2);
985 gtk_tree_path_free (path);
989 level = elt->children;
992 if (level->array->len < 2)
994 gtk_tree_path_free (path);
998 tmp_array = g_new (int, level->array->len);
999 for (i = 0; i < level->array->len; i++)
1001 for (j = 0; j < level->array->len; j++)
1003 if (g_array_index (level->array, SortElt, i).offset == new_order[j])
1008 for (i = 0; i < level->array->len; i++)
1009 g_array_index (level->array, SortElt, i).offset = tmp_array[i];
1012 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
1013 priv->default_sort_func == NO_SORT_FUNC)
1016 gtk_tree_model_sort_sort_level (tree_model_sort, level,
1018 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1020 if (gtk_tree_path_get_depth (path))
1022 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
1025 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
1026 path, &iter, new_order);
1030 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
1031 path, NULL, new_order);
1035 gtk_tree_path_free (path);
1038 /* Fulfill our model requirements */
1039 static GtkTreeModelFlags
1040 gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model)
1042 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1043 GtkTreeModelFlags flags;
1045 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, 0);
1047 flags = gtk_tree_model_get_flags (tree_model_sort->priv->child_model);
1049 if ((flags & GTK_TREE_MODEL_LIST_ONLY) == GTK_TREE_MODEL_LIST_ONLY)
1050 return GTK_TREE_MODEL_LIST_ONLY;
1056 gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
1058 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1060 if (tree_model_sort->priv->child_model == 0)
1063 return gtk_tree_model_get_n_columns (tree_model_sort->priv->child_model);
1067 gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
1070 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1072 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, G_TYPE_INVALID);
1074 return gtk_tree_model_get_column_type (tree_model_sort->priv->child_model, index);
1078 gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
1082 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1083 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1088 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1090 indices = gtk_tree_path_get_indices (path);
1092 if (priv->root == NULL)
1093 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1094 level = SORT_LEVEL (priv->root);
1096 depth = gtk_tree_path_get_depth (path);
1103 for (i = 0; i < depth - 1; i++)
1105 if ((level == NULL) ||
1106 (indices[i] >= level->array->len))
1112 if (g_array_index (level->array, SortElt, indices[i]).children == NULL)
1113 gtk_tree_model_sort_build_level (tree_model_sort, level,
1114 &g_array_index (level->array, SortElt, indices[i]));
1115 level = g_array_index (level->array, SortElt, indices[i]).children;
1118 if (!level || indices[i] >= level->array->len)
1124 iter->stamp = priv->stamp;
1125 iter->user_data = level;
1126 iter->user_data2 = &g_array_index (level->array, SortElt, indices[depth - 1]);
1131 static GtkTreePath *
1132 gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
1135 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1136 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1137 GtkTreePath *retval;
1141 g_return_val_if_fail (priv->child_model != NULL, NULL);
1142 g_return_val_if_fail (priv->stamp == iter->stamp, NULL);
1144 retval = gtk_tree_path_new ();
1146 level = SORT_LEVEL (iter->user_data);
1147 elt = SORT_ELT (iter->user_data2);
1151 gtk_tree_path_prepend_index (retval, elt - (SortElt *)level->array->data);
1153 elt = level->parent_elt;
1154 level = level->parent_level;
1161 gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
1166 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1167 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1168 GtkTreeIter child_iter;
1170 g_return_if_fail (priv->child_model != NULL);
1171 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1173 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1174 gtk_tree_model_get_value (priv->child_model,
1175 &child_iter, column, value);
1179 gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
1182 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1183 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1187 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1188 g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1190 level = iter->user_data;
1191 elt = iter->user_data2;
1193 if (elt - (SortElt *)level->array->data >= level->array->len - 1)
1198 iter->user_data2 = elt + 1;
1204 gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
1207 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1208 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1212 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1213 g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1215 level = iter->user_data;
1216 elt = iter->user_data2;
1218 if (elt == (SortElt *)level->array->data)
1223 iter->user_data2 = elt - 1;
1229 gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
1231 GtkTreeIter *parent)
1233 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1234 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1238 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1240 g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1244 if (priv->root == NULL)
1245 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1246 if (priv->root == NULL)
1250 iter->stamp = priv->stamp;
1251 iter->user_data = level;
1252 iter->user_data2 = level->array->data;
1258 level = SORT_LEVEL (parent->user_data);
1259 elt = SORT_ELT (parent->user_data2);
1261 if (elt->children == NULL)
1262 gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
1264 if (elt->children == NULL)
1267 iter->stamp = priv->stamp;
1268 iter->user_data = elt->children;
1269 iter->user_data2 = elt->children->array->data;
1276 gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
1279 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1280 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1281 GtkTreeIter child_iter;
1283 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1284 g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), FALSE);
1286 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1288 return gtk_tree_model_iter_has_child (priv->child_model, &child_iter);
1292 gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
1295 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1296 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1297 GtkTreeIter child_iter;
1299 g_return_val_if_fail (priv->child_model != NULL, 0);
1301 g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), 0);
1304 return gtk_tree_model_iter_n_children (priv->child_model, NULL);
1306 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1308 return gtk_tree_model_iter_n_children (priv->child_model, &child_iter);
1312 gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
1314 GtkTreeIter *parent,
1317 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1319 /* We have this for the iter == parent case */
1320 GtkTreeIter children;
1323 g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1325 /* Use this instead of has_child to force us to build the level, if needed */
1326 if (gtk_tree_model_sort_iter_children (tree_model, &children, parent) == FALSE)
1332 level = children.user_data;
1333 if (n >= level->array->len)
1339 iter->stamp = tree_model_sort->priv->stamp;
1340 iter->user_data = level;
1341 iter->user_data2 = &g_array_index (level->array, SortElt, n);
1347 gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
1351 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1352 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1356 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1357 g_return_val_if_fail (VALID_ITER (child, tree_model_sort), FALSE);
1359 level = child->user_data;
1361 if (level->parent_level)
1363 iter->stamp = priv->stamp;
1364 iter->user_data = level->parent_level;
1365 iter->user_data2 = level->parent_elt;
1373 gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
1376 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1377 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1378 GtkTreeIter child_iter;
1382 g_return_if_fail (priv->child_model != NULL);
1383 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1385 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1387 /* Reference the node in the child model */
1388 gtk_tree_model_ref_node (priv->child_model, &child_iter);
1390 /* Increase the reference count of this element and its level */
1391 level = iter->user_data;
1392 elt = iter->user_data2;
1397 if (level->ref_count == 1)
1399 SortLevel *parent_level = level->parent_level;
1400 SortElt *parent_elt = level->parent_elt;
1402 /* We were at zero -- time to decrement the zero_ref_count val */
1403 while (parent_level)
1405 parent_elt->zero_ref_count--;
1407 parent_elt = parent_level->parent_elt;
1408 parent_level = parent_level->parent_level;
1411 if (priv->root != level)
1412 priv->zero_ref_count--;
1417 gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
1419 gboolean propagate_unref)
1421 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1422 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1426 g_return_if_fail (priv->child_model != NULL);
1427 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1429 if (propagate_unref)
1431 GtkTreeIter child_iter;
1433 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1434 gtk_tree_model_unref_node (priv->child_model, &child_iter);
1437 level = iter->user_data;
1438 elt = iter->user_data2;
1440 g_return_if_fail (elt->ref_count > 0);
1445 if (level->ref_count == 0)
1447 SortLevel *parent_level = level->parent_level;
1448 SortElt *parent_elt = level->parent_elt;
1450 /* We are at zero -- time to increment the zero_ref_count val */
1451 while (parent_level)
1453 parent_elt->zero_ref_count++;
1455 parent_elt = parent_level->parent_elt;
1456 parent_level = parent_level->parent_level;
1459 if (priv->root != level)
1460 priv->zero_ref_count++;
1465 gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
1468 gtk_tree_model_sort_real_unref_node (tree_model, iter, TRUE);
1471 /* Sortable interface */
1473 gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
1474 gint *sort_column_id,
1477 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1478 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1481 *sort_column_id = priv->sort_column_id;
1483 *order = priv->order;
1485 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
1486 priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1493 gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
1494 gint sort_column_id,
1497 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1498 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1500 if (sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1502 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1504 GtkTreeDataSortHeader *header = NULL;
1506 header = _gtk_tree_data_list_get_header (priv->sort_list,
1509 /* we want to make sure that we have a function */
1510 g_return_if_fail (header != NULL);
1511 g_return_if_fail (header->func != NULL);
1514 g_return_if_fail (priv->default_sort_func != NULL);
1516 if (priv->sort_column_id == sort_column_id)
1518 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1520 if (priv->order == order)
1528 priv->sort_column_id = sort_column_id;
1529 priv->order = order;
1531 gtk_tree_sortable_sort_column_changed (sortable);
1533 gtk_tree_model_sort_sort (tree_model_sort);
1537 gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
1538 gint sort_column_id,
1539 GtkTreeIterCompareFunc func,
1541 GDestroyNotify destroy)
1543 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1544 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1546 priv->sort_list = _gtk_tree_data_list_set_header (priv->sort_list,
1548 func, data, destroy);
1550 if (priv->sort_column_id == sort_column_id)
1551 gtk_tree_model_sort_sort (tree_model_sort);
1555 gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
1556 GtkTreeIterCompareFunc func,
1558 GDestroyNotify destroy)
1560 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1561 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1563 if (priv->default_sort_destroy)
1565 GDestroyNotify d = priv->default_sort_destroy;
1567 priv->default_sort_destroy = NULL;
1568 d (priv->default_sort_data);
1571 priv->default_sort_func = func;
1572 priv->default_sort_data = data;
1573 priv->default_sort_destroy = destroy;
1575 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1576 gtk_tree_model_sort_sort (tree_model_sort);
1580 gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable)
1582 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1584 return (tree_model_sort->priv->default_sort_func != NULL);
1587 /* DragSource interface */
1589 gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
1592 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1593 GtkTreePath *child_path;
1596 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort,
1598 draggable = gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1599 gtk_tree_path_free (child_path);
1605 gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
1607 GtkSelectionData *selection_data)
1609 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1610 GtkTreePath *child_path;
1613 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1614 gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path, selection_data);
1615 gtk_tree_path_free (child_path);
1621 gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
1624 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1625 GtkTreePath *child_path;
1628 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1629 deleted = gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1630 gtk_tree_path_free (child_path);
1635 /* sorting code - private */
1637 gtk_tree_model_sort_compare_func (gconstpointer a,
1641 SortData *data = (SortData *)user_data;
1642 GtkTreeModelSort *tree_model_sort = data->tree_model_sort;
1643 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1644 SortTuple *sa = (SortTuple *)a;
1645 SortTuple *sb = (SortTuple *)b;
1647 GtkTreeIter iter_a, iter_b;
1650 /* shortcut, if we've the same offsets here, they should be equal */
1651 if (sa->offset == sb->offset)
1654 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1656 iter_a = sa->elt->iter;
1657 iter_b = sb->elt->iter;
1661 data->parent_path_indices [data->parent_path_depth-1] = sa->elt->offset;
1662 gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_a, data->parent_path);
1663 data->parent_path_indices [data->parent_path_depth-1] = sb->elt->offset;
1664 gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_b, data->parent_path);
1667 retval = (* data->sort_func) (GTK_TREE_MODEL (priv->child_model),
1671 if (priv->order == GTK_SORT_DESCENDING)
1675 else if (retval < 0)
1683 gtk_tree_model_sort_offset_compare_func (gconstpointer a,
1689 SortTuple *sa = (SortTuple *)a;
1690 SortTuple *sb = (SortTuple *)b;
1692 SortData *data = (SortData *)user_data;
1694 if (sa->elt->offset < sb->elt->offset)
1696 else if (sa->elt->offset > sb->elt->offset)
1701 if (data->tree_model_sort->priv->order == GTK_SORT_DESCENDING)
1705 else if (retval < 0)
1713 gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
1716 gboolean emit_reordered)
1718 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1730 g_return_if_fail (level != NULL);
1732 if (level->array->len < 1 && !((SortElt *)level->array->data)->children)
1735 iter.stamp = priv->stamp;
1736 iter.user_data = level;
1737 iter.user_data2 = &g_array_index (level->array, SortElt, 0);
1739 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1740 ref_offset = g_array_index (level->array, SortElt, 0).offset;
1743 data.tree_model_sort = tree_model_sort;
1744 if (level->parent_elt)
1746 data.parent_path = gtk_tree_model_sort_elt_get_path (level->parent_level,
1748 gtk_tree_path_append_index (data.parent_path, 0);
1752 data.parent_path = gtk_tree_path_new_first ();
1754 data.parent_path_depth = gtk_tree_path_get_depth (data.parent_path);
1755 data.parent_path_indices = gtk_tree_path_get_indices (data.parent_path);
1757 /* make the array to be sorted */
1758 sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), level->array->len);
1759 for (i = 0; i < level->array->len; i++)
1763 tuple.elt = &g_array_index (level->array, SortElt, i);
1766 g_array_append_val (sort_array, tuple);
1769 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1771 GtkTreeDataSortHeader *header = NULL;
1773 header = _gtk_tree_data_list_get_header (priv->sort_list,
1774 priv->sort_column_id);
1776 g_return_if_fail (header != NULL);
1777 g_return_if_fail (header->func != NULL);
1779 data.sort_func = header->func;
1780 data.sort_data = header->data;
1784 /* absolutely SHOULD NOT happen: */
1785 g_return_if_fail (priv->default_sort_func != NULL);
1787 data.sort_func = priv->default_sort_func;
1788 data.sort_data = priv->default_sort_data;
1791 if (data.sort_func == NO_SORT_FUNC)
1792 g_array_sort_with_data (sort_array,
1793 gtk_tree_model_sort_offset_compare_func,
1796 g_array_sort_with_data (sort_array,
1797 gtk_tree_model_sort_compare_func,
1800 gtk_tree_path_free (data.parent_path);
1802 new_array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), level->array->len);
1803 new_order = g_new (gint, level->array->len);
1805 for (i = 0; i < level->array->len; i++)
1809 elt = g_array_index (sort_array, SortTuple, i).elt;
1810 new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1812 g_array_append_val (new_array, *elt);
1814 elt->children->parent_elt = elt;
1817 g_array_free (level->array, TRUE);
1818 level->array = new_array;
1819 g_array_free (sort_array, TRUE);
1823 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1824 if (level->parent_elt)
1826 iter.stamp = priv->stamp;
1827 iter.user_data = level->parent_level;
1828 iter.user_data2 = level->parent_elt;
1830 path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort),
1833 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1839 path = gtk_tree_path_new ();
1840 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1844 gtk_tree_path_free (path);
1847 /* recurse, if possible */
1850 for (i = 0; i < level->array->len; i++)
1852 SortElt *elt = &g_array_index (level->array, SortElt, i);
1855 gtk_tree_model_sort_sort_level (tree_model_sort,
1857 TRUE, emit_reordered);
1863 /* get the iter we referenced at the beginning of this function and
1866 iter.stamp = priv->stamp;
1867 iter.user_data = level;
1869 for (i = 0; i < level->array->len; i++)
1871 if (g_array_index (level->array, SortElt, i).offset == ref_offset)
1873 iter.user_data2 = &g_array_index (level->array, SortElt, i);
1878 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1882 gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort)
1884 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1886 if (priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1892 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1894 GtkTreeDataSortHeader *header = NULL;
1896 header = _gtk_tree_data_list_get_header (priv->sort_list,
1897 priv->sort_column_id);
1899 /* we want to make sure that we have a function */
1900 g_return_if_fail (header != NULL);
1901 g_return_if_fail (header->func != NULL);
1904 g_return_if_fail (priv->default_sort_func != NULL);
1906 gtk_tree_model_sort_sort_level (tree_model_sort, priv->root,
1910 /* signal helpers */
1912 gtk_tree_model_sort_level_find_insert (GtkTreeModelSort *tree_model_sort,
1917 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1918 gint start, middle, end;
1921 GtkTreeIter tmp_iter;
1923 GtkTreeIterCompareFunc func;
1926 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1928 GtkTreeDataSortHeader *header;
1930 header = _gtk_tree_data_list_get_header (priv->sort_list,
1931 priv->sort_column_id);
1933 g_return_val_if_fail (header != NULL, 0);
1935 func = header->func;
1936 data = header->data;
1940 func = priv->default_sort_func;
1941 data = priv->default_sort_data;
1943 g_return_val_if_fail (func != NO_SORT_FUNC, 0);
1946 g_return_val_if_fail (func != NULL, 0);
1949 end = level->array->len;
1958 while (start != end)
1960 middle = (start + end) / 2;
1962 if (middle < skip_index)
1963 tmp_elt = &(g_array_index (level->array, SortElt, middle));
1965 tmp_elt = &(g_array_index (level->array, SortElt, middle + 1));
1967 if (!GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1969 GtkTreePath *path = gtk_tree_model_sort_elt_get_path (level, tmp_elt);
1970 gtk_tree_model_get_iter (priv->child_model,
1972 gtk_tree_path_free (path);
1975 tmp_iter = tmp_elt->iter;
1977 if (priv->order == GTK_SORT_ASCENDING)
1978 cmp = (* func) (GTK_TREE_MODEL (priv->child_model),
1979 &tmp_iter, iter, data);
1981 cmp = (* func) (GTK_TREE_MODEL (priv->child_model),
1982 iter, &tmp_iter, data);
1997 gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
1999 GtkTreePath *s_path,
2000 GtkTreeIter *s_iter)
2002 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2003 gint offset, index, i;
2008 offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];
2010 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2012 elt.offset = offset;
2013 elt.zero_ref_count = 0;
2015 elt.children = NULL;
2017 /* update all larger offsets */
2018 tmp_elt = SORT_ELT (level->array->data);
2019 for (i = 0; i < level->array->len; i++, tmp_elt++)
2020 if (tmp_elt->offset >= offset)
2023 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
2024 priv->default_sort_func == NO_SORT_FUNC)
2027 index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
2031 g_array_insert_vals (level->array, index, &elt, 1);
2032 tmp_elt = SORT_ELT (level->array->data);
2033 for (i = 0; i < level->array->len; i++, tmp_elt++)
2034 if (tmp_elt->children)
2035 tmp_elt->children->parent_elt = tmp_elt;
2040 /* sort elt stuff */
2041 static GtkTreePath *
2042 gtk_tree_model_sort_elt_get_path (SortLevel *level,
2045 SortLevel *walker = level;
2046 SortElt *walker2 = elt;
2049 g_return_val_if_fail (level != NULL, NULL);
2050 g_return_val_if_fail (elt != NULL, NULL);
2052 path = gtk_tree_path_new ();
2056 gtk_tree_path_prepend_index (path, walker2->offset);
2058 if (!walker->parent_level)
2061 walker2 = walker->parent_elt;
2062 walker = walker->parent_level;
2069 * gtk_tree_model_sort_set_model:
2070 * @tree_model_sort: The #GtkTreeModelSort.
2071 * @child_model: (allow-none): A #GtkTreeModel, or %NULL.
2073 * Sets the model of @tree_model_sort to be @model. If @model is %NULL,
2074 * then the old model is unset. The sort function is unset as a result
2075 * of this call. The model will be in an unsorted state until a sort
2079 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
2080 GtkTreeModel *child_model)
2082 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2085 g_object_ref (child_model);
2087 if (priv->child_model)
2089 g_signal_handler_disconnect (priv->child_model,
2091 g_signal_handler_disconnect (priv->child_model,
2093 g_signal_handler_disconnect (priv->child_model,
2094 priv->has_child_toggled_id);
2095 g_signal_handler_disconnect (priv->child_model,
2097 g_signal_handler_disconnect (priv->child_model,
2098 priv->reordered_id);
2100 /* reset our state */
2102 gtk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE);
2104 _gtk_tree_data_list_header_free (priv->sort_list);
2105 priv->sort_list = NULL;
2106 g_object_unref (priv->child_model);
2109 priv->child_model = child_model;
2117 g_signal_connect (child_model, "row-changed",
2118 G_CALLBACK (gtk_tree_model_sort_row_changed),
2121 g_signal_connect (child_model, "row-inserted",
2122 G_CALLBACK (gtk_tree_model_sort_row_inserted),
2124 priv->has_child_toggled_id =
2125 g_signal_connect (child_model, "row-has-child-toggled",
2126 G_CALLBACK (gtk_tree_model_sort_row_has_child_toggled),
2129 g_signal_connect (child_model, "row-deleted",
2130 G_CALLBACK (gtk_tree_model_sort_row_deleted),
2132 priv->reordered_id =
2133 g_signal_connect (child_model, "rows-reordered",
2134 G_CALLBACK (gtk_tree_model_sort_rows_reordered),
2137 priv->child_flags = gtk_tree_model_get_flags (child_model);
2138 n_columns = gtk_tree_model_get_n_columns (child_model);
2140 types = g_new (GType, n_columns);
2141 for (i = 0; i < n_columns; i++)
2142 types[i] = gtk_tree_model_get_column_type (child_model, i);
2144 priv->sort_list = _gtk_tree_data_list_header_new (n_columns, types);
2147 priv->default_sort_func = NO_SORT_FUNC;
2148 priv->stamp = g_random_int ();
2153 * gtk_tree_model_sort_get_model:
2154 * @tree_model: a #GtkTreeModelSort
2156 * Returns the model the #GtkTreeModelSort is sorting.
2158 * Return value: (transfer none): the "child model" being sorted
2161 gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model)
2163 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
2165 return tree_model->priv->child_model;
2169 static GtkTreePath *
2170 gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2171 GtkTreePath *child_path,
2172 gboolean build_levels)
2174 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2175 gint *child_indices;
2176 GtkTreePath *retval;
2180 g_return_val_if_fail (priv->child_model != NULL, NULL);
2181 g_return_val_if_fail (child_path != NULL, NULL);
2183 retval = gtk_tree_path_new ();
2184 child_indices = gtk_tree_path_get_indices (child_path);
2186 if (priv->root == NULL && build_levels)
2187 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
2188 level = SORT_LEVEL (priv->root);
2190 for (i = 0; i < gtk_tree_path_get_depth (child_path); i++)
2193 gboolean found_child = FALSE;
2197 gtk_tree_path_free (retval);
2201 if (child_indices[i] >= level->array->len)
2203 gtk_tree_path_free (retval);
2206 for (j = 0; j < level->array->len; j++)
2208 if ((g_array_index (level->array, SortElt, j)).offset == child_indices[i])
2210 gtk_tree_path_append_index (retval, j);
2211 if (g_array_index (level->array, SortElt, j).children == NULL && build_levels)
2213 gtk_tree_model_sort_build_level (tree_model_sort, level,
2214 &g_array_index (level->array, SortElt, j));
2216 level = g_array_index (level->array, SortElt, j).children;
2223 gtk_tree_path_free (retval);
2233 * gtk_tree_model_sort_convert_child_path_to_path:
2234 * @tree_model_sort: A #GtkTreeModelSort
2235 * @child_path: A #GtkTreePath to convert
2237 * Converts @child_path to a path relative to @tree_model_sort. That is,
2238 * @child_path points to a path in the child model. The returned path will
2239 * point to the same row in the sorted model. If @child_path isn't a valid
2240 * path on the child model, then %NULL is returned.
2242 * Return value: A newly allocated #GtkTreePath, or %NULL
2245 gtk_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2246 GtkTreePath *child_path)
2248 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2249 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, NULL);
2250 g_return_val_if_fail (child_path != NULL, NULL);
2252 return gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path, TRUE);
2256 * gtk_tree_model_sort_convert_child_iter_to_iter:
2257 * @tree_model_sort: A #GtkTreeModelSort
2258 * @sort_iter: (out): An uninitialized #GtkTreeIter.
2259 * @child_iter: A valid #GtkTreeIter pointing to a row on the child model
2261 * Sets @sort_iter to point to the row in @tree_model_sort that corresponds to
2262 * the row pointed at by @child_iter. If @sort_iter was not set, %FALSE
2263 * is returned. Note: a boolean is only returned since 2.14.
2265 * Return value: %TRUE, if @sort_iter was set, i.e. if @sort_iter is a
2266 * valid iterator pointer to a visible row in the child model.
2269 gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sort,
2270 GtkTreeIter *sort_iter,
2271 GtkTreeIter *child_iter)
2274 GtkTreePath *child_path, *path;
2275 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2277 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2278 g_return_val_if_fail (priv->child_model != NULL, FALSE);
2279 g_return_val_if_fail (sort_iter != NULL, FALSE);
2280 g_return_val_if_fail (child_iter != NULL, FALSE);
2281 g_return_val_if_fail (sort_iter != child_iter, FALSE);
2283 sort_iter->stamp = 0;
2285 child_path = gtk_tree_model_get_path (priv->child_model, child_iter);
2286 g_return_val_if_fail (child_path != NULL, FALSE);
2288 path = gtk_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path);
2289 gtk_tree_path_free (child_path);
2293 g_warning ("%s: The conversion of the child path to a GtkTreeModel sort path failed", G_STRLOC);
2297 ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
2299 gtk_tree_path_free (path);
2305 * gtk_tree_model_sort_convert_path_to_child_path:
2306 * @tree_model_sort: A #GtkTreeModelSort
2307 * @sorted_path: A #GtkTreePath to convert
2309 * Converts @sorted_path to a path on the child model of @tree_model_sort.
2310 * That is, @sorted_path points to a location in @tree_model_sort. The
2311 * returned path will point to the same location in the model not being
2312 * sorted. If @sorted_path does not point to a location in the child model,
2313 * %NULL is returned.
2315 * Return value: A newly allocated #GtkTreePath, or %NULL
2318 gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sort,
2319 GtkTreePath *sorted_path)
2321 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2322 gint *sorted_indices;
2323 GtkTreePath *retval;
2327 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2328 g_return_val_if_fail (priv->child_model != NULL, NULL);
2329 g_return_val_if_fail (sorted_path != NULL, NULL);
2331 retval = gtk_tree_path_new ();
2332 sorted_indices = gtk_tree_path_get_indices (sorted_path);
2333 if (priv->root == NULL)
2334 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
2335 level = SORT_LEVEL (priv->root);
2337 for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++)
2339 gint count = sorted_indices[i];
2341 if ((level == NULL) ||
2342 (level->array->len <= count))
2344 gtk_tree_path_free (retval);
2348 if (g_array_index (level->array, SortElt, count).children == NULL)
2349 gtk_tree_model_sort_build_level (tree_model_sort, level,
2350 &g_array_index (level->array, SortElt, count));
2354 gtk_tree_path_free (retval);
2358 gtk_tree_path_append_index (retval, g_array_index (level->array, SortElt, count).offset);
2359 level = g_array_index (level->array, SortElt, count).children;
2366 * gtk_tree_model_sort_convert_iter_to_child_iter:
2367 * @tree_model_sort: A #GtkTreeModelSort
2368 * @child_iter: (out): An uninitialized #GtkTreeIter
2369 * @sorted_iter: A valid #GtkTreeIter pointing to a row on @tree_model_sort.
2371 * Sets @child_iter to point to the row pointed to by @sorted_iter.
2374 gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sort,
2375 GtkTreeIter *child_iter,
2376 GtkTreeIter *sorted_iter)
2378 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2379 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2380 g_return_if_fail (priv->child_model != NULL);
2381 g_return_if_fail (child_iter != NULL);
2382 g_return_if_fail (VALID_ITER (sorted_iter, tree_model_sort));
2383 g_return_if_fail (sorted_iter != child_iter);
2385 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2387 *child_iter = SORT_ELT (sorted_iter->user_data2)->iter;
2392 gboolean valid = FALSE;
2394 path = gtk_tree_model_sort_elt_get_path (sorted_iter->user_data,
2395 sorted_iter->user_data2);
2396 valid = gtk_tree_model_get_iter (priv->child_model, child_iter, path);
2397 gtk_tree_path_free (path);
2399 g_return_if_fail (valid == TRUE);
2404 gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
2405 SortLevel *parent_level,
2406 SortElt *parent_elt)
2408 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2410 SortLevel *new_level;
2414 g_assert (priv->child_model != NULL);
2416 if (parent_level == NULL)
2418 if (gtk_tree_model_get_iter_first (priv->child_model, &iter) == FALSE)
2420 length = gtk_tree_model_iter_n_children (priv->child_model, NULL);
2424 GtkTreeIter parent_iter;
2425 GtkTreeIter child_parent_iter;
2427 parent_iter.stamp = priv->stamp;
2428 parent_iter.user_data = parent_level;
2429 parent_iter.user_data2 = parent_elt;
2431 gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2434 if (gtk_tree_model_iter_children (priv->child_model,
2436 &child_parent_iter) == FALSE)
2439 /* stamp may have changed */
2440 gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2444 length = gtk_tree_model_iter_n_children (priv->child_model, &child_parent_iter);
2446 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort),
2450 g_return_if_fail (length > 0);
2452 new_level = g_new (SortLevel, 1);
2453 new_level->array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), length);
2454 new_level->ref_count = 0;
2455 new_level->parent_level = parent_level;
2456 new_level->parent_elt = parent_elt;
2459 parent_elt->children = new_level;
2461 priv->root = new_level;
2463 /* increase the count of zero ref_counts.*/
2464 while (parent_level)
2466 parent_elt->zero_ref_count++;
2468 parent_elt = parent_level->parent_elt;
2469 parent_level = parent_level->parent_level;
2472 if (new_level != priv->root)
2473 priv->zero_ref_count++;
2475 for (i = 0; i < length; i++)
2478 sort_elt.offset = i;
2479 sort_elt.zero_ref_count = 0;
2480 sort_elt.ref_count = 0;
2481 sort_elt.children = NULL;
2483 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2485 sort_elt.iter = iter;
2486 if (gtk_tree_model_iter_next (priv->child_model, &iter) == FALSE &&
2494 level = gtk_tree_model_sort_elt_get_path (parent_level,
2496 str = gtk_tree_path_to_string (level);
2497 gtk_tree_path_free (level);
2499 g_warning ("%s: There is a discrepancy between the sort model "
2500 "and the child model. The child model is "
2501 "advertising a wrong length for level %s:.",
2507 g_warning ("%s: There is a discrepancy between the sort model "
2508 "and the child model. The child model is "
2509 "advertising a wrong length for the root level.",
2516 g_array_append_val (new_level->array, sort_elt);
2520 gtk_tree_model_sort_sort_level (tree_model_sort, new_level,
2525 gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
2526 SortLevel *sort_level,
2529 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2532 g_assert (sort_level);
2534 for (i = 0; i < sort_level->array->len; i++)
2536 if (g_array_index (sort_level->array, SortElt, i).children)
2537 gtk_tree_model_sort_free_level (tree_model_sort,
2538 SORT_LEVEL (g_array_index (sort_level->array, SortElt, i).children), unref);
2541 if (sort_level->ref_count == 0)
2543 SortLevel *parent_level = sort_level->parent_level;
2544 SortElt *parent_elt = sort_level->parent_elt;
2546 while (parent_level)
2548 parent_elt->zero_ref_count--;
2550 parent_elt = parent_level->parent_elt;
2551 parent_level = parent_level->parent_level;
2554 if (sort_level != priv->root)
2555 priv->zero_ref_count--;
2558 if (sort_level->parent_elt)
2562 GtkTreeIter parent_iter;
2564 parent_iter.stamp = tree_model_sort->priv->stamp;
2565 parent_iter.user_data = sort_level->parent_level;
2566 parent_iter.user_data2 = sort_level->parent_elt;
2568 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort),
2572 sort_level->parent_elt->children = NULL;
2577 g_array_free (sort_level->array, TRUE);
2578 sort_level->array = NULL;
2580 g_free (sort_level);
2585 gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort)
2587 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2593 while (priv->stamp == 0);
2595 gtk_tree_model_sort_clear_cache (tree_model_sort);
2599 gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
2604 g_assert (level != NULL);
2606 for (i = 0; i < level->array->len; i++)
2608 if (g_array_index (level->array, SortElt, i).zero_ref_count > 0)
2609 gtk_tree_model_sort_clear_cache_helper (tree_model_sort, g_array_index (level->array, SortElt, i).children);
2612 if (level->ref_count == 0 && level != tree_model_sort->priv->root)
2613 gtk_tree_model_sort_free_level (tree_model_sort, level, TRUE);
2617 * gtk_tree_model_sort_reset_default_sort_func:
2618 * @tree_model_sort: A #GtkTreeModelSort
2620 * This resets the default sort function to be in the 'unsorted' state. That
2621 * is, it is in the same order as the child model. It will re-sort the model
2622 * to be in the same order as the child model only if the #GtkTreeModelSort
2623 * is in 'unsorted' state.
2626 gtk_tree_model_sort_reset_default_sort_func (GtkTreeModelSort *tree_model_sort)
2628 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2630 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2632 if (priv->default_sort_destroy)
2634 GDestroyNotify d = priv->default_sort_destroy;
2636 priv->default_sort_destroy = NULL;
2637 d (priv->default_sort_data);
2640 priv->default_sort_func = NO_SORT_FUNC;
2641 priv->default_sort_data = NULL;
2642 priv->default_sort_destroy = NULL;
2644 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
2645 gtk_tree_model_sort_sort (tree_model_sort);
2646 priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
2650 * gtk_tree_model_sort_clear_cache:
2651 * @tree_model_sort: A #GtkTreeModelSort
2653 * This function should almost never be called. It clears the @tree_model_sort
2654 * of any cached iterators that haven't been reffed with
2655 * gtk_tree_model_ref_node(). This might be useful if the child model being
2656 * sorted is static (and doesn't change often) and there has been a lot of
2657 * unreffed access to nodes. As a side effect of this function, all unreffed
2658 * iters will be invalid.
2661 gtk_tree_model_sort_clear_cache (GtkTreeModelSort *tree_model_sort)
2663 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2665 if (tree_model_sort->priv->zero_ref_count > 0)
2666 gtk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->priv->root);
2670 gtk_tree_model_sort_iter_is_valid_helper (GtkTreeIter *iter,
2675 for (i = 0; i < level->array->len; i++)
2677 SortElt *elt = &g_array_index (level->array, SortElt, i);
2679 if (iter->user_data == level && iter->user_data2 == elt)
2683 if (gtk_tree_model_sort_iter_is_valid_helper (iter, elt->children))
2691 * gtk_tree_model_sort_iter_is_valid:
2692 * @tree_model_sort: A #GtkTreeModelSort.
2693 * @iter: A #GtkTreeIter.
2696 * This function is slow. Only use it for debugging and/or testing purposes.
2699 * Checks if the given iter is a valid iter for this #GtkTreeModelSort.
2701 * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
2706 gtk_tree_model_sort_iter_is_valid (GtkTreeModelSort *tree_model_sort,
2709 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2710 g_return_val_if_fail (iter != NULL, FALSE);
2712 if (!VALID_ITER (iter, tree_model_sort))
2715 return gtk_tree_model_sort_iter_is_valid_helper (iter,
2716 tree_model_sort->priv->root);