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 | |
20 | static void |
21 | test_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 | |
74 | static void |
75 | test_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 | |
110 | static void |
111 | test_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 | |
166 | static gboolean |
167 | test_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 | |
182 | static void |
183 | test_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 | |
235 | static void |
236 | test_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 | |
288 | static void G_GNUC_NORETURN |
289 | abort_cb (GtkTreeModel *model, |
290 | GtkTreePath *path, |
291 | GtkTreeIter *iter, |
292 | gpointer data) |
293 | { |
294 | g_assert_not_reached (); |
295 | } |
296 | |
297 | static void |
298 | test_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 | |
342 | int |
343 | main (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 | |