1 /* Extensive GtkTreeModelSort tests.
2  * Copyright (C) 2009,2011  Kristian Rietveld  <kris@gtk.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <gtk/gtk.h>
19 
20 #include "treemodel.h"
21 #include "gtktreemodelrefcount.h"
22 
23 
24 static void
ref_count_single_level(void)25 ref_count_single_level (void)
26 {
27   GtkTreeIter iter;
28   GtkTreeModel *model;
29   GtkTreeModelRefCount *ref_model;
30   GtkTreeModel *sort_model;
31   GtkWidget *tree_view;
32 
33   model = gtk_tree_model_ref_count_new ();
34   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
35 
36   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
37   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
38   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
39   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
40   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, NULL);
41 
42   assert_root_level_unreferenced (ref_model);
43 
44   sort_model = gtk_tree_model_sort_new_with_model (model);
45   tree_view = gtk_tree_view_new_with_model (sort_model);
46 
47   assert_entire_model_referenced (ref_model, 1);
48 
49   g_object_unref (g_object_ref_sink (tree_view));
50 
51   assert_entire_model_unreferenced (ref_model);
52 
53   g_object_unref (sort_model);
54   g_object_unref (ref_model);
55 }
56 
57 static void
ref_count_two_levels(void)58 ref_count_two_levels (void)
59 {
60   GtkTreeIter parent1, parent2, iter;
61   GtkTreeModel *model;
62   GtkTreeModelRefCount *ref_model;
63   GtkTreeModel *sort_model;
64   GtkWidget *tree_view;
65 
66   model = gtk_tree_model_ref_count_new ();
67   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
68 
69   gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, NULL);
70   gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, NULL);
71   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
72   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
73   gtk_tree_store_append (GTK_TREE_STORE (model), &iter, &parent2);
74 
75   assert_entire_model_unreferenced (ref_model);
76 
77   sort_model = gtk_tree_model_sort_new_with_model (model);
78   tree_view = gtk_tree_view_new_with_model (sort_model);
79 
80   assert_root_level_referenced (ref_model, 1);
81   assert_node_ref_count (ref_model, &iter, 0);
82 
83   gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
84 
85   assert_node_ref_count (ref_model, &parent1, 1);
86   assert_node_ref_count (ref_model, &parent2, 2);
87   assert_node_ref_count (ref_model, &iter, 1);
88 
89   gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
90 
91   assert_node_ref_count (ref_model, &parent1, 1);
92   assert_node_ref_count (ref_model, &parent2, 2);
93   assert_node_ref_count (ref_model, &iter, 0);
94 
95   gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
96 
97   assert_root_level_referenced (ref_model, 1);
98   assert_node_ref_count (ref_model, &iter, 0);
99 
100   g_object_unref (g_object_ref_sink (tree_view));
101 
102   assert_entire_model_unreferenced (ref_model);
103 
104   g_object_unref (sort_model);
105   g_object_unref (ref_model);
106 }
107 
108 static void
ref_count_three_levels(void)109 ref_count_three_levels (void)
110 {
111   GtkTreeIter grandparent1, grandparent2, parent1, parent2;
112   GtkTreeIter iter_parent1, iter_parent2;
113   GtkTreeModel *model;
114   GtkTreeModelRefCount *ref_model;
115   GtkTreeModel *sort_model;
116   GtkTreePath *path;
117   GtkWidget *tree_view;
118 
119   model = gtk_tree_model_ref_count_new ();
120   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
121 
122   /* + grandparent1
123    * + grandparent2
124    *   + parent1
125    *     + iter_parent1
126    *   + parent2
127    *     + iter_parent2
128    *     + iter_parent2
129    */
130 
131   gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
132   gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
133   gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
134   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
135   gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
136   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
137   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
138 
139   assert_entire_model_unreferenced (ref_model);
140 
141   sort_model = gtk_tree_model_sort_new_with_model (model);
142   tree_view = gtk_tree_view_new_with_model (sort_model);
143 
144   assert_root_level_referenced (ref_model, 1);
145   assert_node_ref_count (ref_model, &parent1, 0);
146   assert_node_ref_count (ref_model, &parent2, 0);
147   assert_level_unreferenced (ref_model, &parent1);
148   assert_level_unreferenced (ref_model, &parent2);
149 
150   path = gtk_tree_path_new_from_indices (1, -1);
151   gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
152 
153   assert_node_ref_count (ref_model, &grandparent1, 1);
154   assert_node_ref_count (ref_model, &grandparent2, 2);
155   assert_node_ref_count (ref_model, &parent1, 1);
156   assert_node_ref_count (ref_model, &parent2, 1);
157   assert_node_ref_count (ref_model, &iter_parent1, 0);
158   assert_node_ref_count (ref_model, &iter_parent2, 0);
159 
160   gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
161 
162   assert_node_ref_count (ref_model, &grandparent1, 1);
163   assert_node_ref_count (ref_model, &grandparent2, 2);
164   assert_node_ref_count (ref_model, &parent1, 2);
165   assert_node_ref_count (ref_model, &parent2, 2);
166   assert_node_ref_count (ref_model, &iter_parent1, 1);
167   assert_node_ref_count (ref_model, &iter_parent2, 1);
168 
169   gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
170 
171   assert_node_ref_count (ref_model, &grandparent1, 1);
172   assert_node_ref_count (ref_model, &grandparent2, 2);
173   assert_node_ref_count (ref_model, &parent1, 1);
174   assert_node_ref_count (ref_model, &parent2, 1);
175   assert_node_ref_count (ref_model, &iter_parent1, 0);
176   assert_node_ref_count (ref_model, &iter_parent2, 0);
177 
178   gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
179 
180   assert_root_level_referenced (ref_model, 1);
181   assert_node_ref_count (ref_model, &parent1, 0);
182   assert_node_ref_count (ref_model, &parent2, 0);
183 
184   gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
185 
186   assert_node_ref_count (ref_model, &grandparent1, 1);
187   assert_node_ref_count (ref_model, &grandparent2, 2);
188   assert_node_ref_count (ref_model, &parent1, 1);
189   assert_node_ref_count (ref_model, &parent2, 1);
190   assert_node_ref_count (ref_model, &iter_parent1, 0);
191   assert_node_ref_count (ref_model, &iter_parent2, 0);
192 
193   gtk_tree_path_append_index (path, 1);
194   gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
195 
196   assert_node_ref_count (ref_model, &grandparent1, 1);
197   assert_node_ref_count (ref_model, &grandparent2, 2);
198   assert_node_ref_count (ref_model, &parent1, 1);
199   assert_node_ref_count (ref_model, &parent2, 2);
200   assert_node_ref_count (ref_model, &iter_parent1, 0);
201   assert_node_ref_count (ref_model, &iter_parent2, 1);
202 
203   gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
204 
205   assert_node_ref_count (ref_model, &grandparent1, 1);
206   assert_node_ref_count (ref_model, &grandparent2, 2);
207   assert_node_ref_count (ref_model, &parent1, 1);
208   assert_node_ref_count (ref_model, &parent2, 2);
209   assert_node_ref_count (ref_model, &iter_parent1, 0);
210   assert_node_ref_count (ref_model, &iter_parent2, 0);
211 
212   gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
213 
214   assert_node_ref_count (ref_model, &grandparent1, 1);
215   assert_node_ref_count (ref_model, &grandparent2, 2);
216   assert_node_ref_count (ref_model, &parent1, 1);
217   assert_node_ref_count (ref_model, &parent2, 1);
218   assert_node_ref_count (ref_model, &iter_parent1, 0);
219   assert_node_ref_count (ref_model, &iter_parent2, 0);
220 
221   gtk_tree_path_up (path);
222   gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
223   gtk_tree_path_free (path);
224 
225   assert_node_ref_count (ref_model, &grandparent1, 1);
226   assert_node_ref_count (ref_model, &grandparent2, 2);
227   assert_node_ref_count (ref_model, &parent1, 0);
228   assert_node_ref_count (ref_model, &parent2, 0);
229   assert_node_ref_count (ref_model, &iter_parent1, 0);
230   assert_node_ref_count (ref_model, &iter_parent2, 0);
231 
232   gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
233 
234   assert_node_ref_count (ref_model, &grandparent1, 1);
235   assert_node_ref_count (ref_model, &grandparent2, 1);
236   assert_node_ref_count (ref_model, &parent1, 0);
237   assert_node_ref_count (ref_model, &parent2, 0);
238   assert_node_ref_count (ref_model, &iter_parent1, 0);
239   assert_node_ref_count (ref_model, &iter_parent2, 0);
240 
241   g_object_unref (g_object_ref_sink (tree_view));
242 
243   assert_entire_model_unreferenced (ref_model);
244 
245   g_object_unref (sort_model);
246   g_object_unref (ref_model);
247 }
248 
249 static void
ref_count_delete_row(void)250 ref_count_delete_row (void)
251 {
252   GtkTreeIter grandparent1, grandparent2, parent1, parent2;
253   GtkTreeIter iter_parent1, iter_parent2;
254   GtkTreeModel *model;
255   GtkTreeModelRefCount *ref_model;
256   GtkTreeModel *sort_model;
257   GtkTreePath *path;
258   GtkWidget *tree_view;
259 
260   model = gtk_tree_model_ref_count_new ();
261   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
262 
263   /* + grandparent1
264    * + grandparent2
265    *   + parent1
266    *     + iter_parent1
267    *   + parent2
268    *     + iter_parent2
269    *     + iter_parent2
270    */
271 
272   gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
273   gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
274   gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
275   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
276   gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
277   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
278   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
279 
280   assert_entire_model_unreferenced (ref_model);
281 
282   sort_model = gtk_tree_model_sort_new_with_model (model);
283   tree_view = gtk_tree_view_new_with_model (sort_model);
284 
285   assert_root_level_referenced (ref_model, 1);
286   assert_node_ref_count (ref_model, &parent1, 0);
287   assert_node_ref_count (ref_model, &parent2, 0);
288   assert_level_unreferenced (ref_model, &parent1);
289   assert_level_unreferenced (ref_model, &parent2);
290 
291   path = gtk_tree_path_new_from_indices (1, -1);
292   gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
293   gtk_tree_path_free (path);
294 
295   assert_node_ref_count (ref_model, &grandparent1, 1);
296   assert_node_ref_count (ref_model, &grandparent2, 2);
297   assert_node_ref_count (ref_model, &parent1, 2);
298   assert_node_ref_count (ref_model, &parent2, 2);
299   assert_node_ref_count (ref_model, &iter_parent1, 1);
300   assert_node_ref_count (ref_model, &iter_parent2, 1);
301 
302   gtk_tree_store_remove (GTK_TREE_STORE (model), &iter_parent2);
303 
304   assert_node_ref_count (ref_model, &grandparent1, 1);
305   assert_node_ref_count (ref_model, &grandparent2, 2);
306   assert_node_ref_count (ref_model, &parent1, 2);
307   assert_level_referenced (ref_model, 1, &parent1);
308   assert_node_ref_count (ref_model, &parent2, 2);
309   assert_level_referenced (ref_model, 1, &parent2);
310 
311   gtk_tree_store_remove (GTK_TREE_STORE (model), &parent1);
312 
313   assert_node_ref_count (ref_model, &grandparent1, 1);
314   assert_node_ref_count (ref_model, &grandparent2, 2);
315   assert_node_ref_count (ref_model, &parent2, 2);
316   assert_level_referenced (ref_model, 1, &parent2);
317 
318   gtk_tree_store_remove (GTK_TREE_STORE (model), &grandparent2);
319 
320   assert_node_ref_count (ref_model, &grandparent1, 1);
321 
322   gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
323 
324   assert_node_ref_count (ref_model, &grandparent1, 1);
325 
326   g_object_unref (g_object_ref_sink (tree_view));
327 
328   assert_entire_model_unreferenced (ref_model);
329 
330   g_object_unref (sort_model);
331   g_object_unref (ref_model);
332 }
333 
334 static void
ref_count_cleanup(void)335 ref_count_cleanup (void)
336 {
337   GtkTreeIter grandparent1, grandparent2, parent1, parent2;
338   GtkTreeIter iter_parent1, iter_parent2;
339   GtkTreeModel *model;
340   GtkTreeModelRefCount *ref_model;
341   GtkTreeModel *sort_model;
342   GtkWidget *tree_view;
343 
344   model = gtk_tree_model_ref_count_new ();
345   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
346 
347   /* + grandparent1
348    * + grandparent2
349    *   + parent1
350    *     + iter_parent1
351    *   + parent2
352    *     + iter_parent2
353    *     + iter_parent2
354    */
355 
356   gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
357   gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
358   gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
359   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
360   gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
361   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
362   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
363 
364   sort_model = gtk_tree_model_sort_new_with_model (model);
365   tree_view = gtk_tree_view_new_with_model (sort_model);
366 
367   gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
368 
369   g_object_unref (g_object_ref_sink (tree_view));
370 
371   assert_node_ref_count (ref_model, &grandparent1, 0);
372   assert_node_ref_count (ref_model, &grandparent2, 1);
373   assert_node_ref_count (ref_model, &parent1, 1);
374   assert_node_ref_count (ref_model, &parent2, 1);
375   assert_node_ref_count (ref_model, &iter_parent1, 0);
376   assert_node_ref_count (ref_model, &iter_parent2, 0);
377 
378   gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
379 
380   assert_entire_model_unreferenced (ref_model);
381 
382   g_object_unref (sort_model);
383   g_object_unref (ref_model);
384 }
385 
386 static void
ref_count_row_ref(void)387 ref_count_row_ref (void)
388 {
389   GtkTreeIter grandparent1, grandparent2, parent1, parent2;
390   GtkTreeIter iter_parent1, iter_parent2;
391   GtkTreeModel *model;
392   GtkTreeModelRefCount *ref_model;
393   GtkTreeModel *sort_model;
394   GtkWidget *tree_view;
395   GtkTreePath *path;
396   GtkTreeRowReference *row_ref;
397 
398   model = gtk_tree_model_ref_count_new ();
399   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
400 
401   /* + grandparent1
402    * + grandparent2
403    *   + parent1
404    *     + iter_parent1
405    *   + parent2
406    *     + iter_parent2
407    *     + iter_parent2
408    */
409 
410   gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent1, NULL);
411   gtk_tree_store_append (GTK_TREE_STORE (model), &grandparent2, NULL);
412   gtk_tree_store_append (GTK_TREE_STORE (model), &parent1, &grandparent2);
413   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent1, &parent1);
414   gtk_tree_store_append (GTK_TREE_STORE (model), &parent2, &grandparent2);
415   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
416   gtk_tree_store_append (GTK_TREE_STORE (model), &iter_parent2, &parent2);
417 
418   sort_model = gtk_tree_model_sort_new_with_model (model);
419   tree_view = gtk_tree_view_new_with_model (sort_model);
420 
421   path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
422   row_ref = gtk_tree_row_reference_new (sort_model, path);
423   gtk_tree_path_free (path);
424 
425   assert_node_ref_count (ref_model, &grandparent1, 1);
426   /* Referenced because the node is visible, its child level is built
427    * and referenced by the row ref.
428    */
429   assert_node_ref_count (ref_model, &grandparent2, 3);
430   assert_node_ref_count (ref_model, &parent1, 0);
431   /* Referenced by the row ref and because its child level is built. */
432   assert_node_ref_count (ref_model, &parent2, 2);
433   assert_node_ref_count (ref_model, &iter_parent1, 0);
434   assert_node_ref_count (ref_model, &iter_parent2, 1);
435 
436   gtk_tree_row_reference_free (row_ref);
437 
438   assert_node_ref_count (ref_model, &grandparent1, 1);
439   assert_node_ref_count (ref_model, &grandparent2, 2);
440   assert_node_ref_count (ref_model, &parent1, 0);
441   assert_node_ref_count (ref_model, &parent2, 1);
442   assert_node_ref_count (ref_model, &iter_parent1, 0);
443   assert_node_ref_count (ref_model, &iter_parent2, 0);
444 
445   path = gtk_tree_path_new_from_indices (1, 1, 1, -1);
446   row_ref = gtk_tree_row_reference_new (sort_model, path);
447   gtk_tree_path_free (path);
448 
449   assert_node_ref_count (ref_model, &grandparent1, 1);
450   /* Referenced because the node is visible, its child level is built
451    * and referenced by the row ref.
452    */
453   assert_node_ref_count (ref_model, &grandparent2, 3);
454   assert_node_ref_count (ref_model, &parent1, 0);
455   /* Referenced by the row ref and because its child level is built. */
456   assert_node_ref_count (ref_model, &parent2, 2);
457   assert_node_ref_count (ref_model, &iter_parent1, 0);
458   assert_node_ref_count (ref_model, &iter_parent2, 1);
459 
460   gtk_tree_store_remove (GTK_TREE_STORE (model), &parent2);
461 
462   assert_node_ref_count (ref_model, &grandparent1, 1);
463   assert_node_ref_count (ref_model, &grandparent2, 1);
464   assert_node_ref_count (ref_model, &parent1, 0);
465   assert_node_ref_count (ref_model, &iter_parent1, 0);
466 
467   gtk_tree_row_reference_free (row_ref);
468 
469   assert_node_ref_count (ref_model, &grandparent1, 1);
470   assert_node_ref_count (ref_model, &grandparent2, 1);
471   assert_node_ref_count (ref_model, &parent1, 0);
472   assert_node_ref_count (ref_model, &iter_parent1, 0);
473 
474   g_object_unref (g_object_ref_sink (tree_view));
475   g_object_unref (sort_model);
476 
477   assert_entire_model_unreferenced (ref_model);
478 
479   g_object_unref (ref_model);
480 }
481 
482 static void
ref_count_reorder_single(void)483 ref_count_reorder_single (void)
484 {
485   GtkTreeIter iter1, iter2, iter3, iter4, iter5;
486   GtkTreeIter siter1, siter2, siter3, siter4, siter5;
487   GtkTreeModel *model;
488   GtkTreeModelRefCount *ref_model;
489   GtkTreeModel *sort_model;
490   GtkWidget *tree_view;
491   GType column_types[] = { G_TYPE_INT };
492 
493   model = gtk_tree_model_ref_count_new ();
494   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
495 
496   gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
497                                    column_types);
498 
499   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
500                                      0, 30, -1);
501   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
502                                      0, 40, -1);
503   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
504                                      0, 10, -1);
505   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
506                                      0, 20, -1);
507   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
508                                      0, 60, -1);
509 
510   assert_root_level_unreferenced (ref_model);
511 
512   sort_model = gtk_tree_model_sort_new_with_model (model);
513   tree_view = gtk_tree_view_new_with_model (sort_model);
514 
515   assert_entire_model_referenced (ref_model, 1);
516 
517   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
518   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
519   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
520   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
521   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
522 
523   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
524   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
525 
526   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
527   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
528   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
529 
530   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter5);
531 
532   assert_node_ref_count (ref_model, &iter1, 3);
533   assert_node_ref_count (ref_model, &iter2, 1);
534   assert_node_ref_count (ref_model, &iter3, 4);
535   assert_node_ref_count (ref_model, &iter4, 1);
536   assert_node_ref_count (ref_model, &iter5, 2);
537 
538   /* Sort */
539   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
540                                         0, GTK_SORT_ASCENDING);
541 
542   assert_node_ref_count (ref_model, &iter1, 3);
543   assert_node_ref_count (ref_model, &iter2, 1);
544   assert_node_ref_count (ref_model, &iter3, 4);
545   assert_node_ref_count (ref_model, &iter4, 1);
546   assert_node_ref_count (ref_model, &iter5, 2);
547 
548   /* Re-translate the iters after sorting */
549   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
550   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
551   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
552   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
553   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
554 
555   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
556   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
557 
558   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
559   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
560   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
561 
562   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter5);
563 
564   assert_entire_model_referenced (ref_model, 1);
565 
566   g_object_unref (g_object_ref_sink (tree_view));
567   g_object_unref (sort_model);
568 
569   assert_entire_model_unreferenced (ref_model);
570 
571   g_object_unref (ref_model);
572 }
573 
574 static void
ref_count_reorder_two(void)575 ref_count_reorder_two (void)
576 {
577   GtkTreeIter iter1, iter2, iter3, iter4, iter5;
578   GtkTreeIter citer1, citer2, citer3, citer4, citer5;
579   GtkTreeIter siter1, siter2, siter3, siter4, siter5;
580   GtkTreeIter sciter1, sciter2, sciter3, sciter4, sciter5;
581   GtkTreeModel *model;
582   GtkTreeModelRefCount *ref_model;
583   GtkTreeModel *sort_model;
584   GtkWidget *tree_view;
585   GType column_types[] = { G_TYPE_INT };
586 
587   model = gtk_tree_model_ref_count_new ();
588   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
589 
590   gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
591                                    column_types);
592 
593   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
594                                      0, 30, -1);
595   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
596                                      0, 40, -1);
597   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
598                                      0, 10, -1);
599   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
600                                      0, 20, -1);
601   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
602                                      0, 60, -1);
603 
604   /* Child level */
605   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer1, &iter1, 0,
606                                      0, 30, -1);
607   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer2, &iter1, 1,
608                                      0, 40, -1);
609   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer3, &iter1, 2,
610                                      0, 10, -1);
611   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer4, &iter1, 3,
612                                      0, 20, -1);
613   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer5, &iter1, 4,
614                                      0, 60, -1);
615 
616   assert_root_level_unreferenced (ref_model);
617 
618   sort_model = gtk_tree_model_sort_new_with_model (model);
619   tree_view = gtk_tree_view_new_with_model (sort_model);
620   gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
621 
622   assert_node_ref_count (ref_model, &iter1, 2);
623   assert_node_ref_count (ref_model, &iter2, 1);
624   assert_node_ref_count (ref_model, &iter3, 1);
625   assert_node_ref_count (ref_model, &iter4, 1);
626   assert_node_ref_count (ref_model, &iter5, 1);
627 
628   assert_level_referenced (ref_model, 1, &iter1);
629 
630   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
631   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
632   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
633   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
634   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
635 
636   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter1, &citer1);
637   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter2, &citer2);
638   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter3, &citer3);
639   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter4, &citer4);
640   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter5, &citer5);
641 
642   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
643   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter1);
644 
645   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
646   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
647   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter3);
648 
649   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &siter5);
650 
651   assert_node_ref_count (ref_model, &iter1, 4);
652   assert_node_ref_count (ref_model, &iter2, 1);
653   assert_node_ref_count (ref_model, &iter3, 4);
654   assert_node_ref_count (ref_model, &iter4, 1);
655   assert_node_ref_count (ref_model, &iter5, 2);
656 
657   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter3);
658   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter3);
659 
660   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter5);
661   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter5);
662   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter5);
663 
664   gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), &sciter1);
665 
666   assert_node_ref_count (ref_model, &citer1, 2);
667   assert_node_ref_count (ref_model, &citer2, 1);
668   assert_node_ref_count (ref_model, &citer3, 3);
669   assert_node_ref_count (ref_model, &citer4, 1);
670   assert_node_ref_count (ref_model, &citer5, 4);
671 
672   /* Sort */
673   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
674                                         0, GTK_SORT_ASCENDING);
675 
676   assert_node_ref_count (ref_model, &iter1, 4);
677   assert_node_ref_count (ref_model, &iter2, 1);
678   assert_node_ref_count (ref_model, &iter3, 4);
679   assert_node_ref_count (ref_model, &iter4, 1);
680   assert_node_ref_count (ref_model, &iter5, 2);
681 
682   assert_node_ref_count (ref_model, &citer1, 2);
683   assert_node_ref_count (ref_model, &citer2, 1);
684   assert_node_ref_count (ref_model, &citer3, 3);
685   assert_node_ref_count (ref_model, &citer4, 1);
686   assert_node_ref_count (ref_model, &citer5, 4);
687 
688   /* Re-translate the iters after sorting */
689   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter1, &iter1);
690   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter2, &iter2);
691   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter3, &iter3);
692   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter4, &iter4);
693   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &siter5, &iter5);
694 
695   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter1, &citer1);
696   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter2, &citer2);
697   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter3, &citer3);
698   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter4, &citer4);
699   gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), &sciter5, &citer5);
700 
701   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
702   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter1);
703 
704   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
705   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
706   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter3);
707 
708   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &siter5);
709 
710   assert_node_ref_count (ref_model, &iter1, 2);
711   assert_node_ref_count (ref_model, &iter2, 1);
712   assert_node_ref_count (ref_model, &iter3, 1);
713   assert_node_ref_count (ref_model, &iter4, 1);
714   assert_node_ref_count (ref_model, &iter5, 1);
715 
716   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter3);
717   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter3);
718 
719   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter5);
720   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter5);
721   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter5);
722 
723   gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), &sciter1);
724 
725   assert_level_referenced (ref_model, 1, &iter1);
726 
727   g_object_unref (g_object_ref_sink (tree_view));
728   g_object_unref (sort_model);
729 
730   assert_entire_model_unreferenced (ref_model);
731 
732   g_object_unref (ref_model);
733 }
734 
735 static void
check_sort_order(GtkTreeModel * sort_model,GtkSortType sort_order,const char * parent_path)736 check_sort_order (GtkTreeModel *sort_model,
737                   GtkSortType   sort_order,
738                   const char   *parent_path)
739 {
740   int prev_value;
741   GtkTreeIter siter;
742 
743   if (!parent_path)
744     gtk_tree_model_get_iter_first (sort_model, &siter);
745   else
746     {
747       GtkTreePath *path;
748 
749       path = gtk_tree_path_new_from_string (parent_path);
750       gtk_tree_path_append_index (path, 0);
751 
752       gtk_tree_model_get_iter (sort_model, &siter, path);
753 
754       gtk_tree_path_free (path);
755     }
756 
757   if (sort_order == GTK_SORT_ASCENDING)
758     prev_value = -1;
759   else
760     prev_value = INT_MAX;
761 
762   do
763     {
764       int value;
765 
766       gtk_tree_model_get (sort_model, &siter, 0, &value, -1);
767       if (sort_order == GTK_SORT_ASCENDING)
768         g_assert_cmpint (prev_value, <=, value);
769       else
770         g_assert_cmpint (prev_value, >=, value);
771 
772       prev_value = value;
773     }
774   while (gtk_tree_model_iter_next (sort_model, &siter));
775 }
776 
777 static void
rows_reordered_single_level(void)778 rows_reordered_single_level (void)
779 {
780   GtkTreeIter iter1, iter2, iter3, iter4, iter5;
781   GtkTreeModel *model;
782   GtkTreeModelRefCount *ref_model;
783   GtkTreeModel *sort_model;
784   GtkWidget *tree_view;
785   SignalMonitor *monitor;
786   GtkTreePath *path;
787   GType column_types[] = { G_TYPE_INT };
788   int order[][5] =
789     {
790         { 2, 3, 0, 1, 4 },
791         { 4, 3, 2, 1, 0 },
792         { 2, 1, 4, 3, 0 }
793     };
794 
795   model = gtk_tree_model_ref_count_new ();
796   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
797 
798   gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
799                                    column_types);
800 
801   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
802                                      0, 30, -1);
803   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
804                                      0, 40, -1);
805   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
806                                      0, 10, -1);
807   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
808                                      0, 20, -1);
809   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
810                                      0, 60, -1);
811 
812   sort_model = gtk_tree_model_sort_new_with_model (model);
813   tree_view = gtk_tree_view_new_with_model (sort_model);
814 
815   monitor = signal_monitor_new (sort_model);
816 
817   /* Sort */
818   path = gtk_tree_path_new ();
819   signal_monitor_append_signal_reordered (monitor,
820                                           ROWS_REORDERED,
821                                           path, order[0], 5);
822   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
823                                         0, GTK_SORT_ASCENDING);
824   signal_monitor_assert_is_empty (monitor);
825   check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
826 
827   signal_monitor_append_signal_reordered (monitor,
828                                           ROWS_REORDERED,
829                                           path, order[1], 5);
830   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
831                                         0, GTK_SORT_DESCENDING);
832   signal_monitor_assert_is_empty (monitor);
833   check_sort_order (sort_model, GTK_SORT_DESCENDING, NULL);
834 
835   signal_monitor_append_signal_reordered (monitor,
836                                           ROWS_REORDERED,
837                                           path, order[2], 5);
838   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
839                                         GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
840                                         GTK_SORT_ASCENDING);
841   signal_monitor_assert_is_empty (monitor);
842 
843   gtk_tree_path_free (path);
844   signal_monitor_free (monitor);
845 
846   g_object_unref (g_object_ref_sink (tree_view));
847   g_object_unref (sort_model);
848 
849   assert_entire_model_unreferenced (ref_model);
850 
851   g_object_unref (ref_model);
852 }
853 
854 static void
rows_reordered_two_levels(void)855 rows_reordered_two_levels (void)
856 {
857   GtkTreeIter iter1, iter2, iter3, iter4, iter5;
858   GtkTreeIter citer1, citer2, citer3, citer4, citer5;
859   GtkTreeModel *model;
860   GtkTreeModelRefCount *ref_model;
861   GtkTreeModel *sort_model;
862   GtkWidget *tree_view;
863   SignalMonitor *monitor;
864   GtkTreePath *path, *child_path;
865   GType column_types[] = { G_TYPE_INT };
866   int order[][5] =
867     {
868         { 2, 3, 0, 1, 4 },
869         { 4, 3, 2, 1, 0 },
870         { 2, 1, 4, 3, 0 }
871     };
872 
873   model = gtk_tree_model_ref_count_new ();
874   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
875 
876   gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
877                                    column_types);
878 
879   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
880                                      0, 30, -1);
881   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
882                                      0, 40, -1);
883   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
884                                      0, 10, -1);
885   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
886                                      0, 20, -1);
887   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
888                                      0, 60, -1);
889 
890   /* Child level */
891   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer1, &iter1, 0,
892                                      0, 30, -1);
893   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer2, &iter1, 1,
894                                      0, 40, -1);
895   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer3, &iter1, 2,
896                                      0, 10, -1);
897   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer4, &iter1, 3,
898                                      0, 20, -1);
899   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &citer5, &iter1, 4,
900                                      0, 60, -1);
901 
902   sort_model = gtk_tree_model_sort_new_with_model (model);
903   tree_view = gtk_tree_view_new_with_model (sort_model);
904   gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
905 
906   monitor = signal_monitor_new (sort_model);
907 
908   /* Sort */
909   path = gtk_tree_path_new ();
910   child_path = gtk_tree_path_new_from_indices (2, -1);
911   signal_monitor_append_signal_reordered (monitor,
912                                           ROWS_REORDERED,
913                                           path, order[0], 5);
914   signal_monitor_append_signal_reordered (monitor,
915                                           ROWS_REORDERED,
916                                           child_path, order[0], 5);
917   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
918                                         0, GTK_SORT_ASCENDING);
919   signal_monitor_assert_is_empty (monitor);
920   check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
921   /* The parent node of the child level moved due to sorting */
922   check_sort_order (sort_model, GTK_SORT_ASCENDING, "2");
923 
924   signal_monitor_append_signal_reordered (monitor,
925                                           ROWS_REORDERED,
926                                           path, order[1], 5);
927   signal_monitor_append_signal_reordered (monitor,
928                                           ROWS_REORDERED,
929                                           child_path, order[1], 5);
930   gtk_tree_path_free (child_path);
931   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
932                                         0, GTK_SORT_DESCENDING);
933   signal_monitor_assert_is_empty (monitor);
934   check_sort_order (sort_model, GTK_SORT_DESCENDING, NULL);
935   /* The parent node of the child level moved due to sorting */
936   check_sort_order (sort_model, GTK_SORT_DESCENDING, "2");
937 
938   child_path = gtk_tree_path_new_from_indices (0, -1);
939   signal_monitor_append_signal_reordered (monitor,
940                                           ROWS_REORDERED,
941                                           path, order[2], 5);
942   signal_monitor_append_signal_reordered (monitor,
943                                           ROWS_REORDERED,
944                                           child_path, order[2], 5);
945   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
946                                         GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
947                                         GTK_SORT_ASCENDING);
948   signal_monitor_assert_is_empty (monitor);
949 
950   gtk_tree_path_free (path);
951   gtk_tree_path_free (child_path);
952   signal_monitor_free (monitor);
953 
954   g_object_unref (g_object_ref_sink (tree_view));
955   g_object_unref (sort_model);
956 
957   g_object_unref (ref_model);
958 }
959 
960 static void
sorted_insert(void)961 sorted_insert (void)
962 {
963   GtkTreeIter iter1, iter2, iter3, iter4, iter5, new_iter;
964   GtkTreeModel *model;
965   GtkTreeModelRefCount *ref_model;
966   GtkTreeModel *sort_model;
967   GtkWidget *tree_view;
968   SignalMonitor *monitor;
969   GtkTreePath *path;
970   GType column_types[] = { G_TYPE_INT };
971   int order0[] = { 1, 2, 3, 0, 4, 5, 6 };
972 
973   model = gtk_tree_model_ref_count_new ();
974   ref_model = GTK_TREE_MODEL_REF_COUNT (model);
975 
976   gtk_tree_store_set_column_types (GTK_TREE_STORE (model), 1,
977                                    column_types);
978 
979   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter1, NULL, 0,
980                                      0, 30, -1);
981   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter2, NULL, 1,
982                                      0, 40, -1);
983   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter3, NULL, 2,
984                                      0, 10, -1);
985   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter4, NULL, 3,
986                                      0, 20, -1);
987   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &iter5, NULL, 4,
988                                      0, 60, -1);
989 
990   sort_model = gtk_tree_model_sort_new_with_model (model);
991   tree_view = gtk_tree_view_new_with_model (sort_model);
992 
993   /* Sort */
994   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
995                                         0, GTK_SORT_ASCENDING);
996   check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
997 
998   monitor = signal_monitor_new (sort_model);
999 
1000   /* Insert a new item */
1001   signal_monitor_append_signal (monitor, ROW_INSERTED, "4");
1002   gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &new_iter, NULL,
1003                                      5, 0, 50, -1);
1004   signal_monitor_assert_is_empty (monitor);
1005   check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
1006 
1007   /* Sort the tree sort and append a new item */
1008   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model),
1009                                         0, GTK_SORT_ASCENDING);
1010   check_sort_order (model, GTK_SORT_ASCENDING, NULL);
1011 
1012   path = gtk_tree_path_new ();
1013   signal_monitor_append_signal (monitor, ROW_INSERTED, "0");
1014   signal_monitor_append_signal_reordered (monitor,
1015                                           ROWS_REORDERED,
1016                                           path, order0, 7);
1017   signal_monitor_append_signal (monitor, ROW_CHANGED, "3");
1018   gtk_tree_store_append (GTK_TREE_STORE (model), &new_iter, NULL);
1019   gtk_tree_store_set (GTK_TREE_STORE (model), &new_iter, 0, 35, -1);
1020   check_sort_order (model, GTK_SORT_ASCENDING, NULL);
1021   check_sort_order (sort_model, GTK_SORT_ASCENDING, NULL);
1022 
1023   gtk_tree_path_free (path);
1024   signal_monitor_free (monitor);
1025 
1026   g_object_unref (g_object_ref_sink (tree_view));
1027   g_object_unref (sort_model);
1028 
1029   g_object_unref (ref_model);
1030 }
1031 
1032 
1033 static void
specific_bug_300089(void)1034 specific_bug_300089 (void)
1035 {
1036   /* Test case for GNOME Bugzilla bug 300089.  Written by
1037    * Matthias Clasen.
1038    */
1039   GtkTreeModel *sort_model, *child_model;
1040   GtkTreePath *path;
1041   GtkTreeIter iter, iter2, sort_iter;
1042 
1043   /*http://bugzilla.gnome.org/show_bug.cgi?id=300089 */
1044 
1045   child_model = GTK_TREE_MODEL (gtk_tree_store_new (1, G_TYPE_STRING));
1046 
1047   gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
1048   gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
1049   gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
1050   gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "B", -1);
1051 
1052   gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
1053   gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "D", -1);
1054   gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter2, &iter);
1055   gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter2, 0, "E", -1);
1056 
1057   gtk_tree_store_append (GTK_TREE_STORE (child_model), &iter, NULL);
1058   gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "C", -1);
1059 
1060 
1061   sort_model = GTK_TREE_MODEL (gtk_tree_model_sort_new_with_model (child_model));
1062   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
1063                                         0, GTK_SORT_ASCENDING);
1064 
1065   path = gtk_tree_path_new_from_indices (1, 1, -1);
1066 
1067   /* make sure a level is constructed */
1068   gtk_tree_model_get_iter (sort_model, &sort_iter, path);
1069 
1070   /* change the "E" row in a way that causes it to change position */
1071   gtk_tree_model_get_iter (child_model, &iter, path);
1072   gtk_tree_store_set (GTK_TREE_STORE (child_model), &iter, 0, "A", -1);
1073 
1074   gtk_tree_path_free (path);
1075 }
1076 
1077 static void
specific_bug_364946(void)1078 specific_bug_364946 (void)
1079 {
1080   /* This is a test case for GNOME Bugzilla bug 364946.  It was written
1081    * by Andreas Koehler.
1082    */
1083   GtkTreeStore *store;
1084   GtkTreeIter a, aa, aaa, aab, iter;
1085   GtkTreeModel *s_model;
1086 
1087   /*http://bugzilla.gnome.org/show_bug.cgi?id=364946 */
1088 
1089   store = gtk_tree_store_new (1, G_TYPE_STRING);
1090 
1091   gtk_tree_store_append (store, &a, NULL);
1092   gtk_tree_store_set (store, &a, 0, "0", -1);
1093 
1094   gtk_tree_store_append (store, &aa, &a);
1095   gtk_tree_store_set (store, &aa, 0, "0:0", -1);
1096 
1097   gtk_tree_store_append (store, &aaa, &aa);
1098   gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
1099 
1100   gtk_tree_store_append (store, &aab, &aa);
1101   gtk_tree_store_set (store, &aab, 0, "0:0:1", -1);
1102 
1103   s_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
1104   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (s_model), 0,
1105                                         GTK_SORT_ASCENDING);
1106 
1107   gtk_tree_model_get_iter_from_string (s_model, &iter, "0:0:0");
1108 
1109   gtk_tree_store_set (store, &aaa, 0, "0:0:0", -1);
1110   gtk_tree_store_remove (store, &aaa);
1111   gtk_tree_store_remove (store, &aab);
1112 
1113   gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (s_model));
1114 }
1115 
1116 static void
iter_test(GtkTreeModel * model)1117 iter_test (GtkTreeModel *model)
1118 {
1119   GtkTreeIter a, b;
1120 
1121   g_assert_true (gtk_tree_model_get_iter_first (model, &a));
1122 
1123   g_assert_true (gtk_tree_model_iter_next (model, &a));
1124   g_assert_true (gtk_tree_model_iter_next (model, &a));
1125   b = a;
1126   g_assert_false (gtk_tree_model_iter_next (model, &b));
1127 
1128   g_assert_true (gtk_tree_model_iter_previous (model, &a));
1129   g_assert_true (gtk_tree_model_iter_previous (model, &a));
1130   b = a;
1131   g_assert_false (gtk_tree_model_iter_previous (model, &b));
1132 }
1133 
1134 static void
specific_bug_674587(void)1135 specific_bug_674587 (void)
1136 {
1137   GtkListStore *l;
1138   GtkTreeStore *t;
1139   GtkTreeModel *m;
1140   GtkTreeIter a;
1141 
1142   l = gtk_list_store_new (1, G_TYPE_STRING);
1143 
1144   gtk_list_store_append (l, &a);
1145   gtk_list_store_set (l, &a, 0, "0", -1);
1146   gtk_list_store_append (l, &a);
1147   gtk_list_store_set (l, &a, 0, "1", -1);
1148   gtk_list_store_append (l, &a);
1149   gtk_list_store_set (l, &a, 0, "2", -1);
1150 
1151   iter_test (GTK_TREE_MODEL (l));
1152 
1153   g_object_unref (l);
1154 
1155   t = gtk_tree_store_new (1, G_TYPE_STRING);
1156 
1157   gtk_tree_store_append (t, &a, NULL);
1158   gtk_tree_store_set (t, &a, 0, "0", -1);
1159   gtk_tree_store_append (t, &a, NULL);
1160   gtk_tree_store_set (t, &a, 0, "1", -1);
1161   gtk_tree_store_append (t, &a, NULL);
1162   gtk_tree_store_set (t, &a, 0, "2", -1);
1163 
1164   iter_test (GTK_TREE_MODEL (t));
1165 
1166   m = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (t));
1167 
1168   iter_test (m);
1169 
1170   g_object_unref (t);
1171   g_object_unref (m);
1172 }
1173 
1174 static void
row_deleted_cb(GtkTreeModel * tree_model,GtkTreePath * path,guint * count)1175 row_deleted_cb (GtkTreeModel *tree_model,
1176     GtkTreePath  *path,
1177     guint *count)
1178 {
1179   *count = *count + 1;
1180 }
1181 
1182 static void
specific_bug_698846(void)1183 specific_bug_698846 (void)
1184 {
1185   GtkListStore *store;
1186   GtkTreeModel *sorted;
1187   GtkTreeIter iter;
1188   guint count = 0;
1189 
1190   /*http://bugzilla.gnome.org/show_bug.cgi?id=698846 */
1191 
1192   store = gtk_list_store_new (1, G_TYPE_STRING);
1193   sorted = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
1194 
1195   gtk_list_store_insert_with_values (store, &iter, 0, 0, "a", -1);
1196   gtk_list_store_insert_with_values (store, &iter, 1, 0, "b", -1);
1197 
1198   g_signal_connect (sorted, "row-deleted", G_CALLBACK (row_deleted_cb), &count);
1199 
1200   gtk_list_store_clear (store);
1201 
1202   g_assert_cmpuint (count, ==, 2);
1203 }
1204 
1205 static int
sort_func(GtkTreeModel * model,GtkTreeIter * a,GtkTreeIter * b,gpointer data)1206 sort_func (GtkTreeModel *model,
1207            GtkTreeIter  *a,
1208            GtkTreeIter  *b,
1209            gpointer      data)
1210 {
1211   return 0;
1212 }
1213 
1214 static int column_changed;
1215 
1216 static void
sort_column_changed(GtkTreeSortable * sortable)1217 sort_column_changed (GtkTreeSortable *sortable)
1218 {
1219   column_changed++;
1220 }
1221 
1222 static void
sort_column_change(void)1223 sort_column_change (void)
1224 {
1225   GtkListStore *store;
1226   GtkTreeModel *sorted;
1227   int col;
1228   GtkSortType order;
1229   gboolean ret;
1230 
1231   /*http://bugzilla.gnome.org/show_bug.cgi?id=792459 */
1232 
1233   store = gtk_list_store_new (1, G_TYPE_STRING);
1234   sorted = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (store));
1235 
1236   column_changed = 0;
1237   g_signal_connect (sorted, "sort-column-changed", G_CALLBACK (sort_column_changed), NULL);
1238 
1239   g_assert_false (gtk_tree_sortable_has_default_sort_func (GTK_TREE_SORTABLE (sorted)));
1240   gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (sorted), sort_func, NULL, NULL);
1241   g_assert_true (gtk_tree_sortable_has_default_sort_func (GTK_TREE_SORTABLE (sorted)));
1242 
1243   gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (sorted), 0, sort_func, NULL, NULL);
1244 
1245   ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), &col, &order);
1246   g_assert_cmpint (column_changed, ==, 0);
1247   g_assert_false (ret);
1248   g_assert_cmpint (col, ==, GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID);
1249   g_assert_cmpint (order, ==, GTK_SORT_ASCENDING);
1250 
1251   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sorted),
1252                                         GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_DESCENDING);
1253   ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), &col, &order);
1254   g_assert_cmpint (column_changed, ==, 1);
1255   g_assert_false (ret);
1256   g_assert_cmpint (col, ==, GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID);
1257   g_assert_cmpint (order, ==, GTK_SORT_DESCENDING);
1258 
1259   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sorted),
1260                                         GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_DESCENDING);
1261   ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), &col, &order);
1262   g_assert_cmpint (column_changed, ==, 1);
1263   g_assert_false (ret);
1264   g_assert_cmpint (col, ==, GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID);
1265   g_assert_cmpint (order, ==, GTK_SORT_DESCENDING);
1266 
1267   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sorted),
1268                                         0, GTK_SORT_DESCENDING);
1269   ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), &col, &order);
1270   g_assert_cmpint (column_changed, ==, 2);
1271   g_assert_true (ret);
1272   g_assert_cmpint (col, ==, 0);
1273   g_assert_cmpint (order, ==, GTK_SORT_DESCENDING);
1274 
1275   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sorted),
1276                                         GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
1277   ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), &col, &order);
1278   g_assert_cmpint (column_changed, ==, 3);
1279   g_assert_false (ret);
1280   g_assert_cmpint (col, ==, GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID);
1281   g_assert_cmpint (order, ==, GTK_SORT_ASCENDING);
1282 
1283   gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sorted),
1284                                         GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID, GTK_SORT_ASCENDING);
1285   ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), &col, &order);
1286   g_assert_cmpint (column_changed, ==, 4);
1287   g_assert_false (ret);
1288   g_assert_cmpint (col, ==, GTK_TREE_SORTABLE_UNSORTED_SORT_COLUMN_ID);
1289   g_assert_cmpint (order, ==, GTK_SORT_ASCENDING);
1290 }
1291 
1292 /* main */
1293 
1294 void
register_sort_model_tests(void)1295 register_sort_model_tests (void)
1296 {
1297   g_test_add_func ("/TreeModelSort/ref-count/single-level",
1298                    ref_count_single_level);
1299   g_test_add_func ("/TreeModelSort/ref-count/two-levels",
1300                    ref_count_two_levels);
1301   g_test_add_func ("/TreeModelSort/ref-count/three-levels",
1302                    ref_count_three_levels);
1303   g_test_add_func ("/TreeModelSort/ref-count/delete-row",
1304                    ref_count_delete_row);
1305   g_test_add_func ("/TreeModelSort/ref-count/cleanup",
1306                    ref_count_cleanup);
1307   g_test_add_func ("/TreeModelSort/ref-count/row-ref",
1308                    ref_count_row_ref);
1309   g_test_add_func ("/TreeModelSort/ref-count/reorder/single-level",
1310                    ref_count_reorder_single);
1311   g_test_add_func ("/TreeModelSort/ref-count/reorder/two-levels",
1312                    ref_count_reorder_two);
1313 
1314   g_test_add_func ("/TreeModelSort/rows-reordered/single-level",
1315                    rows_reordered_single_level);
1316   g_test_add_func ("/TreeModelSort/rows-reordered/two-levels",
1317                    rows_reordered_two_levels);
1318   g_test_add_func ("/TreeModelSort/sorted-insert",
1319                    sorted_insert);
1320 
1321   g_test_add_func ("/TreeModelSort/specific/bug-300089",
1322                    specific_bug_300089);
1323   g_test_add_func ("/TreeModelSort/specific/bug-364946",
1324                    specific_bug_364946);
1325   g_test_add_func ("/TreeModelSort/specific/bug-674587",
1326                    specific_bug_674587);
1327   g_test_add_func ("/TreeModelSort/specific/bug-698846",
1328                    specific_bug_698846);
1329   g_test_add_func ("/TreeModelSort/specific/bug-792459",
1330                    sort_column_change);
1331 }
1332 
1333