2 * Copyright (C) 2011 SUSE Linux Products GmbH, Nurenberg, Germany
5 * Mike Gorse <mgorse@suse.com>
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Library General Public
9 * License as published by the Free Software Foundation; either
10 * version 2 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Library General Public License for more details.
17 * You should have received a copy of the GNU Library General Public
18 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
23 const gchar list_ui[] =
25 " <object class='GtkListStore' id='liststore1'>"
27 " <column type='gchararray'/>"
28 " <column type='gchararray'/>"
29 " <column type='gchararray'/>"
30 " <column type='gboolean'/>"
31 " <column type='gint'/>"
32 " <column type='gint'/>"
35 " <row><col id='0'>One</col><col id='1'>Two</col><col id='2'>Three</col><col id='3'>True</col><col id='4'>50</col><col id='5'>50</col></row>"
38 " <object class='GtkWindow' id='window1'>"
40 " <object class='GtkTreeView' id='treeview1'>"
41 " <property name='visible'>True</property>"
42 " <property name='model'>liststore1</property>"
44 " <object class='GtkTreeViewColumn' id='column1'>"
45 " <property name='title' translatable='yes'>First column</property>"
47 " <object class='GtkCellRendererText' id='renderer1'>"
50 " <attribute name='text'>0</attribute>"
54 " <object class='GtkCellRendererToggle' id='renderer2'>"
57 " <attribute name='active'>3</attribute>"
63 " <object class='GtkTreeViewColumn' id='column2'>"
64 " <property name='title' translatable='yes'>Second column</property>"
66 " <object class='GtkCellRendererText' id='renderer3'>"
69 " <attribute name='text'>1</attribute>"
73 " <object class='GtkCellRendererProgress' id='renderer4'>"
76 " <attribute name='value'>4</attribute>"
87 builder_get_toplevel (GtkBuilder *builder)
90 GtkWidget *window = NULL;
92 list = gtk_builder_get_objects (builder);
93 for (walk = list; walk; walk = walk->next)
95 if (GTK_IS_WINDOW (walk->data) &&
96 gtk_widget_get_parent (walk->data) == NULL)
108 const gchar tree_ui[] =
110 " <object class='GtkTreeStore' id='treestore1'>"
112 " <column type='gchararray'/>"
113 " <column type='gchararray'/>"
114 " <column type='gchararray'/>"
115 " <column type='gboolean'/>"
116 " <column type='gint'/>"
117 " <column type='gint'/>"
120 " <object class='GtkWindow' id='window1'>"
122 " <object class='GtkTreeView' id='treeview1'>"
123 " <property name='visible'>True</property>"
124 " <property name='model'>treestore1</property>"
126 " <object class='GtkTreeViewColumn' id='column1'>"
127 " <property name='title' translatable='yes'>First column</property>"
129 " <object class='GtkCellRendererText' id='renderer1'>"
132 " <attribute name='text'>0</attribute>"
136 " <object class='GtkCellRendererToggle' id='renderer2'>"
139 " <attribute name='active'>3</attribute>"
145 " <object class='GtkTreeViewColumn' id='column2'>"
146 " <property name='title' translatable='yes'>Second column</property>"
148 " <object class='GtkCellRendererText' id='renderer3'>"
151 " <attribute name='text'>1</attribute>"
155 " <object class='GtkCellRendererProgress' id='renderer4'>"
158 " <attribute name='value'>4</attribute>"
169 populate_tree (GtkBuilder *builder)
175 tv = (GtkTreeView *)gtk_builder_get_object (builder, "treeview1");
176 store = (GtkTreeStore *)gtk_tree_view_get_model (tv);
178 /* append some rows */
179 gtk_tree_store_append (store, &iter, NULL);
180 gtk_tree_store_set (store, &iter, 0, "a(1)", 1, "a(2)", 2, "a(3)", 3, TRUE, 4, 0, 5, 0, -1);
181 gtk_tree_store_append (store, &iter, &iter);
182 gtk_tree_store_set (store, &iter, 0, "aa(1)", 1, "aa(2)", 2, "aa(3)", 3, TRUE, 4, 0, 5, 0, -1);
183 gtk_tree_store_append (store, &iter, &iter);
184 gtk_tree_store_set (store, &iter, 0, "aaa(1)", 1, "aaa(2)", 2, "aaa(3)", 3, TRUE, 4, 0, 5, 0, -1);
186 gtk_tree_store_append (store, &iter, NULL);
187 gtk_tree_store_set (store, &iter, 0, "b(1)", 1, "b(2)", 2, "b(3)", 3, TRUE, 4, 0, 5, 0, -1);
188 gtk_tree_store_append (store, &iter, &iter);
189 gtk_tree_store_set (store, &iter, 0, "bb(1)", 1, "bb(2)", 2, "bb(3)", 3, TRUE, 4, 0, 5, 0, -1);
190 gtk_tree_store_append (store, &iter, &iter);
191 gtk_tree_store_set (store, &iter, 0, "bbb(1)", 1, "bbb(2)", 2, "bbb(3)", 3, TRUE, 4, 0, 5, 0, -1);
196 AtkObject *descendant;
200 active_descendant_changed (AtkObject *accessible,
201 AtkObject *descendant,
205 if (data->descendant)
206 g_object_unref (data->descendant);
207 data->descendant = g_object_ref (descendant);
211 quit_loop (gpointer data)
213 GMainLoop *loop = data;
214 g_main_loop_quit (loop);
219 process_pending_idles ()
221 GMainLoop *loop = g_main_loop_new (NULL, FALSE);
222 gdk_threads_add_idle (quit_loop, loop);
223 g_main_loop_run (loop);
227 test_a11y_tree_focus (void)
231 GError *error = NULL;
233 GtkTreePath *path = NULL;
234 GtkTreeViewColumn *focus_column = NULL;
236 AtkObject *accessible;
240 builder = gtk_builder_new ();
241 gtk_builder_add_from_string (builder, tree_ui, -1, &error);
242 g_assert_no_error (error);
243 window = builder_get_toplevel (builder);
246 populate_tree (builder);
248 tv = (GtkTreeView *)gtk_builder_get_object (builder, "treeview1");
249 gtk_tree_view_expand_all (tv);
251 gtk_widget_show (window);
253 gtk_tree_view_get_cursor (tv, &path, &focus_column);
254 gtk_tree_path_down (path);
256 data.descendant = NULL;
257 accessible = gtk_widget_get_accessible (GTK_WIDGET (tv));
258 g_signal_connect (accessible, "active_descendant_changed",
259 G_CALLBACK (active_descendant_changed), &data);
260 gtk_tree_view_set_cursor (tv, path, focus_column, FALSE);
261 /* hack: active_descendant_change gets fired in an idle handler */
262 process_pending_idles ();
263 /* Getting only one signal might be ideal, although we get three or so */
264 g_assert_cmpint (data.count, >=, 1);
265 child = atk_object_ref_accessible_child (data.descendant, 0);
266 text = atk_text_get_text (ATK_TEXT (child), 0, -1);
267 g_assert_cmpstr (text, ==, "aa(1)");
270 g_object_unref (child);
272 g_object_unref (data.descendant);
273 g_object_unref (builder);
278 find_root_accessible (GtkTreeView *tv, const char *name)
280 AtkObject *tvaccessible = gtk_widget_get_accessible (GTK_WIDGET (tv));
285 AtkObject *child = atk_object_ref_accessible_child (tvaccessible, i);
290 item = atk_object_ref_accessible_child (child, 0);
293 text = atk_text_get_text (ATK_TEXT (item), 0, -1);
294 g_object_unref (item);
295 if (!g_strcmp0 (text, name))
301 g_object_unref (child);
306 test_node_child_of (AtkObject *child, AtkObject *parent)
308 AtkRelationSet *set = atk_object_ref_relation_set (child);
309 AtkRelation *relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_NODE_CHILD_OF);
311 g_assert (relation != NULL);
312 g_assert_cmpint (relation->target->len, ==, 1);
313 g_assert (g_ptr_array_index (relation->target, 0) == parent);
314 g_object_unref (set);
318 test_node_parent_of (AtkObject *parent, AtkObject *child)
320 AtkRelationSet *set = atk_object_ref_relation_set (parent);
321 AtkRelation *relation = atk_relation_set_get_relation_by_type (set, ATK_RELATION_NODE_PARENT_OF);
323 g_assert (relation != NULL);
324 g_assert_cmpint (relation->target->len, ==, 1);
325 g_assert (g_ptr_array_index (relation->target, 0) == child);
326 g_object_unref (set);
330 test_relations (AtkObject *parent, AtkObject *child)
332 test_node_parent_of (parent, child);
333 test_node_child_of (child, parent);
337 test_a11y_tree_relations (void)
341 GError *error = NULL;
343 AtkObject *parent, *child;
345 builder = gtk_builder_new ();
346 gtk_builder_add_from_string (builder, tree_ui, -1, &error);
347 g_assert_no_error (error);
348 window = builder_get_toplevel (builder);
351 populate_tree (builder);
353 tv = (GtkTreeView *)gtk_builder_get_object (builder, "treeview1");
354 gtk_tree_view_expand_all (tv);
356 gtk_widget_show (window);
358 parent = find_root_accessible (tv, "a(1)");
359 child = find_root_accessible (tv, "aa(1)");
360 test_relations (parent, child);
361 g_object_unref (parent);
363 child = find_root_accessible (tv, "aaa(1)");
364 test_relations (parent, child);
365 g_object_unref (parent);
366 g_object_unref (child);
368 g_object_unref (builder);
373 main (int argc, char *argv[])
375 gtk_test_init (&argc, &argv, NULL);
377 g_test_add_func ("/a11y/tree/focus", test_a11y_tree_focus);
378 g_test_add_func ("/a11y/tree/relations", test_a11y_tree_relations);
380 return g_test_run ();