1/* Basic GtkTreeView unit tests.
2 * Copyright (C) 2009 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
20static void
21test_bug_546005 (void)
22{
23 GtkTreeIter iter;
24 GtkTreePath *path;
25 GtkTreePath *cursor_path;
26 GtkListStore *list_store;
27 GtkWidget *view;
28
29 /*http://bugzilla.gnome.org/show_bug.cgi?id=546005 */
30
31 /* Tests provided by Bjorn Lindqvist, Paul Pogonyshev */
32 view = gtk_tree_view_new ();
33
34 /* Invalid path on tree view without model */
35 path = gtk_tree_path_new_from_indices (first_index: 1, -1);
36 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
37 NULL, FALSE);
38 gtk_tree_path_free (path);
39
40 list_store = gtk_list_store_new (n_columns: 1, G_TYPE_STRING);
41 gtk_tree_view_set_model (GTK_TREE_VIEW (view),
42 GTK_TREE_MODEL (list_store));
43
44 /* Invalid path on tree view with empty model */
45 path = gtk_tree_path_new_from_indices (first_index: 1, -1);
46 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
47 NULL, FALSE);
48 gtk_tree_path_free (path);
49
50 /* Valid path */
51 gtk_list_store_insert_with_values (list_store, iter: &iter, position: 0,
52 0, "hi",
53 -1);
54
55 path = gtk_tree_path_new_from_indices (first_index: 0, -1);
56 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
57 NULL, FALSE);
58
59 gtk_tree_view_get_cursor (GTK_TREE_VIEW (view), path: &cursor_path, NULL);
60 //gtk_assert_cmptreepath (cursor_path, ==, path);
61
62 gtk_tree_path_free (path);
63 gtk_tree_path_free (path: cursor_path);
64
65 /* Invalid path on tree view with model */
66 path = gtk_tree_path_new_from_indices (first_index: 1, -1);
67 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path,
68 NULL, FALSE);
69 gtk_tree_path_free (path);
70
71 g_object_unref (g_object_ref_sink (view));
72}
73
74static void
75test_bug_539377 (void)
76{
77 GtkWidget *view;
78 GtkTreePath *path;
79 GtkListStore *list_store;
80 gboolean ret;
81
82 /*http://bugzilla.gnome.org/show_bug.cgi?id=539377 */
83
84 /* Test provided by Bjorn Lindqvist */
85
86 /* Non-realized view, no model */
87 view = gtk_tree_view_new ();
88 ret = gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), x: 10, y: 10, path: &path,
89 NULL, NULL, NULL);
90 g_assert_false (ret);
91 ret = gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), drag_x: 10, drag_y: 10,
92 path: &path, NULL);
93 g_assert_false (ret);
94
95 /* Non-realized view, with model */
96 list_store = gtk_list_store_new (n_columns: 1, G_TYPE_STRING);
97 gtk_tree_view_set_model (GTK_TREE_VIEW (view),
98 GTK_TREE_MODEL (list_store));
99
100 ret = gtk_tree_view_get_path_at_pos (GTK_TREE_VIEW (view), x: 10, y: 10, path: &path,
101 NULL, NULL, NULL);
102 g_assert_false (ret);
103 ret = gtk_tree_view_get_dest_row_at_pos (GTK_TREE_VIEW (view), drag_x: 10, drag_y: 10,
104 path: &path, NULL);
105 g_assert_false (ret);
106
107 g_object_unref (g_object_ref_sink (view));
108}
109
110static void
111test_select_collapsed_row (void)
112{
113 GtkTreeIter child, parent;
114 GtkTreePath *path;
115 GtkTreeStore *tree_store;
116 GtkTreeSelection *selection;
117 GtkWidget *view;
118
119 /* Reported by Michael Natterer */
120 tree_store = gtk_tree_store_new (n_columns: 1, G_TYPE_STRING);
121 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (tree_store));
122
123 gtk_tree_store_insert_with_values (tree_store, iter: &parent, NULL, position: 0,
124 0, "Parent",
125 -1);
126
127 gtk_tree_store_insert_with_values (tree_store, iter: &child, parent: &parent, position: 0,
128 0, "Child",
129 -1);
130 gtk_tree_store_insert_with_values (tree_store, iter: &child, parent: &parent, position: 0,
131 0, "Child",
132 -1);
133
134
135 /* Try to select a child path. */
136 path = gtk_tree_path_new_from_indices (first_index: 0, 1, -1);
137 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
138
139 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
140
141 /* Check that the parent is not selected. */
142 gtk_tree_path_up (path);
143 g_assert_false (gtk_tree_selection_path_is_selected (selection, path));
144
145 /* Nothing should be selected at this point. */
146 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 0);
147
148 /* Check that selection really still works. */
149 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
150 g_assert_true (gtk_tree_selection_path_is_selected (selection, path));
151 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 1);
152
153 /* Expand and select child node now. */
154 gtk_tree_path_append_index (path, index_: 1);
155 gtk_tree_view_expand_all (GTK_TREE_VIEW (view));
156
157 gtk_tree_view_set_cursor (GTK_TREE_VIEW (view), path, NULL, FALSE);
158 g_assert_true (gtk_tree_selection_path_is_selected (selection, path));
159 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 1);
160
161 gtk_tree_path_free (path);
162
163 g_object_unref (g_object_ref_sink (view));
164}
165
166static gboolean
167test_row_separator_height_func (GtkTreeModel *model,
168 GtkTreeIter *iter,
169 gpointer data)
170{
171 gboolean ret = FALSE;
172 GtkTreePath *path;
173
174 path = gtk_tree_model_get_path (tree_model: model, iter);
175 if (gtk_tree_path_get_indices (path)[0] == 2)
176 ret = TRUE;
177 gtk_tree_path_free (path);
178
179 return ret;
180}
181
182static void
183test_row_separator_height (void)
184{
185 int height;
186 GtkTreeIter iter;
187 GtkTreePath *path;
188 GtkListStore *store;
189 GtkWidget *window;
190 GtkWidget *tree_view;
191 GdkRectangle rect = { 0, }, cell_rect = { 0, };
192
193 store = gtk_list_store_new (n_columns: 1, G_TYPE_STRING);
194 gtk_list_store_insert_with_values (list_store: store, iter: &iter, position: 0, 0, "Row content", -1);
195 gtk_list_store_insert_with_values (list_store: store, iter: &iter, position: 1, 0, "Row content", -1);
196 gtk_list_store_insert_with_values (list_store: store, iter: &iter, position: 2, 0, "Row content", -1);
197 gtk_list_store_insert_with_values (list_store: store, iter: &iter, position: 3, 0, "Row content", -1);
198 gtk_list_store_insert_with_values (list_store: store, iter: &iter, position: 4, 0, "Row content", -1);
199
200 window = gtk_window_new ();
201
202 tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (store));
203 gtk_tree_view_set_row_separator_func (GTK_TREE_VIEW (tree_view),
204 func: test_row_separator_height_func,
205 NULL,
206 NULL);
207
208 gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (tree_view),
209 position: 0,
210 title: "Test",
211 cell: gtk_cell_renderer_text_new (),
212 "text", 0,
213 NULL);
214
215 gtk_window_set_child (GTK_WINDOW (window), child: tree_view);
216 gtk_widget_show (widget: window);
217
218 gtk_test_widget_wait_for_draw (widget: window);
219
220 path = gtk_tree_path_new_from_indices (first_index: 2, -1);
221 gtk_tree_view_get_background_area (GTK_TREE_VIEW (tree_view),
222 path, NULL, rect: &rect);
223 gtk_tree_view_get_cell_area (GTK_TREE_VIEW (tree_view),
224 path, NULL, rect: &cell_rect);
225 gtk_tree_path_free (path);
226
227 height = 2;
228
229 g_assert_cmpint (rect.height, ==, height);
230 g_assert_cmpint (cell_rect.height, ==, height);
231
232 gtk_window_destroy (GTK_WINDOW (window));
233}
234
235static void
236test_selection_count (void)
237{
238 GtkTreePath *path;
239 GtkListStore *list_store;
240 GtkTreeSelection *selection;
241 GtkWidget *view;
242
243 /*http://bugzilla.gnome.org/show_bug.cgi?id=702957 */
244
245 list_store = gtk_list_store_new (n_columns: 1, G_TYPE_STRING);
246 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
247
248 gtk_list_store_insert_with_values (list_store, NULL, position: 0, 0, "One", -1);
249 gtk_list_store_insert_with_values (list_store, NULL, position: 1, 0, "Two", -1);
250 gtk_list_store_insert_with_values (list_store, NULL, position: 2, 0, "Tree", -1);
251
252 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
253 gtk_tree_selection_set_mode (selection, type: GTK_SELECTION_MULTIPLE);
254
255 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 0);
256
257 path = gtk_tree_path_new_from_indices (first_index: 0, -1);
258 gtk_tree_selection_select_path (selection, path);
259 gtk_tree_path_free (path);
260
261 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 1);
262
263 path = gtk_tree_path_new_from_indices (first_index: 2, -1);
264 gtk_tree_selection_select_path (selection, path);
265 gtk_tree_path_free (path);
266
267 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 2);
268
269 path = gtk_tree_path_new_from_indices (first_index: 2, -1);
270 gtk_tree_selection_select_path (selection, path);
271 gtk_tree_path_free (path);
272
273 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 2);
274
275 path = gtk_tree_path_new_from_indices (first_index: 1, -1);
276 gtk_tree_selection_select_path (selection, path);
277 gtk_tree_path_free (path);
278
279 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 3);
280
281 gtk_tree_selection_unselect_all (selection);
282
283 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 0);
284
285 g_object_unref (g_object_ref_sink (view));
286}
287
288static void G_GNUC_NORETURN
289abort_cb (GtkTreeModel *model,
290 GtkTreePath *path,
291 GtkTreeIter *iter,
292 gpointer data)
293{
294 g_assert_not_reached ();
295}
296
297static void
298test_selection_empty (void)
299{
300 GtkTreePath *path;
301 GtkListStore *list_store;
302 GtkTreeSelection *selection;
303 GtkWidget *view;
304 GtkTreeIter iter;
305
306 /*http://bugzilla.gnome.org/show_bug.cgi?id=712760 */
307
308 list_store = gtk_list_store_new (n_columns: 1, G_TYPE_STRING);
309 view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (list_store));
310 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (view));
311
312 g_assert_false (gtk_tree_selection_get_selected (selection, NULL, &iter));
313 gtk_tree_selection_selected_foreach (selection, func: abort_cb, NULL);
314 g_assert_null (gtk_tree_selection_get_selected_rows (selection, NULL));
315 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 0);
316
317 path = gtk_tree_path_new_from_indices (first_index: 0, -1);
318
319 gtk_tree_selection_select_path (selection, path);
320 gtk_tree_selection_unselect_path (selection, path);
321 g_assert_false (gtk_tree_selection_path_is_selected (selection, path));
322
323 gtk_tree_selection_set_mode (selection, type: GTK_SELECTION_MULTIPLE);
324
325 gtk_tree_selection_select_all (selection);
326 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 0);
327
328 gtk_tree_selection_unselect_all (selection);
329 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 0);
330
331 gtk_tree_selection_select_range (selection, start_path: path, end_path: path);
332 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 0);
333
334 gtk_tree_selection_unselect_range (selection, start_path: path, end_path: path);
335 g_assert_cmpint (gtk_tree_selection_count_selected_rows (selection), ==, 0);
336
337 gtk_tree_path_free (path);
338
339 g_object_unref (g_object_ref_sink (view));
340}
341
342int
343main (int argc,
344 char **argv)
345{
346 gtk_test_init (argcp: &argc, argvp: &argv, NULL);
347
348 g_test_add_func (testpath: "/TreeView/cursor/bug-546005", test_func: test_bug_546005);
349 g_test_add_func (testpath: "/TreeView/cursor/bug-539377", test_func: test_bug_539377);
350 g_test_add_func (testpath: "/TreeView/cursor/select-collapsed_row",
351 test_func: test_select_collapsed_row);
352 g_test_add_func (testpath: "/TreeView/sizing/row-separator-height",
353 test_func: test_row_separator_height);
354 g_test_add_func (testpath: "/TreeView/selection/count", test_func: test_selection_count);
355 g_test_add_func (testpath: "/TreeView/selection/empty", test_func: test_selection_empty);
356
357 return g_test_run ();
358}
359

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