1 /* gtktreemodelsort.c
2  * Copyright (C) 2000,2001  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
3  * Copyright (C) 2001,2002  Kristian Rietveld <kris@gtk.org>
4  *
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.
9  *
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.
14  *
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.
19  */
20 
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);
25  */
26 
27 /* ITER FORMAT:
28  *
29  * iter->stamp = tree_model_sort->stamp
30  * iter->user_data = SortLevel
31  * iter->user_data2 = SortElt
32  */
33 
34 /* WARNING: this code is dangerous, can cause sleepless nights,
35  * can cause your dog to die among other bad things
36  *
37  * we warned you and we're not liable for any head injuries.
38  */
39 
40 #include "config.h"
41 #include <string.h>
42 
43 #include "gtktreemodelsort.h"
44 #include "gtktreesortable.h"
45 #include "gtktreestore.h"
46 #include "gtktreedatalist.h"
47 #include "gtkintl.h"
48 #include "gtkprivate.h"
49 #include "gtktreednd.h"
50 #include "gtkalias.h"
51 
52 typedef struct _SortElt SortElt;
53 typedef struct _SortLevel SortLevel;
54 typedef struct _SortData SortData;
55 typedef struct _SortTuple SortTuple;
56 
57 struct _SortElt
58 {
59   GtkTreeIter  iter;
60   SortLevel   *children;
61   gint         offset;
62   gint         ref_count;
63   gint         zero_ref_count;
64 };
65 
66 struct _SortLevel
67 {
68   GArray    *array;
69   gint       ref_count;
70   gint       parent_elt_index;
71   SortLevel *parent_level;
72 };
73 
74 struct _SortData
75 {
76   GtkTreeModelSort *tree_model_sort;
77   GtkTreePath *parent_path;
78   gint parent_path_depth;
79   gint *parent_path_indices;
80   GtkTreeIterCompareFunc sort_func;
81   gpointer sort_data;
82 };
83 
84 struct _SortTuple
85 {
86   SortElt   *elt;
87   gint       offset;
88 };
89 
90 /* Properties */
91 enum {
92   PROP_0,
93   /* Construct args */
94   PROP_MODEL
95 };
96 
97 
98 
99 #define GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS(tree_model_sort) \
100 	(((GtkTreeModelSort *)tree_model_sort)->child_flags&GTK_TREE_MODEL_ITERS_PERSIST)
101 #define SORT_ELT(sort_elt) ((SortElt *)sort_elt)
102 #define SORT_LEVEL(sort_level) ((SortLevel *)sort_level)
103 
104 #define SORT_LEVEL_PARENT_ELT(level) (&g_array_index (SORT_LEVEL ((level))->parent_level->array, SortElt, SORT_LEVEL ((level))->parent_elt_index))
105 #define SORT_LEVEL_ELT_INDEX(level, elt) (SORT_ELT ((elt)) - SORT_ELT (SORT_LEVEL ((level))->array->data))
106 
107 
108 #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));
109 
110 #define NO_SORT_FUNC ((GtkTreeIterCompareFunc) 0x1)
111 
112 #define VALID_ITER(iter, tree_model_sort) ((iter) != NULL && (iter)->user_data != NULL && (iter)->user_data2 != NULL && (tree_model_sort)->stamp == (iter)->stamp)
113 
114 /* general (object/interface init, etc) */
115 static void gtk_tree_model_sort_tree_model_init       (GtkTreeModelIface     *iface);
116 static void gtk_tree_model_sort_tree_sortable_init    (GtkTreeSortableIface  *iface);
117 static void gtk_tree_model_sort_drag_source_init      (GtkTreeDragSourceIface*iface);
118 static void gtk_tree_model_sort_finalize              (GObject               *object);
119 static void gtk_tree_model_sort_set_property          (GObject               *object,
120 						       guint                  prop_id,
121 						       const GValue          *value,
122 						       GParamSpec            *pspec);
123 static void gtk_tree_model_sort_get_property          (GObject               *object,
124 						       guint                  prop_id,
125 						       GValue                *value,
126 						       GParamSpec            *pspec);
127 
128 /* our signal handlers */
129 static void gtk_tree_model_sort_row_changed           (GtkTreeModel          *model,
130 						       GtkTreePath           *start_path,
131 						       GtkTreeIter           *start_iter,
132 						       gpointer               data);
133 static void gtk_tree_model_sort_row_inserted          (GtkTreeModel          *model,
134 						       GtkTreePath           *path,
135 						       GtkTreeIter           *iter,
136 						       gpointer               data);
137 static void gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel          *model,
138 						       GtkTreePath           *path,
139 						       GtkTreeIter           *iter,
140 						       gpointer               data);
141 static void gtk_tree_model_sort_row_deleted           (GtkTreeModel          *model,
142 						       GtkTreePath           *path,
143 						       gpointer               data);
144 static void gtk_tree_model_sort_rows_reordered        (GtkTreeModel          *s_model,
145 						       GtkTreePath           *s_path,
146 						       GtkTreeIter           *s_iter,
147 						       gint                  *new_order,
148 						       gpointer               data);
149 
150 /* TreeModel interface */
151 static GtkTreeModelFlags gtk_tree_model_sort_get_flags     (GtkTreeModel          *tree_model);
152 static gint         gtk_tree_model_sort_get_n_columns      (GtkTreeModel          *tree_model);
153 static GType        gtk_tree_model_sort_get_column_type    (GtkTreeModel          *tree_model,
154                                                             gint                   index);
155 static gboolean     gtk_tree_model_sort_get_iter           (GtkTreeModel          *tree_model,
156                                                             GtkTreeIter           *iter,
157                                                             GtkTreePath           *path);
158 static GtkTreePath *gtk_tree_model_sort_get_path           (GtkTreeModel          *tree_model,
159                                                             GtkTreeIter           *iter);
160 static void         gtk_tree_model_sort_get_value          (GtkTreeModel          *tree_model,
161                                                             GtkTreeIter           *iter,
162                                                             gint                   column,
163                                                             GValue                *value);
164 static gboolean     gtk_tree_model_sort_iter_next          (GtkTreeModel          *tree_model,
165                                                             GtkTreeIter           *iter);
166 static gboolean     gtk_tree_model_sort_iter_children      (GtkTreeModel          *tree_model,
167                                                             GtkTreeIter           *iter,
168                                                             GtkTreeIter           *parent);
169 static gboolean     gtk_tree_model_sort_iter_has_child     (GtkTreeModel          *tree_model,
170                                                             GtkTreeIter           *iter);
171 static gint         gtk_tree_model_sort_iter_n_children    (GtkTreeModel          *tree_model,
172                                                             GtkTreeIter           *iter);
173 static gboolean     gtk_tree_model_sort_iter_nth_child     (GtkTreeModel          *tree_model,
174                                                             GtkTreeIter           *iter,
175                                                             GtkTreeIter           *parent,
176                                                             gint                   n);
177 static gboolean     gtk_tree_model_sort_iter_parent        (GtkTreeModel          *tree_model,
178                                                             GtkTreeIter           *iter,
179                                                             GtkTreeIter           *child);
180 static void         gtk_tree_model_sort_ref_node           (GtkTreeModel          *tree_model,
181                                                             GtkTreeIter           *iter);
182 static void         gtk_tree_model_sort_real_unref_node    (GtkTreeModel          *tree_model,
183                                                             GtkTreeIter           *iter,
184 							    gboolean               propagate_unref);
185 static void         gtk_tree_model_sort_unref_node         (GtkTreeModel          *tree_model,
186                                                             GtkTreeIter           *iter);
187 
188 /* TreeDragSource interface */
189 static gboolean     gtk_tree_model_sort_row_draggable         (GtkTreeDragSource      *drag_source,
190                                                                GtkTreePath            *path);
191 static gboolean     gtk_tree_model_sort_drag_data_get         (GtkTreeDragSource      *drag_source,
192                                                                GtkTreePath            *path,
193 							       GtkSelectionData       *selection_data);
194 static gboolean     gtk_tree_model_sort_drag_data_delete      (GtkTreeDragSource      *drag_source,
195                                                                GtkTreePath            *path);
196 
197 /* TreeSortable interface */
198 static gboolean     gtk_tree_model_sort_get_sort_column_id    (GtkTreeSortable        *sortable,
199 							       gint                   *sort_column_id,
200 							       GtkSortType            *order);
201 static void         gtk_tree_model_sort_set_sort_column_id    (GtkTreeSortable        *sortable,
202 							       gint                    sort_column_id,
203 							       GtkSortType        order);
204 static void         gtk_tree_model_sort_set_sort_func         (GtkTreeSortable        *sortable,
205 							       gint                    sort_column_id,
206 							       GtkTreeIterCompareFunc  func,
207 							       gpointer                data,
208 							       GDestroyNotify          destroy);
209 static void         gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable        *sortable,
210 							       GtkTreeIterCompareFunc  func,
211 							       gpointer                data,
212 							       GDestroyNotify          destroy);
213 static gboolean     gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable     *sortable);
214 
215 /* Private functions (sort funcs, level handling and other utils) */
216 static void         gtk_tree_model_sort_build_level       (GtkTreeModelSort *tree_model_sort,
217 							   SortLevel        *parent_level,
218 							   gint              parent_elt_index);
219 static void         gtk_tree_model_sort_free_level        (GtkTreeModelSort *tree_model_sort,
220 							   SortLevel        *sort_level);
221 static void         gtk_tree_model_sort_increment_stamp   (GtkTreeModelSort *tree_model_sort);
222 static void         gtk_tree_model_sort_sort_level        (GtkTreeModelSort *tree_model_sort,
223 							   SortLevel        *level,
224 							   gboolean          recurse,
225 							   gboolean          emit_reordered);
226 static void         gtk_tree_model_sort_sort              (GtkTreeModelSort *tree_model_sort);
227 static gint         gtk_tree_model_sort_level_find_insert (GtkTreeModelSort *tree_model_sort,
228 							   SortLevel        *level,
229 							   GtkTreeIter      *iter,
230 							   gint             skip_index);
231 static gboolean     gtk_tree_model_sort_insert_value      (GtkTreeModelSort *tree_model_sort,
232 							   SortLevel        *level,
233 							   GtkTreePath      *s_path,
234 							   GtkTreeIter      *s_iter);
235 static GtkTreePath *gtk_tree_model_sort_elt_get_path      (SortLevel        *level,
236 							   SortElt          *elt);
237 static void         gtk_tree_model_sort_set_model         (GtkTreeModelSort *tree_model_sort,
238 							   GtkTreeModel     *child_model);
239 static GtkTreePath *gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
240 									 GtkTreePath      *child_path,
241 									 gboolean          build_levels);
242 
243 
G_DEFINE_TYPE_WITH_CODE(GtkTreeModelSort,gtk_tree_model_sort,G_TYPE_OBJECT,G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,gtk_tree_model_sort_tree_model_init)G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,gtk_tree_model_sort_tree_sortable_init)G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,gtk_tree_model_sort_drag_source_init))244 G_DEFINE_TYPE_WITH_CODE (GtkTreeModelSort, gtk_tree_model_sort, G_TYPE_OBJECT,
245 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_MODEL,
246 						gtk_tree_model_sort_tree_model_init)
247 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_SORTABLE,
248 						gtk_tree_model_sort_tree_sortable_init)
249 			 G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE,
250 						gtk_tree_model_sort_drag_source_init))
251 
252 static void
253 gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
254 {
255   tree_model_sort->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
256   tree_model_sort->stamp = 0;
257   tree_model_sort->zero_ref_count = 0;
258   tree_model_sort->root = NULL;
259   tree_model_sort->sort_list = NULL;
260 }
261 
262 static void
gtk_tree_model_sort_class_init(GtkTreeModelSortClass * class)263 gtk_tree_model_sort_class_init (GtkTreeModelSortClass *class)
264 {
265   GObjectClass *object_class;
266 
267   object_class = (GObjectClass *) class;
268 
269   object_class->set_property = gtk_tree_model_sort_set_property;
270   object_class->get_property = gtk_tree_model_sort_get_property;
271 
272   object_class->finalize = gtk_tree_model_sort_finalize;
273 
274   /* Properties */
275   g_object_class_install_property (object_class,
276                                    PROP_MODEL,
277                                    g_param_spec_object ("model",
278 							P_("TreeModelSort Model"),
279 							P_("The model for the TreeModelSort to sort"),
280 							GTK_TYPE_TREE_MODEL,
281 							GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
282 }
283 
284 static void
gtk_tree_model_sort_tree_model_init(GtkTreeModelIface * iface)285 gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
286 {
287   iface->get_flags = gtk_tree_model_sort_get_flags;
288   iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
289   iface->get_column_type = gtk_tree_model_sort_get_column_type;
290   iface->get_iter = gtk_tree_model_sort_get_iter;
291   iface->get_path = gtk_tree_model_sort_get_path;
292   iface->get_value = gtk_tree_model_sort_get_value;
293   iface->iter_next = gtk_tree_model_sort_iter_next;
294   iface->iter_children = gtk_tree_model_sort_iter_children;
295   iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
296   iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
297   iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
298   iface->iter_parent = gtk_tree_model_sort_iter_parent;
299   iface->ref_node = gtk_tree_model_sort_ref_node;
300   iface->unref_node = gtk_tree_model_sort_unref_node;
301 }
302 
303 static void
gtk_tree_model_sort_tree_sortable_init(GtkTreeSortableIface * iface)304 gtk_tree_model_sort_tree_sortable_init (GtkTreeSortableIface *iface)
305 {
306   iface->get_sort_column_id = gtk_tree_model_sort_get_sort_column_id;
307   iface->set_sort_column_id = gtk_tree_model_sort_set_sort_column_id;
308   iface->set_sort_func = gtk_tree_model_sort_set_sort_func;
309   iface->set_default_sort_func = gtk_tree_model_sort_set_default_sort_func;
310   iface->has_default_sort_func = gtk_tree_model_sort_has_default_sort_func;
311 }
312 
313 static void
gtk_tree_model_sort_drag_source_init(GtkTreeDragSourceIface * iface)314 gtk_tree_model_sort_drag_source_init (GtkTreeDragSourceIface *iface)
315 {
316   iface->row_draggable = gtk_tree_model_sort_row_draggable;
317   iface->drag_data_delete = gtk_tree_model_sort_drag_data_delete;
318   iface->drag_data_get = gtk_tree_model_sort_drag_data_get;
319 }
320 
321 /**
322  * gtk_tree_model_sort_new_with_model:
323  * @child_model: A #GtkTreeModel
324  *
325  * Creates a new #GtkTreeModel, with @child_model as the child model.
326  *
327  * Return value: (transfer full): A new #GtkTreeModel.
328  */
329 GtkTreeModel *
gtk_tree_model_sort_new_with_model(GtkTreeModel * child_model)330 gtk_tree_model_sort_new_with_model (GtkTreeModel *child_model)
331 {
332   GtkTreeModel *retval;
333 
334   g_return_val_if_fail (GTK_IS_TREE_MODEL (child_model), NULL);
335 
336   retval = g_object_new (gtk_tree_model_sort_get_type (), NULL);
337 
338   gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), child_model);
339 
340   return retval;
341 }
342 
343 /* GObject callbacks */
344 static void
gtk_tree_model_sort_finalize(GObject * object)345 gtk_tree_model_sort_finalize (GObject *object)
346 {
347   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
348 
349   gtk_tree_model_sort_set_model (tree_model_sort, NULL);
350 
351   if (tree_model_sort->root)
352     gtk_tree_model_sort_free_level (tree_model_sort, tree_model_sort->root);
353 
354   if (tree_model_sort->sort_list)
355     {
356       _gtk_tree_data_list_header_free (tree_model_sort->sort_list);
357       tree_model_sort->sort_list = NULL;
358     }
359 
360   if (tree_model_sort->default_sort_destroy)
361     {
362       tree_model_sort->default_sort_destroy (tree_model_sort->default_sort_data);
363       tree_model_sort->default_sort_destroy = NULL;
364       tree_model_sort->default_sort_data = NULL;
365     }
366 
367 
368   /* must chain up */
369   G_OBJECT_CLASS (gtk_tree_model_sort_parent_class)->finalize (object);
370 }
371 
372 static void
gtk_tree_model_sort_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)373 gtk_tree_model_sort_set_property (GObject      *object,
374 				  guint         prop_id,
375 				  const GValue *value,
376 				  GParamSpec   *pspec)
377 {
378   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
379 
380   switch (prop_id)
381     {
382     case PROP_MODEL:
383       gtk_tree_model_sort_set_model (tree_model_sort, g_value_get_object (value));
384       break;
385     default:
386       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
387       break;
388     }
389 }
390 
391 static void
gtk_tree_model_sort_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)392 gtk_tree_model_sort_get_property (GObject    *object,
393 				  guint       prop_id,
394 				  GValue     *value,
395 				  GParamSpec *pspec)
396 {
397   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (object);
398 
399   switch (prop_id)
400     {
401     case PROP_MODEL:
402       g_value_set_object (value, gtk_tree_model_sort_get_model(tree_model_sort));
403       break;
404     default:
405       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
406       break;
407     }
408 }
409 
410 static void
gtk_tree_model_sort_row_changed(GtkTreeModel * s_model,GtkTreePath * start_s_path,GtkTreeIter * start_s_iter,gpointer data)411 gtk_tree_model_sort_row_changed (GtkTreeModel *s_model,
412 				 GtkTreePath  *start_s_path,
413 				 GtkTreeIter  *start_s_iter,
414 				 gpointer      data)
415 {
416   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
417   GtkTreePath *path = NULL;
418   GtkTreeIter iter;
419   GtkTreeIter tmpiter;
420 
421   SortElt tmp;
422   SortElt *elt;
423   SortLevel *level;
424 
425   gboolean free_s_path = FALSE;
426 
427   gint index = 0, old_index, i;
428 
429   g_return_if_fail (start_s_path != NULL || start_s_iter != NULL);
430 
431   if (!start_s_path)
432     {
433       free_s_path = TRUE;
434       start_s_path = gtk_tree_model_get_path (s_model, start_s_iter);
435     }
436 
437   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
438 							      start_s_path,
439 							      FALSE);
440   if (!path)
441     {
442       if (free_s_path)
443 	gtk_tree_path_free (start_s_path);
444       return;
445     }
446 
447   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
448   gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (data), &iter);
449 
450   level = iter.user_data;
451   elt = iter.user_data2;
452 
453   if (level->array->len < 2 ||
454       (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
455        tree_model_sort->default_sort_func == NO_SORT_FUNC))
456     {
457       if (free_s_path)
458 	gtk_tree_path_free (start_s_path);
459 
460       gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
461       gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
462 
463       gtk_tree_path_free (path);
464 
465       return;
466     }
467 
468   if (!GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
469     {
470       gtk_tree_model_get_iter (tree_model_sort->child_model,
471 			       &tmpiter, start_s_path);
472     }
473 
474   old_index = elt - SORT_ELT (level->array->data);
475 
476   memcpy (&tmp, elt, sizeof (SortElt));
477 
478   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
479     index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
480 						   level,
481 						   &tmp.iter,
482 						   old_index);
483   else
484     index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
485 						   level,
486 						   &tmpiter,
487 						   old_index);
488 
489   if (index < old_index)
490     {
491       g_memmove (level->array->data + ((index + 1)*sizeof (SortElt)),
492 		 level->array->data + ((index)*sizeof (SortElt)),
493 		 (old_index - index)* sizeof(SortElt));
494     }
495   else if (index > old_index)
496     {
497       g_memmove (level->array->data + ((old_index)*sizeof (SortElt)),
498 		 level->array->data + ((old_index + 1)*sizeof (SortElt)),
499 		 (index - old_index)* sizeof(SortElt));
500     }
501   memcpy (level->array->data + ((index)*sizeof (SortElt)),
502 	  &tmp, sizeof (SortElt));
503 
504   for (i = 0; i < level->array->len; i++)
505     if (g_array_index (level->array, SortElt, i).children)
506       g_array_index (level->array, SortElt, i).children->parent_elt_index = i;
507 
508   gtk_tree_path_up (path);
509   gtk_tree_path_append_index (path, index);
510 
511   gtk_tree_model_sort_increment_stamp (tree_model_sort);
512 
513   /* if the item moved, then emit rows_reordered */
514   if (old_index != index)
515     {
516       gint *new_order;
517       gint j;
518 
519       GtkTreePath *tmppath;
520 
521       new_order = g_new (gint, level->array->len);
522 
523       for (j = 0; j < level->array->len; j++)
524         {
525 	  if (index > old_index)
526 	    {
527 	      if (j == index)
528 		new_order[j] = old_index;
529 	      else if (j >= old_index && j < index)
530 		new_order[j] = j + 1;
531 	      else
532 		new_order[j] = j;
533 	    }
534 	  else if (index < old_index)
535 	    {
536 	      if (j == index)
537 		new_order[j] = old_index;
538 	      else if (j > index && j <= old_index)
539 		new_order[j] = j - 1;
540 	      else
541 		new_order[j] = j;
542 	    }
543 	  /* else? shouldn't really happen */
544 	}
545 
546       if (level->parent_elt_index >= 0)
547         {
548 	  iter.stamp = tree_model_sort->stamp;
549 	  iter.user_data = level->parent_level;
550 	  iter.user_data2 = SORT_LEVEL_PARENT_ELT (level);
551 
552 	  tmppath = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort), &iter);
553 
554 	  gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
555 	                                 tmppath, &iter, new_order);
556 	}
557       else
558         {
559 	  /* toplevel */
560 	  tmppath = gtk_tree_path_new ();
561 
562           gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), tmppath,
563 	                                 NULL, new_order);
564 	}
565 
566       gtk_tree_path_free (tmppath);
567       g_free (new_order);
568     }
569 
570   /* emit row_changed signal (at new location) */
571   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
572   gtk_tree_model_row_changed (GTK_TREE_MODEL (data), path, &iter);
573   gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (data), &iter);
574 
575   gtk_tree_path_free (path);
576   if (free_s_path)
577     gtk_tree_path_free (start_s_path);
578 }
579 
580 static void
gtk_tree_model_sort_row_inserted(GtkTreeModel * s_model,GtkTreePath * s_path,GtkTreeIter * s_iter,gpointer data)581 gtk_tree_model_sort_row_inserted (GtkTreeModel          *s_model,
582 				  GtkTreePath           *s_path,
583 				  GtkTreeIter           *s_iter,
584 				  gpointer               data)
585 {
586   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
587   GtkTreePath *path;
588   GtkTreeIter iter;
589   GtkTreeIter real_s_iter;
590 
591   gint i = 0;
592 
593   gboolean free_s_path = FALSE;
594 
595   SortElt *elt;
596   SortLevel *level;
597   SortLevel *parent_level = NULL;
598 
599   parent_level = level = SORT_LEVEL (tree_model_sort->root);
600 
601   g_return_if_fail (s_path != NULL || s_iter != NULL);
602 
603   if (!s_path)
604     {
605       s_path = gtk_tree_model_get_path (s_model, s_iter);
606       free_s_path = TRUE;
607     }
608 
609   if (!s_iter)
610     gtk_tree_model_get_iter (s_model, &real_s_iter, s_path);
611   else
612     real_s_iter = *s_iter;
613 
614   if (!tree_model_sort->root)
615     {
616       gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
617 
618       /* the build level already put the inserted iter in the level,
619 	 so no need to handle this signal anymore */
620 
621       goto done_and_submit;
622     }
623 
624   /* find the parent level */
625   while (i < gtk_tree_path_get_depth (s_path) - 1)
626     {
627       gint j;
628 
629       if (!level)
630 	{
631 	  /* level not yet build, we won't cover this signal */
632 	  goto done;
633 	}
634 
635       if (level->array->len < gtk_tree_path_get_indices (s_path)[i])
636 	{
637 	  g_warning ("%s: A node was inserted with a parent that's not in the tree.\n"
638 		     "This possibly means that a GtkTreeModel inserted a child node\n"
639 		     "before the parent was inserted.",
640 		     G_STRLOC);
641 	  goto done;
642 	}
643 
644       elt = NULL;
645       for (j = 0; j < level->array->len; j++)
646 	if (g_array_index (level->array, SortElt, j).offset == gtk_tree_path_get_indices (s_path)[i])
647 	  {
648 	    elt = &g_array_index (level->array, SortElt, j);
649 	    break;
650 	  }
651 
652       g_return_if_fail (elt != NULL);
653 
654       if (!elt->children)
655 	{
656 	  /* not covering this signal */
657 	  goto done;
658 	}
659 
660       level = elt->children;
661       parent_level = level;
662       i++;
663     }
664 
665   if (!parent_level)
666     goto done;
667 
668   if (level->ref_count == 0 && level != tree_model_sort->root)
669     {
670       gtk_tree_model_sort_free_level (tree_model_sort, level);
671       goto done;
672     }
673 
674   if (!gtk_tree_model_sort_insert_value (tree_model_sort,
675 					 parent_level,
676 					 s_path,
677 					 &real_s_iter))
678     goto done;
679 
680  done_and_submit:
681   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort,
682 							      s_path,
683 							      FALSE);
684 
685   if (!path)
686     return;
687 
688   gtk_tree_model_sort_increment_stamp (tree_model_sort);
689 
690   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
691   gtk_tree_model_row_inserted (GTK_TREE_MODEL (data), path, &iter);
692   gtk_tree_path_free (path);
693 
694  done:
695   if (free_s_path)
696     gtk_tree_path_free (s_path);
697 
698   return;
699 }
700 
701 static void
gtk_tree_model_sort_row_has_child_toggled(GtkTreeModel * s_model,GtkTreePath * s_path,GtkTreeIter * s_iter,gpointer data)702 gtk_tree_model_sort_row_has_child_toggled (GtkTreeModel *s_model,
703 					   GtkTreePath  *s_path,
704 					   GtkTreeIter  *s_iter,
705 					   gpointer      data)
706 {
707   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
708   GtkTreePath *path;
709   GtkTreeIter iter;
710 
711   g_return_if_fail (s_path != NULL && s_iter != NULL);
712 
713   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
714   if (path == NULL)
715     return;
716 
717   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
718   gtk_tree_model_row_has_child_toggled (GTK_TREE_MODEL (data), path, &iter);
719 
720   gtk_tree_path_free (path);
721 }
722 
723 static void
gtk_tree_model_sort_row_deleted(GtkTreeModel * s_model,GtkTreePath * s_path,gpointer data)724 gtk_tree_model_sort_row_deleted (GtkTreeModel *s_model,
725 				 GtkTreePath  *s_path,
726 				 gpointer      data)
727 {
728   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
729   GtkTreePath *path = NULL;
730   SortElt *elt;
731   SortLevel *level;
732   GtkTreeIter iter;
733   gint offset;
734   gint i;
735 
736   g_return_if_fail (s_path != NULL);
737 
738   path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
739   if (path == NULL)
740     return;
741 
742   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
743 
744   level = SORT_LEVEL (iter.user_data);
745   elt = SORT_ELT (iter.user_data2);
746   offset = elt->offset;
747 
748   /* we _need_ to emit ::row_deleted before we start unreffing the node
749    * itself. This is because of the row refs, which start unreffing nodes
750    * when we emit ::row_deleted
751    */
752   gtk_tree_model_row_deleted (GTK_TREE_MODEL (data), path);
753 
754   gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
755 
756   while (elt->ref_count > 0)
757     gtk_tree_model_sort_real_unref_node (GTK_TREE_MODEL (data), &iter, FALSE);
758 
759   if (level->ref_count == 0)
760     {
761       /* This will prune the level, so I can just emit the signal and
762        * not worry about cleaning this level up.
763        * Careful, root level is not cleaned up in increment stamp.
764        */
765       gtk_tree_model_sort_increment_stamp (tree_model_sort);
766       gtk_tree_path_free (path);
767       if (level == tree_model_sort->root)
768 	{
769 	  gtk_tree_model_sort_free_level (tree_model_sort,
770 					  tree_model_sort->root);
771 	  tree_model_sort->root = NULL;
772 	}
773       return;
774     }
775 
776   gtk_tree_model_sort_increment_stamp (tree_model_sort);
777 
778   /* Remove the row */
779   for (i = 0; i < level->array->len; i++)
780     if (elt->offset == g_array_index (level->array, SortElt, i).offset)
781       break;
782 
783   g_array_remove_index (level->array, i);
784 
785   /* update all offsets */
786   for (i = 0; i < level->array->len; i++)
787     {
788       elt = & (g_array_index (level->array, SortElt, i));
789       if (elt->offset > offset)
790 	elt->offset--;
791       if (elt->children)
792 	elt->children->parent_elt_index = i;
793     }
794 
795   gtk_tree_path_free (path);
796 }
797 
798 static void
gtk_tree_model_sort_rows_reordered(GtkTreeModel * s_model,GtkTreePath * s_path,GtkTreeIter * s_iter,gint * new_order,gpointer data)799 gtk_tree_model_sort_rows_reordered (GtkTreeModel *s_model,
800 				    GtkTreePath  *s_path,
801 				    GtkTreeIter  *s_iter,
802 				    gint         *new_order,
803 				    gpointer      data)
804 {
805   SortElt *elt;
806   SortLevel *level;
807   GtkTreeIter iter;
808   gint *tmp_array;
809   int i, j;
810   GtkTreePath *path;
811   GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
812 
813   g_return_if_fail (new_order != NULL);
814 
815   if (s_path == NULL || gtk_tree_path_get_depth (s_path) == 0)
816     {
817       if (tree_model_sort->root == NULL)
818 	return;
819       path = gtk_tree_path_new ();
820       level = SORT_LEVEL (tree_model_sort->root);
821     }
822   else
823     {
824       path = gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, s_path, FALSE);
825       if (path == NULL)
826 	return;
827       gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &iter, path);
828 
829       level = SORT_LEVEL (iter.user_data);
830       elt = SORT_ELT (iter.user_data2);
831 
832       if (!elt->children)
833 	{
834 	  gtk_tree_path_free (path);
835 	  return;
836 	}
837 
838       level = elt->children;
839     }
840 
841   if (level->array->len < 2)
842     {
843       gtk_tree_path_free (path);
844       return;
845     }
846 
847   tmp_array = g_new (int, level->array->len);
848   for (i = 0; i < level->array->len; i++)
849     {
850       for (j = 0; j < level->array->len; j++)
851 	{
852 	  if (g_array_index (level->array, SortElt, i).offset == new_order[j])
853 	    tmp_array[i] = j;
854 	}
855     }
856 
857   for (i = 0; i < level->array->len; i++)
858     g_array_index (level->array, SortElt, i).offset = tmp_array[i];
859   g_free (tmp_array);
860 
861   if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
862       tree_model_sort->default_sort_func == NO_SORT_FUNC)
863     {
864 
865       gtk_tree_model_sort_sort_level (tree_model_sort, level,
866 				      FALSE, FALSE);
867       gtk_tree_model_sort_increment_stamp (tree_model_sort);
868 
869       if (gtk_tree_path_get_depth (path))
870 	{
871 	  gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
872 				   &iter,
873 				   path);
874 	  gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
875 					 path, &iter, new_order);
876 	}
877       else
878 	{
879 	  gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort),
880 					 path, NULL, new_order);
881 	}
882     }
883 
884   gtk_tree_path_free (path);
885 }
886 
887 /* Fulfill our model requirements */
888 static GtkTreeModelFlags
gtk_tree_model_sort_get_flags(GtkTreeModel * tree_model)889 gtk_tree_model_sort_get_flags (GtkTreeModel *tree_model)
890 {
891   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
892   GtkTreeModelFlags flags;
893 
894   g_return_val_if_fail (tree_model_sort->child_model != NULL, 0);
895 
896   flags = gtk_tree_model_get_flags (tree_model_sort->child_model);
897 
898   if ((flags & GTK_TREE_MODEL_LIST_ONLY) == GTK_TREE_MODEL_LIST_ONLY)
899     return GTK_TREE_MODEL_LIST_ONLY;
900 
901   return 0;
902 }
903 
904 static gint
gtk_tree_model_sort_get_n_columns(GtkTreeModel * tree_model)905 gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
906 {
907   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
908 
909   if (tree_model_sort->child_model == 0)
910     return 0;
911 
912   return gtk_tree_model_get_n_columns (tree_model_sort->child_model);
913 }
914 
915 static GType
gtk_tree_model_sort_get_column_type(GtkTreeModel * tree_model,gint index)916 gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
917                                      gint          index)
918 {
919   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
920 
921   g_return_val_if_fail (tree_model_sort->child_model != NULL, G_TYPE_INVALID);
922 
923   return gtk_tree_model_get_column_type (tree_model_sort->child_model, index);
924 }
925 
926 static gboolean
gtk_tree_model_sort_get_iter(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreePath * path)927 gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
928 			      GtkTreeIter  *iter,
929 			      GtkTreePath  *path)
930 {
931   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
932   gint *indices;
933   SortLevel *level;
934   gint depth, i;
935 
936   g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
937 
938   indices = gtk_tree_path_get_indices (path);
939 
940   if (tree_model_sort->root == NULL)
941     gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
942   level = SORT_LEVEL (tree_model_sort->root);
943 
944   depth = gtk_tree_path_get_depth (path);
945   if (depth == 0)
946     return FALSE;
947 
948   for (i = 0; i < depth - 1; i++)
949     {
950       if ((level == NULL) ||
951 	  (indices[i] >= level->array->len))
952 	return FALSE;
953 
954       if (g_array_index (level->array, SortElt, indices[i]).children == NULL)
955 	gtk_tree_model_sort_build_level (tree_model_sort, level, indices[i]);
956       level = g_array_index (level->array, SortElt, indices[i]).children;
957     }
958 
959   if (!level || indices[i] >= level->array->len)
960     {
961       iter->stamp = 0;
962       return FALSE;
963     }
964 
965   iter->stamp = tree_model_sort->stamp;
966   iter->user_data = level;
967   iter->user_data2 = &g_array_index (level->array, SortElt, indices[depth - 1]);
968 
969   return TRUE;
970 }
971 
972 static GtkTreePath *
gtk_tree_model_sort_get_path(GtkTreeModel * tree_model,GtkTreeIter * iter)973 gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
974 			      GtkTreeIter  *iter)
975 {
976   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
977   GtkTreePath *retval;
978   SortLevel *level;
979   gint elt_index;
980 
981   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
982   g_return_val_if_fail (tree_model_sort->stamp == iter->stamp, NULL);
983 
984   retval = gtk_tree_path_new ();
985 
986   level = SORT_LEVEL (iter->user_data);
987   elt_index = SORT_LEVEL_ELT_INDEX (level, iter->user_data2);
988 
989   while (level)
990     {
991       gtk_tree_path_prepend_index (retval, elt_index);
992 
993       elt_index = level->parent_elt_index;
994       level = level->parent_level;
995     }
996 
997   return retval;
998 }
999 
1000 static void
gtk_tree_model_sort_get_value(GtkTreeModel * tree_model,GtkTreeIter * iter,gint column,GValue * value)1001 gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
1002 			       GtkTreeIter  *iter,
1003 			       gint          column,
1004 			       GValue       *value)
1005 {
1006   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1007   GtkTreeIter child_iter;
1008 
1009   g_return_if_fail (tree_model_sort->child_model != NULL);
1010   g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1011 
1012   GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1013   gtk_tree_model_get_value (tree_model_sort->child_model,
1014 			    &child_iter, column, value);
1015 }
1016 
1017 static gboolean
gtk_tree_model_sort_iter_next(GtkTreeModel * tree_model,GtkTreeIter * iter)1018 gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
1019 			       GtkTreeIter  *iter)
1020 {
1021   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1022   SortLevel *level;
1023   SortElt *elt;
1024 
1025   g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
1026   g_return_val_if_fail (tree_model_sort->stamp == iter->stamp, FALSE);
1027 
1028   level = iter->user_data;
1029   elt = iter->user_data2;
1030 
1031   if (elt - (SortElt *)level->array->data >= level->array->len - 1)
1032     {
1033       iter->stamp = 0;
1034       return FALSE;
1035     }
1036   iter->user_data2 = elt + 1;
1037 
1038   return TRUE;
1039 }
1040 
1041 static gboolean
gtk_tree_model_sort_iter_children(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreeIter * parent)1042 gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
1043 				   GtkTreeIter  *iter,
1044 				   GtkTreeIter  *parent)
1045 {
1046   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1047   SortLevel *level;
1048 
1049   iter->stamp = 0;
1050   g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
1051   if (parent)
1052     g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1053 
1054   if (parent == NULL)
1055     {
1056       if (tree_model_sort->root == NULL)
1057 	gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
1058       if (tree_model_sort->root == NULL)
1059 	return FALSE;
1060 
1061       level = tree_model_sort->root;
1062       iter->stamp = tree_model_sort->stamp;
1063       iter->user_data = level;
1064       iter->user_data2 = level->array->data;
1065     }
1066   else
1067     {
1068       SortElt *elt;
1069 
1070       level = SORT_LEVEL (parent->user_data);
1071       elt = SORT_ELT (parent->user_data2);
1072 
1073       if (elt->children == NULL)
1074         gtk_tree_model_sort_build_level (tree_model_sort, level,
1075                                          SORT_LEVEL_ELT_INDEX (level, elt));
1076 
1077       if (elt->children == NULL)
1078 	return FALSE;
1079 
1080       iter->stamp = tree_model_sort->stamp;
1081       iter->user_data = elt->children;
1082       iter->user_data2 = elt->children->array->data;
1083     }
1084 
1085   return TRUE;
1086 }
1087 
1088 static gboolean
gtk_tree_model_sort_iter_has_child(GtkTreeModel * tree_model,GtkTreeIter * iter)1089 gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
1090 				    GtkTreeIter  *iter)
1091 {
1092   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1093   GtkTreeIter child_iter;
1094 
1095   g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
1096   g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), FALSE);
1097 
1098   GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1099 
1100   return gtk_tree_model_iter_has_child (tree_model_sort->child_model, &child_iter);
1101 }
1102 
1103 static gint
gtk_tree_model_sort_iter_n_children(GtkTreeModel * tree_model,GtkTreeIter * iter)1104 gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
1105 				     GtkTreeIter  *iter)
1106 {
1107   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1108   GtkTreeIter child_iter;
1109 
1110   g_return_val_if_fail (tree_model_sort->child_model != NULL, 0);
1111   if (iter)
1112     g_return_val_if_fail (VALID_ITER (iter, tree_model_sort), 0);
1113 
1114   if (iter == NULL)
1115     return gtk_tree_model_iter_n_children (tree_model_sort->child_model, NULL);
1116 
1117   GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1118 
1119   return gtk_tree_model_iter_n_children (tree_model_sort->child_model, &child_iter);
1120 }
1121 
1122 static gboolean
gtk_tree_model_sort_iter_nth_child(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreeIter * parent,gint n)1123 gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
1124 				    GtkTreeIter  *iter,
1125 				    GtkTreeIter  *parent,
1126 				    gint          n)
1127 {
1128   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1129   SortLevel *level;
1130   /* We have this for the iter == parent case */
1131   GtkTreeIter children;
1132 
1133   if (parent)
1134     g_return_val_if_fail (VALID_ITER (parent, tree_model_sort), FALSE);
1135 
1136   /* Use this instead of has_child to force us to build the level, if needed */
1137   if (gtk_tree_model_sort_iter_children (tree_model, &children, parent) == FALSE)
1138     {
1139       iter->stamp = 0;
1140       return FALSE;
1141     }
1142 
1143   level = children.user_data;
1144   if (n >= level->array->len)
1145     {
1146       iter->stamp = 0;
1147       return FALSE;
1148     }
1149 
1150   iter->stamp = tree_model_sort->stamp;
1151   iter->user_data = level;
1152   iter->user_data2 = &g_array_index (level->array, SortElt, n);
1153 
1154   return TRUE;
1155 }
1156 
1157 static gboolean
gtk_tree_model_sort_iter_parent(GtkTreeModel * tree_model,GtkTreeIter * iter,GtkTreeIter * child)1158 gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
1159 				 GtkTreeIter  *iter,
1160 				 GtkTreeIter  *child)
1161 {
1162   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1163   SortLevel *level;
1164 
1165   iter->stamp = 0;
1166   g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
1167   g_return_val_if_fail (VALID_ITER (child, tree_model_sort), FALSE);
1168 
1169   level = child->user_data;
1170 
1171   if (level->parent_level)
1172     {
1173       iter->stamp = tree_model_sort->stamp;
1174       iter->user_data = level->parent_level;
1175       iter->user_data2 = SORT_LEVEL_PARENT_ELT (level);
1176 
1177       return TRUE;
1178     }
1179   return FALSE;
1180 }
1181 
1182 static void
gtk_tree_model_sort_ref_node(GtkTreeModel * tree_model,GtkTreeIter * iter)1183 gtk_tree_model_sort_ref_node (GtkTreeModel *tree_model,
1184 			      GtkTreeIter  *iter)
1185 {
1186   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1187   GtkTreeIter child_iter;
1188   SortLevel *level, *parent_level;
1189   SortElt *elt;
1190   gint parent_elt_index;
1191 
1192   g_return_if_fail (tree_model_sort->child_model != NULL);
1193   g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1194 
1195   GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1196 
1197   /* Reference the node in the child model */
1198   gtk_tree_model_ref_node (tree_model_sort->child_model, &child_iter);
1199 
1200   /* Increase the reference count of this element and its level */
1201   level = iter->user_data;
1202   elt = iter->user_data2;
1203 
1204   elt->ref_count++;
1205   level->ref_count++;
1206 
1207   /* Increase the reference count of all parent elements */
1208   parent_level = level->parent_level;
1209   parent_elt_index = level->parent_elt_index;
1210 
1211   while (parent_level)
1212     {
1213       GtkTreeIter tmp_iter;
1214 
1215       tmp_iter.stamp = tree_model_sort->stamp;
1216       tmp_iter.user_data = parent_level;
1217       tmp_iter.user_data2 = &g_array_index (parent_level->array, SortElt, parent_elt_index);
1218 
1219       gtk_tree_model_sort_ref_node (tree_model, &tmp_iter);
1220 
1221       parent_elt_index = parent_level->parent_elt_index;
1222       parent_level = parent_level->parent_level;
1223     }
1224 
1225   if (level->ref_count == 1)
1226     {
1227       SortLevel *parent_level = level->parent_level;
1228       gint parent_elt_index = level->parent_elt_index;
1229 
1230       /* We were at zero -- time to decrement the zero_ref_count val */
1231       while (parent_level)
1232         {
1233 	  g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count--;
1234 
1235           parent_elt_index = parent_level->parent_elt_index;
1236 	  parent_level = parent_level->parent_level;
1237 	}
1238 
1239       if (tree_model_sort->root != level)
1240 	tree_model_sort->zero_ref_count--;
1241     }
1242 }
1243 
1244 static void
gtk_tree_model_sort_real_unref_node(GtkTreeModel * tree_model,GtkTreeIter * iter,gboolean propagate_unref)1245 gtk_tree_model_sort_real_unref_node (GtkTreeModel *tree_model,
1246 				     GtkTreeIter  *iter,
1247 				     gboolean      propagate_unref)
1248 {
1249   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) tree_model;
1250   SortLevel *level, *parent_level;
1251   SortElt *elt;
1252   gint parent_elt_index;
1253 
1254   g_return_if_fail (tree_model_sort->child_model != NULL);
1255   g_return_if_fail (VALID_ITER (iter, tree_model_sort));
1256 
1257   if (propagate_unref)
1258     {
1259       GtkTreeIter child_iter;
1260 
1261       GET_CHILD_ITER (tree_model_sort, &child_iter, iter);
1262       gtk_tree_model_unref_node (tree_model_sort->child_model, &child_iter);
1263     }
1264 
1265   level = iter->user_data;
1266   elt = iter->user_data2;
1267 
1268   g_return_if_fail (elt->ref_count > 0);
1269 
1270   elt->ref_count--;
1271   level->ref_count--;
1272 
1273   /* Decrease the reference count of all parent elements */
1274   parent_level = level->parent_level;
1275   parent_elt_index = level->parent_elt_index;
1276 
1277   while (parent_level)
1278     {
1279       GtkTreeIter tmp_iter;
1280 
1281       tmp_iter.stamp = tree_model_sort->stamp;
1282       tmp_iter.user_data = parent_level;
1283       tmp_iter.user_data2 = &g_array_index (parent_level->array, SortElt, parent_elt_index);
1284 
1285       gtk_tree_model_sort_real_unref_node (tree_model, &tmp_iter, FALSE);
1286 
1287       parent_elt_index = parent_level->parent_elt_index;
1288       parent_level = parent_level->parent_level;
1289     }
1290 
1291   if (level->ref_count == 0)
1292     {
1293       SortLevel *parent_level = level->parent_level;
1294       gint parent_elt_index = level->parent_elt_index;
1295 
1296       /* We are at zero -- time to increment the zero_ref_count val */
1297       while (parent_level)
1298 	{
1299 	  g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count++;
1300 
1301 	  parent_elt_index = parent_level->parent_elt_index;
1302 	  parent_level = parent_level->parent_level;
1303 	}
1304 
1305       if (tree_model_sort->root != level)
1306 	tree_model_sort->zero_ref_count++;
1307     }
1308 }
1309 
1310 static void
gtk_tree_model_sort_unref_node(GtkTreeModel * tree_model,GtkTreeIter * iter)1311 gtk_tree_model_sort_unref_node (GtkTreeModel *tree_model,
1312 				GtkTreeIter  *iter)
1313 {
1314   gtk_tree_model_sort_real_unref_node (tree_model, iter, TRUE);
1315 }
1316 
1317 /* Sortable interface */
1318 static gboolean
gtk_tree_model_sort_get_sort_column_id(GtkTreeSortable * sortable,gint * sort_column_id,GtkSortType * order)1319 gtk_tree_model_sort_get_sort_column_id (GtkTreeSortable *sortable,
1320 					gint            *sort_column_id,
1321 					GtkSortType     *order)
1322 {
1323   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1324 
1325   if (sort_column_id)
1326     *sort_column_id = tree_model_sort->sort_column_id;
1327   if (order)
1328     *order = tree_model_sort->order;
1329 
1330   if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID ||
1331       tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1332     return FALSE;
1333 
1334   return TRUE;
1335 }
1336 
1337 static void
gtk_tree_model_sort_set_sort_column_id(GtkTreeSortable * sortable,gint sort_column_id,GtkSortType order)1338 gtk_tree_model_sort_set_sort_column_id (GtkTreeSortable *sortable,
1339 					gint             sort_column_id,
1340 					GtkSortType      order)
1341 {
1342   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1343 
1344   if (sort_column_id != GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1345     {
1346       if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1347         {
1348           GtkTreeDataSortHeader *header = NULL;
1349 
1350           header = _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1351 	  				           sort_column_id);
1352 
1353           /* we want to make sure that we have a function */
1354           g_return_if_fail (header != NULL);
1355           g_return_if_fail (header->func != NULL);
1356         }
1357       else
1358         g_return_if_fail (tree_model_sort->default_sort_func != NULL);
1359 
1360       if (tree_model_sort->sort_column_id == sort_column_id)
1361         {
1362           if (sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1363 	    {
1364 	      if (tree_model_sort->order == order)
1365 	        return;
1366 	    }
1367           else
1368 	    return;
1369         }
1370     }
1371 
1372   tree_model_sort->sort_column_id = sort_column_id;
1373   tree_model_sort->order = order;
1374 
1375   gtk_tree_sortable_sort_column_changed (sortable);
1376 
1377   gtk_tree_model_sort_sort (tree_model_sort);
1378 }
1379 
1380 static void
gtk_tree_model_sort_set_sort_func(GtkTreeSortable * sortable,gint sort_column_id,GtkTreeIterCompareFunc func,gpointer data,GDestroyNotify destroy)1381 gtk_tree_model_sort_set_sort_func (GtkTreeSortable        *sortable,
1382 				   gint                    sort_column_id,
1383 				   GtkTreeIterCompareFunc  func,
1384 				   gpointer                data,
1385 				   GDestroyNotify          destroy)
1386 {
1387   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) sortable;
1388 
1389   tree_model_sort->sort_list = _gtk_tree_data_list_set_header (tree_model_sort->sort_list,
1390 							       sort_column_id,
1391 							       func, data, destroy);
1392 
1393   if (tree_model_sort->sort_column_id == sort_column_id)
1394     gtk_tree_model_sort_sort (tree_model_sort);
1395 }
1396 
1397 static void
gtk_tree_model_sort_set_default_sort_func(GtkTreeSortable * sortable,GtkTreeIterCompareFunc func,gpointer data,GDestroyNotify destroy)1398 gtk_tree_model_sort_set_default_sort_func (GtkTreeSortable        *sortable,
1399 					   GtkTreeIterCompareFunc  func,
1400 					   gpointer                data,
1401 					   GDestroyNotify          destroy)
1402 {
1403   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1404 
1405   if (tree_model_sort->default_sort_destroy)
1406     {
1407       GDestroyNotify d = tree_model_sort->default_sort_destroy;
1408 
1409       tree_model_sort->default_sort_destroy = NULL;
1410       d (tree_model_sort->default_sort_data);
1411     }
1412 
1413   tree_model_sort->default_sort_func = func;
1414   tree_model_sort->default_sort_data = data;
1415   tree_model_sort->default_sort_destroy = destroy;
1416 
1417   if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1418     gtk_tree_model_sort_sort (tree_model_sort);
1419 }
1420 
1421 static gboolean
gtk_tree_model_sort_has_default_sort_func(GtkTreeSortable * sortable)1422 gtk_tree_model_sort_has_default_sort_func (GtkTreeSortable *sortable)
1423 {
1424   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)sortable;
1425 
1426   return (tree_model_sort->default_sort_func != NULL);
1427 }
1428 
1429 /* DragSource interface */
1430 static gboolean
gtk_tree_model_sort_row_draggable(GtkTreeDragSource * drag_source,GtkTreePath * path)1431 gtk_tree_model_sort_row_draggable (GtkTreeDragSource *drag_source,
1432                                    GtkTreePath       *path)
1433 {
1434   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1435   GtkTreePath *child_path;
1436   gboolean draggable;
1437 
1438   child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort,
1439                                                                path);
1440   draggable = gtk_tree_drag_source_row_draggable (GTK_TREE_DRAG_SOURCE (tree_model_sort->child_model), child_path);
1441   gtk_tree_path_free (child_path);
1442 
1443   return draggable;
1444 }
1445 
1446 static gboolean
gtk_tree_model_sort_drag_data_get(GtkTreeDragSource * drag_source,GtkTreePath * path,GtkSelectionData * selection_data)1447 gtk_tree_model_sort_drag_data_get (GtkTreeDragSource *drag_source,
1448                                    GtkTreePath       *path,
1449                                    GtkSelectionData  *selection_data)
1450 {
1451   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1452   GtkTreePath *child_path;
1453   gboolean gotten;
1454 
1455   child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1456   gotten = gtk_tree_drag_source_drag_data_get (GTK_TREE_DRAG_SOURCE (tree_model_sort->child_model), child_path, selection_data);
1457   gtk_tree_path_free (child_path);
1458 
1459   return gotten;
1460 }
1461 
1462 static gboolean
gtk_tree_model_sort_drag_data_delete(GtkTreeDragSource * drag_source,GtkTreePath * path)1463 gtk_tree_model_sort_drag_data_delete (GtkTreeDragSource *drag_source,
1464                                       GtkTreePath       *path)
1465 {
1466   GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *)drag_source;
1467   GtkTreePath *child_path;
1468   gboolean deleted;
1469 
1470   child_path = gtk_tree_model_sort_convert_path_to_child_path (tree_model_sort, path);
1471   deleted = gtk_tree_drag_source_drag_data_delete (GTK_TREE_DRAG_SOURCE (tree_model_sort->child_model), child_path);
1472   gtk_tree_path_free (child_path);
1473 
1474   return deleted;
1475 }
1476 
1477 /* sorting code - private */
1478 static gint
gtk_tree_model_sort_compare_func(gconstpointer a,gconstpointer b,gpointer user_data)1479 gtk_tree_model_sort_compare_func (gconstpointer a,
1480 				  gconstpointer b,
1481 				  gpointer      user_data)
1482 {
1483   SortData *data = (SortData *)user_data;
1484   GtkTreeModelSort *tree_model_sort = data->tree_model_sort;
1485   SortTuple *sa = (SortTuple *)a;
1486   SortTuple *sb = (SortTuple *)b;
1487 
1488   GtkTreeIter iter_a, iter_b;
1489   gint retval;
1490 
1491   /* shortcut, if we've the same offsets here, they should be equal */
1492   if (sa->offset == sb->offset)
1493     return 0;
1494 
1495   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1496     {
1497       iter_a = sa->elt->iter;
1498       iter_b = sb->elt->iter;
1499     }
1500   else
1501     {
1502       data->parent_path_indices [data->parent_path_depth-1] = sa->elt->offset;
1503       gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort->child_model), &iter_a, data->parent_path);
1504       data->parent_path_indices [data->parent_path_depth-1] = sb->elt->offset;
1505       gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort->child_model), &iter_b, data->parent_path);
1506     }
1507 
1508   retval = (* data->sort_func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1509 				&iter_a, &iter_b,
1510 				data->sort_data);
1511 
1512   if (tree_model_sort->order == GTK_SORT_DESCENDING)
1513     {
1514       if (retval > 0)
1515 	retval = -1;
1516       else if (retval < 0)
1517 	retval = 1;
1518     }
1519 
1520   return retval;
1521 }
1522 
1523 static gint
gtk_tree_model_sort_offset_compare_func(gconstpointer a,gconstpointer b,gpointer user_data)1524 gtk_tree_model_sort_offset_compare_func (gconstpointer a,
1525 					 gconstpointer b,
1526 					 gpointer      user_data)
1527 {
1528   gint retval;
1529 
1530   SortTuple *sa = (SortTuple *)a;
1531   SortTuple *sb = (SortTuple *)b;
1532 
1533   SortData *data = (SortData *)user_data;
1534 
1535   if (sa->elt->offset < sb->elt->offset)
1536     retval = -1;
1537   else if (sa->elt->offset > sb->elt->offset)
1538     retval = 1;
1539   else
1540     retval = 0;
1541 
1542   if (data->tree_model_sort->order == GTK_SORT_DESCENDING)
1543     {
1544       if (retval > 0)
1545 	retval = -1;
1546       else if (retval < 0)
1547 	retval = 1;
1548     }
1549 
1550   return retval;
1551 }
1552 
1553 static void
gtk_tree_model_sort_sort_level(GtkTreeModelSort * tree_model_sort,SortLevel * level,gboolean recurse,gboolean emit_reordered)1554 gtk_tree_model_sort_sort_level (GtkTreeModelSort *tree_model_sort,
1555 				SortLevel        *level,
1556 				gboolean          recurse,
1557 				gboolean          emit_reordered)
1558 {
1559   gint i;
1560   gint ref_offset;
1561   GArray *sort_array;
1562   GArray *new_array;
1563   gint *new_order;
1564 
1565   GtkTreeIter iter;
1566   GtkTreePath *path;
1567 
1568   SortData data;
1569 
1570   g_return_if_fail (level != NULL);
1571 
1572   if (level->array->len < 1 && !((SortElt *)level->array->data)->children)
1573     return;
1574 
1575   iter.stamp = tree_model_sort->stamp;
1576   iter.user_data = level;
1577   iter.user_data2 = &g_array_index (level->array, SortElt, 0);
1578 
1579   gtk_tree_model_sort_ref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1580   ref_offset = g_array_index (level->array, SortElt, 0).offset;
1581 
1582   /* Set up data */
1583   data.tree_model_sort = tree_model_sort;
1584   if (level->parent_elt_index >= 0)
1585     {
1586       data.parent_path = gtk_tree_model_sort_elt_get_path (level->parent_level,
1587 							   SORT_LEVEL_PARENT_ELT (level));
1588       gtk_tree_path_append_index (data.parent_path, 0);
1589     }
1590   else
1591     {
1592       data.parent_path = gtk_tree_path_new_first ();
1593     }
1594   data.parent_path_depth = gtk_tree_path_get_depth (data.parent_path);
1595   data.parent_path_indices = gtk_tree_path_get_indices (data.parent_path);
1596 
1597   /* make the array to be sorted */
1598   sort_array = g_array_sized_new (FALSE, FALSE, sizeof (SortTuple), level->array->len);
1599   for (i = 0; i < level->array->len; i++)
1600     {
1601       SortTuple tuple;
1602 
1603       tuple.elt = &g_array_index (level->array, SortElt, i);
1604       tuple.offset = i;
1605 
1606       g_array_append_val (sort_array, tuple);
1607     }
1608 
1609     if (tree_model_sort->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1610       {
1611 	GtkTreeDataSortHeader *header = NULL;
1612 
1613 	header = _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1614 						 tree_model_sort->sort_column_id);
1615 
1616 	g_return_if_fail (header != NULL);
1617 	g_return_if_fail (header->func != NULL);
1618 
1619 	data.sort_func = header->func;
1620 	data.sort_data = header->data;
1621       }
1622     else
1623       {
1624 	/* absolutely SHOULD NOT happen: */
1625 	g_return_if_fail (tree_model_sort->default_sort_func != NULL);
1626 
1627 	data.sort_func = tree_model_sort->default_sort_func;
1628 	data.sort_data = tree_model_sort->default_sort_data;
1629       }
1630 
1631   if (data.sort_func == NO_SORT_FUNC)
1632     g_array_sort_with_data (sort_array,
1633 			    gtk_tree_model_sort_offset_compare_func,
1634 			    &data);
1635   else
1636     g_array_sort_with_data (sort_array,
1637 			    gtk_tree_model_sort_compare_func,
1638 			    &data);
1639 
1640   gtk_tree_path_free (data.parent_path);
1641 
1642   new_array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), level->array->len);
1643   new_order = g_new (gint, level->array->len);
1644 
1645   for (i = 0; i < level->array->len; i++)
1646     {
1647       SortElt *elt;
1648 
1649       elt = g_array_index (sort_array, SortTuple, i).elt;
1650       new_order[i] = g_array_index (sort_array, SortTuple, i).offset;
1651 
1652       g_array_append_val (new_array, *elt);
1653       if (elt->children)
1654 	elt->children->parent_elt_index = i;
1655     }
1656 
1657   g_array_free (level->array, TRUE);
1658   level->array = new_array;
1659   g_array_free (sort_array, TRUE);
1660 
1661   if (emit_reordered)
1662     {
1663       gtk_tree_model_sort_increment_stamp (tree_model_sort);
1664       if (level->parent_elt_index >= 0)
1665 	{
1666 	  iter.stamp = tree_model_sort->stamp;
1667 	  iter.user_data = level->parent_level;
1668 	  iter.user_data2 = SORT_LEVEL_PARENT_ELT (level);
1669 
1670 	  path = gtk_tree_model_get_path (GTK_TREE_MODEL (tree_model_sort),
1671 					  &iter);
1672 
1673 	  gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1674 					 &iter, new_order);
1675 	}
1676       else
1677 	{
1678 	  /* toplevel list */
1679 	  path = gtk_tree_path_new ();
1680 	  gtk_tree_model_rows_reordered (GTK_TREE_MODEL (tree_model_sort), path,
1681 					 NULL, new_order);
1682 	}
1683 
1684       gtk_tree_path_free (path);
1685     }
1686 
1687   /* recurse, if possible */
1688   if (recurse)
1689     {
1690       for (i = 0; i < level->array->len; i++)
1691 	{
1692 	  SortElt *elt = &g_array_index (level->array, SortElt, i);
1693 
1694 	  if (elt->children)
1695 	    gtk_tree_model_sort_sort_level (tree_model_sort,
1696 					    elt->children,
1697 					    TRUE, emit_reordered);
1698 	}
1699     }
1700 
1701   g_free (new_order);
1702 
1703   /* get the iter we referenced at the beginning of this function and
1704    * unref it again
1705    */
1706   iter.stamp = tree_model_sort->stamp;
1707   iter.user_data = level;
1708 
1709   for (i = 0; i < level->array->len; i++)
1710     {
1711       if (g_array_index (level->array, SortElt, i).offset == ref_offset)
1712         {
1713 	  iter.user_data2 = &g_array_index (level->array, SortElt, i);
1714 	  break;
1715 	}
1716     }
1717 
1718   gtk_tree_model_sort_unref_node (GTK_TREE_MODEL (tree_model_sort), &iter);
1719 }
1720 
1721 static void
gtk_tree_model_sort_sort(GtkTreeModelSort * tree_model_sort)1722 gtk_tree_model_sort_sort (GtkTreeModelSort *tree_model_sort)
1723 {
1724   if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID)
1725     return;
1726 
1727   if (!tree_model_sort->root)
1728     return;
1729 
1730   if (tree_model_sort->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1731     {
1732       GtkTreeDataSortHeader *header = NULL;
1733 
1734       header = _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1735 					       tree_model_sort->sort_column_id);
1736 
1737       /* we want to make sure that we have a function */
1738       g_return_if_fail (header != NULL);
1739       g_return_if_fail (header->func != NULL);
1740     }
1741   else
1742     g_return_if_fail (tree_model_sort->default_sort_func != NULL);
1743 
1744   gtk_tree_model_sort_sort_level (tree_model_sort, tree_model_sort->root,
1745 				  TRUE, TRUE);
1746 }
1747 
1748 /* signal helpers */
1749 static gint
gtk_tree_model_sort_level_find_insert(GtkTreeModelSort * tree_model_sort,SortLevel * level,GtkTreeIter * iter,gint skip_index)1750 gtk_tree_model_sort_level_find_insert (GtkTreeModelSort *tree_model_sort,
1751 				       SortLevel        *level,
1752 				       GtkTreeIter      *iter,
1753 				       gint             skip_index)
1754 {
1755   gint start, middle, end;
1756   gint cmp;
1757   SortElt *tmp_elt;
1758   GtkTreeIter tmp_iter;
1759 
1760   GtkTreeIterCompareFunc func;
1761   gpointer data;
1762 
1763   if (tree_model_sort->sort_column_id != GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
1764     {
1765       GtkTreeDataSortHeader *header;
1766 
1767       header = _gtk_tree_data_list_get_header (tree_model_sort->sort_list,
1768 					       tree_model_sort->sort_column_id);
1769 
1770       g_return_val_if_fail (header != NULL, 0);
1771 
1772       func = header->func;
1773       data = header->data;
1774     }
1775   else
1776     {
1777       func = tree_model_sort->default_sort_func;
1778       data = tree_model_sort->default_sort_data;
1779 
1780       g_return_val_if_fail (func != NO_SORT_FUNC, 0);
1781     }
1782 
1783   g_return_val_if_fail (func != NULL, 0);
1784 
1785   start = 0;
1786   end = level->array->len;
1787   if (skip_index < 0)
1788     skip_index = end;
1789   else
1790     end--;
1791 
1792   if (start == end)
1793     return 0;
1794 
1795   while (start != end)
1796     {
1797       middle = (start + end) / 2;
1798 
1799       if (middle < skip_index)
1800 	tmp_elt = &(g_array_index (level->array, SortElt, middle));
1801       else
1802 	tmp_elt = &(g_array_index (level->array, SortElt, middle + 1));
1803 
1804       if (!GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1805 	{
1806 	  GtkTreePath *path = gtk_tree_model_sort_elt_get_path (level, tmp_elt);
1807 	  gtk_tree_model_get_iter (tree_model_sort->child_model,
1808 				   &tmp_iter, path);
1809 	  gtk_tree_path_free (path);
1810 	}
1811       else
1812 	tmp_iter = tmp_elt->iter;
1813 
1814       if (tree_model_sort->order == GTK_SORT_ASCENDING)
1815 	cmp = (* func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1816 			&tmp_iter, iter, data);
1817       else
1818 	cmp = (* func) (GTK_TREE_MODEL (tree_model_sort->child_model),
1819 			iter, &tmp_iter, data);
1820 
1821       if (cmp <= 0)
1822 	start = middle + 1;
1823       else
1824 	end = middle;
1825     }
1826 
1827   if (cmp <= 0)
1828     return middle + 1;
1829   else
1830     return middle;
1831 }
1832 
1833 static gboolean
gtk_tree_model_sort_insert_value(GtkTreeModelSort * tree_model_sort,SortLevel * level,GtkTreePath * s_path,GtkTreeIter * s_iter)1834 gtk_tree_model_sort_insert_value (GtkTreeModelSort *tree_model_sort,
1835 				  SortLevel        *level,
1836 				  GtkTreePath      *s_path,
1837 				  GtkTreeIter      *s_iter)
1838 {
1839   gint offset, index, i;
1840 
1841   SortElt elt;
1842   SortElt *tmp_elt;
1843 
1844   offset = gtk_tree_path_get_indices (s_path)[gtk_tree_path_get_depth (s_path) - 1];
1845 
1846   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
1847     elt.iter = *s_iter;
1848   elt.offset = offset;
1849   elt.zero_ref_count = 0;
1850   elt.ref_count = 0;
1851   elt.children = NULL;
1852 
1853   /* update all larger offsets */
1854   tmp_elt = SORT_ELT (level->array->data);
1855   for (i = 0; i < level->array->len; i++, tmp_elt++)
1856     if (tmp_elt->offset >= offset)
1857       tmp_elt->offset++;
1858 
1859   if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID &&
1860       tree_model_sort->default_sort_func == NO_SORT_FUNC)
1861     index = offset;
1862   else
1863     index = gtk_tree_model_sort_level_find_insert (tree_model_sort,
1864                                                    level, s_iter,
1865                                                    -1);
1866 
1867   g_array_insert_vals (level->array, index, &elt, 1);
1868   tmp_elt = SORT_ELT (level->array->data);
1869   for (i = 0; i < level->array->len; i++, tmp_elt++)
1870     if (tmp_elt->children)
1871       tmp_elt->children->parent_elt_index = i;
1872 
1873   return TRUE;
1874 }
1875 
1876 /* sort elt stuff */
1877 static GtkTreePath *
gtk_tree_model_sort_elt_get_path(SortLevel * level,SortElt * elt)1878 gtk_tree_model_sort_elt_get_path (SortLevel *level,
1879 				  SortElt *elt)
1880 {
1881   SortLevel *walker = level;
1882   SortElt *walker2 = elt;
1883   GtkTreePath *path;
1884 
1885   g_return_val_if_fail (level != NULL, NULL);
1886   g_return_val_if_fail (elt != NULL, NULL);
1887 
1888   path = gtk_tree_path_new ();
1889 
1890   while (walker)
1891     {
1892       gtk_tree_path_prepend_index (path, walker2->offset);
1893 
1894       if (!walker->parent_level)
1895 	break;
1896 
1897       walker2 = SORT_LEVEL_PARENT_ELT (walker);
1898       walker = walker->parent_level;
1899     }
1900 
1901   return path;
1902 }
1903 
1904 /**
1905  * gtk_tree_model_sort_set_model:
1906  * @tree_model_sort: The #GtkTreeModelSort.
1907  * @child_model: (allow-none): A #GtkTreeModel, or %NULL.
1908  *
1909  * Sets the model of @tree_model_sort to be @model.  If @model is %NULL,
1910  * then the old model is unset.  The sort function is unset as a result
1911  * of this call. The model will be in an unsorted state until a sort
1912  * function is set.
1913  **/
1914 static void
gtk_tree_model_sort_set_model(GtkTreeModelSort * tree_model_sort,GtkTreeModel * child_model)1915 gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
1916                                GtkTreeModel     *child_model)
1917 {
1918   if (child_model)
1919     g_object_ref (child_model);
1920 
1921   if (tree_model_sort->child_model)
1922     {
1923       g_signal_handler_disconnect (tree_model_sort->child_model,
1924                                    tree_model_sort->changed_id);
1925       g_signal_handler_disconnect (tree_model_sort->child_model,
1926                                    tree_model_sort->inserted_id);
1927       g_signal_handler_disconnect (tree_model_sort->child_model,
1928                                    tree_model_sort->has_child_toggled_id);
1929       g_signal_handler_disconnect (tree_model_sort->child_model,
1930                                    tree_model_sort->deleted_id);
1931       g_signal_handler_disconnect (tree_model_sort->child_model,
1932 				   tree_model_sort->reordered_id);
1933 
1934       /* reset our state */
1935       if (tree_model_sort->root)
1936 	gtk_tree_model_sort_free_level (tree_model_sort, tree_model_sort->root);
1937       tree_model_sort->root = NULL;
1938       _gtk_tree_data_list_header_free (tree_model_sort->sort_list);
1939       tree_model_sort->sort_list = NULL;
1940       g_object_unref (tree_model_sort->child_model);
1941     }
1942 
1943   tree_model_sort->child_model = child_model;
1944 
1945   if (child_model)
1946     {
1947       GType *types;
1948       gint i, n_columns;
1949 
1950       tree_model_sort->changed_id =
1951         g_signal_connect (child_model, "row-changed",
1952                           G_CALLBACK (gtk_tree_model_sort_row_changed),
1953                           tree_model_sort);
1954       tree_model_sort->inserted_id =
1955         g_signal_connect (child_model, "row-inserted",
1956                           G_CALLBACK (gtk_tree_model_sort_row_inserted),
1957                           tree_model_sort);
1958       tree_model_sort->has_child_toggled_id =
1959         g_signal_connect (child_model, "row-has-child-toggled",
1960                           G_CALLBACK (gtk_tree_model_sort_row_has_child_toggled),
1961                           tree_model_sort);
1962       tree_model_sort->deleted_id =
1963         g_signal_connect (child_model, "row-deleted",
1964                           G_CALLBACK (gtk_tree_model_sort_row_deleted),
1965                           tree_model_sort);
1966       tree_model_sort->reordered_id =
1967 	g_signal_connect (child_model, "rows-reordered",
1968 			  G_CALLBACK (gtk_tree_model_sort_rows_reordered),
1969 			  tree_model_sort);
1970 
1971       tree_model_sort->child_flags = gtk_tree_model_get_flags (child_model);
1972       n_columns = gtk_tree_model_get_n_columns (child_model);
1973 
1974       types = g_new (GType, n_columns);
1975       for (i = 0; i < n_columns; i++)
1976         types[i] = gtk_tree_model_get_column_type (child_model, i);
1977 
1978       tree_model_sort->sort_list = _gtk_tree_data_list_header_new (n_columns, types);
1979       g_free (types);
1980 
1981       tree_model_sort->default_sort_func = NO_SORT_FUNC;
1982       tree_model_sort->stamp = g_random_int ();
1983     }
1984 }
1985 
1986 /**
1987  * gtk_tree_model_sort_get_model:
1988  * @tree_model: a #GtkTreeModelSort
1989  *
1990  * Returns the model the #GtkTreeModelSort is sorting.
1991  *
1992  * Return value: (transfer none): the "child model" being sorted
1993  **/
1994 GtkTreeModel *
gtk_tree_model_sort_get_model(GtkTreeModelSort * tree_model)1995 gtk_tree_model_sort_get_model (GtkTreeModelSort *tree_model)
1996 {
1997   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
1998 
1999   return tree_model->child_model;
2000 }
2001 
2002 
2003 static GtkTreePath *
gtk_real_tree_model_sort_convert_child_path_to_path(GtkTreeModelSort * tree_model_sort,GtkTreePath * child_path,gboolean build_levels)2004 gtk_real_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2005 						     GtkTreePath      *child_path,
2006 						     gboolean          build_levels)
2007 {
2008   gint *child_indices;
2009   GtkTreePath *retval;
2010   SortLevel *level;
2011   gint i;
2012 
2013   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
2014   g_return_val_if_fail (child_path != NULL, NULL);
2015 
2016   retval = gtk_tree_path_new ();
2017   child_indices = gtk_tree_path_get_indices (child_path);
2018 
2019   if (tree_model_sort->root == NULL && build_levels)
2020     gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
2021   level = SORT_LEVEL (tree_model_sort->root);
2022 
2023   for (i = 0; i < gtk_tree_path_get_depth (child_path); i++)
2024     {
2025       gint j;
2026       gboolean found_child = FALSE;
2027 
2028       if (!level)
2029 	{
2030 	  gtk_tree_path_free (retval);
2031 	  return NULL;
2032 	}
2033 
2034       if (child_indices[i] >= level->array->len)
2035 	{
2036 	  gtk_tree_path_free (retval);
2037 	  return NULL;
2038 	}
2039       for (j = 0; j < level->array->len; j++)
2040 	{
2041 	  if ((g_array_index (level->array, SortElt, j)).offset == child_indices[i])
2042 	    {
2043 	      gtk_tree_path_append_index (retval, j);
2044 	      if (g_array_index (level->array, SortElt, j).children == NULL && build_levels)
2045 		{
2046 		  gtk_tree_model_sort_build_level (tree_model_sort, level, j);
2047 		}
2048 	      level = g_array_index (level->array, SortElt, j).children;
2049 	      found_child = TRUE;
2050 	      break;
2051 	    }
2052 	}
2053       if (! found_child)
2054 	{
2055 	  gtk_tree_path_free (retval);
2056 	  return NULL;
2057 	}
2058     }
2059 
2060   return retval;
2061 }
2062 
2063 
2064 /**
2065  * gtk_tree_model_sort_convert_child_path_to_path:
2066  * @tree_model_sort: A #GtkTreeModelSort
2067  * @child_path: A #GtkTreePath to convert
2068  *
2069  * Converts @child_path to a path relative to @tree_model_sort.  That is,
2070  * @child_path points to a path in the child model.  The returned path will
2071  * point to the same row in the sorted model.  If @child_path isn't a valid
2072  * path on the child model, then %NULL is returned.
2073  *
2074  * Return value: A newly allocated #GtkTreePath, or %NULL
2075  **/
2076 GtkTreePath *
gtk_tree_model_sort_convert_child_path_to_path(GtkTreeModelSort * tree_model_sort,GtkTreePath * child_path)2077 gtk_tree_model_sort_convert_child_path_to_path (GtkTreeModelSort *tree_model_sort,
2078 						GtkTreePath      *child_path)
2079 {
2080   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2081   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
2082   g_return_val_if_fail (child_path != NULL, NULL);
2083 
2084   return gtk_real_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path, TRUE);
2085 }
2086 
2087 /**
2088  * gtk_tree_model_sort_convert_child_iter_to_iter:
2089  * @tree_model_sort: A #GtkTreeModelSort
2090  * @sort_iter: (out): An uninitialized #GtkTreeIter.
2091  * @child_iter: A valid #GtkTreeIter pointing to a row on the child model
2092  *
2093  * Sets @sort_iter to point to the row in @tree_model_sort that corresponds to
2094  * the row pointed at by @child_iter.  If @sort_iter was not set, %FALSE
2095  * is returned.  Note: a boolean is only returned since 2.14.
2096  *
2097  * Return value: %TRUE, if @sort_iter was set, i.e. if @sort_iter is a
2098  * valid iterator pointer to a visible row in the child model.
2099  **/
2100 gboolean
gtk_tree_model_sort_convert_child_iter_to_iter(GtkTreeModelSort * tree_model_sort,GtkTreeIter * sort_iter,GtkTreeIter * child_iter)2101 gtk_tree_model_sort_convert_child_iter_to_iter (GtkTreeModelSort *tree_model_sort,
2102 						GtkTreeIter      *sort_iter,
2103 						GtkTreeIter      *child_iter)
2104 {
2105   gboolean ret;
2106   GtkTreePath *child_path, *path;
2107 
2108   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2109   g_return_val_if_fail (tree_model_sort->child_model != NULL, FALSE);
2110   g_return_val_if_fail (sort_iter != NULL, FALSE);
2111   g_return_val_if_fail (child_iter != NULL, FALSE);
2112   g_return_val_if_fail (sort_iter != child_iter, FALSE);
2113 
2114   sort_iter->stamp = 0;
2115 
2116   child_path = gtk_tree_model_get_path (tree_model_sort->child_model, child_iter);
2117   g_return_val_if_fail (child_path != NULL, FALSE);
2118 
2119   path = gtk_tree_model_sort_convert_child_path_to_path (tree_model_sort, child_path);
2120   gtk_tree_path_free (child_path);
2121 
2122   if (!path)
2123     {
2124       g_warning ("%s: The conversion of the child path to a GtkTreeModel sort path failed", G_STRLOC);
2125       return FALSE;
2126     }
2127 
2128   ret = gtk_tree_model_get_iter (GTK_TREE_MODEL (tree_model_sort),
2129                                  sort_iter, path);
2130   gtk_tree_path_free (path);
2131 
2132   return ret;
2133 }
2134 
2135 /**
2136  * gtk_tree_model_sort_convert_path_to_child_path:
2137  * @tree_model_sort: A #GtkTreeModelSort
2138  * @sorted_path: A #GtkTreePath to convert
2139  *
2140  * Converts @sorted_path to a path on the child model of @tree_model_sort.
2141  * That is, @sorted_path points to a location in @tree_model_sort.  The
2142  * returned path will point to the same location in the model not being
2143  * sorted.  If @sorted_path does not point to a location in the child model,
2144  * %NULL is returned.
2145  *
2146  * Return value: A newly allocated #GtkTreePath, or %NULL
2147  **/
2148 GtkTreePath *
gtk_tree_model_sort_convert_path_to_child_path(GtkTreeModelSort * tree_model_sort,GtkTreePath * sorted_path)2149 gtk_tree_model_sort_convert_path_to_child_path (GtkTreeModelSort *tree_model_sort,
2150 						GtkTreePath      *sorted_path)
2151 {
2152   gint *sorted_indices;
2153   GtkTreePath *retval;
2154   SortLevel *level;
2155   gint i;
2156 
2157   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), NULL);
2158   g_return_val_if_fail (tree_model_sort->child_model != NULL, NULL);
2159   g_return_val_if_fail (sorted_path != NULL, NULL);
2160 
2161   retval = gtk_tree_path_new ();
2162   sorted_indices = gtk_tree_path_get_indices (sorted_path);
2163   if (tree_model_sort->root == NULL)
2164     gtk_tree_model_sort_build_level (tree_model_sort, NULL, -1);
2165   level = SORT_LEVEL (tree_model_sort->root);
2166 
2167   for (i = 0; i < gtk_tree_path_get_depth (sorted_path); i++)
2168     {
2169       gint count = sorted_indices[i];
2170 
2171       if ((level == NULL) ||
2172 	  (level->array->len <= count))
2173 	{
2174 	  gtk_tree_path_free (retval);
2175 	  return NULL;
2176 	}
2177 
2178       if (g_array_index (level->array, SortElt, count).children == NULL)
2179 	gtk_tree_model_sort_build_level (tree_model_sort, level, count);
2180 
2181       if (level == NULL)
2182         {
2183 	  gtk_tree_path_free (retval);
2184 	  break;
2185 	}
2186 
2187       gtk_tree_path_append_index (retval, g_array_index (level->array, SortElt, count).offset);
2188       level = g_array_index (level->array, SortElt, count).children;
2189     }
2190 
2191   return retval;
2192 }
2193 
2194 /**
2195  * gtk_tree_model_sort_convert_iter_to_child_iter:
2196  * @tree_model_sort: A #GtkTreeModelSort
2197  * @child_iter: (out): An uninitialized #GtkTreeIter
2198  * @sorted_iter: A valid #GtkTreeIter pointing to a row on @tree_model_sort.
2199  *
2200  * Sets @child_iter to point to the row pointed to by @sorted_iter.
2201  **/
2202 void
gtk_tree_model_sort_convert_iter_to_child_iter(GtkTreeModelSort * tree_model_sort,GtkTreeIter * child_iter,GtkTreeIter * sorted_iter)2203 gtk_tree_model_sort_convert_iter_to_child_iter (GtkTreeModelSort *tree_model_sort,
2204 						GtkTreeIter      *child_iter,
2205 						GtkTreeIter      *sorted_iter)
2206 {
2207   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2208   g_return_if_fail (tree_model_sort->child_model != NULL);
2209   g_return_if_fail (child_iter != NULL);
2210   g_return_if_fail (VALID_ITER (sorted_iter, tree_model_sort));
2211   g_return_if_fail (sorted_iter != child_iter);
2212 
2213   if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2214     {
2215       *child_iter = SORT_ELT (sorted_iter->user_data2)->iter;
2216     }
2217   else
2218     {
2219       GtkTreePath *path;
2220 
2221       path = gtk_tree_model_sort_elt_get_path (sorted_iter->user_data,
2222 					       sorted_iter->user_data2);
2223       gtk_tree_model_get_iter (tree_model_sort->child_model, child_iter, path);
2224       gtk_tree_path_free (path);
2225     }
2226 }
2227 
2228 static void
gtk_tree_model_sort_build_level(GtkTreeModelSort * tree_model_sort,SortLevel * parent_level,gint parent_elt_index)2229 gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
2230 				 SortLevel        *parent_level,
2231 				 gint              parent_elt_index)
2232 {
2233   GtkTreeIter iter;
2234   SortElt *parent_elt = NULL;
2235   SortLevel *new_level;
2236   gint length = 0;
2237   gint i;
2238 
2239   g_assert (tree_model_sort->child_model != NULL);
2240 
2241   if (parent_level == NULL)
2242     {
2243       if (gtk_tree_model_get_iter_first (tree_model_sort->child_model, &iter) == FALSE)
2244 	return;
2245       length = gtk_tree_model_iter_n_children (tree_model_sort->child_model, NULL);
2246     }
2247   else
2248     {
2249       GtkTreeIter parent_iter;
2250       GtkTreeIter child_parent_iter;
2251 
2252       parent_elt = &g_array_index (parent_level->array, SortElt, parent_elt_index);
2253 
2254       parent_iter.stamp = tree_model_sort->stamp;
2255       parent_iter.user_data = parent_level;
2256       parent_iter.user_data2 = parent_elt;
2257 
2258       gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2259 						      &child_parent_iter,
2260 						      &parent_iter);
2261       if (gtk_tree_model_iter_children (tree_model_sort->child_model,
2262 					&iter,
2263 					&child_parent_iter) == FALSE)
2264 	return;
2265 
2266       /* stamp may have changed */
2267       gtk_tree_model_sort_convert_iter_to_child_iter (tree_model_sort,
2268 						      &child_parent_iter,
2269 						      &parent_iter);
2270 
2271       length = gtk_tree_model_iter_n_children (tree_model_sort->child_model, &child_parent_iter);
2272     }
2273 
2274   g_return_if_fail (length > 0);
2275 
2276   new_level = g_new (SortLevel, 1);
2277   new_level->array = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), length);
2278   new_level->ref_count = 0;
2279   new_level->parent_level = parent_level;
2280   new_level->parent_elt_index = parent_elt_index;
2281 
2282   if (parent_elt_index >= 0)
2283     parent_elt->children = new_level;
2284   else
2285     tree_model_sort->root = new_level;
2286 
2287   /* increase the count of zero ref_counts.*/
2288   while (parent_level)
2289     {
2290       g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count++;
2291 
2292       parent_elt_index = parent_level->parent_elt_index;
2293       parent_level = parent_level->parent_level;
2294     }
2295 
2296   if (new_level != tree_model_sort->root)
2297     tree_model_sort->zero_ref_count++;
2298 
2299   for (i = 0; i < length; i++)
2300     {
2301       SortElt sort_elt;
2302       sort_elt.offset = i;
2303       sort_elt.zero_ref_count = 0;
2304       sort_elt.ref_count = 0;
2305       sort_elt.children = NULL;
2306 
2307       if (GTK_TREE_MODEL_SORT_CACHE_CHILD_ITERS (tree_model_sort))
2308 	{
2309 	  sort_elt.iter = iter;
2310 	  if (gtk_tree_model_iter_next (tree_model_sort->child_model, &iter) == FALSE &&
2311 	      i < length - 1)
2312 	    {
2313 	      if (parent_level)
2314 	        {
2315 	          GtkTreePath *level;
2316 		  gchar *str;
2317 
2318 		  level = gtk_tree_model_sort_elt_get_path (parent_level,
2319 							    parent_elt);
2320 		  str = gtk_tree_path_to_string (level);
2321 		  gtk_tree_path_free (level);
2322 
2323 		  g_warning ("%s: There is a discrepancy between the sort model "
2324 			     "and the child model.  The child model is "
2325 			     "advertising a wrong length for level %s:.",
2326 			     G_STRLOC, str);
2327 		  g_free (str);
2328 		}
2329 	      else
2330 	        {
2331 		  g_warning ("%s: There is a discrepancy between the sort model "
2332 			     "and the child model.  The child model is "
2333 			     "advertising a wrong length for the root level.",
2334 			     G_STRLOC);
2335 		}
2336 
2337 	      return;
2338 	    }
2339 	}
2340       g_array_append_val (new_level->array, sort_elt);
2341     }
2342 
2343   /* sort level */
2344   gtk_tree_model_sort_sort_level (tree_model_sort, new_level,
2345 				  FALSE, FALSE);
2346 }
2347 
2348 static void
gtk_tree_model_sort_free_level(GtkTreeModelSort * tree_model_sort,SortLevel * sort_level)2349 gtk_tree_model_sort_free_level (GtkTreeModelSort *tree_model_sort,
2350 				SortLevel        *sort_level)
2351 {
2352   gint i;
2353 
2354   g_assert (sort_level);
2355 
2356   for (i = 0; i < sort_level->array->len; i++)
2357     {
2358       if (g_array_index (sort_level->array, SortElt, i).children)
2359 	gtk_tree_model_sort_free_level (tree_model_sort,
2360 					SORT_LEVEL (g_array_index (sort_level->array, SortElt, i).children));
2361     }
2362 
2363   if (sort_level->ref_count == 0)
2364     {
2365       SortLevel *parent_level = sort_level->parent_level;
2366       gint parent_elt_index = sort_level->parent_elt_index;
2367 
2368       while (parent_level)
2369         {
2370 	  g_array_index (parent_level->array, SortElt, parent_elt_index).zero_ref_count--;
2371 
2372           parent_elt_index = parent_level->parent_elt_index;
2373 	  parent_level = parent_level->parent_level;
2374 	}
2375 
2376       if (sort_level != tree_model_sort->root)
2377 	tree_model_sort->zero_ref_count--;
2378     }
2379 
2380   if (sort_level->parent_elt_index >= 0)
2381     SORT_LEVEL_PARENT_ELT (sort_level)->children = NULL;
2382   else
2383     tree_model_sort->root = NULL;
2384 
2385   g_array_free (sort_level->array, TRUE);
2386   sort_level->array = NULL;
2387 
2388   g_free (sort_level);
2389   sort_level = NULL;
2390 }
2391 
2392 static void
gtk_tree_model_sort_increment_stamp(GtkTreeModelSort * tree_model_sort)2393 gtk_tree_model_sort_increment_stamp (GtkTreeModelSort *tree_model_sort)
2394 {
2395   do
2396     {
2397       tree_model_sort->stamp++;
2398     }
2399   while (tree_model_sort->stamp == 0);
2400 
2401   gtk_tree_model_sort_clear_cache (tree_model_sort);
2402 }
2403 
2404 static void
gtk_tree_model_sort_clear_cache_helper(GtkTreeModelSort * tree_model_sort,SortLevel * level)2405 gtk_tree_model_sort_clear_cache_helper (GtkTreeModelSort *tree_model_sort,
2406 					SortLevel        *level)
2407 {
2408   gint i;
2409 
2410   g_assert (level != NULL);
2411 
2412   for (i = 0; i < level->array->len; i++)
2413     {
2414       if (g_array_index (level->array, SortElt, i).zero_ref_count > 0)
2415 	gtk_tree_model_sort_clear_cache_helper (tree_model_sort, g_array_index (level->array, SortElt, i).children);
2416     }
2417 
2418   if (level->ref_count == 0 && level != tree_model_sort->root)
2419     gtk_tree_model_sort_free_level (tree_model_sort, level);
2420 }
2421 
2422 /**
2423  * gtk_tree_model_sort_reset_default_sort_func:
2424  * @tree_model_sort: A #GtkTreeModelSort
2425  *
2426  * This resets the default sort function to be in the 'unsorted' state.  That
2427  * is, it is in the same order as the child model. It will re-sort the model
2428  * to be in the same order as the child model only if the #GtkTreeModelSort
2429  * is in 'unsorted' state.
2430  **/
2431 void
gtk_tree_model_sort_reset_default_sort_func(GtkTreeModelSort * tree_model_sort)2432 gtk_tree_model_sort_reset_default_sort_func (GtkTreeModelSort *tree_model_sort)
2433 {
2434   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2435 
2436   if (tree_model_sort->default_sort_destroy)
2437     {
2438       GDestroyNotify d = tree_model_sort->default_sort_destroy;
2439 
2440       tree_model_sort->default_sort_destroy = NULL;
2441       d (tree_model_sort->default_sort_data);
2442     }
2443 
2444   tree_model_sort->default_sort_func = NO_SORT_FUNC;
2445   tree_model_sort->default_sort_data = NULL;
2446   tree_model_sort->default_sort_destroy = NULL;
2447 
2448   if (tree_model_sort->sort_column_id == GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID)
2449     gtk_tree_model_sort_sort (tree_model_sort);
2450   tree_model_sort->sort_column_id = GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID;
2451 }
2452 
2453 /**
2454  * gtk_tree_model_sort_clear_cache:
2455  * @tree_model_sort: A #GtkTreeModelSort
2456  *
2457  * This function should almost never be called.  It clears the @tree_model_sort
2458  * of any cached iterators that haven't been reffed with
2459  * gtk_tree_model_ref_node().  This might be useful if the child model being
2460  * sorted is static (and doesn't change often) and there has been a lot of
2461  * unreffed access to nodes.  As a side effect of this function, all unreffed
2462  * iters will be invalid.
2463  **/
2464 void
gtk_tree_model_sort_clear_cache(GtkTreeModelSort * tree_model_sort)2465 gtk_tree_model_sort_clear_cache (GtkTreeModelSort *tree_model_sort)
2466 {
2467   g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
2468 
2469   if (tree_model_sort->zero_ref_count > 0)
2470     gtk_tree_model_sort_clear_cache_helper (tree_model_sort, (SortLevel *)tree_model_sort->root);
2471 }
2472 
2473 static gboolean
gtk_tree_model_sort_iter_is_valid_helper(GtkTreeIter * iter,SortLevel * level)2474 gtk_tree_model_sort_iter_is_valid_helper (GtkTreeIter *iter,
2475 					  SortLevel   *level)
2476 {
2477   gint i;
2478 
2479   for (i = 0; i < level->array->len; i++)
2480     {
2481       SortElt *elt = &g_array_index (level->array, SortElt, i);
2482 
2483       if (iter->user_data == level && iter->user_data2 == elt)
2484 	return TRUE;
2485 
2486       if (elt->children)
2487 	if (gtk_tree_model_sort_iter_is_valid_helper (iter, elt->children))
2488 	  return TRUE;
2489     }
2490 
2491   return FALSE;
2492 }
2493 
2494 /**
2495  * gtk_tree_model_sort_iter_is_valid:
2496  * @tree_model_sort: A #GtkTreeModelSort.
2497  * @iter: A #GtkTreeIter.
2498  *
2499  * <warning><para>
2500  * This function is slow. Only use it for debugging and/or testing purposes.
2501  * </para></warning>
2502  *
2503  * Checks if the given iter is a valid iter for this #GtkTreeModelSort.
2504  *
2505  * Return value: %TRUE if the iter is valid, %FALSE if the iter is invalid.
2506  *
2507  * Since: 2.2
2508  **/
2509 gboolean
gtk_tree_model_sort_iter_is_valid(GtkTreeModelSort * tree_model_sort,GtkTreeIter * iter)2510 gtk_tree_model_sort_iter_is_valid (GtkTreeModelSort *tree_model_sort,
2511                                    GtkTreeIter      *iter)
2512 {
2513   g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort), FALSE);
2514   g_return_val_if_fail (iter != NULL, FALSE);
2515 
2516   if (!VALID_ITER (iter, tree_model_sort))
2517     return FALSE;
2518 
2519   return gtk_tree_model_sort_iter_is_valid_helper (iter,
2520 						   tree_model_sort->root);
2521 }
2522 
2523 #define __GTK_TREE_MODEL_SORT_C__
2524 #include "gtkaliasdef.c"
2525