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
24static void
25ref_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: &iter, NULL);
37 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter, NULL);
38 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter, NULL);
39 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter, NULL);
40 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter, NULL);
41
42 assert_root_level_unreferenced (ref_model);
43
44 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
45 tree_view = gtk_tree_view_new_with_model (model: sort_model);
46
47 assert_entire_model_referenced (ref_model, ref_count: 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 (object: sort_model);
54 g_object_unref (object: ref_model);
55}
56
57static void
58ref_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), iter: &parent1, NULL);
70 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &parent2, NULL);
71 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter, parent: &parent2);
72 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter, parent: &parent2);
73 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter, parent: &parent2);
74
75 assert_entire_model_unreferenced (ref_model);
76
77 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
78 tree_view = gtk_tree_view_new_with_model (model: sort_model);
79
80 assert_root_level_referenced (ref_model, ref_count: 1);
81 assert_node_ref_count (ref_model, iter: &iter, ref_count: 0);
82
83 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
84
85 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 1);
86 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
87 assert_node_ref_count (ref_model, iter: &iter, ref_count: 1);
88
89 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
90
91 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 1);
92 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
93 assert_node_ref_count (ref_model, iter: &iter, ref_count: 0);
94
95 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
96
97 assert_root_level_referenced (ref_model, ref_count: 1);
98 assert_node_ref_count (ref_model, iter: &iter, ref_count: 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 (object: sort_model);
105 g_object_unref (object: ref_model);
106}
107
108static void
109ref_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), iter: &grandparent1, NULL);
132 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &grandparent2, NULL);
133 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &parent1, parent: &grandparent2);
134 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent1, parent: &parent1);
135 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &parent2, parent: &grandparent2);
136 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent2, parent: &parent2);
137 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent2, parent: &parent2);
138
139 assert_entire_model_unreferenced (ref_model);
140
141 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
142 tree_view = gtk_tree_view_new_with_model (model: sort_model);
143
144 assert_root_level_referenced (ref_model, ref_count: 1);
145 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
146 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 0);
147 assert_level_unreferenced (ref_model, iter: &parent1);
148 assert_level_unreferenced (ref_model, iter: &parent2);
149
150 path = gtk_tree_path_new_from_indices (first_index: 1, -1);
151 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
152
153 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
154 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
155 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 1);
156 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 1);
157 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
158 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 0);
159
160 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, TRUE);
161
162 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
163 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
164 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 2);
165 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
166 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 1);
167 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 1);
168
169 gtk_tree_view_collapse_all (GTK_TREE_VIEW (tree_view));
170
171 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
172 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
173 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 1);
174 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 1);
175 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
176 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 0);
177
178 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
179
180 assert_root_level_referenced (ref_model, ref_count: 1);
181 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
182 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 0);
183
184 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
185
186 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
187 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
188 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 1);
189 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 1);
190 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
191 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 0);
192
193 gtk_tree_path_append_index (path, index_: 1);
194 gtk_tree_view_expand_row (GTK_TREE_VIEW (tree_view), path, FALSE);
195
196 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
197 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
198 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 1);
199 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
200 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
201 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 1);
202
203 gtk_tree_view_collapse_row (GTK_TREE_VIEW (tree_view), path);
204
205 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
206 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
207 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 1);
208 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
209 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
210 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 0);
211
212 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
213
214 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
215 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
216 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 1);
217 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 1);
218 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
219 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 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, iter: &grandparent1, ref_count: 1);
226 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
227 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
228 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 0);
229 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
230 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 0);
231
232 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
233
234 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
235 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 1);
236 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
237 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 0);
238 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
239 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 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 (object: sort_model);
246 g_object_unref (object: ref_model);
247}
248
249static void
250ref_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), iter: &grandparent1, NULL);
273 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &grandparent2, NULL);
274 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &parent1, parent: &grandparent2);
275 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent1, parent: &parent1);
276 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &parent2, parent: &grandparent2);
277 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent2, parent: &parent2);
278 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent2, parent: &parent2);
279
280 assert_entire_model_unreferenced (ref_model);
281
282 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
283 tree_view = gtk_tree_view_new_with_model (model: sort_model);
284
285 assert_root_level_referenced (ref_model, ref_count: 1);
286 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
287 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 0);
288 assert_level_unreferenced (ref_model, iter: &parent1);
289 assert_level_unreferenced (ref_model, iter: &parent2);
290
291 path = gtk_tree_path_new_from_indices (first_index: 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, iter: &grandparent1, ref_count: 1);
296 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
297 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 2);
298 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
299 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 1);
300 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 1);
301
302 gtk_tree_store_remove (GTK_TREE_STORE (model), iter: &iter_parent2);
303
304 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
305 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
306 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 2);
307 assert_level_referenced (ref_model, ref_count: 1, iter: &parent1);
308 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
309 assert_level_referenced (ref_model, ref_count: 1, iter: &parent2);
310
311 gtk_tree_store_remove (GTK_TREE_STORE (model), iter: &parent1);
312
313 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
314 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
315 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
316 assert_level_referenced (ref_model, ref_count: 1, iter: &parent2);
317
318 gtk_tree_store_remove (GTK_TREE_STORE (model), iter: &grandparent2);
319
320 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
321
322 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (sort_model));
323
324 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 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 (object: sort_model);
331 g_object_unref (object: ref_model);
332}
333
334static void
335ref_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), iter: &grandparent1, NULL);
357 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &grandparent2, NULL);
358 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &parent1, parent: &grandparent2);
359 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent1, parent: &parent1);
360 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &parent2, parent: &grandparent2);
361 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent2, parent: &parent2);
362 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent2, parent: &parent2);
363
364 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
365 tree_view = gtk_tree_view_new_with_model (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, iter: &grandparent1, ref_count: 0);
372 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 1);
373 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 1);
374 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 1);
375 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
376 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 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 (object: sort_model);
383 g_object_unref (object: ref_model);
384}
385
386static void
387ref_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), iter: &grandparent1, NULL);
411 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &grandparent2, NULL);
412 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &parent1, parent: &grandparent2);
413 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent1, parent: &parent1);
414 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &parent2, parent: &grandparent2);
415 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent2, parent: &parent2);
416 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &iter_parent2, parent: &parent2);
417
418 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
419 tree_view = gtk_tree_view_new_with_model (model: sort_model);
420
421 path = gtk_tree_path_new_from_indices (first_index: 1, 1, 1, -1);
422 row_ref = gtk_tree_row_reference_new (model: sort_model, path);
423 gtk_tree_path_free (path);
424
425 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 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, iter: &grandparent2, ref_count: 3);
430 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
431 /* Referenced by the row ref and because its child level is built. */
432 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
433 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
434 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 1);
435
436 gtk_tree_row_reference_free (reference: row_ref);
437
438 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
439 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 2);
440 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
441 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 1);
442 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
443 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 0);
444
445 path = gtk_tree_path_new_from_indices (first_index: 1, 1, 1, -1);
446 row_ref = gtk_tree_row_reference_new (model: sort_model, path);
447 gtk_tree_path_free (path);
448
449 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 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, iter: &grandparent2, ref_count: 3);
454 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
455 /* Referenced by the row ref and because its child level is built. */
456 assert_node_ref_count (ref_model, iter: &parent2, ref_count: 2);
457 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
458 assert_node_ref_count (ref_model, iter: &iter_parent2, ref_count: 1);
459
460 gtk_tree_store_remove (GTK_TREE_STORE (model), iter: &parent2);
461
462 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
463 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 1);
464 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
465 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
466
467 gtk_tree_row_reference_free (reference: row_ref);
468
469 assert_node_ref_count (ref_model, iter: &grandparent1, ref_count: 1);
470 assert_node_ref_count (ref_model, iter: &grandparent2, ref_count: 1);
471 assert_node_ref_count (ref_model, iter: &parent1, ref_count: 0);
472 assert_node_ref_count (ref_model, iter: &iter_parent1, ref_count: 0);
473
474 g_object_unref (g_object_ref_sink (tree_view));
475 g_object_unref (object: sort_model);
476
477 assert_entire_model_unreferenced (ref_model);
478
479 g_object_unref (object: ref_model);
480}
481
482static void
483ref_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), n_columns: 1,
497 types: column_types);
498
499 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter1, NULL, position: 0,
500 0, 30, -1);
501 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter2, NULL, position: 1,
502 0, 40, -1);
503 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter3, NULL, position: 2,
504 0, 10, -1);
505 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter4, NULL, position: 3,
506 0, 20, -1);
507 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter5, NULL, position: 4,
508 0, 60, -1);
509
510 assert_root_level_unreferenced (ref_model);
511
512 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
513 tree_view = gtk_tree_view_new_with_model (model: sort_model);
514
515 assert_entire_model_referenced (ref_model, ref_count: 1);
516
517 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter1, child_iter: &iter1);
518 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter2, child_iter: &iter2);
519 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter3, child_iter: &iter3);
520 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter4, child_iter: &iter4);
521 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter5, child_iter: &iter5);
522
523 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter1);
524 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter1);
525
526 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
527 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
528 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
529
530 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter5);
531
532 assert_node_ref_count (ref_model, iter: &iter1, ref_count: 3);
533 assert_node_ref_count (ref_model, iter: &iter2, ref_count: 1);
534 assert_node_ref_count (ref_model, iter: &iter3, ref_count: 4);
535 assert_node_ref_count (ref_model, iter: &iter4, ref_count: 1);
536 assert_node_ref_count (ref_model, iter: &iter5, ref_count: 2);
537
538 /* Sort */
539 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
540 sort_column_id: 0, order: GTK_SORT_ASCENDING);
541
542 assert_node_ref_count (ref_model, iter: &iter1, ref_count: 3);
543 assert_node_ref_count (ref_model, iter: &iter2, ref_count: 1);
544 assert_node_ref_count (ref_model, iter: &iter3, ref_count: 4);
545 assert_node_ref_count (ref_model, iter: &iter4, ref_count: 1);
546 assert_node_ref_count (ref_model, iter: &iter5, ref_count: 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), sort_iter: &siter1, child_iter: &iter1);
550 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter2, child_iter: &iter2);
551 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter3, child_iter: &iter3);
552 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter4, child_iter: &iter4);
553 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter5, child_iter: &iter5);
554
555 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter1);
556 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter1);
557
558 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
559 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
560 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
561
562 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter5);
563
564 assert_entire_model_referenced (ref_model, ref_count: 1);
565
566 g_object_unref (g_object_ref_sink (tree_view));
567 g_object_unref (object: sort_model);
568
569 assert_entire_model_unreferenced (ref_model);
570
571 g_object_unref (object: ref_model);
572}
573
574static void
575ref_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), n_columns: 1,
591 types: column_types);
592
593 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter1, NULL, position: 0,
594 0, 30, -1);
595 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter2, NULL, position: 1,
596 0, 40, -1);
597 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter3, NULL, position: 2,
598 0, 10, -1);
599 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter4, NULL, position: 3,
600 0, 20, -1);
601 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter5, NULL, position: 4,
602 0, 60, -1);
603
604 /* Child level */
605 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer1, parent: &iter1, position: 0,
606 0, 30, -1);
607 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer2, parent: &iter1, position: 1,
608 0, 40, -1);
609 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer3, parent: &iter1, position: 2,
610 0, 10, -1);
611 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer4, parent: &iter1, position: 3,
612 0, 20, -1);
613 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer5, parent: &iter1, position: 4,
614 0, 60, -1);
615
616 assert_root_level_unreferenced (ref_model);
617
618 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
619 tree_view = gtk_tree_view_new_with_model (model: sort_model);
620 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
621
622 assert_node_ref_count (ref_model, iter: &iter1, ref_count: 2);
623 assert_node_ref_count (ref_model, iter: &iter2, ref_count: 1);
624 assert_node_ref_count (ref_model, iter: &iter3, ref_count: 1);
625 assert_node_ref_count (ref_model, iter: &iter4, ref_count: 1);
626 assert_node_ref_count (ref_model, iter: &iter5, ref_count: 1);
627
628 assert_level_referenced (ref_model, ref_count: 1, iter: &iter1);
629
630 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter1, child_iter: &iter1);
631 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter2, child_iter: &iter2);
632 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter3, child_iter: &iter3);
633 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter4, child_iter: &iter4);
634 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter5, child_iter: &iter5);
635
636 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter1, child_iter: &citer1);
637 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter2, child_iter: &citer2);
638 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter3, child_iter: &citer3);
639 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter4, child_iter: &citer4);
640 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter5, child_iter: &citer5);
641
642 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter1);
643 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter1);
644
645 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
646 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
647 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
648
649 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &siter5);
650
651 assert_node_ref_count (ref_model, iter: &iter1, ref_count: 4);
652 assert_node_ref_count (ref_model, iter: &iter2, ref_count: 1);
653 assert_node_ref_count (ref_model, iter: &iter3, ref_count: 4);
654 assert_node_ref_count (ref_model, iter: &iter4, ref_count: 1);
655 assert_node_ref_count (ref_model, iter: &iter5, ref_count: 2);
656
657 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &sciter3);
658 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &sciter3);
659
660 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &sciter5);
661 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &sciter5);
662 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &sciter5);
663
664 gtk_tree_model_ref_node (GTK_TREE_MODEL (sort_model), iter: &sciter1);
665
666 assert_node_ref_count (ref_model, iter: &citer1, ref_count: 2);
667 assert_node_ref_count (ref_model, iter: &citer2, ref_count: 1);
668 assert_node_ref_count (ref_model, iter: &citer3, ref_count: 3);
669 assert_node_ref_count (ref_model, iter: &citer4, ref_count: 1);
670 assert_node_ref_count (ref_model, iter: &citer5, ref_count: 4);
671
672 /* Sort */
673 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
674 sort_column_id: 0, order: GTK_SORT_ASCENDING);
675
676 assert_node_ref_count (ref_model, iter: &iter1, ref_count: 4);
677 assert_node_ref_count (ref_model, iter: &iter2, ref_count: 1);
678 assert_node_ref_count (ref_model, iter: &iter3, ref_count: 4);
679 assert_node_ref_count (ref_model, iter: &iter4, ref_count: 1);
680 assert_node_ref_count (ref_model, iter: &iter5, ref_count: 2);
681
682 assert_node_ref_count (ref_model, iter: &citer1, ref_count: 2);
683 assert_node_ref_count (ref_model, iter: &citer2, ref_count: 1);
684 assert_node_ref_count (ref_model, iter: &citer3, ref_count: 3);
685 assert_node_ref_count (ref_model, iter: &citer4, ref_count: 1);
686 assert_node_ref_count (ref_model, iter: &citer5, ref_count: 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), sort_iter: &siter1, child_iter: &iter1);
690 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter2, child_iter: &iter2);
691 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter3, child_iter: &iter3);
692 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter4, child_iter: &iter4);
693 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &siter5, child_iter: &iter5);
694
695 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter1, child_iter: &citer1);
696 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter2, child_iter: &citer2);
697 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter3, child_iter: &citer3);
698 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter4, child_iter: &citer4);
699 gtk_tree_model_sort_convert_child_iter_to_iter (GTK_TREE_MODEL_SORT (sort_model), sort_iter: &sciter5, child_iter: &citer5);
700
701 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter1);
702 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter1);
703
704 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
705 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
706 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter3);
707
708 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &siter5);
709
710 assert_node_ref_count (ref_model, iter: &iter1, ref_count: 2);
711 assert_node_ref_count (ref_model, iter: &iter2, ref_count: 1);
712 assert_node_ref_count (ref_model, iter: &iter3, ref_count: 1);
713 assert_node_ref_count (ref_model, iter: &iter4, ref_count: 1);
714 assert_node_ref_count (ref_model, iter: &iter5, ref_count: 1);
715
716 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &sciter3);
717 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &sciter3);
718
719 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &sciter5);
720 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &sciter5);
721 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &sciter5);
722
723 gtk_tree_model_unref_node (GTK_TREE_MODEL (sort_model), iter: &sciter1);
724
725 assert_level_referenced (ref_model, ref_count: 1, iter: &iter1);
726
727 g_object_unref (g_object_ref_sink (tree_view));
728 g_object_unref (object: sort_model);
729
730 assert_entire_model_unreferenced (ref_model);
731
732 g_object_unref (object: ref_model);
733}
734
735static void
736check_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 (tree_model: sort_model, iter: &siter);
745 else
746 {
747 GtkTreePath *path;
748
749 path = gtk_tree_path_new_from_string (path: parent_path);
750 gtk_tree_path_append_index (path, index_: 0);
751
752 gtk_tree_model_get_iter (tree_model: sort_model, iter: &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 (tree_model: sort_model, iter: &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 (tree_model: sort_model, iter: &siter));
775}
776
777static void
778rows_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), n_columns: 1,
799 types: column_types);
800
801 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter1, NULL, position: 0,
802 0, 30, -1);
803 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter2, NULL, position: 1,
804 0, 40, -1);
805 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter3, NULL, position: 2,
806 0, 10, -1);
807 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter4, NULL, position: 3,
808 0, 20, -1);
809 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter5, NULL, position: 4,
810 0, 60, -1);
811
812 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
813 tree_view = gtk_tree_view_new_with_model (model: sort_model);
814
815 monitor = signal_monitor_new (client: sort_model);
816
817 /* Sort */
818 path = gtk_tree_path_new ();
819 signal_monitor_append_signal_reordered (m: monitor,
820 signal: ROWS_REORDERED,
821 path, new_order: order[0], len: 5);
822 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
823 sort_column_id: 0, order: GTK_SORT_ASCENDING);
824 signal_monitor_assert_is_empty (m: monitor);
825 check_sort_order (sort_model, sort_order: GTK_SORT_ASCENDING, NULL);
826
827 signal_monitor_append_signal_reordered (m: monitor,
828 signal: ROWS_REORDERED,
829 path, new_order: order[1], len: 5);
830 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
831 sort_column_id: 0, order: GTK_SORT_DESCENDING);
832 signal_monitor_assert_is_empty (m: monitor);
833 check_sort_order (sort_model, sort_order: GTK_SORT_DESCENDING, NULL);
834
835 signal_monitor_append_signal_reordered (m: monitor,
836 signal: ROWS_REORDERED,
837 path, new_order: order[2], len: 5);
838 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
839 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
840 order: GTK_SORT_ASCENDING);
841 signal_monitor_assert_is_empty (m: monitor);
842
843 gtk_tree_path_free (path);
844 signal_monitor_free (m: monitor);
845
846 g_object_unref (g_object_ref_sink (tree_view));
847 g_object_unref (object: sort_model);
848
849 assert_entire_model_unreferenced (ref_model);
850
851 g_object_unref (object: ref_model);
852}
853
854static void
855rows_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), n_columns: 1,
877 types: column_types);
878
879 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter1, NULL, position: 0,
880 0, 30, -1);
881 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter2, NULL, position: 1,
882 0, 40, -1);
883 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter3, NULL, position: 2,
884 0, 10, -1);
885 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter4, NULL, position: 3,
886 0, 20, -1);
887 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter5, NULL, position: 4,
888 0, 60, -1);
889
890 /* Child level */
891 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer1, parent: &iter1, position: 0,
892 0, 30, -1);
893 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer2, parent: &iter1, position: 1,
894 0, 40, -1);
895 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer3, parent: &iter1, position: 2,
896 0, 10, -1);
897 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer4, parent: &iter1, position: 3,
898 0, 20, -1);
899 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &citer5, parent: &iter1, position: 4,
900 0, 60, -1);
901
902 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
903 tree_view = gtk_tree_view_new_with_model (model: sort_model);
904 gtk_tree_view_expand_all (GTK_TREE_VIEW (tree_view));
905
906 monitor = signal_monitor_new (client: sort_model);
907
908 /* Sort */
909 path = gtk_tree_path_new ();
910 child_path = gtk_tree_path_new_from_indices (first_index: 2, -1);
911 signal_monitor_append_signal_reordered (m: monitor,
912 signal: ROWS_REORDERED,
913 path, new_order: order[0], len: 5);
914 signal_monitor_append_signal_reordered (m: monitor,
915 signal: ROWS_REORDERED,
916 path: child_path, new_order: order[0], len: 5);
917 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
918 sort_column_id: 0, order: GTK_SORT_ASCENDING);
919 signal_monitor_assert_is_empty (m: monitor);
920 check_sort_order (sort_model, sort_order: GTK_SORT_ASCENDING, NULL);
921 /* The parent node of the child level moved due to sorting */
922 check_sort_order (sort_model, sort_order: GTK_SORT_ASCENDING, parent_path: "2");
923
924 signal_monitor_append_signal_reordered (m: monitor,
925 signal: ROWS_REORDERED,
926 path, new_order: order[1], len: 5);
927 signal_monitor_append_signal_reordered (m: monitor,
928 signal: ROWS_REORDERED,
929 path: child_path, new_order: order[1], len: 5);
930 gtk_tree_path_free (path: child_path);
931 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
932 sort_column_id: 0, order: GTK_SORT_DESCENDING);
933 signal_monitor_assert_is_empty (m: monitor);
934 check_sort_order (sort_model, sort_order: GTK_SORT_DESCENDING, NULL);
935 /* The parent node of the child level moved due to sorting */
936 check_sort_order (sort_model, sort_order: GTK_SORT_DESCENDING, parent_path: "2");
937
938 child_path = gtk_tree_path_new_from_indices (first_index: 0, -1);
939 signal_monitor_append_signal_reordered (m: monitor,
940 signal: ROWS_REORDERED,
941 path, new_order: order[2], len: 5);
942 signal_monitor_append_signal_reordered (m: monitor,
943 signal: ROWS_REORDERED,
944 path: child_path, new_order: order[2], len: 5);
945 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
946 GTK_TREE_SORTABLE_DEFAULT_SORT_COLUMN_ID,
947 order: GTK_SORT_ASCENDING);
948 signal_monitor_assert_is_empty (m: monitor);
949
950 gtk_tree_path_free (path);
951 gtk_tree_path_free (path: child_path);
952 signal_monitor_free (m: monitor);
953
954 g_object_unref (g_object_ref_sink (tree_view));
955 g_object_unref (object: sort_model);
956
957 g_object_unref (object: ref_model);
958}
959
960static void
961sorted_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), n_columns: 1,
977 types: column_types);
978
979 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter1, NULL, position: 0,
980 0, 30, -1);
981 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter2, NULL, position: 1,
982 0, 40, -1);
983 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter3, NULL, position: 2,
984 0, 10, -1);
985 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter4, NULL, position: 3,
986 0, 20, -1);
987 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &iter5, NULL, position: 4,
988 0, 60, -1);
989
990 sort_model = gtk_tree_model_sort_new_with_model (child_model: model);
991 tree_view = gtk_tree_view_new_with_model (model: sort_model);
992
993 /* Sort */
994 gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (sort_model),
995 sort_column_id: 0, order: GTK_SORT_ASCENDING);
996 check_sort_order (sort_model, sort_order: GTK_SORT_ASCENDING, NULL);
997
998 monitor = signal_monitor_new (client: sort_model);
999
1000 /* Insert a new item */
1001 signal_monitor_append_signal (m: monitor, signal: ROW_INSERTED, path_string: "4");
1002 gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), iter: &new_iter, NULL,
1003 position: 5, 0, 50, -1);
1004 signal_monitor_assert_is_empty (m: monitor);
1005 check_sort_order (sort_model, sort_order: 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 sort_column_id: 0, order: GTK_SORT_ASCENDING);
1010 check_sort_order (sort_model: model, sort_order: GTK_SORT_ASCENDING, NULL);
1011
1012 path = gtk_tree_path_new ();
1013 signal_monitor_append_signal (m: monitor, signal: ROW_INSERTED, path_string: "0");
1014 signal_monitor_append_signal_reordered (m: monitor,
1015 signal: ROWS_REORDERED,
1016 path, new_order: order0, len: 7);
1017 signal_monitor_append_signal (m: monitor, signal: ROW_CHANGED, path_string: "3");
1018 gtk_tree_store_append (GTK_TREE_STORE (model), iter: &new_iter, NULL);
1019 gtk_tree_store_set (GTK_TREE_STORE (model), iter: &new_iter, 0, 35, -1);
1020 check_sort_order (sort_model: model, sort_order: GTK_SORT_ASCENDING, NULL);
1021 check_sort_order (sort_model, sort_order: GTK_SORT_ASCENDING, NULL);
1022
1023 gtk_tree_path_free (path);
1024 signal_monitor_free (m: monitor);
1025
1026 g_object_unref (g_object_ref_sink (tree_view));
1027 g_object_unref (object: sort_model);
1028
1029 g_object_unref (object: ref_model);
1030}
1031
1032
1033static void
1034specific_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: &iter, NULL);
1048 gtk_tree_store_set (GTK_TREE_STORE (child_model), iter: &iter, 0, "A", -1);
1049 gtk_tree_store_append (GTK_TREE_STORE (child_model), iter: &iter, NULL);
1050 gtk_tree_store_set (GTK_TREE_STORE (child_model), iter: &iter, 0, "B", -1);
1051
1052 gtk_tree_store_append (GTK_TREE_STORE (child_model), iter: &iter2, parent: &iter);
1053 gtk_tree_store_set (GTK_TREE_STORE (child_model), iter: &iter2, 0, "D", -1);
1054 gtk_tree_store_append (GTK_TREE_STORE (child_model), iter: &iter2, parent: &iter);
1055 gtk_tree_store_set (GTK_TREE_STORE (child_model), iter: &iter2, 0, "E", -1);
1056
1057 gtk_tree_store_append (GTK_TREE_STORE (child_model), iter: &iter, NULL);
1058 gtk_tree_store_set (GTK_TREE_STORE (child_model), iter: &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 sort_column_id: 0, order: GTK_SORT_ASCENDING);
1064
1065 path = gtk_tree_path_new_from_indices (first_index: 1, 1, -1);
1066
1067 /* make sure a level is constructed */
1068 gtk_tree_model_get_iter (tree_model: sort_model, iter: &sort_iter, path);
1069
1070 /* change the "E" row in a way that causes it to change position */
1071 gtk_tree_model_get_iter (tree_model: child_model, iter: &iter, path);
1072 gtk_tree_store_set (GTK_TREE_STORE (child_model), iter: &iter, 0, "A", -1);
1073
1074 gtk_tree_path_free (path);
1075}
1076
1077static void
1078specific_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 (n_columns: 1, G_TYPE_STRING);
1090
1091 gtk_tree_store_append (tree_store: store, iter: &a, NULL);
1092 gtk_tree_store_set (tree_store: store, iter: &a, 0, "0", -1);
1093
1094 gtk_tree_store_append (tree_store: store, iter: &aa, parent: &a);
1095 gtk_tree_store_set (tree_store: store, iter: &aa, 0, "0:0", -1);
1096
1097 gtk_tree_store_append (tree_store: store, iter: &aaa, parent: &aa);
1098 gtk_tree_store_set (tree_store: store, iter: &aaa, 0, "0:0:0", -1);
1099
1100 gtk_tree_store_append (tree_store: store, iter: &aab, parent: &aa);
1101 gtk_tree_store_set (tree_store: store, iter: &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), sort_column_id: 0,
1105 order: GTK_SORT_ASCENDING);
1106
1107 gtk_tree_model_get_iter_from_string (tree_model: s_model, iter: &iter, path_string: "0:0:0");
1108
1109 gtk_tree_store_set (tree_store: store, iter: &aaa, 0, "0:0:0", -1);
1110 gtk_tree_store_remove (tree_store: store, iter: &aaa);
1111 gtk_tree_store_remove (tree_store: store, iter: &aab);
1112
1113 gtk_tree_model_sort_clear_cache (GTK_TREE_MODEL_SORT (s_model));
1114}
1115
1116static void
1117iter_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
1134static void
1135specific_bug_674587 (void)
1136{
1137 GtkListStore *l;
1138 GtkTreeStore *t;
1139 GtkTreeModel *m;
1140 GtkTreeIter a;
1141
1142 l = gtk_list_store_new (n_columns: 1, G_TYPE_STRING);
1143
1144 gtk_list_store_append (list_store: l, iter: &a);
1145 gtk_list_store_set (list_store: l, iter: &a, 0, "0", -1);
1146 gtk_list_store_append (list_store: l, iter: &a);
1147 gtk_list_store_set (list_store: l, iter: &a, 0, "1", -1);
1148 gtk_list_store_append (list_store: l, iter: &a);
1149 gtk_list_store_set (list_store: l, iter: &a, 0, "2", -1);
1150
1151 iter_test (GTK_TREE_MODEL (l));
1152
1153 g_object_unref (object: l);
1154
1155 t = gtk_tree_store_new (n_columns: 1, G_TYPE_STRING);
1156
1157 gtk_tree_store_append (tree_store: t, iter: &a, NULL);
1158 gtk_tree_store_set (tree_store: t, iter: &a, 0, "0", -1);
1159 gtk_tree_store_append (tree_store: t, iter: &a, NULL);
1160 gtk_tree_store_set (tree_store: t, iter: &a, 0, "1", -1);
1161 gtk_tree_store_append (tree_store: t, iter: &a, NULL);
1162 gtk_tree_store_set (tree_store: t, iter: &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 (model: m);
1169
1170 g_object_unref (object: t);
1171 g_object_unref (object: m);
1172}
1173
1174static void
1175row_deleted_cb (GtkTreeModel *tree_model,
1176 GtkTreePath *path,
1177 guint *count)
1178{
1179 *count = *count + 1;
1180}
1181
1182static void
1183specific_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 (n_columns: 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 (list_store: store, iter: &iter, position: 0, 0, "a", -1);
1196 gtk_list_store_insert_with_values (list_store: store, iter: &iter, position: 1, 0, "b", -1);
1197
1198 g_signal_connect (sorted, "row-deleted", G_CALLBACK (row_deleted_cb), &count);
1199
1200 gtk_list_store_clear (list_store: store);
1201
1202 g_assert_cmpuint (count, ==, 2);
1203}
1204
1205static int
1206sort_func (GtkTreeModel *model,
1207 GtkTreeIter *a,
1208 GtkTreeIter *b,
1209 gpointer data)
1210{
1211 return 0;
1212}
1213
1214static int column_changed;
1215
1216static void
1217sort_column_changed (GtkTreeSortable *sortable)
1218{
1219 column_changed++;
1220}
1221
1222static void
1223sort_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 (n_columns: 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), sort_column_id: 0, sort_func, NULL, NULL);
1244
1245 ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), sort_column_id: &col, order: &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, order: GTK_SORT_DESCENDING);
1253 ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), sort_column_id: &col, order: &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, order: GTK_SORT_DESCENDING);
1261 ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), sort_column_id: &col, order: &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 sort_column_id: 0, order: GTK_SORT_DESCENDING);
1269 ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), sort_column_id: &col, order: &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, order: GTK_SORT_ASCENDING);
1277 ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), sort_column_id: &col, order: &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, order: GTK_SORT_ASCENDING);
1285 ret = gtk_tree_sortable_get_sort_column_id (GTK_TREE_SORTABLE (sorted), sort_column_id: &col, order: &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
1294void
1295register_sort_model_tests (void)
1296{
1297 g_test_add_func (testpath: "/TreeModelSort/ref-count/single-level",
1298 test_func: ref_count_single_level);
1299 g_test_add_func (testpath: "/TreeModelSort/ref-count/two-levels",
1300 test_func: ref_count_two_levels);
1301 g_test_add_func (testpath: "/TreeModelSort/ref-count/three-levels",
1302 test_func: ref_count_three_levels);
1303 g_test_add_func (testpath: "/TreeModelSort/ref-count/delete-row",
1304 test_func: ref_count_delete_row);
1305 g_test_add_func (testpath: "/TreeModelSort/ref-count/cleanup",
1306 test_func: ref_count_cleanup);
1307 g_test_add_func (testpath: "/TreeModelSort/ref-count/row-ref",
1308 test_func: ref_count_row_ref);
1309 g_test_add_func (testpath: "/TreeModelSort/ref-count/reorder/single-level",
1310 test_func: ref_count_reorder_single);
1311 g_test_add_func (testpath: "/TreeModelSort/ref-count/reorder/two-levels",
1312 test_func: ref_count_reorder_two);
1313
1314 g_test_add_func (testpath: "/TreeModelSort/rows-reordered/single-level",
1315 test_func: rows_reordered_single_level);
1316 g_test_add_func (testpath: "/TreeModelSort/rows-reordered/two-levels",
1317 test_func: rows_reordered_two_levels);
1318 g_test_add_func (testpath: "/TreeModelSort/sorted-insert",
1319 test_func: sorted_insert);
1320
1321 g_test_add_func (testpath: "/TreeModelSort/specific/bug-300089",
1322 test_func: specific_bug_300089);
1323 g_test_add_func (testpath: "/TreeModelSort/specific/bug-364946",
1324 test_func: specific_bug_364946);
1325 g_test_add_func (testpath: "/TreeModelSort/specific/bug-674587",
1326 test_func: specific_bug_674587);
1327 g_test_add_func (testpath: "/TreeModelSort/specific/bug-698846",
1328 test_func: specific_bug_698846);
1329 g_test_add_func (testpath: "/TreeModelSort/specific/bug-792459",
1330 test_func: sort_column_change);
1331}
1332
1333

source code of gtk/testsuite/gtk/sortmodel.c