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
34 /* WARNING: this code is dangerous, can cause sleepless nights,
35 * can cause your dog to die among other bad things
37 * we warned you and we're not liable for any head injuries.
43 #include "gtktreemodelsort.h"
44 #include "gtktreesortable.h"
45 #include "gtktreestore.h"
46 #include "gtktreedatalist.h"
48 #include "gtkprivate.h"
49 #include "gtktreednd.h"
52 typedef struct _SortElt SortElt;
53 typedef struct _SortLevel SortLevel;
54 typedef struct _SortData SortData;
55 typedef struct _SortTuple SortTuple;
70 gint parent_elt_index;
71 SortLevel *parent_level;
76 GtkTreeModelSort *tree_model_sort;
77 GtkTreePath *parent_path;
78 gint parent_path_depth;
79 gint *parent_path_indices;
80 GtkTreeIterCompareFunc sort_func;
98 struct _GtkTreeModelSortPrivate
103 GtkTreeModel *child_model;
106 /* sort information */
112 GtkTreeIterCompareFunc default_sort_func;
113 gpointer default_sort_data;
114 GDestroyNotify default_sort_destroy;
119 gulong has_child_toggled_id;
125 #define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) \
126 (((GtkTreeModelSort *)tree_model_sort)->priv->child_flags>K_TREE_MODEL_ITERS_PERSIST)
127 #define SORT_ELT(sort_elt) ((SortElt *)sort_elt)
128 #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level)
130 #define SORT_LEVEL_PARENT_ELT(level) (&g_array_index (SORT_LEVEL ((level))->parent_level->array, SortElt, SORT_LEVEL ((level))->parent_elt_index))
131 #define SORT_LEVEL_ELT_INDEX(level, elt) (SORT_ELT ((elt)) - SORT_ELT (SORT_LEVEL ((level))->array->data))
134 #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));
136 #define NO_SORT_FUNC ((GtkTreeIterCompareFunc) 0x1)
138 #define VALID_ITER(iter, tree_model_sort) ((iter) != NULL && (iter)->user_data != NULL && (iter)->user_data2 != NULL && (tree_model_sort)->priv->stamp == (iter)->stamp)
140 /* general (object/interface init, etc) */
141 static void gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface);
142 static void gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface);
143 static void gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface*iface);
144 static void gtk_tree_model_sort_finalize (GObject *object);
145 static void gtk_tree_model_sort_set_property (GObject *object,
149 static void gtk_tree_model_sort_get_property (GObject *object,
154 /* our signal handlers */
155 static void gtk_tree_model_sort_row_changed (GtkTreeModel *model,
156 GtkTreePath *start_path,
157 GtkTreeIter *start_iter,
159 static void gtk_tree_model_sort_row_inserted (GtkTreeModel *model,
163 static void gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *model,
167 static void gtk_tree_model_sort_row_deleted (GtkTreeModel *model,
170 static void gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
176 /* TreeModel interface */
177 static GtkTreeModelFlags gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model);
178 static gint gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model);
179 static GType gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
181 static gboolean gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
184 static GtkTreePath *gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
186 static void gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
190 static gboolean gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
192 static gboolean gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
194 static gboolean gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
196 GtkTreeIter *parent);
197 static gboolean gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
199 static gint gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
201 static gboolean gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
205 static gboolean gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
208 static void gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
210 static void gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
212 gboolean propagate_unref);
213 static void gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
216 /* TreeDragSource interface */
217 static gboolean gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
219 static gboolean gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
221 GtkSelectionData *selection_data);
222 static gboolean gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
225 /* TreeSortable interface */
226 static gboolean gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
227 gint *sort_column_id,
229 static void gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
232 static void gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
234 GtkTreeIterCompareFunc func,
236 GDestroyNotify destroy);
237 static void gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
238 GtkTreeIterCompareFunc func,
240 GDestroyNotify destroy);
241 static gboolean gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable);
243 /* Private functions (sort funcs, level handling and other utils) */
244 static void gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
245 SortLevel *parent_level,
246 gint parent_elt_index);
247 static void gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
248 SortLevel *sort_level);
249 static void gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort);
250 static void gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
253 gboolean emit_reordered);
254 static void gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort);
255 static gint gtk_tree_model_sort_level_find_insert (GtkTreeModelSort *tree_model_sort,
259 static gboolean gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
262 GtkTreeIter *s_iter);
263 static GtkTreePath *gtk_tree_model_sort_elt_get_path (SortLevel *level,
265 static void gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
266 GtkTreeModel *child_model);
267 static GtkTreePath *gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
268 GtkTreePath *child_path,
269 gboolean build_levels);
272 G_DEFINE_TYPE_WITH_CODE (GtkTreeModelSort, gtk_tree_model_sort, G_TYPE_OBJECT,
273 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
274 gtk_tree_model_sort_tree_model_init)
275 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
276 gtk_tree_model_sort_tree_sortable_init)
277 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
278 gtk_tree_model_sort_drag_source_init))
281 gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
283 GtkTreeModelSortPrivate *priv;
285 priv = G_TYPE_INSTANCE_GET_PRIVATE (tree_model_sort,
286 GTK_TYPE_TREE_MODEL_SORT,
287 GtkTreeModelSortPrivate);
288 tree_model_sort->priv = priv;
289 priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
291 priv->zero_ref_count = 0;
293 priv->sort_list = NULL;
297 gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
299 GObjectClass *object_class;
301 object_class = (GObjectClass *) class;
303 object_class->set_property = gtk_tree_model_sort_set_property;
304 object_class->get_property = gtk_tree_model_sort_get_property;
306 object_class->finalize = gtk_tree_model_sort_finalize;
309 g_object_class_install_property (object_class,
311 g_param_spec_object ("model",
312 P_("TreeModelSort Model"),
313 P_("The model for the TreeModelSort to sort"),
315 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
317 g_type_class_add_private (class, sizeof (GtkTreeModelSortPrivate));
321 gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
323 iface->get_flags = gtk_tree_model_sort_get_flags;
324 iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
325 iface->get_column_type = gtk_tree_model_sort_get_column_type;
326 iface->get_iter = gtk_tree_model_sort_get_iter;
327 iface->get_path = gtk_tree_model_sort_get_path;
328 iface->get_value = gtk_tree_model_sort_get_value;
329 iface->iter_next = gtk_tree_model_sort_iter_next;
330 iface->iter_previous = gtk_tree_model_sort_iter_previous;
331 iface->iter_children = gtk_tree_model_sort_iter_children;
332 iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
333 iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
334 iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
335 iface->iter_parent = gtk_tree_model_sort_iter_parent;
336 iface->ref_node = gtk_tree_model_sort_ref_node;
337 iface->unref_node = gtk_tree_model_sort_unref_node;
341 gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface)
343 iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id;
344 iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id;
345 iface->set_sort_func = gtk_tree_model_sort_set_sort_func;
346 iface->set_default_sort_func = gtk_tree_model_sort_set_default_sort_func;
347 iface->has_default_sort_func = gtk_tree_model_sort_has_default_sort_func;
351 gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface *iface)
353 iface->row_draggable = gtk_tree_model_sort_row_draggable;
354 iface->drag_data_delete = gtk_tree_model_sort_drag_data_delete;
355 iface->drag_data_get = gtk_tree_model_sort_drag_data_get;
359 * gtk_tree_model_sort_new_with_model:
360 * @child_model: A #GtkTreeModel
362 * Creates a new #GtkTreeModel, with @child_model as the child model.
364 * Return value: (transfer full): A new #GtkTreeModel.
367 gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model)
369 GtkTreeModel *retval;
371 g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
373 retval = g_object_new (gtk_tree_model_sort_get_type (), NULL);
375 gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model);
380 /* GObject callbacks */
382 gtk_tree_model_sort_finalize (GObject *object)
384 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
385 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
387 gtk_tree_model_sort_set_model (tree_model_sort, NULL);
390 gtk_tree_model_sort_free_level (tree_model_sort, priv->root);
394 _gtk_tree_data_list_header_free (priv->sort_list);
395 priv->sort_list = NULL;
398 if (priv->default_sort_destroy)
400 priv->default_sort_destroy (priv->default_sort_data);
401 priv->default_sort_destroy = NULL;
402 priv->default_sort_data = NULL;
407 G_OBJECT_CLASS (gtk_tree_model_sort_parent_class)->finalize (object);
411 gtk_tree_model_sort_set_property (GObject *object,
416 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
421 gtk_tree_model_sort_set_model (tree_model_sort, g_value_get_object (value));
424 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
430 gtk_tree_model_sort_get_property (GObject *object,
435 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
440 g_value_set_object (value, gtk_tree_model_sort_get_model (tree_model_sort));
443 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
449 gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
450 GtkTreePath *start_s_path,
451 GtkTreeIter *start_s_iter,
454 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
455 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
456 GtkTreePath *path = NULL;
464 gboolean free_s_path = FALSE;
466 gint index = 0, old_index, i;
468 g_return_if_fail (start_s_path != NULL || start_s_iter != NULL);
473 start_s_path = gtk_tree_model_get_path (s_model, start_s_iter);
476 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
482 gtk_tree_path_free (start_s_path);
486 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
487 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (data), &iter);
489 level = iter.user_data;
490 elt = iter.user_data2;
492 if (level->array->len < 2 ||
493 (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
494 priv->default_sort_func == NO_SORT_FUNC))
497 gtk_tree_path_free (start_s_path);
499 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
500 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
502 gtk_tree_path_free (path);
507 if (!GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
509 gtk_tree_model_get_iter (priv->child_model,
510 &tmpiter, start_s_path);
513 old_index = elt - SORT_ELT (level->array->data);
515 memcpy (&tmp, elt, sizeof (SortElt));
517 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
518 index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
523 index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
528 if (index < old_index)
530 g_memmove (level->array->data + ((index + 1)*sizeof (SortElt)),
531 level->array->data + ((index)*sizeof (SortElt)),
532 (old_index - index)* sizeof(SortElt));
534 else if (index > old_index)
536 g_memmove (level->array->data + ((old_index)*sizeof (SortElt)),
537 level->array->data + ((old_index + 1)*sizeof (SortElt)),
538 (index - old_index)* sizeof(SortElt));
540 memcpy (level->array->data + ((index)*sizeof (SortElt)),
541 &tmp, sizeof (SortElt));
543 for (i = 0; i < level->array->len; i++)
544 if (g_array_index (level->array, SortElt, i).children)
545 g_array_index (level->array, SortElt, i).children->parent_elt_index = i;
547 gtk_tree_path_up (path);
548 gtk_tree_path_append_index (path, index);
550 gtk_tree_model_sort_increment_stamp (tree_model_sort);
552 /* if the item moved, then emit rows_reordered */
553 if (old_index != index)
558 GtkTreePath *tmppath;
560 new_order = g_new (gint, level->array->len);
562 for (j = 0; j < level->array->len; j++)
564 if (index > old_index)
567 new_order[j] = old_index;
568 else if (j >= old_index && j < index)
569 new_order[j] = j + 1;
573 else if (index < old_index)
576 new_order[j] = old_index;
577 else if (j > index && j <= old_index)
578 new_order[j] = j - 1;
582 /* else? shouldn't really happen */
585 if (level->parent_elt_index >= 0)
587 iter.stamp = priv->stamp;
588 iter.user_data = level->parent_level;
589 iter.user_data2 = SORT_LEVEL_PARENT_ELT (level);
591 tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter);
593 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
594 tmppath, &iter, new_order);
599 tmppath = gtk_tree_path_new ();
601 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), tmppath,
605 gtk_tree_path_free (tmppath);
609 /* emit row_changed signal (at new location) */
610 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
611 gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
612 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
614 gtk_tree_path_free (path);
616 gtk_tree_path_free (start_s_path);
620 gtk_tree_model_sort_row_inserted (GtkTreeModel *s_model,
625 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
626 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
629 GtkTreeIter real_s_iter;
633 gboolean free_s_path = FALSE;
637 SortLevel *parent_level = NULL;
639 parent_level = level = SORT_LEVEL (priv->root);
641 g_return_if_fail (s_path != NULL || s_iter != NULL);
645 s_path = gtk_tree_model_get_path (s_model, s_iter);
650 gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
652 real_s_iter = *s_iter;
656 gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
658 /* the build level already put the inserted iter in the level,
659 so no need to handle this signal anymore */
661 goto done_and_submit;
664 /* find the parent level */
665 while (i < gtk_tree_path_get_depth (s_path) - 1)
671 /* level not yet build, we won't cover this signal */
675 if (level->array->len < gtk_tree_path_get_indices (s_path)[i])
677 g_warning ("%s: A node was inserted with a parent that's not in the tree.\n"
678 "This possibly means that a GtkTreeModel inserted a child node\n"
679 "before the parent was inserted.",
685 for (j = 0; j < level->array->len; j++)
686 if (g_array_index (level->array, SortElt, j).offset == gtk_tree_path_get_indices (s_path)[i])
688 elt = &g_array_index (level->array, SortElt, j);
692 g_return_if_fail (elt != NULL);
696 /* not covering this signal */
700 level = elt->children;
701 parent_level = level;
708 if (level->ref_count == 0 && level != priv->root)
710 gtk_tree_model_sort_free_level (tree_model_sort, level);
714 if (!gtk_tree_model_sort_insert_value (tree_model_sort,
721 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
728 gtk_tree_model_sort_increment_stamp (tree_model_sort);
730 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
731 gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
732 gtk_tree_path_free (path);
736 gtk_tree_path_free (s_path);
742 gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *s_model,
747 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
751 g_return_if_fail (s_path != NULL && s_iter != NULL);
753 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
757 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
758 gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
760 gtk_tree_path_free (path);
764 gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
768 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
769 GtkTreePath *path = NULL;
776 g_return_if_fail (s_path != NULL);
778 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
782 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
784 level = SORT_LEVEL (iter.user_data);
785 elt = SORT_ELT (iter.user_data2);
786 offset = elt->offset;
788 /* we _need_ to emit ::row_deleted before we start unreffing the node
789 * itself. This is because of the row refs, which start unreffing nodes
790 * when we emit ::row_deleted
792 gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
794 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
796 while (elt->ref_count > 0)
797 gtk_tree_model_sort_real_unref_node (GTK_TREE_MODEL (data), &iter, FALSE);
799 if (level->ref_count == 0)
801 /* This will prune the level, so I can just emit the signal and
802 * not worry about cleaning this level up.
803 * Careful, root level is not cleaned up in increment stamp.
805 gtk_tree_model_sort_increment_stamp (tree_model_sort);
806 gtk_tree_path_free (path);
807 if (level == tree_model_sort->priv->root)
809 gtk_tree_model_sort_free_level (tree_model_sort,
810 tree_model_sort->priv->root);
811 tree_model_sort->priv->root = NULL;
816 gtk_tree_model_sort_increment_stamp (tree_model_sort);
819 for (i = 0; i < level->array->len; i++)
820 if (elt->offset == g_array_index (level->array, SortElt, i).offset)
823 g_array_remove_index (level->array, i);
825 /* update all offsets */
826 for (i = 0; i < level->array->len; i++)
828 elt = & (g_array_index (level->array, SortElt, i));
829 if (elt->offset > offset)
832 elt->children->parent_elt_index = i;
835 gtk_tree_path_free (path);
839 gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
851 GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
852 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
854 g_return_if_fail (new_order != NULL);
856 if (s_path == NULL || gtk_tree_path_get_depth (s_path) == 0)
858 if (priv->root == NULL)
860 path = gtk_tree_path_new ();
861 level = SORT_LEVEL (priv->root);
865 path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
868 gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
870 level = SORT_LEVEL (iter.user_data);
871 elt = SORT_ELT (iter.user_data2);
875 gtk_tree_path_free (path);
879 level = elt->children;
882 if (level->array->len < 2)
884 gtk_tree_path_free (path);
888 tmp_array = g_new (int, level->array->len);
889 for (i = 0; i < level->array->len; i++)
891 for (j = 0; j < level->array->len; j++)
893 if (g_array_index (level->array, SortElt, i).offset == new_order[j])
898 for (i = 0; i < level->array->len; i++)
899 g_array_index (level->array, SortElt, i).offset = tmp_array[i];
902 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
903 priv->default_sort_func == NO_SORT_FUNC)
906 gtk_tree_model_sort_sort_level (tree_model_sort, level,
908 gtk_tree_model_sort_increment_stamp (tree_model_sort);
910 if (gtk_tree_path_get_depth (path))
912 gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
915 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
916 path, &iter, new_order);
920 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
921 path, NULL, new_order);
925 gtk_tree_path_free (path);
928 /* Fulfill our model requirements */
929 static GtkTreeModelFlags
930 gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model)
932 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
933 GtkTreeModelFlags flags;
935 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, 0);
937 flags = gtk_tree_model_get_flags (tree_model_sort->priv->child_model);
939 if ((flags & GTK_TREE_MODEL_LIST_ONLY) == GTK_TREE_MODEL_LIST_ONLY)
940 return GTK_TREE_MODEL_LIST_ONLY;
946 gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
948 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
950 if (tree_model_sort->priv->child_model == 0)
953 return gtk_tree_model_get_n_columns (tree_model_sort->priv->child_model);
957 gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
960 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
962 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, G_TYPE_INVALID);
964 return gtk_tree_model_get_column_type (tree_model_sort->priv->child_model, index);
968 gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
972 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
973 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
978 g_return_val_if_fail (priv->child_model != NULL, FALSE);
980 indices = gtk_tree_path_get_indices (path);
982 if (priv->root == NULL)
983 gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
984 level = SORT_LEVEL (priv->root);
986 depth = gtk_tree_path_get_depth (path);
990 for (i = 0; i < depth - 1; i++)
992 if ((level == NULL) ||
993 (indices[i] >= level->array->len))
996 if (g_array_index (level->array, SortElt, indices[i]).children == NULL)
997 gtk_tree_model_sort_build_level (tree_model_sort, level, indices[i]);
998 level = g_array_index (level->array, SortElt, indices[i]).children;
1001 if (!level || indices[i] >= level->array->len)
1007 iter->stamp = priv->stamp;
1008 iter->user_data = level;
1009 iter->user_data2 = &g_array_index (level->array, SortElt, indices[depth - 1]);
1014 static GtkTreePath *
1015 gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
1018 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1019 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1020 GtkTreePath *retval;
1024 g_return_val_if_fail (priv->child_model != NULL, NULL);
1025 g_return_val_if_fail (priv->stamp == iter->stamp, NULL);
1027 retval = gtk_tree_path_new ();
1029 level = SORT_LEVEL (iter->user_data);
1030 elt_index = SORT_LEVEL_ELT_INDEX (level, iter->user_data2);
1034 gtk_tree_path_prepend_index (retval, elt_index);
1036 elt_index = level->parent_elt_index;
1037 level = level->parent_level;
1044 gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
1049 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1050 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1051 GtkTreeIter child_iter;
1053 g_return_if_fail (priv->child_model != NULL);
1054 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1056 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1057 gtk_tree_model_get_value (priv->child_model,
1058 &child_iter, column, value);
1062 gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
1065 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1066 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1070 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1071 g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1073 level = iter->user_data;
1074 elt = iter->user_data2;
1076 if (elt - (SortElt *)level->array->data >= level->array->len - 1)
1081 iter->user_data2 = elt + 1;
1087 gtk_tree_model_sort_iter_previous (GtkTreeModel *tree_model,
1090 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1091 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1095 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1096 g_return_val_if_fail (priv->stamp == iter->stamp, FALSE);
1098 level = iter->user_data;
1099 elt = iter->user_data2;
1101 if (elt == (SortElt *)level->array->data)
1106 iter->user_data2 = elt - 1;
1112 gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
1114 GtkTreeIter *parent)
1116 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1117 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1121 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1123 g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1127 if (priv->root == NULL)
1128 gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
1129 if (priv->root == NULL)
1133 iter->stamp = priv->stamp;
1134 iter->user_data = level;
1135 iter->user_data2 = level->array->data;
1141 level = SORT_LEVEL (parent->user_data);
1142 elt = SORT_ELT (parent->user_data2);
1144 if (elt->children == NULL)
1145 gtk_tree_model_sort_build_level (tree_model_sort, level,
1146 SORT_LEVEL_ELT_INDEX (level, elt));
1148 if (elt->children == NULL)
1151 iter->stamp = priv->stamp;
1152 iter->user_data = elt->children;
1153 iter->user_data2 = elt->children->array->data;
1160 gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
1163 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1164 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1165 GtkTreeIter child_iter;
1167 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1168 g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), FALSE);
1170 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1172 return gtk_tree_model_iter_has_child (priv->child_model, &child_iter);
1176 gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
1179 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1180 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1181 GtkTreeIter child_iter;
1183 g_return_val_if_fail (priv->child_model != NULL, 0);
1185 g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), 0);
1188 return gtk_tree_model_iter_n_children (priv->child_model, NULL);
1190 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1192 return gtk_tree_model_iter_n_children (priv->child_model, &child_iter);
1196 gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
1198 GtkTreeIter *parent,
1201 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1203 /* We have this for the iter == parent case */
1204 GtkTreeIter children;
1207 g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1209 /* Use this instead of has_child to force us to build the level, if needed */
1210 if (gtk_tree_model_sort_iter_children (tree_model, &children, parent) == FALSE)
1216 level = children.user_data;
1217 if (n >= level->array->len)
1223 iter->stamp = tree_model_sort->priv->stamp;
1224 iter->user_data = level;
1225 iter->user_data2 = &g_array_index (level->array, SortElt, n);
1231 gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
1235 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1236 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1240 g_return_val_if_fail (priv->child_model != NULL, FALSE);
1241 g_return_val_if_fail (VALID_ITER (child, tree_model_sort), FALSE);
1243 level = child->user_data;
1245 if (level->parent_level)
1247 iter->stamp = priv->stamp;
1248 iter->user_data = level->parent_level;
1249 iter->user_data2 = SORT_LEVEL_PARENT_ELT (level);
1257 gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
1260 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1261 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1262 GtkTreeIter child_iter;
1263 SortLevel *level, *parent_level;
1265 gint parent_elt_index;
1267 g_return_if_fail (priv->child_model != NULL);
1268 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1270 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1272 /* Reference the node in the child model */
1273 gtk_tree_model_ref_node (priv->child_model, &child_iter);
1275 /* Increase the reference count of this element and its level */
1276 level = iter->user_data;
1277 elt = iter->user_data2;
1282 /* Increase the reference count of all parent elements */
1283 parent_level = level->parent_level;
1284 parent_elt_index = level->parent_elt_index;
1286 while (parent_level)
1288 GtkTreeIter tmp_iter;
1290 tmp_iter.stamp = priv->stamp;
1291 tmp_iter.user_data = parent_level;
1292 tmp_iter.user_data2 = &g_array_index (parent_level->array, SortElt, parent_elt_index);
1294 gtk_tree_model_sort_ref_node (tree_model, &tmp_iter);
1296 parent_elt_index = parent_level->parent_elt_index;
1297 parent_level = parent_level->parent_level;
1300 if (level->ref_count == 1)
1302 SortLevel *parent_level = level->parent_level;
1303 gint parent_elt_index = level->parent_elt_index;
1305 /* We were at zero -- time to decrement the zero_ref_count val */
1306 while (parent_level)
1308 g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count--;
1310 parent_elt_index = parent_level->parent_elt_index;
1311 parent_level = parent_level->parent_level;
1314 if (priv->root != level)
1315 priv->zero_ref_count--;
1320 gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
1322 gboolean propagate_unref)
1324 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1325 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1326 SortLevel *level, *parent_level;
1328 gint parent_elt_index;
1330 g_return_if_fail (priv->child_model != NULL);
1331 g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1333 if (propagate_unref)
1335 GtkTreeIter child_iter;
1337 GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1338 gtk_tree_model_unref_node (priv->child_model, &child_iter);
1341 level = iter->user_data;
1342 elt = iter->user_data2;
1344 g_return_if_fail (elt->ref_count > 0);
1349 /* Decrease the reference count of all parent elements */
1350 parent_level = level->parent_level;
1351 parent_elt_index = level->parent_elt_index;
1353 while (parent_level)
1355 GtkTreeIter tmp_iter;
1357 tmp_iter.stamp = priv->stamp;
1358 tmp_iter.user_data = parent_level;
1359 tmp_iter.user_data2 = &g_array_index (parent_level->array, SortElt, parent_elt_index);
1361 gtk_tree_model_sort_real_unref_node (tree_model, &tmp_iter, FALSE);
1363 parent_elt_index = parent_level->parent_elt_index;
1364 parent_level = parent_level->parent_level;
1367 if (level->ref_count == 0)
1369 SortLevel *parent_level = level->parent_level;
1370 gint parent_elt_index = level->parent_elt_index;
1372 /* We are at zero -- time to increment the zero_ref_count val */
1373 while (parent_level)
1375 g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count++;
1377 parent_elt_index = parent_level->parent_elt_index;
1378 parent_level = parent_level->parent_level;
1381 if (priv->root != level)
1382 priv->zero_ref_count++;
1387 gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
1390 gtk_tree_model_sort_real_unref_node (tree_model, iter, TRUE);
1393 /* Sortable interface */
1395 gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
1396 gint *sort_column_id,
1399 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1400 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1403 *sort_column_id = priv->sort_column_id;
1405 *order = priv->order;
1407 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
1408 priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1415 gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
1416 gint sort_column_id,
1419 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1420 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1422 if (sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1424 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1426 GtkTreeDataSortHeader *header = NULL;
1428 header = _gtk_tree_data_list_get_header (priv->sort_list,
1431 /* we want to make sure that we have a function */
1432 g_return_if_fail (header != NULL);
1433 g_return_if_fail (header->func != NULL);
1436 g_return_if_fail (priv->default_sort_func != NULL);
1438 if (priv->sort_column_id == sort_column_id)
1440 if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1442 if (priv->order == order)
1450 priv->sort_column_id = sort_column_id;
1451 priv->order = order;
1453 gtk_tree_sortable_sort_column_changed (sortable);
1455 gtk_tree_model_sort_sort (tree_model_sort);
1459 gtk_tree_model_sort_set_sort_func (GtkTreeSortable *sortable,
1460 gint sort_column_id,
1461 GtkTreeIterCompareFunc func,
1463 GDestroyNotify destroy)
1465 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1466 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1468 priv->sort_list = _gtk_tree_data_list_set_header (priv->sort_list,
1470 func, data, destroy);
1472 if (priv->sort_column_id == sort_column_id)
1473 gtk_tree_model_sort_sort (tree_model_sort);
1477 gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable *sortable,
1478 GtkTreeIterCompareFunc func,
1480 GDestroyNotify destroy)
1482 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1483 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1485 if (priv->default_sort_destroy)
1487 GDestroyNotify d = priv->default_sort_destroy;
1489 priv->default_sort_destroy = NULL;
1490 d (priv->default_sort_data);
1493 priv->default_sort_func = func;
1494 priv->default_sort_data = data;
1495 priv->default_sort_destroy = destroy;
1497 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1498 gtk_tree_model_sort_sort (tree_model_sort);
1502 gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable)
1504 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1506 return (tree_model_sort->priv->default_sort_func != NULL);
1509 /* DragSource interface */
1511 gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
1514 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1515 GtkTreePath *child_path;
1518 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort,
1520 draggable = gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1521 gtk_tree_path_free (child_path);
1527 gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
1529 GtkSelectionData *selection_data)
1531 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1532 GtkTreePath *child_path;
1535 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1536 gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path, selection_data);
1537 gtk_tree_path_free (child_path);
1543 gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
1546 GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1547 GtkTreePath *child_path;
1550 child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1551 deleted = gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (tree_model_sort->priv->child_model), child_path);
1552 gtk_tree_path_free (child_path);
1557 /* sorting code - private */
1559 gtk_tree_model_sort_compare_func (gconstpointer a,
1563 SortData *data = (SortData *)user_data;
1564 GtkTreeModelSort *tree_model_sort = data->tree_model_sort;
1565 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1566 SortTuple *sa = (SortTuple *)a;
1567 SortTuple *sb = (SortTuple *)b;
1569 GtkTreeIter iter_a, iter_b;
1572 /* shortcut, if we've the same offsets here, they should be equal */
1573 if (sa->offset == sb->offset)
1576 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1578 iter_a = sa->elt->iter;
1579 iter_b = sb->elt->iter;
1583 data->parent_path_indices [data->parent_path_depth-1] = sa->elt->offset;
1584 gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_a, data->parent_path);
1585 data->parent_path_indices [data->parent_path_depth-1] = sb->elt->offset;
1586 gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->child_model), &iter_b, data->parent_path);
1589 retval = (* data->sort_func) (GTK_TREE_MODEL (priv->child_model),
1593 if (priv->order == GTK_SORT_DESCENDING)
1597 else if (retval < 0)
1605 gtk_tree_model_sort_offset_compare_func (gconstpointer a,
1611 SortTuple *sa = (SortTuple *)a;
1612 SortTuple *sb = (SortTuple *)b;
1614 SortData *data = (SortData *)user_data;
1616 if (sa->elt->offset < sb->elt->offset)
1618 else if (sa->elt->offset > sb->elt->offset)
1623 if (data->tree_model_sort->priv->order == GTK_SORT_DESCENDING)
1627 else if (retval < 0)
1635 gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
1638 gboolean emit_reordered)
1640 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1652 g_return_if_fail (level != NULL);
1654 if (level->array->len < 1 && !((SortElt *)level->array->data)->children)
1657 iter.stamp = priv->stamp;
1658 iter.user_data = level;
1659 iter.user_data2 = &g_array_index (level->array, SortElt, 0);
1661 gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1662 ref_offset = g_array_index (level->array, SortElt, 0).offset;
1665 data.tree_model_sort = tree_model_sort;
1666 if (level->parent_elt_index >= 0)
1668 data.parent_path = gtk_tree_model_sort_elt_get_path (level->parent_level,
1669 SORT_LEVEL_PARENT_ELT (level));
1670 gtk_tree_path_append_index (data.parent_path, 0);
1674 data.parent_path = gtk_tree_path_new_first ();
1676 data.parent_path_depth = gtk_tree_path_get_depth (data.parent_path);
1677 data.parent_path_indices = gtk_tree_path_get_indices (data.parent_path);
1679 /* make the array to be sorted */
1680 sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), level->array->len);
1681 for (i = 0; i < level->array->len; i++)
1685 tuple.elt = &g_array_index (level->array, SortElt, i);
1688 g_array_append_val (sort_array, tuple);
1691 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1693 GtkTreeDataSortHeader *header = NULL;
1695 header = _gtk_tree_data_list_get_header (priv->sort_list,
1696 priv->sort_column_id);
1698 g_return_if_fail (header != NULL);
1699 g_return_if_fail (header->func != NULL);
1701 data.sort_func = header->func;
1702 data.sort_data = header->data;
1706 /* absolutely SHOULD NOT happen: */
1707 g_return_if_fail (priv->default_sort_func != NULL);
1709 data.sort_func = priv->default_sort_func;
1710 data.sort_data = priv->default_sort_data;
1713 if (data.sort_func == NO_SORT_FUNC)
1714 g_array_sort_with_data (sort_array,
1715 gtk_tree_model_sort_offset_compare_func,
1718 g_array_sort_with_data (sort_array,
1719 gtk_tree_model_sort_compare_func,
1722 gtk_tree_path_free (data.parent_path);
1724 new_array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), level->array->len);
1725 new_order = g_new (gint, level->array->len);
1727 for (i = 0; i < level->array->len; i++)
1731 elt = g_array_index (sort_array, SortTuple, i).elt;
1732 new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1734 g_array_append_val (new_array, *elt);
1736 elt->children->parent_elt_index = i;
1739 g_array_free (level->array, TRUE);
1740 level->array = new_array;
1741 g_array_free (sort_array, TRUE);
1745 gtk_tree_model_sort_increment_stamp (tree_model_sort);
1746 if (level->parent_elt_index >= 0)
1748 iter.stamp = priv->stamp;
1749 iter.user_data = level->parent_level;
1750 iter.user_data2 = SORT_LEVEL_PARENT_ELT (level);
1752 path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort),
1755 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1761 path = gtk_tree_path_new ();
1762 gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1766 gtk_tree_path_free (path);
1769 /* recurse, if possible */
1772 for (i = 0; i < level->array->len; i++)
1774 SortElt *elt = &g_array_index (level->array, SortElt, i);
1777 gtk_tree_model_sort_sort_level (tree_model_sort,
1779 TRUE, emit_reordered);
1785 /* get the iter we referenced at the beginning of this function and
1788 iter.stamp = priv->stamp;
1789 iter.user_data = level;
1791 for (i = 0; i < level->array->len; i++)
1793 if (g_array_index (level->array, SortElt, i).offset == ref_offset)
1795 iter.user_data2 = &g_array_index (level->array, SortElt, i);
1800 gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1804 gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort)
1806 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1808 if (priv->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1814 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1816 GtkTreeDataSortHeader *header = NULL;
1818 header = _gtk_tree_data_list_get_header (priv->sort_list,
1819 priv->sort_column_id);
1821 /* we want to make sure that we have a function */
1822 g_return_if_fail (header != NULL);
1823 g_return_if_fail (header->func != NULL);
1826 g_return_if_fail (priv->default_sort_func != NULL);
1828 gtk_tree_model_sort_sort_level (tree_model_sort, priv->root,
1832 /* signal helpers */
1834 gtk_tree_model_sort_level_find_insert (GtkTreeModelSort *tree_model_sort,
1839 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1840 gint start, middle, end;
1843 GtkTreeIter tmp_iter;
1845 GtkTreeIterCompareFunc func;
1848 if (priv->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1850 GtkTreeDataSortHeader *header;
1852 header = _gtk_tree_data_list_get_header (priv->sort_list,
1853 priv->sort_column_id);
1855 g_return_val_if_fail (header != NULL, 0);
1857 func = header->func;
1858 data = header->data;
1862 func = priv->default_sort_func;
1863 data = priv->default_sort_data;
1865 g_return_val_if_fail (func != NO_SORT_FUNC, 0);
1868 g_return_val_if_fail (func != NULL, 0);
1871 end = level->array->len;
1880 while (start != end)
1882 middle = (start + end) / 2;
1884 if (middle < skip_index)
1885 tmp_elt = &(g_array_index (level->array, SortElt, middle));
1887 tmp_elt = &(g_array_index (level->array, SortElt, middle + 1));
1889 if (!GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1891 GtkTreePath *path = gtk_tree_model_sort_elt_get_path (level, tmp_elt);
1892 gtk_tree_model_get_iter (priv->child_model,
1894 gtk_tree_path_free (path);
1897 tmp_iter = tmp_elt->iter;
1899 if (priv->order == GTK_SORT_ASCENDING)
1900 cmp = (* func) (GTK_TREE_MODEL (priv->child_model),
1901 &tmp_iter, iter, data);
1903 cmp = (* func) (GTK_TREE_MODEL (priv->child_model),
1904 iter, &tmp_iter, data);
1919 gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
1921 GtkTreePath *s_path,
1922 GtkTreeIter *s_iter)
1924 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
1925 gint offset, index, i;
1930 offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];
1932 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1934 elt.offset = offset;
1935 elt.zero_ref_count = 0;
1937 elt.children = NULL;
1939 /* update all larger offsets */
1940 tmp_elt = SORT_ELT (level->array->data);
1941 for (i = 0; i < level->array->len; i++, tmp_elt++)
1942 if (tmp_elt->offset >= offset)
1945 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
1946 priv->default_sort_func == NO_SORT_FUNC)
1949 index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
1953 g_array_insert_vals (level->array, index, &elt, 1);
1954 tmp_elt = SORT_ELT (level->array->data);
1955 for (i = 0; i < level->array->len; i++, tmp_elt++)
1956 if (tmp_elt->children)
1957 tmp_elt->children->parent_elt_index = i;
1962 /* sort elt stuff */
1963 static GtkTreePath *
1964 gtk_tree_model_sort_elt_get_path (SortLevel *level,
1967 SortLevel *walker = level;
1968 SortElt *walker2 = elt;
1971 g_return_val_if_fail (level != NULL, NULL);
1972 g_return_val_if_fail (elt != NULL, NULL);
1974 path = gtk_tree_path_new ();
1978 gtk_tree_path_prepend_index (path, walker2->offset);
1980 if (!walker->parent_level)
1983 walker2 = SORT_LEVEL_PARENT_ELT (walker);
1984 walker = walker->parent_level;
1991 * gtk_tree_model_sort_set_model:
1992 * @tree_model_sort: The #GtkTreeModelSort.
1993 * @child_model: (allow-none): A #GtkTreeModel, or %NULL.
1995 * Sets the model of @tree_model_sort to be @model. If @model is %NULL,
1996 * then the old model is unset. The sort function is unset as a result
1997 * of this call. The model will be in an unsorted state until a sort
2001 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
2002 GtkTreeModel *child_model)
2004 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2007 g_object_ref (child_model);
2009 if (priv->child_model)
2011 g_signal_handler_disconnect (priv->child_model,
2013 g_signal_handler_disconnect (priv->child_model,
2015 g_signal_handler_disconnect (priv->child_model,
2016 priv->has_child_toggled_id);
2017 g_signal_handler_disconnect (priv->child_model,
2019 g_signal_handler_disconnect (priv->child_model,
2020 priv->reordered_id);
2022 /* reset our state */
2024 gtk_tree_model_sort_free_level (tree_model_sort, priv->root);
2026 _gtk_tree_data_list_header_free (priv->sort_list);
2027 priv->sort_list = NULL;
2028 g_object_unref (priv->child_model);
2031 priv->child_model = child_model;
2039 g_signal_connect (child_model, "row-changed",
2040 G_CALLBACK (gtk_tree_model_sort_row_changed),
2043 g_signal_connect (child_model, "row-inserted",
2044 G_CALLBACK (gtk_tree_model_sort_row_inserted),
2046 priv->has_child_toggled_id =
2047 g_signal_connect (child_model, "row-has-child-toggled",
2048 G_CALLBACK (gtk_tree_model_sort_row_has_child_toggled),
2051 g_signal_connect (child_model, "row-deleted",
2052 G_CALLBACK (gtk_tree_model_sort_row_deleted),
2054 priv->reordered_id =
2055 g_signal_connect (child_model, "rows-reordered",
2056 G_CALLBACK (gtk_tree_model_sort_rows_reordered),
2059 priv->child_flags = gtk_tree_model_get_flags (child_model);
2060 n_columns = gtk_tree_model_get_n_columns (child_model);
2062 types = g_new (GType, n_columns);
2063 for (i = 0; i < n_columns; i++)
2064 types[i] = gtk_tree_model_get_column_type (child_model, i);
2066 priv->sort_list = _gtk_tree_data_list_header_new (n_columns, types);
2069 priv->default_sort_func = NO_SORT_FUNC;
2070 priv->stamp = g_random_int ();
2075 * gtk_tree_model_sort_get_model:
2076 * @tree_model: a #GtkTreeModelSort
2078 * Returns the model the #GtkTreeModelSort is sorting.
2080 * Return value: (transfer none): the "child model" being sorted
2083 gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model)
2085 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
2087 return tree_model->priv->child_model;
2091 static GtkTreePath *
2092 gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2093 GtkTreePath *child_path,
2094 gboolean build_levels)
2096 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2097 gint *child_indices;
2098 GtkTreePath *retval;
2102 g_return_val_if_fail (priv->child_model != NULL, NULL);
2103 g_return_val_if_fail (child_path != NULL, NULL);
2105 retval = gtk_tree_path_new ();
2106 child_indices = gtk_tree_path_get_indices (child_path);
2108 if (priv->root == NULL && build_levels)
2109 gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
2110 level = SORT_LEVEL (priv->root);
2112 for (i = 0; i < gtk_tree_path_get_depth (child_path); i++)
2115 gboolean found_child = FALSE;
2119 gtk_tree_path_free (retval);
2123 if (child_indices[i] >= level->array->len)
2125 gtk_tree_path_free (retval);
2128 for (j = 0; j < level->array->len; j++)
2130 if ((g_array_index (level->array, SortElt, j)).offset == child_indices[i])
2132 gtk_tree_path_append_index (retval, j);
2133 if (g_array_index (level->array, SortElt, j).children == NULL && build_levels)
2135 gtk_tree_model_sort_build_level (tree_model_sort, level, j);
2137 level = g_array_index (level->array, SortElt, j).children;
2144 gtk_tree_path_free (retval);
2154 * gtk_tree_model_sort_convert_child_path_to_path:
2155 * @tree_model_sort: A #GtkTreeModelSort
2156 * @child_path: A #GtkTreePath to convert
2158 * Converts @child_path to a path relative to @tree_model_sort. That is,
2159 * @child_path points to a path in the child model. The returned path will
2160 * point to the same row in the sorted model. If @child_path isn't a valid
2161 * path on the child model, then %NULL is returned.
2163 * Return value: A newly allocated #GtkTreePath, or %NULL
2166 gtk_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2167 GtkTreePath *child_path)
2169 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2170 g_return_val_if_fail (tree_model_sort->priv->child_model != NULL, NULL);
2171 g_return_val_if_fail (child_path != NULL, NULL);
2173 return gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path, TRUE);
2177 * gtk_tree_model_sort_convert_child_iter_to_iter:
2178 * @tree_model_sort: A #GtkTreeModelSort
2179 * @sort_iter: (out): An uninitialized #GtkTreeIter.
2180 * @child_iter: A valid #GtkTreeIter pointing to a row on the child model
2182 * Sets @sort_iter to point to the row in @tree_model_sort that corresponds to
2183 * the row pointed at by @child_iter. If @sort_iter was not set, %FALSE
2184 * is returned. Note: a boolean is only returned since 2.14.
2186 * Return value: %TRUE, if @sort_iter was set, i.e. if @sort_iter is a
2187 * valid iterator pointer to a visible row in the child model.
2190 gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sort,
2191 GtkTreeIter *sort_iter,
2192 GtkTreeIter *child_iter)
2195 GtkTreePath *child_path, *path;
2196 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2198 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2199 g_return_val_if_fail (priv->child_model != NULL, FALSE);
2200 g_return_val_if_fail (sort_iter != NULL, FALSE);
2201 g_return_val_if_fail (child_iter != NULL, FALSE);
2202 g_return_val_if_fail (sort_iter != child_iter, FALSE);
2204 sort_iter->stamp = 0;
2206 child_path = gtk_tree_model_get_path (priv->child_model, child_iter);
2207 g_return_val_if_fail (child_path != NULL, FALSE);
2209 path = gtk_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path);
2210 gtk_tree_path_free (child_path);
2214 g_warning ("%s: The conversion of the child path to a GtkTreeModel sort path failed", G_STRLOC);
2218 ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
2220 gtk_tree_path_free (path);
2226 * gtk_tree_model_sort_convert_path_to_child_path:
2227 * @tree_model_sort: A #GtkTreeModelSort
2228 * @sorted_path: A #GtkTreePath to convert
2230 * Converts @sorted_path to a path on the child model of @tree_model_sort.
2231 * That is, @sorted_path points to a location in @tree_model_sort. The
2232 * returned path will point to the same location in the model not being
2233 * sorted. If @sorted_path does not point to a location in the child model,
2234 * %NULL is returned.
2236 * Return value: A newly allocated #GtkTreePath, or %NULL
2239 gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sort,
2240 GtkTreePath *sorted_path)
2242 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2243 gint *sorted_indices;
2244 GtkTreePath *retval;
2248 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2249 g_return_val_if_fail (priv->child_model != NULL, NULL);
2250 g_return_val_if_fail (sorted_path != NULL, NULL);
2252 retval = gtk_tree_path_new ();
2253 sorted_indices = gtk_tree_path_get_indices (sorted_path);
2254 if (priv->root == NULL)
2255 gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
2256 level = SORT_LEVEL (priv->root);
2258 for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++)
2260 gint count = sorted_indices[i];
2262 if ((level == NULL) ||
2263 (level->array->len <= count))
2265 gtk_tree_path_free (retval);
2269 if (g_array_index (level->array, SortElt, count).children == NULL)
2270 gtk_tree_model_sort_build_level (tree_model_sort, level, count);
2274 gtk_tree_path_free (retval);
2278 gtk_tree_path_append_index (retval, g_array_index (level->array, SortElt, count).offset);
2279 level = g_array_index (level->array, SortElt, count).children;
2286 * gtk_tree_model_sort_convert_iter_to_child_iter:
2287 * @tree_model_sort: A #GtkTreeModelSort
2288 * @child_iter: (out): An uninitialized #GtkTreeIter
2289 * @sorted_iter: A valid #GtkTreeIter pointing to a row on @tree_model_sort.
2291 * Sets @child_iter to point to the row pointed to by @sorted_iter.
2294 gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sort,
2295 GtkTreeIter *child_iter,
2296 GtkTreeIter *sorted_iter)
2298 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2299 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2300 g_return_if_fail (priv->child_model != NULL);
2301 g_return_if_fail (child_iter != NULL);
2302 g_return_if_fail (VALID_ITER (sorted_iter, tree_model_sort));
2303 g_return_if_fail (sorted_iter != child_iter);
2305 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2307 *child_iter = SORT_ELT (sorted_iter->user_data2)->iter;
2313 path = gtk_tree_model_sort_elt_get_path (sorted_iter->user_data,
2314 sorted_iter->user_data2);
2315 gtk_tree_model_get_iter (priv->child_model, child_iter, path);
2316 gtk_tree_path_free (path);
2321 gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
2322 SortLevel *parent_level,
2323 gint parent_elt_index)
2325 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2327 SortElt *parent_elt = NULL;
2328 SortLevel *new_level;
2332 g_assert (priv->child_model != NULL);
2334 if (parent_level == NULL)
2336 if (gtk_tree_model_get_iter_first (priv->child_model, &iter) == FALSE)
2338 length = gtk_tree_model_iter_n_children (priv->child_model, NULL);
2342 GtkTreeIter parent_iter;
2343 GtkTreeIter child_parent_iter;
2345 parent_elt = &g_array_index (parent_level->array, SortElt, parent_elt_index);
2347 parent_iter.stamp = priv->stamp;
2348 parent_iter.user_data = parent_level;
2349 parent_iter.user_data2 = parent_elt;
2351 gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2354 if (gtk_tree_model_iter_children (priv->child_model,
2356 &child_parent_iter) == FALSE)
2359 /* stamp may have changed */
2360 gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2364 length = gtk_tree_model_iter_n_children (priv->child_model, &child_parent_iter);
2367 g_return_if_fail (length > 0);
2369 new_level = g_new (SortLevel, 1);
2370 new_level->array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), length);
2371 new_level->ref_count = 0;
2372 new_level->parent_level = parent_level;
2373 new_level->parent_elt_index = parent_elt_index;
2375 if (parent_elt_index >= 0)
2376 parent_elt->children = new_level;
2378 priv->root = new_level;
2380 /* increase the count of zero ref_counts.*/
2381 while (parent_level)
2383 g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count++;
2385 parent_elt_index = parent_level->parent_elt_index;
2386 parent_level = parent_level->parent_level;
2389 if (new_level != priv->root)
2390 priv->zero_ref_count++;
2392 for (i = 0; i < length; i++)
2395 sort_elt.offset = i;
2396 sort_elt.zero_ref_count = 0;
2397 sort_elt.ref_count = 0;
2398 sort_elt.children = NULL;
2400 if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2402 sort_elt.iter = iter;
2403 if (gtk_tree_model_iter_next (priv->child_model, &iter) == FALSE &&
2411 level = gtk_tree_model_sort_elt_get_path (parent_level,
2413 str = gtk_tree_path_to_string (level);
2414 gtk_tree_path_free (level);
2416 g_warning ("%s: There is a discrepancy between the sort model "
2417 "and the child model. The child model is "
2418 "advertising a wrong length for level %s:.",
2424 g_warning ("%s: There is a discrepancy between the sort model "
2425 "and the child model. The child model is "
2426 "advertising a wrong length for the root level.",
2433 g_array_append_val (new_level->array, sort_elt);
2437 gtk_tree_model_sort_sort_level (tree_model_sort, new_level,
2442 gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
2443 SortLevel *sort_level)
2445 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2448 g_assert (sort_level);
2450 for (i = 0; i < sort_level->array->len; i++)
2452 if (g_array_index (sort_level->array, SortElt, i).children)
2453 gtk_tree_model_sort_free_level (tree_model_sort,
2454 SORT_LEVEL (g_array_index (sort_level->array, SortElt, i).children));
2457 if (sort_level->ref_count == 0)
2459 SortLevel *parent_level = sort_level->parent_level;
2460 gint parent_elt_index = sort_level->parent_elt_index;
2462 while (parent_level)
2464 g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count--;
2466 parent_elt_index = parent_level->parent_elt_index;
2467 parent_level = parent_level->parent_level;
2470 if (sort_level != priv->root)
2471 priv->zero_ref_count--;
2474 if (sort_level->parent_elt_index >= 0)
2475 SORT_LEVEL_PARENT_ELT (sort_level)->children = NULL;
2479 g_array_free (sort_level->array, TRUE);
2480 sort_level->array = NULL;
2482 g_free (sort_level);
2487 gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort)
2489 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2495 while (priv->stamp == 0);
2497 gtk_tree_model_sort_clear_cache (tree_model_sort);
2501 gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
2506 g_assert (level != NULL);
2508 for (i = 0; i < level->array->len; i++)
2510 if (g_array_index (level->array, SortElt, i).zero_ref_count > 0)
2511 gtk_tree_model_sort_clear_cache_helper (tree_model_sort, g_array_index (level->array, SortElt, i).children);
2514 if (level->ref_count == 0 && level != tree_model_sort->priv->root)
2515 gtk_tree_model_sort_free_level (tree_model_sort, level);
2519 * gtk_tree_model_sort_reset_default_sort_func:
2520 * @tree_model_sort: A #GtkTreeModelSort
2522 * This resets the default sort function to be in the 'unsorted' state. That
2523 * is, it is in the same order as the child model. It will re-sort the model
2524 * to be in the same order as the child model only if the #GtkTreeModelSort
2525 * is in 'unsorted' state.
2528 gtk_tree_model_sort_reset_default_sort_func (GtkTreeModelSort *tree_model_sort)
2530 GtkTreeModelSortPrivate *priv = tree_model_sort->priv;
2532 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2534 if (priv->default_sort_destroy)
2536 GDestroyNotify d = priv->default_sort_destroy;
2538 priv->default_sort_destroy = NULL;
2539 d (priv->default_sort_data);
2542 priv->default_sort_func = NO_SORT_FUNC;
2543 priv->default_sort_data = NULL;
2544 priv->default_sort_destroy = NULL;
2546 if (priv->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
2547 gtk_tree_model_sort_sort (tree_model_sort);
2548 priv->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
2552 * gtk_tree_model_sort_clear_cache:
2553 * @tree_model_sort: A #GtkTreeModelSort
2555 * This function should almost never be called. It clears the @tree_model_sort
2556 * of any cached iterators that haven't been reffed with
2557 * gtk_tree_model_ref_node(). This might be useful if the child model being
2558 * sorted is static (and doesn't change often) and there has been a lot of
2559 * unreffed access to nodes. As a side effect of this function, all unreffed
2560 * iters will be invalid.
2563 gtk_tree_model_sort_clear_cache (GtkTreeModelSort *tree_model_sort)
2565 g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2567 if (tree_model_sort->priv->zero_ref_count > 0)
2568 gtk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->priv->root);
2572 gtk_tree_model_sort_iter_is_valid_helper (GtkTreeIter *iter,
2577 for (i = 0; i < level->array->len; i++)
2579 SortElt *elt = &g_array_index (level->array, SortElt, i);
2581 if (iter->user_data == level && iter->user_data2 == elt)
2585 if (gtk_tree_model_sort_iter_is_valid_helper (iter, elt->children))
2593 * gtk_tree_model_sort_iter_is_valid:
2594 * @tree_model_sort: A #GtkTreeModelSort.
2595 * @iter: A #GtkTreeIter.
2598 * This function is slow. Only use it for debugging and/or testing purposes.
2601 * Checks if the given iter is a valid iter for this #GtkTreeModelSort.
2603 * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
2608 gtk_tree_model_sort_iter_is_valid (GtkTreeModelSort *tree_model_sort,
2611 g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2612 g_return_val_if_fail (iter != NULL, FALSE);
2614 if (!VALID_ITER (iter, tree_model_sort))
2617 return gtk_tree_model_sort_iter_is_valid_helper (iter,
2618 tree_model_sort->priv->root);