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.
24 #include "gtktreemodelsort.h"
25 #include "gtktreesortable.h"
26 #include "gtktreestore.h"
27 #include "gtktreedatalist.h"
29 #include "gtkprivate.h"
30 #include "gtktreednd.h"
34 * SECTION:gtktreemodelsort
35 * @Short_description: A GtkTreeModel which makes an underlying tree model sortable
36 * @Title: GtkTreeModelSort
37 * @See_also: #GtkTreeModel, #GtkListStore, #GtkTreeStore, #GtkTreeSortable, #GtkTreeModelFilter
39 * The #GtkTreeModelSort is a model which implements the #GtkTreeSortable
40 * interface. It does not hold any data itself, but rather is created with
41 * a child model and proxies its data. It has identical column types to
42 * this child model, and the changes in the child are propagated. The
43 * primary purpose of this model is to provide a way to sort a different
44 * model without modifying it. Note that the sort function used by
45 * #GtkTreeModelSort is not guaranteed to be stable.
47 * The use of this is best demonstrated through an example. In the
48 * following sample code we create two #GtkTreeView widgets each with a
49 * view of the same data. As the model is wrapped here by a
50 * #GtkTreeModelSort, the two #GtkTreeView<!-- -->s can each sort their
51 * view of the data without affecting the other. By contrast, if we
52 * simply put the same model in each widget, then sorting the first would
56 * <title>Using a <structname>GtkTreeModelSort</structname></title>
59 * GtkTreeView *tree_view1;
60 * GtkTreeView *tree_view2;
61 * GtkTreeModel *sort_model1;
62 * GtkTreeModel *sort_model2;
63 * GtkTreeModel *child_model;
65 * // get the child model
66 * child_model = get_my_model ();
68 * // Create the first tree
69 * sort_model1 = gtk_tree_model_sort_new_with_model (child_model);
70 * tree_view1 = gtk_tree_view_new_with_model (sort_model1);
72 * // Create the second tree
73 * sort_model2 = gtk_tree_model_sort_new_with_model (child_model);
74 * tree_view2 = gtk_tree_view_new_with_model (sort_model2);
76 * // Now we can sort the two models independently
77 * gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model1),
78 * COLUMN_1, GTK_SORT_ASCENDING);
79 * gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model2),
80 * COLUMN_1, GTK_SORT_DESCENDING);
85 * To demonstrate how to access the underlying child model from the sort
86 * model, the next example will be a callback for the #GtkTreeSelection
87 * #GtkTreeSelection::changed signal. In this callback, we get a string
88 * from COLUMN_1 of the model. We then modify the string, find the same
89 * selected row on the child model, and change the row there.
92 * <title>Accessing the child model of in a selection changed callback</title>
95 * selection_changed (GtkTreeSelection *selection, gpointer data)
97 * GtkTreeModel *sort_model = NULL;
98 * GtkTreeModel *child_model;
99 * GtkTreeIter sort_iter;
100 * GtkTreeIter child_iter;
101 * char *some_data = NULL;
102 * char *modified_data;
104 * // Get the current selected row and the model.
105 * if (! gtk_tree_selection_get_selected (selection,
110 * /<!---->* Look up the current value on the selected row and get a new value
113 * gtk_tree_model_get (GTK_TREE_MODEL (sort_model), &sort_iter,
114 * COLUMN_1, &some_data,
117 * modified_data = change_the_data (some_data);
118 * g_free (some_data);
120 * // Get an iterator on the child model, instead of the sort model.
121 * gtk_tree_model_sort_convert_iter_to_child_iter (GTK_TREE_MODEL_SORT (sort_model),
125 * /<!---->* Get the child model and change the value of the row. In this
126 * * example, the child model is a GtkListStore. It could be any other
127 * * type of model, though.
129 * child_model = gtk_tree_model_sort_get_model (GTK_TREE_MODEL_SORT (sort_model));
130 * gtk_list_store_set (GTK_LIST_STORE (child_model), &child_iter,
131 * COLUMN_1, &modified_data,
133 * g_free (modified_data);
140 /* Notes on this implementation of GtkTreeModelSort
141 * ================================================
146 * In this code there is a potential for confusion as to whether an iter,
147 * path or value refers to the GtkTreeModelSort model, or to the child model
148 * that has been set. As a convention, variables referencing the child model
149 * will have an s_ prefix before them (ie. s_iter, s_value, s_path);
150 * Conversion of iterators and paths between GtkTreeModelSort and the child
151 * model is done through the various gtk_tree_model_sort_convert_* functions.
156 * The iterator format of iterators handed out by GtkTreeModelSort is as
159 * iter->stamp = tree_model_sort->stamp
160 * iter->user_data = SortLevel
161 * iter->user_data2 = SortElt
163 * Internal data structure
164 * -----------------------
166 * Using SortLevel and SortElt, GtkTreeModelSort maintains a "cache" of
167 * the mapping from GtkTreeModelSort nodes to nodes in the child model.
168 * This is to avoid sorting a level each time an operation is requested
169 * on GtkTreeModelSort, such as get iter, get path, get value.
171 * A SortElt corresponds to a single node. A node and its siblings are
172 * stored in a SortLevel. The SortLevel keeps a reference to the parent
173 * SortElt and its SortLevel (if any). The SortElt can have a "children"
174 * pointer set, which points at a child level (a sub level).
176 * In a SortLevel, nodes are stored in a GSequence. The GSequence
177 * allows for fast additions and removals, and supports sorting
178 * the level of SortElt nodes.
180 * It is important to recognize the two different mappings that play
181 * a part in this code:
182 * I. The mapping from the client to this model. The order in which
183 * nodes are stored in the GSequence is the order in which the
184 * nodes are exposed to clients of the GtkTreeModelSort.
185 * II. The mapping from this model to its child model. Each SortElt
186 * contains an "offset" field which is the offset of the
187 * corresponding node in the child model.
192 * GtkTreeModelSort forwards all reference and unreference operations
193 * to the corresponding node in the child model. The reference count
194 * of each node is also maintained internally, in the "ref_count"
195 * fields in SortElt and SortLevel. For each ref and unref operation on
196 * a SortElt, the "ref_count" of the SortLevel is updated accordingly.
197 * In addition, if a SortLevel has a parent, a reference is taken on
198 * this parent. This happens in gtk_tree_model_sort_build_level() and
199 * the reference is released again in gtk_tree_model_sort_free_level().
200 * This ensures that when GtkTreeModelSort takes a reference on a node
201 * (for example during sorting), all parent nodes are referenced
202 * according to reference counting rule 1, see the GtkTreeModel
205 * When a level has a reference count of zero, which means that
206 * none of the nodes in the level is referenced, the level has
207 * a "zero ref count" on all its parents. As soon as the level
208 * reaches a reference count of zero, the zero ref count value is
209 * incremented by one on all parents of this level. Similarly, as
210 * soon as the reference count of a level changes from zero, the
211 * zero ref count value is decremented by one on all parents.
213 * The zero ref count value is used to clear unused portions of
214 * the cache. If a SortElt has a zero ref count of one, then
215 * its child level is unused and can be removed from the cache.
216 * If the zero ref count value is higher than one, then the
217 * child level contains sublevels which are unused as well.
218 * gtk_tree_model_sort_clear_cache() uses this to not recurse
219 * into levels which have a zero ref count of zero.
222 typedef struct _SortElt SortElt;
223 typedef struct _SortLevel SortLevel;
224 typedef struct _SortData SortData;
233 GSequenceIter *siter; /* iter into seq */
234 gint old_index; /* used while sorting */
242 SortLevel *parent_level;
247 GtkTreeModelSort *tree_model_sort;
248 GtkTreeIterCompareFunc sort_func;
251 GtkTreePath *parent_path;
252 gint parent_path_depth;
253 gint *parent_path_indices;
264 struct _GtkTreeModelSortPrivate
269 GtkTreeModel *child_model;
272 /* sort information */
278 GtkTreeIterCompareFunc default_sort_func;
279 gpointer default_sort_data;
280 GDestroyNotify default_sort_destroy;
285 gulong has_child_toggled_id;
290 /* Set this to 0 to disable caching of child iterators. This
291 * allows for more stringent testing. It is recommended to set this
292 * to one when refactoring this code and running the unit tests to
296 # define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) \
297 (((GtkTreeModelSort *)tree_model_sort)->priv->child_flags>K_TREE_MODEL_ITERS_PERSIST)
299 # define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) (FALSE)
302 #define SORT_ELT(sort_elt) ((SortElt *)sort_elt)
303 #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level)
304 #define GET_ELT(siter) ((SortElt *) (siter ? g_sequence_get (siter) : NULL))
307 #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));
309 #define NO_SORT_FUNC ((GtkTreeIterCompareFunc) 0x1)
311 #define VALID_ITER(iter, tree_model_sort) ((iter) != NULL && (iter)->user_data != NULL && (iter)->user_data2 != NULL && (tree_model_sort)->priv->stamp == (iter)->stamp)
313 /* general (object/interface init, etc) */
314 static void gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface);
315 static void gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface);
316 static void gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface*iface);
317 static void gtk_tree_model_sort_finalize (GObject *object);
318 static void gtk_tree_model_sort_set_property (GObject *object,
322 static void gtk_tree_model_sort_get_property (GObject *object,
327 /* our signal handlers */
328 static void gtk_tree_model_sort_row_changed (GtkTreeModel *model,
329 GtkTreePath *start_path,
330 GtkTreeIter *start_iter,
332 static void gtk_tree_model_sort_row_inserted (GtkTreeModel *model,
336 static void gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *model,
340 static void gtk_tree_model_sort_row_deleted (GtkTreeModel *model,
343 static void gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
349 /* TreeModel interface */
350 static GtkTreeModelFlags gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model);
351 static gint gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model);
352 static GType gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
354 static gboolean gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
357 static GtkTreePath *gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
359 static void gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
363 static gboolean gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
365 static gboolean gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
367 static gboolean gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
369 GtkTreeIter *parent);
370 static gboolean gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
372 static gint gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
374 static gboolean gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
378 static gboolean gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
381 static void gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
383 static void gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
385 gboolean propagate_unref);
386 static void gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
389 /* TreeDragSource interface */
390 static gboolean gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
392 static gboolean gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
394 GtkSelectionData *selection_data);
395 static gboolean gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
398 /* TreeSortable interface */
399 static gboolean gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
400 gint *sort_column_id,
402 static void gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
405 static void gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
407 GtkTreeIterCompareFunc func,
409 GDestroyNotify destroy);
410 static void gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
411 GtkTreeIterCompareFunc func,
413 GDestroyNotify destroy);
414 static gboolean gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable);
416 /* Private functions (sort funcs, level handling and other utils) */
417 static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
418 SortLevel *parent_level,
419 SortElt *parent_elt);
420 static void gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
421 SortLevel *sort_level,
423 static void gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort);
424 static void gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
427 gboolean emit_reordered);
428 static void gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort);
429 static gboolean gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
432 GtkTreeIter *s_iter);
433 static GtkTreePath *gtk_tree_model_sort_elt_get_path (SortLevel *level,
435 static void gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
436 GtkTreeModel *child_model);
437 static GtkTreePath *gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
438 GtkTreePath *child_path,
439 gboolean build_levels);
441 static gint gtk_tree_model_sort_compare_func (gconstpointer a,
444 static gint gtk_tree_model_sort_offset_compare_func (gconstpointer a,
447 static void gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
451 G_DEFINE_TYPE_WITH_CODE (GtkTreeModelSort, gtk_tree_model_sort, G_TYPE_OBJECT,
452 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
453 gtk_tree_model_sort_tree_model_init)
454 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
455 gtk_tree_model_sort_tree_sortable_init)
456 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
457 gtk_tree_model_sort_drag_source_init))
460 gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
462 GtkTreeModelSortPrivate *priv;
464 priv = G_TYPE_INSTANCE_GET_PRIVATE (tree_model_sort,
465 GTK_TYPE_TREE_MODEL_SORT,
466 GtkTreeModelSortPrivate);
467 tree_model_sort->priv = priv;
468 priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
470 priv->zero_ref_count = 0;
472 priv->sort_list = NULL;
476 gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
478 GObjectClass *object_class;
480 object_class = (GObjectClass *) class;
482 object_class->set_property = gtk_tree_model_sort_set_property;
483 object_class->get_property = gtk_tree_model_sort_get_property;
485 object_class->finalize = gtk_tree_model_sort_finalize;
488 g_object_class_install_property (object_class,
490 g_param_spec_object ("model",
491 P_("TreeModelSort Model"),
492 P_("The model for the TreeModelSort to sort"),
494 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
496 g_type_class_add_private (class, sizeof (GtkTreeModelSortPrivate));
500 gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
502 iface->get_flags = gtk_tree_model_sort_get_flags;
503 iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
504 iface->get_column_type = gtk_tree_model_sort_get_column_type;
505 iface->get_iter = gtk_tree_model_sort_get_iter;
506 iface->get_path = gtk_tree_model_sort_get_path;
507 iface->get_value = gtk_tree_model_sort_get_value;
508 iface->iter_next = gtk_tree_model_sort_iter_next;
509 iface->iter_previous = gtk_tree_model_sort_iter_previous;
510 iface->iter_children = gtk_tree_model_sort_iter_children;
511 iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
512 iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
513 iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
514 iface->iter_parent = gtk_tree_model_sort_iter_parent;
515 iface->ref_node = gtk_tree_model_sort_ref_node;
516 iface->unref_node = gtk_tree_model_sort_unref_node;
520 gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface)
522 iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id;
523 iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id;
524 iface->set_sort_func = gtk_tree_model_sort_set_sort_func;
525 iface->set_default_sort_func = gtk_tree_model_sort_set_default_sort_func;
526 iface->has_default_sort_func = gtk_tree_model_sort_has_default_sort_func;
530 gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface *iface)
532 iface->row_draggable = gtk_tree_model_sort_row_draggable;
533 iface->drag_data_delete = gtk_tree_model_sort_drag_data_delete;
534 iface->drag_data_get = gtk_tree_model_sort_drag_data_get;
538 * gtk_tree_model_sort_new_with_model:
539 * @child_model: A #GtkTreeModel
541 * Creates a new #GtkTreeModel, with @child_model as the child model.
543 * Return value: (transfer full): A new #GtkTreeModel.
546 gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model)
548 GtkTreeModel *retval;
550 g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
552 retval = g_object_new (gtk_tree_model_sort_get_type (), NULL);
554 gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model);
559 /* GObject callbacks */
561 gtk_tree_model_sort_finalize (GObject *object)
563 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
564 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
566 gtk_tree_model_sort_set_model (tree_model_sort, NULL);
569 gtk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE);
573 _gtk_tree_data_list_header_free (priv->sort_list);
574 priv->sort_list = NULL;
577 if (priv->default_sort_destroy)
579 priv->default_sort_destroy (priv->default_sort_data);
580 priv->default_sort_destroy = NULL;
581 priv->default_sort_data = NULL;
586 G_OBJECT_CLASS (gtk_tree_model_sort_parent_class)->finalize (object);
590 gtk_tree_model_sort_set_property (GObject *object,
595 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
600 gtk_tree_model_sort_set_model (tree_model_sort, g_value_get_object (value));
603 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
609 gtk_tree_model_sort_get_property (GObject *object,
614 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
619 g_value_set_object (value, gtk_tree_model_sort_get_model (tree_model_sort));
622 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
631 return g_slice_new (SortElt);
635 sort_elt_free (gpointer elt)
637 g_slice_free (SortElt, elt);
641 increase_offset_iter (gpointer data,
645 gint offset = GPOINTER_TO_INT (user_data);
647 if (elt->offset >= offset)
652 decrease_offset_iter (gpointer data,
656 gint offset = GPOINTER_TO_INT (user_data);
658 if (elt->offset > offset)
663 fill_sort_data (SortData *data,
664 GtkTreeModelSort *tree_model_sort,
667 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
669 data->tree_model_sort = tree_model_sort;
671 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
673 GtkTreeDataSortHeader *header;
675 header = _gtk_tree_data_list_get_header (priv->sort_list,
676 priv->sort_column_id);
678 g_return_if_fail (header != NULL);
679 g_return_if_fail (header->func != NULL);
681 data->sort_func = header->func;
682 data->sort_data = header->data;
686 /* absolutely SHOULD NOT happen: */
687 g_return_if_fail (priv->default_sort_func != NULL);
689 data->sort_func = priv->default_sort_func;
690 data->sort_data = priv->default_sort_data;
693 if (level->parent_elt)
695 data->parent_path = gtk_tree_model_sort_elt_get_path (level->parent_level,
697 gtk_tree_path_append_index (data->parent_path, 0);
701 data->parent_path = gtk_tree_path_new_first ();
703 data->parent_path_depth = gtk_tree_path_get_depth (data->parent_path);
704 data->parent_path_indices = gtk_tree_path_get_indices (data->parent_path);
708 free_sort_data (SortData *data)
710 gtk_tree_path_free (data->parent_path);
714 lookup_elt_with_offset (GtkTreeModelSort *tree_model_sort,
717 GSequenceIter **ret_siter)
719 GSequenceIter *siter, *end_siter;
721 /* FIXME: We have to do a search like this, because the sequence is not
722 * (always) sorted on offset order. Perhaps we should introduce a
723 * second sequence which is sorted on offset order.
725 end_siter = g_sequence_get_end_iter (level->seq);
726 for (siter = g_sequence_get_begin_iter (level->seq);
728 siter = g_sequence_iter_next (siter))
730 SortElt *elt = g_sequence_get (siter);
732 if (elt->offset == offset)
739 return GET_ELT (siter);
744 gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
745 GtkTreePath *start_s_path,
746 GtkTreeIter *start_s_iter,
749 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
750 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
751 GtkTreePath *path = NULL;
759 gboolean free_s_path = FALSE;
761 gint index = 0, old_index;
763 g_return_if_fail (start_s_path != NULL || start_s_iter != NULL);
768 start_s_path = gtk_tree_model_get_path (s_model, start_s_iter);
771 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
777 gtk_tree_path_free (start_s_path);
781 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
782 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (data), &iter);
784 level = iter.user_data;
785 elt = iter.user_data2;
787 if (g_sequence_get_length (level->seq) < 2 ||
788 (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
789 priv->default_sort_func == NO_SORT_FUNC))
792 gtk_tree_path_free (start_s_path);
794 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
795 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
797 gtk_tree_path_free (path);
802 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
805 gtk_tree_model_get_iter (priv->child_model,
806 &tmpiter, start_s_path);
808 old_index = g_sequence_iter_get_position (elt->siter);
810 fill_sort_data (&sort_data, tree_model_sort, level);
811 g_sequence_sort_changed (elt->siter,
812 gtk_tree_model_sort_compare_func,
814 free_sort_data (&sort_data);
816 index = g_sequence_iter_get_position (elt->siter);
818 /* Prepare the path for signal emission */
819 gtk_tree_path_up (path);
820 gtk_tree_path_append_index (path, index);
822 gtk_tree_model_sort_increment_stamp (tree_model_sort);
824 /* if the item moved, then emit rows_reordered */
825 if (old_index != index)
830 GtkTreePath *tmppath;
832 new_order = g_new (gint, g_sequence_get_length (level->seq));
834 for (j = 0; j < g_sequence_get_length (level->seq); j++)
836 if (index > old_index)
839 new_order[j] = old_index;
840 else if (j >= old_index && j < index)
841 new_order[j] = j + 1;
845 else if (index < old_index)
848 new_order[j] = old_index;
849 else if (j > index && j <= old_index)
850 new_order[j] = j - 1;
854 /* else? shouldn't really happen */
857 if (level->parent_elt)
859 iter.stamp = priv->stamp;
860 iter.user_data = level->parent_level;
861 iter.user_data2 = level->parent_elt;
863 tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter);
865 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
866 tmppath, &iter, new_order);
871 tmppath = gtk_tree_path_new ();
873 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), tmppath,
877 gtk_tree_path_free (tmppath);
881 /* emit row_changed signal (at new location) */
882 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
883 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
884 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
886 gtk_tree_path_free (path);
888 gtk_tree_path_free (start_s_path);
892 gtk_tree_model_sort_row_inserted (GtkTreeModel *s_model,
897 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
898 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
901 GtkTreeIter real_s_iter;
905 gboolean free_s_path = FALSE;
909 SortLevel *parent_level = NULL;
911 parent_level = level = SORT_LEVEL (priv->root);
913 g_return_if_fail (s_path != NULL || s_iter != NULL);
917 s_path = gtk_tree_model_get_path (s_model, s_iter);
922 gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
924 real_s_iter = *s_iter;
928 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
930 /* the build level already put the inserted iter in the level,
931 so no need to handle this signal anymore */
933 goto done_and_submit;
936 /* find the parent level */
937 while (i < gtk_tree_path_get_depth (s_path) - 1)
941 /* level not yet build, we won't cover this signal */
945 if (g_sequence_get_length (level->seq) < gtk_tree_path_get_indices (s_path)[i])
947 g_warning ("%s: A node was inserted with a parent that's not in the tree.\n"
948 "This possibly means that a GtkTreeModel inserted a child node\n"
949 "before the parent was inserted.",
954 elt = lookup_elt_with_offset (tree_model_sort, level,
955 gtk_tree_path_get_indices (s_path)[i],
958 g_return_if_fail (elt != NULL);
962 /* not covering this signal */
966 level = elt->children;
967 parent_level = level;
974 if (level->ref_count == 0 && level != priv->root)
976 gtk_tree_model_sort_free_level (tree_model_sort, level, TRUE);
980 if (!gtk_tree_model_sort_insert_value (tree_model_sort,
987 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
994 gtk_tree_model_sort_increment_stamp (tree_model_sort);
996 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
997 gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
998 gtk_tree_path_free (path);
1002 gtk_tree_path_free (s_path);
1008 gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *s_model,
1009 GtkTreePath *s_path,
1010 GtkTreeIter *s_iter,
1013 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
1017 g_return_if_fail (s_path != NULL && s_iter != NULL);
1019 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
1023 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
1024 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
1026 gtk_tree_path_free (path);
1030 gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
1031 GtkTreePath *s_path,
1034 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
1035 GtkTreePath *path = NULL;
1041 g_return_if_fail (s_path != NULL);
1043 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
1047 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
1049 level = SORT_LEVEL (iter.user_data);
1050 elt = SORT_ELT (iter.user_data2);
1051 offset = elt->offset;
1053 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
1055 while (elt->ref_count > 0)
1056 gtk_tree_model_sort_real_unref_node (GTK_TREE_MODEL (data), &iter, FALSE);
1058 /* If this node has children, we free the level (recursively) here
1059 * and specify that unref may not be used, because parent and its
1060 * children have been removed by now.
1063 gtk_tree_model_sort_free_level (tree_model_sort,
1064 elt->children, FALSE);
1066 if (level->ref_count == 0)
1068 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1069 gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
1070 gtk_tree_path_free (path);
1072 if (level == tree_model_sort->priv->root)
1074 gtk_tree_model_sort_free_level (tree_model_sort,
1075 tree_model_sort->priv->root,
1077 tree_model_sort->priv->root = NULL;
1082 g_sequence_remove (elt->siter);
1085 /* The sequence is not ordered on offset, so we traverse the entire
1088 g_sequence_foreach (level->seq, decrease_offset_iter,
1089 GINT_TO_POINTER (offset));
1091 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1092 gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
1094 gtk_tree_path_free (path);
1098 gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
1099 GtkTreePath *s_path,
1100 GtkTreeIter *s_iter,
1110 GSequenceIter *siter, *end_siter;
1111 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
1112 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1114 g_return_if_fail (new_order != NULL);
1116 if (s_path == NULL || gtk_tree_path_get_depth (s_path) == 0)
1118 if (priv->root == NULL)
1120 path = gtk_tree_path_new ();
1121 level = SORT_LEVEL (priv->root);
1125 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
1128 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
1130 elt = SORT_ELT (iter.user_data2);
1134 gtk_tree_path_free (path);
1138 level = elt->children;
1141 length = g_sequence_get_length (level->seq);
1144 gtk_tree_path_free (path);
1148 tmp_array = g_new (int, length);
1150 /* FIXME: I need to think about whether this can be done in a more
1154 end_siter = g_sequence_get_end_iter (level->seq);
1155 for (siter = g_sequence_get_begin_iter (level->seq);
1157 siter = g_sequence_iter_next (siter))
1160 SortElt *elt = g_sequence_get (siter);
1162 for (j = 0; j < length; j++)
1164 if (elt->offset == new_order[j])
1171 /* This loop cannot be merged with the above loop nest, because that
1172 * would introduce duplicate offsets.
1175 end_siter = g_sequence_get_end_iter (level->seq);
1176 for (siter = g_sequence_get_begin_iter (level->seq);
1178 siter = g_sequence_iter_next (siter))
1180 SortElt *elt = g_sequence_get (siter);
1182 elt->offset = tmp_array[i];
1187 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
1188 priv->default_sort_func == NO_SORT_FUNC)
1190 gtk_tree_model_sort_sort_level (tree_model_sort, level,
1192 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1194 if (gtk_tree_path_get_depth (path))
1196 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
1199 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
1200 path, &iter, new_order);
1204 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
1205 path, NULL, new_order);
1209 gtk_tree_path_free (path);
1212 /* Fulfill our model requirements */
1213 static GtkTreeModelFlags
1214 gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model)
1216 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1217 GtkTreeModelFlags flags;
1219 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, 0);
1221 flags = gtk_tree_model_get_flags (tree_model_sort->priv->child_model);
1223 if ((flags & GTK_TREE_MODEL_LIST_ONLY) == GTK_TREE_MODEL_LIST_ONLY)
1224 return GTK_TREE_MODEL_LIST_ONLY;
1230 gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
1232 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1234 if (tree_model_sort->priv->child_model == 0)
1237 return gtk_tree_model_get_n_columns (tree_model_sort->priv->child_model);
1241 gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
1244 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1246 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, G_TYPE_INVALID);
1248 return gtk_tree_model_get_column_type (tree_model_sort->priv->child_model, index);
1252 gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
1256 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1257 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1262 GSequenceIter *siter;
1264 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1266 indices = gtk_tree_path_get_indices (path);
1268 if (priv->root == NULL)
1269 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1270 level = SORT_LEVEL (priv->root);
1272 depth = gtk_tree_path_get_depth (path);
1279 for (i = 0; i < depth - 1; i++)
1281 if ((level == NULL) ||
1282 (indices[i] >= g_sequence_get_length (level->seq)))
1288 siter = g_sequence_get_iter_at_pos (level->seq, indices[i]);
1289 if (g_sequence_iter_is_end (siter))
1295 elt = GET_ELT (siter);
1296 if (elt->children == NULL)
1297 gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
1299 level = elt->children;
1302 if (!level || indices[i] >= g_sequence_get_length (level->seq))
1308 iter->stamp = priv->stamp;
1309 iter->user_data = level;
1311 siter = g_sequence_get_iter_at_pos (level->seq, indices[depth - 1]);
1312 if (g_sequence_iter_is_end (siter))
1317 iter->user_data2 = GET_ELT (siter);
1322 static GtkTreePath *
1323 gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
1326 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1327 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1328 GtkTreePath *retval;
1332 g_return_val_if_fail (priv->child_model != NULL, NULL);
1333 g_return_val_if_fail (priv->stamp == iter->stamp, NULL);
1335 retval = gtk_tree_path_new ();
1337 level = SORT_LEVEL (iter->user_data);
1338 elt = SORT_ELT (iter->user_data2);
1344 index = g_sequence_iter_get_position (elt->siter);
1345 gtk_tree_path_prepend_index (retval, index);
1347 elt = level->parent_elt;
1348 level = level->parent_level;
1355 gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
1360 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1361 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1362 GtkTreeIter child_iter;
1364 g_return_if_fail (priv->child_model != NULL);
1365 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1367 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1368 gtk_tree_model_get_value (priv->child_model,
1369 &child_iter, column, value);
1373 gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
1376 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1377 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1379 GSequenceIter *siter;
1381 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1382 g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1384 elt = iter->user_data2;
1386 siter = g_sequence_iter_next (elt->siter);
1387 if (g_sequence_iter_is_end (siter))
1392 iter->user_data2 = GET_ELT (siter);
1398 gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
1401 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1402 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1404 GSequenceIter *siter;
1406 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1407 g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1409 elt = iter->user_data2;
1411 siter = g_sequence_iter_prev (elt->siter);
1412 if (g_sequence_iter_is_begin (siter))
1417 iter->user_data2 = GET_ELT (siter);
1423 gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
1425 GtkTreeIter *parent)
1427 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1428 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1432 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1434 g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1438 if (priv->root == NULL)
1439 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
1440 if (priv->root == NULL)
1444 iter->stamp = priv->stamp;
1445 iter->user_data = level;
1446 iter->user_data2 = g_sequence_get (g_sequence_get_begin_iter (level->seq));
1452 level = SORT_LEVEL (parent->user_data);
1453 elt = SORT_ELT (parent->user_data2);
1455 if (elt->children == NULL)
1456 gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
1458 if (elt->children == NULL)
1461 iter->stamp = priv->stamp;
1462 iter->user_data = elt->children;
1463 iter->user_data2 = g_sequence_get (g_sequence_get_begin_iter (elt->children->seq));
1470 gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
1473 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1474 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1475 GtkTreeIter child_iter;
1477 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1478 g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), FALSE);
1480 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1482 return gtk_tree_model_iter_has_child (priv->child_model, &child_iter);
1486 gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
1489 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1490 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1491 GtkTreeIter child_iter;
1493 g_return_val_if_fail (priv->child_model != NULL, 0);
1495 g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), 0);
1498 return gtk_tree_model_iter_n_children (priv->child_model, NULL);
1500 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1502 return gtk_tree_model_iter_n_children (priv->child_model, &child_iter);
1506 gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
1508 GtkTreeIter *parent,
1511 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1513 /* We have this for the iter == parent case */
1514 GtkTreeIter children;
1517 g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1519 /* Use this instead of has_child to force us to build the level, if needed */
1520 if (gtk_tree_model_sort_iter_children (tree_model, &children, parent) == FALSE)
1526 level = children.user_data;
1527 if (n >= g_sequence_get_length (level->seq))
1533 iter->stamp = tree_model_sort->priv->stamp;
1534 iter->user_data = level;
1535 iter->user_data2 = g_sequence_get (g_sequence_get_iter_at_pos (level->seq, n));
1541 gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
1545 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1546 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1550 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1551 g_return_val_if_fail (VALID_ITER (child, tree_model_sort), FALSE);
1553 level = child->user_data;
1555 if (level->parent_level)
1557 iter->stamp = priv->stamp;
1558 iter->user_data = level->parent_level;
1559 iter->user_data2 = level->parent_elt;
1567 gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
1570 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1571 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1572 GtkTreeIter child_iter;
1576 g_return_if_fail (priv->child_model != NULL);
1577 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1579 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1581 /* Reference the node in the child model */
1582 gtk_tree_model_ref_node (priv->child_model, &child_iter);
1584 /* Increase the reference count of this element and its level */
1585 level = iter->user_data;
1586 elt = iter->user_data2;
1591 if (level->ref_count == 1)
1593 SortLevel *parent_level = level->parent_level;
1594 SortElt *parent_elt = level->parent_elt;
1596 /* We were at zero -- time to decrement the zero_ref_count val */
1597 while (parent_level)
1599 parent_elt->zero_ref_count--;
1601 parent_elt = parent_level->parent_elt;
1602 parent_level = parent_level->parent_level;
1605 if (priv->root != level)
1606 priv->zero_ref_count--;
1611 gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
1613 gboolean propagate_unref)
1615 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1616 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1620 g_return_if_fail (priv->child_model != NULL);
1621 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1623 if (propagate_unref)
1625 GtkTreeIter child_iter;
1627 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1628 gtk_tree_model_unref_node (priv->child_model, &child_iter);
1631 level = iter->user_data;
1632 elt = iter->user_data2;
1634 g_return_if_fail (elt->ref_count > 0);
1639 if (level->ref_count == 0)
1641 SortLevel *parent_level = level->parent_level;
1642 SortElt *parent_elt = level->parent_elt;
1644 /* We are at zero -- time to increment the zero_ref_count val */
1645 while (parent_level)
1647 parent_elt->zero_ref_count++;
1649 parent_elt = parent_level->parent_elt;
1650 parent_level = parent_level->parent_level;
1653 if (priv->root != level)
1654 priv->zero_ref_count++;
1659 gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
1662 gtk_tree_model_sort_real_unref_node (tree_model, iter, TRUE);
1665 /* Sortable interface */
1667 gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
1668 gint *sort_column_id,
1671 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1672 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1675 *sort_column_id = priv->sort_column_id;
1677 *order = priv->order;
1679 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
1680 priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1687 gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
1688 gint sort_column_id,
1691 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1692 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1694 if (sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1696 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1698 GtkTreeDataSortHeader *header = NULL;
1700 header = _gtk_tree_data_list_get_header (priv->sort_list,
1703 /* we want to make sure that we have a function */
1704 g_return_if_fail (header != NULL);
1705 g_return_if_fail (header->func != NULL);
1708 g_return_if_fail (priv->default_sort_func != NULL);
1710 if (priv->sort_column_id == sort_column_id)
1712 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1714 if (priv->order == order)
1722 priv->sort_column_id = sort_column_id;
1723 priv->order = order;
1725 gtk_tree_sortable_sort_column_changed (sortable);
1727 gtk_tree_model_sort_sort (tree_model_sort);
1731 gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
1732 gint sort_column_id,
1733 GtkTreeIterCompareFunc func,
1735 GDestroyNotify destroy)
1737 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1738 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1740 priv->sort_list = _gtk_tree_data_list_set_header (priv->sort_list,
1742 func, data, destroy);
1744 if (priv->sort_column_id == sort_column_id)
1745 gtk_tree_model_sort_sort (tree_model_sort);
1749 gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
1750 GtkTreeIterCompareFunc func,
1752 GDestroyNotify destroy)
1754 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1755 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1757 if (priv->default_sort_destroy)
1759 GDestroyNotify d = priv->default_sort_destroy;
1761 priv->default_sort_destroy = NULL;
1762 d (priv->default_sort_data);
1765 priv->default_sort_func = func;
1766 priv->default_sort_data = data;
1767 priv->default_sort_destroy = destroy;
1769 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1770 gtk_tree_model_sort_sort (tree_model_sort);
1774 gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable)
1776 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1778 return (tree_model_sort->priv->default_sort_func != NULL);
1781 /* DragSource interface */
1783 gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
1786 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1787 GtkTreePath *child_path;
1790 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort,
1792 draggable = gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1793 gtk_tree_path_free (child_path);
1799 gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
1801 GtkSelectionData *selection_data)
1803 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1804 GtkTreePath *child_path;
1807 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1808 gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path, selection_data);
1809 gtk_tree_path_free (child_path);
1815 gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
1818 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1819 GtkTreePath *child_path;
1822 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1823 deleted = gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1824 gtk_tree_path_free (child_path);
1829 /* sorting code - private */
1831 gtk_tree_model_sort_compare_func (gconstpointer a,
1835 SortData *data = (SortData *)user_data;
1836 GtkTreeModelSort *tree_model_sort = data->tree_model_sort;
1837 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1838 const SortElt *sa = a;
1839 const SortElt *sb = b;
1841 GtkTreeIter iter_a, iter_b;
1844 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1851 data->parent_path_indices [data->parent_path_depth-1] = sa->offset;
1852 gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_a, data->parent_path);
1853 data->parent_path_indices [data->parent_path_depth-1] = sb->offset;
1854 gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_b, data->parent_path);
1857 retval = (* data->sort_func) (GTK_TREE_MODEL (priv->child_model),
1861 if (priv->order == GTK_SORT_DESCENDING)
1865 else if (retval < 0)
1873 gtk_tree_model_sort_offset_compare_func (gconstpointer a,
1879 const SortElt *sa = (SortElt *)a;
1880 const SortElt *sb = (SortElt *)b;
1882 SortData *data = (SortData *)user_data;
1884 if (sa->offset < sb->offset)
1886 else if (sa->offset > sb->offset)
1891 if (data->tree_model_sort->priv->order == GTK_SORT_DESCENDING)
1895 else if (retval < 0)
1903 gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
1906 gboolean emit_reordered)
1908 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1910 GSequenceIter *begin_siter, *end_siter, *siter;
1919 g_return_if_fail (level != NULL);
1921 begin_siter = g_sequence_get_begin_iter (level->seq);
1922 begin_elt = g_sequence_get (begin_siter);
1924 if (g_sequence_get_length (level->seq) < 1 && !begin_elt->children)
1927 iter.stamp = priv->stamp;
1928 iter.user_data = level;
1929 iter.user_data2 = begin_elt;
1931 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1934 end_siter = g_sequence_get_end_iter (level->seq);
1935 for (siter = g_sequence_get_begin_iter (level->seq);
1937 siter = g_sequence_iter_next (siter))
1939 SortElt *elt = g_sequence_get (siter);
1945 fill_sort_data (&data, tree_model_sort, level);
1947 if (data.sort_func == NO_SORT_FUNC)
1948 g_sequence_sort (level->seq, gtk_tree_model_sort_offset_compare_func,
1951 g_sequence_sort (level->seq, gtk_tree_model_sort_compare_func, &data);
1953 free_sort_data (&data);
1955 new_order = g_new (gint, g_sequence_get_length (level->seq));
1958 end_siter = g_sequence_get_end_iter (level->seq);
1959 for (siter = g_sequence_get_begin_iter (level->seq);
1961 siter = g_sequence_iter_next (siter))
1963 SortElt *elt = g_sequence_get (siter);
1965 new_order[i++] = elt->old_index;
1970 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1971 if (level->parent_elt)
1973 iter.stamp = priv->stamp;
1974 iter.user_data = level->parent_level;
1975 iter.user_data2 = level->parent_elt;
1977 path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort),
1980 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1986 path = gtk_tree_path_new ();
1987 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1991 gtk_tree_path_free (path);
1994 /* recurse, if possible */
1997 end_siter = g_sequence_get_end_iter (level->seq);
1998 for (siter = g_sequence_get_begin_iter (level->seq);
2000 siter = g_sequence_iter_next (siter))
2002 SortElt *elt = g_sequence_get (siter);
2005 gtk_tree_model_sort_sort_level (tree_model_sort,
2007 TRUE, emit_reordered);
2013 /* get the iter we referenced at the beginning of this function and
2016 iter.stamp = priv->stamp;
2017 iter.user_data = level;
2018 iter.user_data2 = begin_elt;
2020 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
2024 gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort)
2026 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2028 if (priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
2034 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
2036 GtkTreeDataSortHeader *header = NULL;
2038 header = _gtk_tree_data_list_get_header (priv->sort_list,
2039 priv->sort_column_id);
2041 /* we want to make sure that we have a function */
2042 g_return_if_fail (header != NULL);
2043 g_return_if_fail (header->func != NULL);
2046 g_return_if_fail (priv->default_sort_func != NULL);
2048 gtk_tree_model_sort_sort_level (tree_model_sort, priv->root,
2052 /* signal helpers */
2054 gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
2056 GtkTreePath *s_path,
2057 GtkTreeIter *s_iter)
2059 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2064 elt = sort_elt_new ();
2066 offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];
2068 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2069 elt->iter = *s_iter;
2070 elt->offset = offset;
2071 elt->zero_ref_count = 0;
2073 elt->children = NULL;
2075 /* update all larger offsets */
2076 g_sequence_foreach (level->seq, increase_offset_iter, GINT_TO_POINTER (offset));
2078 fill_sort_data (&data, tree_model_sort, level);
2080 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
2081 priv->default_sort_func == NO_SORT_FUNC)
2083 elt->siter = g_sequence_insert_sorted (level->seq, elt,
2084 gtk_tree_model_sort_offset_compare_func,
2089 elt->siter = g_sequence_insert_sorted (level->seq, elt,
2090 gtk_tree_model_sort_compare_func,
2094 free_sort_data (&data);
2099 /* sort elt stuff */
2100 static GtkTreePath *
2101 gtk_tree_model_sort_elt_get_path (SortLevel *level,
2104 SortLevel *walker = level;
2105 SortElt *walker2 = elt;
2108 g_return_val_if_fail (level != NULL, NULL);
2109 g_return_val_if_fail (elt != NULL, NULL);
2111 path = gtk_tree_path_new ();
2115 gtk_tree_path_prepend_index (path, walker2->offset);
2117 if (!walker->parent_level)
2120 walker2 = walker->parent_elt;
2121 walker = walker->parent_level;
2128 * gtk_tree_model_sort_set_model:
2129 * @tree_model_sort: The #GtkTreeModelSort.
2130 * @child_model: (allow-none): A #GtkTreeModel, or %NULL.
2132 * Sets the model of @tree_model_sort to be @model. If @model is %NULL,
2133 * then the old model is unset. The sort function is unset as a result
2134 * of this call. The model will be in an unsorted state until a sort
2138 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
2139 GtkTreeModel *child_model)
2141 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2144 g_object_ref (child_model);
2146 if (priv->child_model)
2148 g_signal_handler_disconnect (priv->child_model,
2150 g_signal_handler_disconnect (priv->child_model,
2152 g_signal_handler_disconnect (priv->child_model,
2153 priv->has_child_toggled_id);
2154 g_signal_handler_disconnect (priv->child_model,
2156 g_signal_handler_disconnect (priv->child_model,
2157 priv->reordered_id);
2159 /* reset our state */
2161 gtk_tree_model_sort_free_level (tree_model_sort, priv->root, TRUE);
2163 _gtk_tree_data_list_header_free (priv->sort_list);
2164 priv->sort_list = NULL;
2165 g_object_unref (priv->child_model);
2168 priv->child_model = child_model;
2176 g_signal_connect (child_model, "row-changed",
2177 G_CALLBACK (gtk_tree_model_sort_row_changed),
2180 g_signal_connect (child_model, "row-inserted",
2181 G_CALLBACK (gtk_tree_model_sort_row_inserted),
2183 priv->has_child_toggled_id =
2184 g_signal_connect (child_model, "row-has-child-toggled",
2185 G_CALLBACK (gtk_tree_model_sort_row_has_child_toggled),
2188 g_signal_connect (child_model, "row-deleted",
2189 G_CALLBACK (gtk_tree_model_sort_row_deleted),
2191 priv->reordered_id =
2192 g_signal_connect (child_model, "rows-reordered",
2193 G_CALLBACK (gtk_tree_model_sort_rows_reordered),
2196 priv->child_flags = gtk_tree_model_get_flags (child_model);
2197 n_columns = gtk_tree_model_get_n_columns (child_model);
2199 types = g_new (GType, n_columns);
2200 for (i = 0; i < n_columns; i++)
2201 types[i] = gtk_tree_model_get_column_type (child_model, i);
2203 priv->sort_list = _gtk_tree_data_list_header_new (n_columns, types);
2206 priv->default_sort_func = NO_SORT_FUNC;
2207 priv->stamp = g_random_int ();
2212 * gtk_tree_model_sort_get_model:
2213 * @tree_model: a #GtkTreeModelSort
2215 * Returns the model the #GtkTreeModelSort is sorting.
2217 * Return value: (transfer none): the "child model" being sorted
2220 gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model)
2222 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
2224 return tree_model->priv->child_model;
2228 static GtkTreePath *
2229 gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2230 GtkTreePath *child_path,
2231 gboolean build_levels)
2233 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2234 gint *child_indices;
2235 GtkTreePath *retval;
2239 g_return_val_if_fail (priv->child_model != NULL, NULL);
2240 g_return_val_if_fail (child_path != NULL, NULL);
2242 retval = gtk_tree_path_new ();
2243 child_indices = gtk_tree_path_get_indices (child_path);
2245 if (priv->root == NULL && build_levels)
2246 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
2247 level = SORT_LEVEL (priv->root);
2249 for (i = 0; i < gtk_tree_path_get_depth (child_path); i++)
2252 GSequenceIter *siter;
2253 gboolean found_child = FALSE;
2257 gtk_tree_path_free (retval);
2261 if (child_indices[i] >= g_sequence_get_length (level->seq))
2263 gtk_tree_path_free (retval);
2266 tmp = lookup_elt_with_offset (tree_model_sort, level,
2267 child_indices[i], &siter);
2270 gtk_tree_path_append_index (retval, g_sequence_iter_get_position (siter));
2271 if (tmp->children == NULL && build_levels)
2272 gtk_tree_model_sort_build_level (tree_model_sort, level, tmp);
2274 level = tmp->children;
2280 gtk_tree_path_free (retval);
2290 * gtk_tree_model_sort_convert_child_path_to_path:
2291 * @tree_model_sort: A #GtkTreeModelSort
2292 * @child_path: A #GtkTreePath to convert
2294 * Converts @child_path to a path relative to @tree_model_sort. That is,
2295 * @child_path points to a path in the child model. The returned path will
2296 * point to the same row in the sorted model. If @child_path isn't a valid
2297 * path on the child model, then %NULL is returned.
2299 * Return value: A newly allocated #GtkTreePath, or %NULL
2302 gtk_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2303 GtkTreePath *child_path)
2305 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2306 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, NULL);
2307 g_return_val_if_fail (child_path != NULL, NULL);
2309 return gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path, TRUE);
2313 * gtk_tree_model_sort_convert_child_iter_to_iter:
2314 * @tree_model_sort: A #GtkTreeModelSort
2315 * @sort_iter: (out): An uninitialized #GtkTreeIter.
2316 * @child_iter: A valid #GtkTreeIter pointing to a row on the child model
2318 * Sets @sort_iter to point to the row in @tree_model_sort that corresponds to
2319 * the row pointed at by @child_iter. If @sort_iter was not set, %FALSE
2320 * is returned. Note: a boolean is only returned since 2.14.
2322 * Return value: %TRUE, if @sort_iter was set, i.e. if @sort_iter is a
2323 * valid iterator pointer to a visible row in the child model.
2326 gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sort,
2327 GtkTreeIter *sort_iter,
2328 GtkTreeIter *child_iter)
2331 GtkTreePath *child_path, *path;
2332 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2334 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2335 g_return_val_if_fail (priv->child_model != NULL, FALSE);
2336 g_return_val_if_fail (sort_iter != NULL, FALSE);
2337 g_return_val_if_fail (child_iter != NULL, FALSE);
2338 g_return_val_if_fail (sort_iter != child_iter, FALSE);
2340 sort_iter->stamp = 0;
2342 child_path = gtk_tree_model_get_path (priv->child_model, child_iter);
2343 g_return_val_if_fail (child_path != NULL, FALSE);
2345 path = gtk_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path);
2346 gtk_tree_path_free (child_path);
2350 g_warning ("%s: The conversion of the child path to a GtkTreeModel sort path failed", G_STRLOC);
2354 ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
2356 gtk_tree_path_free (path);
2362 * gtk_tree_model_sort_convert_path_to_child_path:
2363 * @tree_model_sort: A #GtkTreeModelSort
2364 * @sorted_path: A #GtkTreePath to convert
2366 * Converts @sorted_path to a path on the child model of @tree_model_sort.
2367 * That is, @sorted_path points to a location in @tree_model_sort. The
2368 * returned path will point to the same location in the model not being
2369 * sorted. If @sorted_path does not point to a location in the child model,
2370 * %NULL is returned.
2372 * Return value: A newly allocated #GtkTreePath, or %NULL
2375 gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sort,
2376 GtkTreePath *sorted_path)
2378 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2379 gint *sorted_indices;
2380 GtkTreePath *retval;
2384 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2385 g_return_val_if_fail (priv->child_model != NULL, NULL);
2386 g_return_val_if_fail (sorted_path != NULL, NULL);
2388 retval = gtk_tree_path_new ();
2389 sorted_indices = gtk_tree_path_get_indices (sorted_path);
2390 if (priv->root == NULL)
2391 gtk_tree_model_sort_build_level (tree_model_sort, NULL, NULL);
2392 level = SORT_LEVEL (priv->root);
2394 for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++)
2396 SortElt *elt = NULL;
2397 GSequenceIter *siter;
2399 if ((level == NULL) ||
2400 (g_sequence_get_length (level->seq) <= sorted_indices[i]))
2402 gtk_tree_path_free (retval);
2406 siter = g_sequence_get_iter_at_pos (level->seq, sorted_indices[i]);
2407 if (g_sequence_iter_is_end (siter))
2409 gtk_tree_path_free (retval);
2413 elt = GET_ELT (siter);
2414 if (elt->children == NULL)
2415 gtk_tree_model_sort_build_level (tree_model_sort, level, elt);
2419 gtk_tree_path_free (retval);
2423 gtk_tree_path_append_index (retval, elt->offset);
2424 level = elt->children;
2431 * gtk_tree_model_sort_convert_iter_to_child_iter:
2432 * @tree_model_sort: A #GtkTreeModelSort
2433 * @child_iter: (out): An uninitialized #GtkTreeIter
2434 * @sorted_iter: A valid #GtkTreeIter pointing to a row on @tree_model_sort.
2436 * Sets @child_iter to point to the row pointed to by @sorted_iter.
2439 gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sort,
2440 GtkTreeIter *child_iter,
2441 GtkTreeIter *sorted_iter)
2443 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2444 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2445 g_return_if_fail (priv->child_model != NULL);
2446 g_return_if_fail (child_iter != NULL);
2447 g_return_if_fail (VALID_ITER (sorted_iter, tree_model_sort));
2448 g_return_if_fail (sorted_iter != child_iter);
2450 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2452 *child_iter = SORT_ELT (sorted_iter->user_data2)->iter;
2457 gboolean valid = FALSE;
2459 path = gtk_tree_model_sort_elt_get_path (sorted_iter->user_data,
2460 sorted_iter->user_data2);
2461 valid = gtk_tree_model_get_iter (priv->child_model, child_iter, path);
2462 gtk_tree_path_free (path);
2464 g_return_if_fail (valid == TRUE);
2469 gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
2470 SortLevel *parent_level,
2471 SortElt *parent_elt)
2473 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2475 SortLevel *new_level;
2479 g_assert (priv->child_model != NULL);
2481 if (parent_level == NULL)
2483 if (gtk_tree_model_get_iter_first (priv->child_model, &iter) == FALSE)
2485 length = gtk_tree_model_iter_n_children (priv->child_model, NULL);
2489 GtkTreeIter parent_iter;
2490 GtkTreeIter child_parent_iter;
2492 parent_iter.stamp = priv->stamp;
2493 parent_iter.user_data = parent_level;
2494 parent_iter.user_data2 = parent_elt;
2496 gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2499 if (gtk_tree_model_iter_children (priv->child_model,
2501 &child_parent_iter) == FALSE)
2504 /* stamp may have changed */
2505 gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2509 length = gtk_tree_model_iter_n_children (priv->child_model, &child_parent_iter);
2511 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort),
2515 g_return_if_fail (length > 0);
2517 new_level = g_new (SortLevel, 1);
2518 new_level->seq = g_sequence_new (sort_elt_free);
2519 new_level->ref_count = 0;
2520 new_level->parent_level = parent_level;
2521 new_level->parent_elt = parent_elt;
2524 parent_elt->children = new_level;
2526 priv->root = new_level;
2528 /* increase the count of zero ref_counts.*/
2529 while (parent_level)
2531 parent_elt->zero_ref_count++;
2533 parent_elt = parent_level->parent_elt;
2534 parent_level = parent_level->parent_level;
2537 if (new_level != priv->root)
2538 priv->zero_ref_count++;
2540 for (i = 0; i < length; i++)
2544 sort_elt = sort_elt_new ();
2545 sort_elt->offset = i;
2546 sort_elt->zero_ref_count = 0;
2547 sort_elt->ref_count = 0;
2548 sort_elt->children = NULL;
2550 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2552 sort_elt->iter = iter;
2553 if (gtk_tree_model_iter_next (priv->child_model, &iter) == FALSE &&
2561 level = gtk_tree_model_sort_elt_get_path (parent_level,
2563 str = gtk_tree_path_to_string (level);
2564 gtk_tree_path_free (level);
2566 g_warning ("%s: There is a discrepancy between the sort model "
2567 "and the child model. The child model is "
2568 "advertising a wrong length for level %s:.",
2574 g_warning ("%s: There is a discrepancy between the sort model "
2575 "and the child model. The child model is "
2576 "advertising a wrong length for the root level.",
2584 sort_elt->siter = g_sequence_append (new_level->seq, sort_elt);
2588 gtk_tree_model_sort_sort_level (tree_model_sort, new_level,
2593 gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
2594 SortLevel *sort_level,
2597 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2598 GSequenceIter *siter;
2599 GSequenceIter *end_siter;
2601 g_assert (sort_level);
2603 end_siter = g_sequence_get_end_iter (sort_level->seq);
2604 for (siter = g_sequence_get_begin_iter (sort_level->seq);
2606 siter = g_sequence_iter_next (siter))
2608 SortElt *elt = g_sequence_get (siter);
2611 gtk_tree_model_sort_free_level (tree_model_sort,
2612 elt->children, unref);
2615 if (sort_level->ref_count == 0)
2617 SortLevel *parent_level = sort_level->parent_level;
2618 SortElt *parent_elt = sort_level->parent_elt;
2620 while (parent_level)
2622 parent_elt->zero_ref_count--;
2624 parent_elt = parent_level->parent_elt;
2625 parent_level = parent_level->parent_level;
2628 if (sort_level != priv->root)
2629 priv->zero_ref_count--;
2632 if (sort_level->parent_elt)
2636 GtkTreeIter parent_iter;
2638 parent_iter.stamp = tree_model_sort->priv->stamp;
2639 parent_iter.user_data = sort_level->parent_level;
2640 parent_iter.user_data2 = sort_level->parent_elt;
2642 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort),
2646 sort_level->parent_elt->children = NULL;
2651 g_sequence_free (sort_level->seq);
2652 sort_level->seq = NULL;
2654 g_free (sort_level);
2659 gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort)
2661 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2667 while (priv->stamp == 0);
2669 gtk_tree_model_sort_clear_cache (tree_model_sort);
2673 gtk_tree_model_sort_clear_cache_helper_iter (gpointer data,
2676 GtkTreeModelSort *tree_model_sort = user_data;
2677 SortElt *elt = data;
2679 if (elt->zero_ref_count > 0)
2680 gtk_tree_model_sort_clear_cache_helper (tree_model_sort, elt->children);
2684 gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
2687 g_assert (level != NULL);
2689 g_sequence_foreach (level->seq, gtk_tree_model_sort_clear_cache_helper_iter,
2692 if (level->ref_count == 0 && level != tree_model_sort->priv->root)
2693 gtk_tree_model_sort_free_level (tree_model_sort, level, TRUE);
2697 * gtk_tree_model_sort_reset_default_sort_func:
2698 * @tree_model_sort: A #GtkTreeModelSort
2700 * This resets the default sort function to be in the 'unsorted' state. That
2701 * is, it is in the same order as the child model. It will re-sort the model
2702 * to be in the same order as the child model only if the #GtkTreeModelSort
2703 * is in 'unsorted' state.
2706 gtk_tree_model_sort_reset_default_sort_func (GtkTreeModelSort *tree_model_sort)
2708 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2710 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2712 if (priv->default_sort_destroy)
2714 GDestroyNotify d = priv->default_sort_destroy;
2716 priv->default_sort_destroy = NULL;
2717 d (priv->default_sort_data);
2720 priv->default_sort_func = NO_SORT_FUNC;
2721 priv->default_sort_data = NULL;
2722 priv->default_sort_destroy = NULL;
2724 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
2725 gtk_tree_model_sort_sort (tree_model_sort);
2726 priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
2730 * gtk_tree_model_sort_clear_cache:
2731 * @tree_model_sort: A #GtkTreeModelSort
2733 * This function should almost never be called. It clears the @tree_model_sort
2734 * of any cached iterators that haven't been reffed with
2735 * gtk_tree_model_ref_node(). This might be useful if the child model being
2736 * sorted is static (and doesn't change often) and there has been a lot of
2737 * unreffed access to nodes. As a side effect of this function, all unreffed
2738 * iters will be invalid.
2741 gtk_tree_model_sort_clear_cache (GtkTreeModelSort *tree_model_sort)
2743 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2745 if (tree_model_sort->priv->zero_ref_count > 0)
2746 gtk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->priv->root);
2750 gtk_tree_model_sort_iter_is_valid_helper (GtkTreeIter *iter,
2753 GSequenceIter *siter;
2754 GSequenceIter *end_siter;
2756 end_siter = g_sequence_get_end_iter (level->seq);
2757 for (siter = g_sequence_get_begin_iter (level->seq);
2758 siter != end_siter; siter = g_sequence_iter_next (siter))
2760 SortElt *elt = g_sequence_get (siter);
2762 if (iter->user_data == level && iter->user_data2 == elt)
2766 if (gtk_tree_model_sort_iter_is_valid_helper (iter, elt->children))
2774 * gtk_tree_model_sort_iter_is_valid:
2775 * @tree_model_sort: A #GtkTreeModelSort.
2776 * @iter: A #GtkTreeIter.
2779 * This function is slow. Only use it for debugging and/or testing purposes.
2782 * Checks if the given iter is a valid iter for this #GtkTreeModelSort.
2784 * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
2789 gtk_tree_model_sort_iter_is_valid (GtkTreeModelSort *tree_model_sort,
2792 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2793 g_return_val_if_fail (iter != NULL, FALSE);
2795 if (!VALID_ITER (iter, tree_model_sort))
2798 return gtk_tree_model_sort_iter_is_valid_helper (iter,
2799 tree_model_sort->priv->root);