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;
164 GSequenceIter *siter; /* iter into seq */
165 gint old_index; /* used while sorting */
173 SortLevel *parent_level;
178 GtkTreeModelSort *tree_model_sort;
179 GtkTreeIterCompareFunc sort_func;
182 GtkTreePath *parent_path;
183 gint parent_path_depth;
184 gint *parent_path_indices;
195 struct _GtkTreeModelSortPrivate
200 GtkTreeModel *child_model;
203 /* sort information */
209 GtkTreeIterCompareFunc default_sort_func;
210 gpointer default_sort_data;
211 GDestroyNotify default_sort_destroy;
216 gulong has_child_toggled_id;
221 /* Set this to 0 to disable caching of child iterators. This
222 * allows for more stringent testing. It is recommended to set this
223 * to one when refactoring this code and running the unit tests to
227 # define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) \
228 (((GtkTreeModelSort *)tree_model_sort)->priv->child_flags>K_TREE_MODEL_ITERS_PERSIST)
230 # define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) (FALSE)
233 #define SORT_ELT(sort_elt) ((SortElt *)sort_elt)
234 #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level)
235 #define GET_ELT(siter) ((SortElt *) (siter ? g_sequence_get (siter) : NULL))
238 #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));
240 #define NO_SORT_FUNC ((GtkTreeIterCompareFunc) 0x1)
242 #define VALID_ITER(iter, tree_model_sort) ((iter) != NULL && (iter)->user_data != NULL && (iter)->user_data2 != NULL && (tree_model_sort)->priv->stamp == (iter)->stamp)
244 /* general (object/interface init, etc) */
245 static void gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface);
246 static void gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface);
247 static void gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface*iface);
248 static void gtk_tree_model_sort_finalize (GObject *object);
249 static void gtk_tree_model_sort_set_property (GObject *object,
253 static void gtk_tree_model_sort_get_property (GObject *object,
258 /* our signal handlers */
259 static void gtk_tree_model_sort_row_changed (GtkTreeModel *model,
260 GtkTreePath *start_path,
261 GtkTreeIter *start_iter,
263 static void gtk_tree_model_sort_row_inserted (GtkTreeModel *model,
267 static void gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *model,
271 static void gtk_tree_model_sort_row_deleted (GtkTreeModel *model,
274 static void gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
280 /* TreeModel interface */
281 static GtkTreeModelFlags gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model);
282 static gint gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model);
283 static GType gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
285 static gboolean gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
288 static GtkTreePath *gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
290 static void gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
294 static gboolean gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
296 static gboolean gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
298 static gboolean gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
300 GtkTreeIter *parent);
301 static gboolean gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
303 static gint gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
305 static gboolean gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
309 static gboolean gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
312 static void gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
314 static void gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
316 gboolean propagate_unref);
317 static void gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
320 /* TreeDragSource interface */
321 static gboolean gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
323 static gboolean gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
325 GtkSelectionData *selection_data);
326 static gboolean gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
329 /* TreeSortable interface */
330 static gboolean gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
331 gint *sort_column_id,
333 static void gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
336 static void gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
338 GtkTreeIterCompareFunc func,
340 GDestroyNotify destroy);
341 static void gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
342 GtkTreeIterCompareFunc func,
344 GDestroyNotify destroy);
345 static gboolean gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable);
347 /* Private functions (sort funcs, level handling and other utils) */
348 static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
349 SortLevel *parent_level,
350 SortElt *parent_elt);
351 static void gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
352 SortLevel *sort_level,
354 static void gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort);
355 static void gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
358 gboolean emit_reordered);
359 static void gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort);
360 static gboolean gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
363 GtkTreeIter *s_iter);
364 static GtkTreePath *gtk_tree_model_sort_elt_get_path (SortLevel *level,
366 static void gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
367 GtkTreeModel *child_model);
368 static GtkTreePath *gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
369 GtkTreePath *child_path,
370 gboolean build_levels);
372 static gint gtk_tree_model_sort_compare_func (gconstpointer a,
375 static gint gtk_tree_model_sort_offset_compare_func (gconstpointer a,
378 static void gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
382 G_DEFINE_TYPE_WITH_CODE (GtkTreeModelSort, gtk_tree_model_sort, G_TYPE_OBJECT,
383 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
384 gtk_tree_model_sort_tree_model_init)
385 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
386 gtk_tree_model_sort_tree_sortable_init)
387 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
388 gtk_tree_model_sort_drag_source_init))
391 gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
393 GtkTreeModelSortPrivate *priv;
395 priv = G_TYPE_INSTANCE_GET_PRIVATE (tree_model_sort,
396 GTK_TYPE_TREE_MODEL_SORT,
397 GtkTreeModelSortPrivate);
398 tree_model_sort->priv = priv;
399 priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
401 priv->zero_ref_count = 0;
403 priv->sort_list = NULL;
407 gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
409 GObjectClass *object_class;
411 object_class = (GObjectClass *) class;
413 object_class->set_property = gtk_tree_model_sort_set_property;
414 object_class->get_property = gtk_tree_model_sort_get_property;
416 object_class->finalize = gtk_tree_model_sort_finalize;
419 g_object_class_install_property (object_class,
421 g_param_spec_object ("model",
422 P_("TreeModelSort Model"),
423 P_("The model for the TreeModelSort to sort"),
425 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
427 g_type_class_add_private (class, sizeof (GtkTreeModelSortPrivate));
431 gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
433 iface->get_flags = gtk_tree_model_sort_get_flags;
434 iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
435 iface->get_column_type = gtk_tree_model_sort_get_column_type;
436 iface->get_iter = gtk_tree_model_sort_get_iter;
437 iface->get_path = gtk_tree_model_sort_get_path;
438 iface->get_value = gtk_tree_model_sort_get_value;
439 iface->iter_next = gtk_tree_model_sort_iter_next;
440 iface->iter_previous = gtk_tree_model_sort_iter_previous;
441 iface->iter_children = gtk_tree_model_sort_iter_children;
442 iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
443 iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
444 iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
445 iface->iter_parent = gtk_tree_model_sort_iter_parent;
446 iface->ref_node = gtk_tree_model_sort_ref_node;
447 iface->unref_node = gtk_tree_model_sort_unref_node;
451 gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface)
453 iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id;
454 iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id;
455 iface->set_sort_func = gtk_tree_model_sort_set_sort_func;
456 iface->set_default_sort_func = gtk_tree_model_sort_set_default_sort_func;
457 iface->has_default_sort_func = gtk_tree_model_sort_has_default_sort_func;
461 gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface *iface)
463 iface->row_draggable = gtk_tree_model_sort_row_draggable;
464 iface->drag_data_delete = gtk_tree_model_sort_drag_data_delete;
465 iface->drag_data_get = gtk_tree_model_sort_drag_data_get;
469 * gtk_tree_model_sort_new_with_model:
470 * @child_model: A #GtkTreeModel
472 * Creates a new #GtkTreeModel, with @child_model as the child model.
474 * Return value: (transfer full): A new #GtkTreeModel.
477 gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model)
479 GtkTreeModel *retval;
481 g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
483 retval = g_object_new (gtk_tree_model_sort_get_type (), NULL);
485 gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model);
490 /* GObject callbacks */
492 gtk_tree_model_sort_finalize (GObject *object)
494 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
495 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
497 gtk_tree_model_sort_set_model (tree_model_sort, NULL);
500 gtk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE);
504 _gtk_tree_data_list_header_free (priv->sort_list);
505 priv->sort_list = NULL;
508 if (priv->default_sort_destroy)
510 priv->default_sort_destroy (priv->default_sort_data);
511 priv->default_sort_destroy = NULL;
512 priv->default_sort_data = NULL;
517 G_OBJECT_CLASS (gtk_tree_model_sort_parent_class)->finalize (object);
521 gtk_tree_model_sort_set_property (GObject *object,
526 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
531 gtk_tree_model_sort_set_model (tree_model_sort, g_value_get_object (value));
534 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
540 gtk_tree_model_sort_get_property (GObject *object,
545 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
550 g_value_set_object (value, gtk_tree_model_sort_get_model (tree_model_sort));
553 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
562 return g_slice_new (SortElt);
566 sort_elt_free (gpointer elt)
568 g_slice_free (SortElt, elt);
572 increase_offset_iter (gpointer data,
576 gint offset = GPOINTER_TO_INT (user_data);
578 if (elt->offset >= offset)
583 decrease_offset_iter (gpointer data,
587 gint offset = GPOINTER_TO_INT (user_data);
589 if (elt->offset > offset)
594 fill_sort_data (SortData *data,
595 GtkTreeModelSort *tree_model_sort,
598 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
600 data->tree_model_sort = tree_model_sort;
602 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
604 GtkTreeDataSortHeader *header;
606 header = _gtk_tree_data_list_get_header (priv->sort_list,
607 priv->sort_column_id);
609 g_return_if_fail (header != NULL);
610 g_return_if_fail (header->func != NULL);
612 data->sort_func = header->func;
613 data->sort_data = header->data;
617 /* absolutely SHOULD NOT happen: */
618 g_return_if_fail (priv->default_sort_func != NULL);
620 data->sort_func = priv->default_sort_func;
621 data->sort_data = priv->default_sort_data;
624 if (level->parent_elt)
626 data->parent_path = gtk_tree_model_sort_elt_get_path (level->parent_level,
628 gtk_tree_path_append_index (data->parent_path, 0);
632 data->parent_path = gtk_tree_path_new_first ();
634 data->parent_path_depth = gtk_tree_path_get_depth (data->parent_path);
635 data->parent_path_indices = gtk_tree_path_get_indices (data->parent_path);
639 free_sort_data (SortData *data)
641 gtk_tree_path_free (data->parent_path);
645 lookup_elt_with_offset (GtkTreeModelSort *tree_model_sort,
648 GSequenceIter **ret_siter)
650 GSequenceIter *siter, *end_siter;
652 /* FIXME: We have to do a search like this, because the sequence is not
653 * (always) sorted on offset order. Perhaps we should introduce a
654 * second sequence which is sorted on offset order.
656 end_siter = g_sequence_get_end_iter (level->seq);
657 for (siter = g_sequence_get_begin_iter (level->seq);
659 siter = g_sequence_iter_next (siter))
661 SortElt *elt = g_sequence_get (siter);
663 if (elt->offset == offset)
670 return GET_ELT (siter);
675 gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
676 GtkTreePath *start_s_path,
677 GtkTreeIter *start_s_iter,
680 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
681 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
682 GtkTreePath *path = NULL;
690 gboolean free_s_path = FALSE;
692 gint index = 0, old_index;
694 g_return_if_fail (start_s_path != NULL || start_s_iter != NULL);
699 start_s_path = gtk_tree_model_get_path (s_model, start_s_iter);
702 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
708 gtk_tree_path_free (start_s_path);
712 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
713 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (data), &iter);
715 level = iter.user_data;
716 elt = iter.user_data2;
718 if (g_sequence_get_length (level->seq) < 2 ||
719 (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
720 priv->default_sort_func == NO_SORT_FUNC))
723 gtk_tree_path_free (start_s_path);
725 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
726 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
728 gtk_tree_path_free (path);
733 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
736 gtk_tree_model_get_iter (priv->child_model,
737 &tmpiter, start_s_path);
739 old_index = g_sequence_iter_get_position (elt->siter);
741 fill_sort_data (&sort_data, tree_model_sort, level);
742 g_sequence_sort_changed (elt->siter,
743 gtk_tree_model_sort_compare_func,
745 free_sort_data (&sort_data);
747 index = g_sequence_iter_get_position (elt->siter);
749 /* Prepare the path for signal emission */
750 gtk_tree_path_up (path);
751 gtk_tree_path_append_index (path, index);
753 gtk_tree_model_sort_increment_stamp (tree_model_sort);
755 /* if the item moved, then emit rows_reordered */
756 if (old_index != index)
761 GtkTreePath *tmppath;
763 new_order = g_new (gint, g_sequence_get_length (level->seq));
765 for (j = 0; j < g_sequence_get_length (level->seq); j++)
767 if (index > old_index)
770 new_order[j] = old_index;
771 else if (j >= old_index && j < index)
772 new_order[j] = j + 1;
776 else if (index < old_index)
779 new_order[j] = old_index;
780 else if (j > index && j <= old_index)
781 new_order[j] = j - 1;
785 /* else? shouldn't really happen */
788 if (level->parent_elt)
790 iter.stamp = priv->stamp;
791 iter.user_data = level->parent_level;
792 iter.user_data2 = level->parent_elt;
794 tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter);
796 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
797 tmppath, &iter, new_order);
802 tmppath = gtk_tree_path_new ();
804 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), tmppath,
808 gtk_tree_path_free (tmppath);
812 /* emit row_changed signal (at new location) */
813 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
814 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
815 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
817 gtk_tree_path_free (path);
819 gtk_tree_path_free (start_s_path);
823 gtk_tree_model_sort_row_inserted (GtkTreeModel *s_model,
828 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
829 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
832 GtkTreeIter real_s_iter;
836 gboolean free_s_path = FALSE;
840 SortLevel *parent_level = NULL;
842 parent_level = level = SORT_LEVEL (priv->root);
844 g_return_if_fail (s_path != NULL || s_iter != NULL);
848 s_path = gtk_tree_model_get_path (s_model, s_iter);
853 gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
855 real_s_iter = *s_iter;
859 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
861 /* the build level already put the inserted iter in the level,
862 so no need to handle this signal anymore */
864 goto done_and_submit;
867 /* find the parent level */
868 while (i < gtk_tree_path_get_depth (s_path) - 1)
872 /* level not yet build, we won't cover this signal */
876 if (g_sequence_get_length (level->seq) < gtk_tree_path_get_indices (s_path)[i])
878 g_warning ("%s: A node was inserted with a parent that's not in the tree.\n"
879 "This possibly means that a GtkTreeModel inserted a child node\n"
880 "before the parent was inserted.",
885 elt = lookup_elt_with_offset (tree_model_sort, level,
886 gtk_tree_path_get_indices (s_path)[i],
889 g_return_if_fail (elt != NULL);
893 /* not covering this signal */
897 level = elt->children;
898 parent_level = level;
905 if (level->ref_count == 0 && level != priv->root)
907 gtk_tree_model_sort_free_level (tree_model_sort, level, TRUE);
911 if (!gtk_tree_model_sort_insert_value (tree_model_sort,
918 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
925 gtk_tree_model_sort_increment_stamp (tree_model_sort);
927 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
928 gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
929 gtk_tree_path_free (path);
933 gtk_tree_path_free (s_path);
939 gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *s_model,
944 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
948 g_return_if_fail (s_path != NULL && s_iter != NULL);
950 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
954 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
955 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
957 gtk_tree_path_free (path);
961 gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
965 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
966 GtkTreePath *path = NULL;
972 g_return_if_fail (s_path != NULL);
974 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);
982 offset = elt->offset;
984 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
986 while (elt->ref_count > 0)
987 gtk_tree_model_sort_real_unref_node (GTK_TREE_MODEL (data), &iter, FALSE);
989 /* If this node has children, we free the level (recursively) here
990 * and specify that unref may not be used, because parent and its
991 * children have been removed by now.
994 gtk_tree_model_sort_free_level (tree_model_sort,
995 elt->children, FALSE);
997 if (level->ref_count == 0)
999 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1000 gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
1001 gtk_tree_path_free (path);
1003 if (level == tree_model_sort->priv->root)
1005 gtk_tree_model_sort_free_level (tree_model_sort,
1006 tree_model_sort->priv->root,
1008 tree_model_sort->priv->root = NULL;
1013 g_sequence_remove (elt->siter);
1016 /* The sequence is not ordered on offset, so we traverse the entire
1019 g_sequence_foreach (level->seq, decrease_offset_iter,
1020 GINT_TO_POINTER (offset));
1022 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1023 gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
1025 gtk_tree_path_free (path);
1029 gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
1030 GtkTreePath *s_path,
1031 GtkTreeIter *s_iter,
1041 GSequenceIter *siter, *end_siter;
1042 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
1043 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1045 g_return_if_fail (new_order != NULL);
1047 if (s_path == NULL || gtk_tree_path_get_depth (s_path) == 0)
1049 if (priv->root == NULL)
1051 path = gtk_tree_path_new ();
1052 level = SORT_LEVEL (priv->root);
1056 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
1059 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
1061 level = SORT_LEVEL (iter.user_data);
1062 elt = SORT_ELT (iter.user_data2);
1066 gtk_tree_path_free (path);
1070 level = elt->children;
1073 length = g_sequence_get_length (level->seq);
1076 gtk_tree_path_free (path);
1080 tmp_array = g_new (int, length);
1082 /* FIXME: I need to think about whether this can be done in a more
1086 end_siter = g_sequence_get_end_iter (level->seq);
1087 for (siter = g_sequence_get_begin_iter (level->seq);
1089 siter = g_sequence_iter_next (siter))
1092 SortElt *elt = g_sequence_get (siter);
1094 for (j = 0; j < length; j++)
1096 if (elt->offset == new_order[j])
1103 /* This loop cannot be merged with the above loop nest, because that
1104 * would introduce duplicate offsets.
1107 end_siter = g_sequence_get_end_iter (level->seq);
1108 for (siter = g_sequence_get_begin_iter (level->seq);
1110 siter = g_sequence_iter_next (siter))
1112 SortElt *elt = g_sequence_get (siter);
1114 elt->offset = tmp_array[i];
1119 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
1120 priv->default_sort_func == NO_SORT_FUNC)
1122 gtk_tree_model_sort_sort_level (tree_model_sort, level,
1124 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1126 if (gtk_tree_path_get_depth (path))
1128 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
1131 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
1132 path, &iter, new_order);
1136 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
1137 path, NULL, new_order);
1141 gtk_tree_path_free (path);
1144 /* Fulfill our model requirements */
1145 static GtkTreeModelFlags
1146 gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model)
1148 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1149 GtkTreeModelFlags flags;
1151 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, 0);
1153 flags = gtk_tree_model_get_flags (tree_model_sort->priv->child_model);
1155 if ((flags & GTK_TREE_MODEL_LIST_ONLY) == GTK_TREE_MODEL_LIST_ONLY)
1156 return GTK_TREE_MODEL_LIST_ONLY;
1162 gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
1164 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1166 if (tree_model_sort->priv->child_model == 0)
1169 return gtk_tree_model_get_n_columns (tree_model_sort->priv->child_model);
1173 gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
1176 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1178 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, G_TYPE_INVALID);
1180 return gtk_tree_model_get_column_type (tree_model_sort->priv->child_model, index);
1184 gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
1188 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1189 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1194 GSequenceIter *siter;
1196 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1198 indices = gtk_tree_path_get_indices (path);
1200 if (priv->root == NULL)
1201 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1202 level = SORT_LEVEL (priv->root);
1204 depth = gtk_tree_path_get_depth (path);
1211 for (i = 0; i < depth - 1; i++)
1213 if ((level == NULL) ||
1214 (indices[i] >= g_sequence_get_length (level->seq)))
1220 siter = g_sequence_get_iter_at_pos (level->seq, indices[i]);
1221 if (g_sequence_iter_is_end (siter))
1227 elt = GET_ELT (siter);
1228 if (elt->children == NULL)
1229 gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
1231 level = elt->children;
1234 if (!level || indices[i] >= g_sequence_get_length (level->seq))
1240 iter->stamp = priv->stamp;
1241 iter->user_data = level;
1243 siter = g_sequence_get_iter_at_pos (level->seq, indices[depth - 1]);
1244 if (g_sequence_iter_is_end (siter))
1249 iter->user_data2 = GET_ELT (siter);
1254 static GtkTreePath *
1255 gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
1258 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1259 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1260 GtkTreePath *retval;
1264 g_return_val_if_fail (priv->child_model != NULL, NULL);
1265 g_return_val_if_fail (priv->stamp == iter->stamp, NULL);
1267 retval = gtk_tree_path_new ();
1269 level = SORT_LEVEL (iter->user_data);
1270 elt = SORT_ELT (iter->user_data2);
1276 index = g_sequence_iter_get_position (elt->siter);
1277 gtk_tree_path_prepend_index (retval, index);
1279 elt = level->parent_elt;
1280 level = level->parent_level;
1287 gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
1292 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1293 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1294 GtkTreeIter child_iter;
1296 g_return_if_fail (priv->child_model != NULL);
1297 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1299 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1300 gtk_tree_model_get_value (priv->child_model,
1301 &child_iter, column, value);
1305 gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
1308 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1309 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1312 GSequenceIter *siter;
1314 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1315 g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1317 level = iter->user_data;
1318 elt = iter->user_data2;
1320 siter = g_sequence_iter_next (elt->siter);
1321 if (g_sequence_iter_is_end (siter))
1326 iter->user_data2 = GET_ELT (siter);
1332 gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
1335 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1336 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1339 GSequenceIter *siter;
1341 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1342 g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1344 level = iter->user_data;
1345 elt = iter->user_data2;
1347 siter = g_sequence_iter_prev (elt->siter);
1348 if (g_sequence_iter_is_begin (siter))
1353 iter->user_data2 = GET_ELT (siter);
1359 gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
1361 GtkTreeIter *parent)
1363 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1364 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1368 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1370 g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1374 if (priv->root == NULL)
1375 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1376 if (priv->root == NULL)
1380 iter->stamp = priv->stamp;
1381 iter->user_data = level;
1382 iter->user_data2 = g_sequence_get (g_sequence_get_begin_iter (level->seq));
1388 level = SORT_LEVEL (parent->user_data);
1389 elt = SORT_ELT (parent->user_data2);
1391 if (elt->children == NULL)
1392 gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
1394 if (elt->children == NULL)
1397 iter->stamp = priv->stamp;
1398 iter->user_data = elt->children;
1399 iter->user_data2 = g_sequence_get (g_sequence_get_begin_iter (elt->children->seq));
1406 gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
1409 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1410 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1411 GtkTreeIter child_iter;
1413 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1414 g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), FALSE);
1416 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1418 return gtk_tree_model_iter_has_child (priv->child_model, &child_iter);
1422 gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
1425 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1426 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1427 GtkTreeIter child_iter;
1429 g_return_val_if_fail (priv->child_model != NULL, 0);
1431 g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), 0);
1434 return gtk_tree_model_iter_n_children (priv->child_model, NULL);
1436 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1438 return gtk_tree_model_iter_n_children (priv->child_model, &child_iter);
1442 gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
1444 GtkTreeIter *parent,
1447 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1449 /* We have this for the iter == parent case */
1450 GtkTreeIter children;
1453 g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1455 /* Use this instead of has_child to force us to build the level, if needed */
1456 if (gtk_tree_model_sort_iter_children (tree_model, &children, parent) == FALSE)
1462 level = children.user_data;
1463 if (n >= g_sequence_get_length (level->seq))
1469 iter->stamp = tree_model_sort->priv->stamp;
1470 iter->user_data = level;
1471 iter->user_data2 = g_sequence_get (g_sequence_get_iter_at_pos (level->seq, n));
1477 gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
1481 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1482 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1486 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1487 g_return_val_if_fail (VALID_ITER (child, tree_model_sort), FALSE);
1489 level = child->user_data;
1491 if (level->parent_level)
1493 iter->stamp = priv->stamp;
1494 iter->user_data = level->parent_level;
1495 iter->user_data2 = level->parent_elt;
1503 gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
1506 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1507 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1508 GtkTreeIter child_iter;
1512 g_return_if_fail (priv->child_model != NULL);
1513 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1515 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1517 /* Reference the node in the child model */
1518 gtk_tree_model_ref_node (priv->child_model, &child_iter);
1520 /* Increase the reference count of this element and its level */
1521 level = iter->user_data;
1522 elt = iter->user_data2;
1527 if (level->ref_count == 1)
1529 SortLevel *parent_level = level->parent_level;
1530 SortElt *parent_elt = level->parent_elt;
1532 /* We were at zero -- time to decrement the zero_ref_count val */
1533 while (parent_level)
1535 parent_elt->zero_ref_count--;
1537 parent_elt = parent_level->parent_elt;
1538 parent_level = parent_level->parent_level;
1541 if (priv->root != level)
1542 priv->zero_ref_count--;
1547 gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
1549 gboolean propagate_unref)
1551 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1552 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1556 g_return_if_fail (priv->child_model != NULL);
1557 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1559 if (propagate_unref)
1561 GtkTreeIter child_iter;
1563 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1564 gtk_tree_model_unref_node (priv->child_model, &child_iter);
1567 level = iter->user_data;
1568 elt = iter->user_data2;
1570 g_return_if_fail (elt->ref_count > 0);
1575 if (level->ref_count == 0)
1577 SortLevel *parent_level = level->parent_level;
1578 SortElt *parent_elt = level->parent_elt;
1580 /* We are at zero -- time to increment the zero_ref_count val */
1581 while (parent_level)
1583 parent_elt->zero_ref_count++;
1585 parent_elt = parent_level->parent_elt;
1586 parent_level = parent_level->parent_level;
1589 if (priv->root != level)
1590 priv->zero_ref_count++;
1595 gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
1598 gtk_tree_model_sort_real_unref_node (tree_model, iter, TRUE);
1601 /* Sortable interface */
1603 gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
1604 gint *sort_column_id,
1607 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1608 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1611 *sort_column_id = priv->sort_column_id;
1613 *order = priv->order;
1615 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
1616 priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1623 gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
1624 gint sort_column_id,
1627 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1628 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1630 if (sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1632 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1634 GtkTreeDataSortHeader *header = NULL;
1636 header = _gtk_tree_data_list_get_header (priv->sort_list,
1639 /* we want to make sure that we have a function */
1640 g_return_if_fail (header != NULL);
1641 g_return_if_fail (header->func != NULL);
1644 g_return_if_fail (priv->default_sort_func != NULL);
1646 if (priv->sort_column_id == sort_column_id)
1648 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1650 if (priv->order == order)
1658 priv->sort_column_id = sort_column_id;
1659 priv->order = order;
1661 gtk_tree_sortable_sort_column_changed (sortable);
1663 gtk_tree_model_sort_sort (tree_model_sort);
1667 gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
1668 gint sort_column_id,
1669 GtkTreeIterCompareFunc func,
1671 GDestroyNotify destroy)
1673 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1674 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1676 priv->sort_list = _gtk_tree_data_list_set_header (priv->sort_list,
1678 func, data, destroy);
1680 if (priv->sort_column_id == sort_column_id)
1681 gtk_tree_model_sort_sort (tree_model_sort);
1685 gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
1686 GtkTreeIterCompareFunc func,
1688 GDestroyNotify destroy)
1690 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1691 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1693 if (priv->default_sort_destroy)
1695 GDestroyNotify d = priv->default_sort_destroy;
1697 priv->default_sort_destroy = NULL;
1698 d (priv->default_sort_data);
1701 priv->default_sort_func = func;
1702 priv->default_sort_data = data;
1703 priv->default_sort_destroy = destroy;
1705 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1706 gtk_tree_model_sort_sort (tree_model_sort);
1710 gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable)
1712 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1714 return (tree_model_sort->priv->default_sort_func != NULL);
1717 /* DragSource interface */
1719 gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
1722 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1723 GtkTreePath *child_path;
1726 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort,
1728 draggable = gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1729 gtk_tree_path_free (child_path);
1735 gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
1737 GtkSelectionData *selection_data)
1739 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1740 GtkTreePath *child_path;
1743 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1744 gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path, selection_data);
1745 gtk_tree_path_free (child_path);
1751 gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
1754 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1755 GtkTreePath *child_path;
1758 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1759 deleted = gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1760 gtk_tree_path_free (child_path);
1765 /* sorting code - private */
1767 gtk_tree_model_sort_compare_func (gconstpointer a,
1771 SortData *data = (SortData *)user_data;
1772 GtkTreeModelSort *tree_model_sort = data->tree_model_sort;
1773 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1774 const SortElt *sa = a;
1775 const SortElt *sb = b;
1777 GtkTreeIter iter_a, iter_b;
1780 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1787 data->parent_path_indices [data->parent_path_depth-1] = sa->offset;
1788 gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_a, data->parent_path);
1789 data->parent_path_indices [data->parent_path_depth-1] = sb->offset;
1790 gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_b, data->parent_path);
1793 retval = (* data->sort_func) (GTK_TREE_MODEL (priv->child_model),
1797 if (priv->order == GTK_SORT_DESCENDING)
1801 else if (retval < 0)
1809 gtk_tree_model_sort_offset_compare_func (gconstpointer a,
1815 const SortElt *sa = (SortElt *)a;
1816 const SortElt *sb = (SortElt *)b;
1818 SortData *data = (SortData *)user_data;
1820 if (sa->offset < sb->offset)
1822 else if (sa->offset > sb->offset)
1827 if (data->tree_model_sort->priv->order == GTK_SORT_DESCENDING)
1831 else if (retval < 0)
1839 gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
1842 gboolean emit_reordered)
1844 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1846 GSequenceIter *begin_siter, *end_siter, *siter;
1855 g_return_if_fail (level != NULL);
1857 begin_siter = g_sequence_get_begin_iter (level->seq);
1858 begin_elt = g_sequence_get (begin_siter);
1860 if (g_sequence_get_length (level->seq) < 1 && !begin_elt->children)
1863 iter.stamp = priv->stamp;
1864 iter.user_data = level;
1865 iter.user_data2 = begin_elt;
1867 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1870 end_siter = g_sequence_get_end_iter (level->seq);
1871 for (siter = g_sequence_get_begin_iter (level->seq);
1873 siter = g_sequence_iter_next (siter))
1875 SortElt *elt = g_sequence_get (siter);
1881 fill_sort_data (&data, tree_model_sort, level);
1883 if (data.sort_func == NO_SORT_FUNC)
1884 g_sequence_sort (level->seq, gtk_tree_model_sort_offset_compare_func,
1887 g_sequence_sort (level->seq, gtk_tree_model_sort_compare_func, &data);
1889 free_sort_data (&data);
1891 new_order = g_new (gint, g_sequence_get_length (level->seq));
1894 end_siter = g_sequence_get_end_iter (level->seq);
1895 for (siter = g_sequence_get_begin_iter (level->seq);
1897 siter = g_sequence_iter_next (siter))
1899 SortElt *elt = g_sequence_get (siter);
1901 new_order[i++] = elt->old_index;
1906 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1907 if (level->parent_elt)
1909 iter.stamp = priv->stamp;
1910 iter.user_data = level->parent_level;
1911 iter.user_data2 = level->parent_elt;
1913 path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort),
1916 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1922 path = gtk_tree_path_new ();
1923 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1927 gtk_tree_path_free (path);
1930 /* recurse, if possible */
1933 end_siter = g_sequence_get_end_iter (level->seq);
1934 for (siter = g_sequence_get_begin_iter (level->seq);
1936 siter = g_sequence_iter_next (siter))
1938 SortElt *elt = g_sequence_get (siter);
1941 gtk_tree_model_sort_sort_level (tree_model_sort,
1943 TRUE, emit_reordered);
1949 /* get the iter we referenced at the beginning of this function and
1952 iter.stamp = priv->stamp;
1953 iter.user_data = level;
1954 iter.user_data2 = begin_elt;
1956 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1960 gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort)
1962 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1964 if (priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1970 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1972 GtkTreeDataSortHeader *header = NULL;
1974 header = _gtk_tree_data_list_get_header (priv->sort_list,
1975 priv->sort_column_id);
1977 /* we want to make sure that we have a function */
1978 g_return_if_fail (header != NULL);
1979 g_return_if_fail (header->func != NULL);
1982 g_return_if_fail (priv->default_sort_func != NULL);
1984 gtk_tree_model_sort_sort_level (tree_model_sort, priv->root,
1988 /* signal helpers */
1990 gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
1992 GtkTreePath *s_path,
1993 GtkTreeIter *s_iter)
1995 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2000 elt = sort_elt_new ();
2002 offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];
2004 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2005 elt->iter = *s_iter;
2006 elt->offset = offset;
2007 elt->zero_ref_count = 0;
2009 elt->children = NULL;
2011 /* update all larger offsets */
2012 g_sequence_foreach (level->seq, increase_offset_iter, GINT_TO_POINTER (offset));
2014 fill_sort_data (&data, tree_model_sort, level);
2016 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
2017 priv->default_sort_func == NO_SORT_FUNC)
2019 elt->siter = g_sequence_insert_sorted (level->seq, elt,
2020 gtk_tree_model_sort_offset_compare_func,
2025 elt->siter = g_sequence_insert_sorted (level->seq, elt,
2026 gtk_tree_model_sort_compare_func,
2030 free_sort_data (&data);
2035 /* sort elt stuff */
2036 static GtkTreePath *
2037 gtk_tree_model_sort_elt_get_path (SortLevel *level,
2040 SortLevel *walker = level;
2041 SortElt *walker2 = elt;
2044 g_return_val_if_fail (level != NULL, NULL);
2045 g_return_val_if_fail (elt != NULL, NULL);
2047 path = gtk_tree_path_new ();
2051 gtk_tree_path_prepend_index (path, walker2->offset);
2053 if (!walker->parent_level)
2056 walker2 = walker->parent_elt;
2057 walker = walker->parent_level;
2064 * gtk_tree_model_sort_set_model:
2065 * @tree_model_sort: The #GtkTreeModelSort.
2066 * @child_model: (allow-none): A #GtkTreeModel, or %NULL.
2068 * Sets the model of @tree_model_sort to be @model. If @model is %NULL,
2069 * then the old model is unset. The sort function is unset as a result
2070 * of this call. The model will be in an unsorted state until a sort
2074 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
2075 GtkTreeModel *child_model)
2077 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2080 g_object_ref (child_model);
2082 if (priv->child_model)
2084 g_signal_handler_disconnect (priv->child_model,
2086 g_signal_handler_disconnect (priv->child_model,
2088 g_signal_handler_disconnect (priv->child_model,
2089 priv->has_child_toggled_id);
2090 g_signal_handler_disconnect (priv->child_model,
2092 g_signal_handler_disconnect (priv->child_model,
2093 priv->reordered_id);
2095 /* reset our state */
2097 gtk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE);
2099 _gtk_tree_data_list_header_free (priv->sort_list);
2100 priv->sort_list = NULL;
2101 g_object_unref (priv->child_model);
2104 priv->child_model = child_model;
2112 g_signal_connect (child_model, "row-changed",
2113 G_CALLBACK (gtk_tree_model_sort_row_changed),
2116 g_signal_connect (child_model, "row-inserted",
2117 G_CALLBACK (gtk_tree_model_sort_row_inserted),
2119 priv->has_child_toggled_id =
2120 g_signal_connect (child_model, "row-has-child-toggled",
2121 G_CALLBACK (gtk_tree_model_sort_row_has_child_toggled),
2124 g_signal_connect (child_model, "row-deleted",
2125 G_CALLBACK (gtk_tree_model_sort_row_deleted),
2127 priv->reordered_id =
2128 g_signal_connect (child_model, "rows-reordered",
2129 G_CALLBACK (gtk_tree_model_sort_rows_reordered),
2132 priv->child_flags = gtk_tree_model_get_flags (child_model);
2133 n_columns = gtk_tree_model_get_n_columns (child_model);
2135 types = g_new (GType, n_columns);
2136 for (i = 0; i < n_columns; i++)
2137 types[i] = gtk_tree_model_get_column_type (child_model, i);
2139 priv->sort_list = _gtk_tree_data_list_header_new (n_columns, types);
2142 priv->default_sort_func = NO_SORT_FUNC;
2143 priv->stamp = g_random_int ();
2148 * gtk_tree_model_sort_get_model:
2149 * @tree_model: a #GtkTreeModelSort
2151 * Returns the model the #GtkTreeModelSort is sorting.
2153 * Return value: (transfer none): the "child model" being sorted
2156 gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model)
2158 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
2160 return tree_model->priv->child_model;
2164 static GtkTreePath *
2165 gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2166 GtkTreePath *child_path,
2167 gboolean build_levels)
2169 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2170 gint *child_indices;
2171 GtkTreePath *retval;
2175 g_return_val_if_fail (priv->child_model != NULL, NULL);
2176 g_return_val_if_fail (child_path != NULL, NULL);
2178 retval = gtk_tree_path_new ();
2179 child_indices = gtk_tree_path_get_indices (child_path);
2181 if (priv->root == NULL && build_levels)
2182 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
2183 level = SORT_LEVEL (priv->root);
2185 for (i = 0; i < gtk_tree_path_get_depth (child_path); i++)
2188 GSequenceIter *siter;
2189 gboolean found_child = FALSE;
2193 gtk_tree_path_free (retval);
2197 if (child_indices[i] >= g_sequence_get_length (level->seq))
2199 gtk_tree_path_free (retval);
2202 tmp = lookup_elt_with_offset (tree_model_sort, level,
2203 child_indices[i], &siter);
2206 gtk_tree_path_append_index (retval, g_sequence_iter_get_position (siter));
2207 if (tmp->children == NULL && build_levels)
2208 gtk_tree_model_sort_build_level (tree_model_sort, level, tmp);
2210 level = tmp->children;
2216 gtk_tree_path_free (retval);
2226 * gtk_tree_model_sort_convert_child_path_to_path:
2227 * @tree_model_sort: A #GtkTreeModelSort
2228 * @child_path: A #GtkTreePath to convert
2230 * Converts @child_path to a path relative to @tree_model_sort. That is,
2231 * @child_path points to a path in the child model. The returned path will
2232 * point to the same row in the sorted model. If @child_path isn't a valid
2233 * path on the child model, then %NULL is returned.
2235 * Return value: A newly allocated #GtkTreePath, or %NULL
2238 gtk_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2239 GtkTreePath *child_path)
2241 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2242 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, NULL);
2243 g_return_val_if_fail (child_path != NULL, NULL);
2245 return gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path, TRUE);
2249 * gtk_tree_model_sort_convert_child_iter_to_iter:
2250 * @tree_model_sort: A #GtkTreeModelSort
2251 * @sort_iter: (out): An uninitialized #GtkTreeIter.
2252 * @child_iter: A valid #GtkTreeIter pointing to a row on the child model
2254 * Sets @sort_iter to point to the row in @tree_model_sort that corresponds to
2255 * the row pointed at by @child_iter. If @sort_iter was not set, %FALSE
2256 * is returned. Note: a boolean is only returned since 2.14.
2258 * Return value: %TRUE, if @sort_iter was set, i.e. if @sort_iter is a
2259 * valid iterator pointer to a visible row in the child model.
2262 gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sort,
2263 GtkTreeIter *sort_iter,
2264 GtkTreeIter *child_iter)
2267 GtkTreePath *child_path, *path;
2268 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2270 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2271 g_return_val_if_fail (priv->child_model != NULL, FALSE);
2272 g_return_val_if_fail (sort_iter != NULL, FALSE);
2273 g_return_val_if_fail (child_iter != NULL, FALSE);
2274 g_return_val_if_fail (sort_iter != child_iter, FALSE);
2276 sort_iter->stamp = 0;
2278 child_path = gtk_tree_model_get_path (priv->child_model, child_iter);
2279 g_return_val_if_fail (child_path != NULL, FALSE);
2281 path = gtk_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path);
2282 gtk_tree_path_free (child_path);
2286 g_warning ("%s: The conversion of the child path to a GtkTreeModel sort path failed", G_STRLOC);
2290 ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
2292 gtk_tree_path_free (path);
2298 * gtk_tree_model_sort_convert_path_to_child_path:
2299 * @tree_model_sort: A #GtkTreeModelSort
2300 * @sorted_path: A #GtkTreePath to convert
2302 * Converts @sorted_path to a path on the child model of @tree_model_sort.
2303 * That is, @sorted_path points to a location in @tree_model_sort. The
2304 * returned path will point to the same location in the model not being
2305 * sorted. If @sorted_path does not point to a location in the child model,
2306 * %NULL is returned.
2308 * Return value: A newly allocated #GtkTreePath, or %NULL
2311 gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sort,
2312 GtkTreePath *sorted_path)
2314 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2315 gint *sorted_indices;
2316 GtkTreePath *retval;
2320 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2321 g_return_val_if_fail (priv->child_model != NULL, NULL);
2322 g_return_val_if_fail (sorted_path != NULL, NULL);
2324 retval = gtk_tree_path_new ();
2325 sorted_indices = gtk_tree_path_get_indices (sorted_path);
2326 if (priv->root == NULL)
2327 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
2328 level = SORT_LEVEL (priv->root);
2330 for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++)
2332 SortElt *elt = NULL;
2333 GSequenceIter *siter;
2335 if ((level == NULL) ||
2336 (g_sequence_get_length (level->seq) <= sorted_indices[i]))
2338 gtk_tree_path_free (retval);
2342 siter = g_sequence_get_iter_at_pos (level->seq, sorted_indices[i]);
2343 if (g_sequence_iter_is_end (siter))
2345 gtk_tree_path_free (retval);
2349 elt = GET_ELT (siter);
2350 if (elt->children == NULL)
2351 gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
2355 gtk_tree_path_free (retval);
2359 gtk_tree_path_append_index (retval, elt->offset);
2360 level = elt->children;
2367 * gtk_tree_model_sort_convert_iter_to_child_iter:
2368 * @tree_model_sort: A #GtkTreeModelSort
2369 * @child_iter: (out): An uninitialized #GtkTreeIter
2370 * @sorted_iter: A valid #GtkTreeIter pointing to a row on @tree_model_sort.
2372 * Sets @child_iter to point to the row pointed to by @sorted_iter.
2375 gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sort,
2376 GtkTreeIter *child_iter,
2377 GtkTreeIter *sorted_iter)
2379 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2380 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2381 g_return_if_fail (priv->child_model != NULL);
2382 g_return_if_fail (child_iter != NULL);
2383 g_return_if_fail (VALID_ITER (sorted_iter, tree_model_sort));
2384 g_return_if_fail (sorted_iter != child_iter);
2386 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2388 *child_iter = SORT_ELT (sorted_iter->user_data2)->iter;
2393 gboolean valid = FALSE;
2395 path = gtk_tree_model_sort_elt_get_path (sorted_iter->user_data,
2396 sorted_iter->user_data2);
2397 valid = gtk_tree_model_get_iter (priv->child_model, child_iter, path);
2398 gtk_tree_path_free (path);
2400 g_return_if_fail (valid == TRUE);
2405 gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
2406 SortLevel *parent_level,
2407 SortElt *parent_elt)
2409 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2411 SortLevel *new_level;
2415 g_assert (priv->child_model != NULL);
2417 if (parent_level == NULL)
2419 if (gtk_tree_model_get_iter_first (priv->child_model, &iter) == FALSE)
2421 length = gtk_tree_model_iter_n_children (priv->child_model, NULL);
2425 GtkTreeIter parent_iter;
2426 GtkTreeIter child_parent_iter;
2428 parent_iter.stamp = priv->stamp;
2429 parent_iter.user_data = parent_level;
2430 parent_iter.user_data2 = parent_elt;
2432 gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2435 if (gtk_tree_model_iter_children (priv->child_model,
2437 &child_parent_iter) == FALSE)
2440 /* stamp may have changed */
2441 gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2445 length = gtk_tree_model_iter_n_children (priv->child_model, &child_parent_iter);
2447 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort),
2451 g_return_if_fail (length > 0);
2453 new_level = g_new (SortLevel, 1);
2454 new_level->seq = g_sequence_new (sort_elt_free);
2455 new_level->ref_count = 0;
2456 new_level->parent_level = parent_level;
2457 new_level->parent_elt = parent_elt;
2460 parent_elt->children = new_level;
2462 priv->root = new_level;
2464 /* increase the count of zero ref_counts.*/
2465 while (parent_level)
2467 parent_elt->zero_ref_count++;
2469 parent_elt = parent_level->parent_elt;
2470 parent_level = parent_level->parent_level;
2473 if (new_level != priv->root)
2474 priv->zero_ref_count++;
2476 for (i = 0; i < length; i++)
2480 sort_elt = sort_elt_new ();
2481 sort_elt->offset = i;
2482 sort_elt->zero_ref_count = 0;
2483 sort_elt->ref_count = 0;
2484 sort_elt->children = NULL;
2486 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2488 sort_elt->iter = iter;
2489 if (gtk_tree_model_iter_next (priv->child_model, &iter) == FALSE &&
2497 level = gtk_tree_model_sort_elt_get_path (parent_level,
2499 str = gtk_tree_path_to_string (level);
2500 gtk_tree_path_free (level);
2502 g_warning ("%s: There is a discrepancy between the sort model "
2503 "and the child model. The child model is "
2504 "advertising a wrong length for level %s:.",
2510 g_warning ("%s: There is a discrepancy between the sort model "
2511 "and the child model. The child model is "
2512 "advertising a wrong length for the root level.",
2520 sort_elt->siter = g_sequence_append (new_level->seq, sort_elt);
2524 gtk_tree_model_sort_sort_level (tree_model_sort, new_level,
2529 gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
2530 SortLevel *sort_level,
2533 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2534 GSequenceIter *siter;
2535 GSequenceIter *end_siter;
2537 g_assert (sort_level);
2539 end_siter = g_sequence_get_end_iter (sort_level->seq);
2540 for (siter = g_sequence_get_begin_iter (sort_level->seq);
2542 siter = g_sequence_iter_next (siter))
2544 SortElt *elt = g_sequence_get (siter);
2547 gtk_tree_model_sort_free_level (tree_model_sort,
2548 elt->children, unref);
2551 if (sort_level->ref_count == 0)
2553 SortLevel *parent_level = sort_level->parent_level;
2554 SortElt *parent_elt = sort_level->parent_elt;
2556 while (parent_level)
2558 parent_elt->zero_ref_count--;
2560 parent_elt = parent_level->parent_elt;
2561 parent_level = parent_level->parent_level;
2564 if (sort_level != priv->root)
2565 priv->zero_ref_count--;
2568 if (sort_level->parent_elt)
2572 GtkTreeIter parent_iter;
2574 parent_iter.stamp = tree_model_sort->priv->stamp;
2575 parent_iter.user_data = sort_level->parent_level;
2576 parent_iter.user_data2 = sort_level->parent_elt;
2578 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort),
2582 sort_level->parent_elt->children = NULL;
2587 g_sequence_free (sort_level->seq);
2588 sort_level->seq = NULL;
2590 g_free (sort_level);
2595 gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort)
2597 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2603 while (priv->stamp == 0);
2605 gtk_tree_model_sort_clear_cache (tree_model_sort);
2609 gtk_tree_model_sort_clear_cache_helper_iter (gpointer data,
2612 GtkTreeModelSort *tree_model_sort = user_data;
2613 SortElt *elt = data;
2615 if (elt->zero_ref_count > 0)
2616 gtk_tree_model_sort_clear_cache_helper (tree_model_sort, elt->children);
2620 gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
2623 g_assert (level != NULL);
2625 g_sequence_foreach (level->seq, gtk_tree_model_sort_clear_cache_helper_iter,
2628 if (level->ref_count == 0 && level != tree_model_sort->priv->root)
2629 gtk_tree_model_sort_free_level (tree_model_sort, level, TRUE);
2633 * gtk_tree_model_sort_reset_default_sort_func:
2634 * @tree_model_sort: A #GtkTreeModelSort
2636 * This resets the default sort function to be in the 'unsorted' state. That
2637 * is, it is in the same order as the child model. It will re-sort the model
2638 * to be in the same order as the child model only if the #GtkTreeModelSort
2639 * is in 'unsorted' state.
2642 gtk_tree_model_sort_reset_default_sort_func (GtkTreeModelSort *tree_model_sort)
2644 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2646 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2648 if (priv->default_sort_destroy)
2650 GDestroyNotify d = priv->default_sort_destroy;
2652 priv->default_sort_destroy = NULL;
2653 d (priv->default_sort_data);
2656 priv->default_sort_func = NO_SORT_FUNC;
2657 priv->default_sort_data = NULL;
2658 priv->default_sort_destroy = NULL;
2660 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
2661 gtk_tree_model_sort_sort (tree_model_sort);
2662 priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
2666 * gtk_tree_model_sort_clear_cache:
2667 * @tree_model_sort: A #GtkTreeModelSort
2669 * This function should almost never be called. It clears the @tree_model_sort
2670 * of any cached iterators that haven't been reffed with
2671 * gtk_tree_model_ref_node(). This might be useful if the child model being
2672 * sorted is static (and doesn't change often) and there has been a lot of
2673 * unreffed access to nodes. As a side effect of this function, all unreffed
2674 * iters will be invalid.
2677 gtk_tree_model_sort_clear_cache (GtkTreeModelSort *tree_model_sort)
2679 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2681 if (tree_model_sort->priv->zero_ref_count > 0)
2682 gtk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->priv->root);
2686 gtk_tree_model_sort_iter_is_valid_helper (GtkTreeIter *iter,
2689 GSequenceIter *siter;
2690 GSequenceIter *end_siter;
2692 end_siter = g_sequence_get_end_iter (level->seq);
2693 for (siter = g_sequence_get_begin_iter (level->seq);
2694 siter != end_siter; siter = g_sequence_iter_next (siter))
2696 SortElt *elt = g_sequence_get (siter);
2698 if (iter->user_data == level && iter->user_data2 == elt)
2702 if (gtk_tree_model_sort_iter_is_valid_helper (iter, elt->children))
2710 * gtk_tree_model_sort_iter_is_valid:
2711 * @tree_model_sort: A #GtkTreeModelSort.
2712 * @iter: A #GtkTreeIter.
2715 * This function is slow. Only use it for debugging and/or testing purposes.
2718 * Checks if the given iter is a valid iter for this #GtkTreeModelSort.
2720 * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
2725 gtk_tree_model_sort_iter_is_valid (GtkTreeModelSort *tree_model_sort,
2728 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2729 g_return_val_if_fail (iter != NULL, FALSE);
2731 if (!VALID_ITER (iter, tree_model_sort))
2734 return gtk_tree_model_sort_iter_is_valid_helper (iter,
2735 tree_model_sort->priv->root);