]> Pileus Git - ~andy/gtk/blob - modules/other/gail/tests/testtreetable.c
dcf1579c1afcb222381affbd2786e4dfb7d26245
[~andy/gtk] / modules / other / gail / tests / testtreetable.c
1 #include <stdlib.h>
2 #include <testlib.h>
3
4 /*
5  * This module is for use with the test program testtreeview
6  */
7 static gboolean state_change_watch  (GSignalInvocationHint *ihint,
8                                      guint                  n_param_values,
9                                      const GValue          *param_values,
10                                      gpointer               data);
11
12 static void _check_table             (AtkObject         *in_obj);
13 static void _check_cell_actions      (AtkObject         *in_obj);
14
15 static gint _find_expander_column    (AtkTable          *table);
16 static void _check_expanders         (AtkTable          *table,
17                                       gint              expander_column);
18 static void _runtest                 (AtkObject         *obj);
19 static void _create_event_watcher    (void);
20 static void row_inserted             (AtkObject         *obj,
21                                       gint              row,
22                                       gint              count);
23 static void row_deleted              (AtkObject         *obj,
24                                       gint              row,
25                                       gint              count);
26 static AtkObject *table_obj = NULL;
27 static gint expander_column = -1;
28 static gboolean editing_cell = FALSE;
29
30 static gboolean 
31 state_change_watch (GSignalInvocationHint *ihint,
32                     guint                  n_param_values,
33                     const GValue          *param_values,
34                     gpointer               data)
35 {
36   GObject *object;
37   gboolean state_set;
38   const gchar *state_name;
39   AtkStateType state_type;
40
41   object = g_value_get_object (param_values + 0);
42   g_return_val_if_fail (ATK_IS_OBJECT (object), FALSE);
43
44   state_name = g_value_get_string (param_values + 1);
45   state_set = g_value_get_boolean (param_values + 2);
46
47   g_print ("Object type: %s state: %s set: %d\n", 
48            g_type_name (G_OBJECT_TYPE (object)), state_name, state_set);
49   state_type = atk_state_type_for_name (state_name);
50   if (state_type == ATK_STATE_EXPANDED)
51     {
52       AtkObject *parent = atk_object_get_parent (ATK_OBJECT (object));
53
54       if (ATK_IS_TABLE (parent))
55         _check_expanders (ATK_TABLE (parent), expander_column);
56     }
57   return TRUE;
58 }
59
60 static void 
61 _check_table (AtkObject *in_obj)
62 {
63   AtkObject *obj;
64   AtkRole role[2];
65   AtkRole obj_role;
66   static gboolean emission_hook_added = FALSE;
67
68   if (!emission_hook_added)
69     {
70       emission_hook_added = TRUE;
71       g_signal_add_emission_hook (
72                     g_signal_lookup ("state-change", ATK_TYPE_OBJECT),
73       /*
74        * To specify an emission hook for a particular state, e.g. 
75        * ATK_STATE_EXPANDED, instead of 0 use
76        * g_quark_from_string (atk_state_type_get_name (ATK_STATE_EXPANDED))
77        */  
78                     0,
79                     state_change_watch, NULL, (GDestroyNotify) NULL);
80     }
81
82   role[0] = ATK_ROLE_TABLE;
83   role[1] = ATK_ROLE_TREE_TABLE;
84   
85   g_print ("focus event for: %s\n", g_type_name (G_OBJECT_TYPE (in_obj)));
86
87   _check_cell_actions (in_obj);
88
89   obj_role = atk_object_get_role (in_obj);
90   if (obj_role == ATK_ROLE_TABLE_CELL)
91     obj = atk_object_get_parent (in_obj);
92   else
93     obj = find_object_by_role (in_obj, role, 2);
94   if (obj == NULL)
95     return;
96
97   editing_cell = FALSE;
98
99   if (obj != table_obj)
100     {
101       table_obj = obj;
102       g_print("Found %s table\n", g_type_name (G_OBJECT_TYPE (obj)));
103       g_signal_connect (G_OBJECT (obj),
104                         "row_inserted",
105                         G_CALLBACK (row_inserted),
106                         NULL);
107       g_signal_connect (G_OBJECT (obj),
108                         "row_deleted",
109                         G_CALLBACK (row_deleted),
110                         NULL);
111       /*
112        * Find expander column
113        */
114       if (ATK_IS_TABLE (obj))
115         {
116           if (atk_object_get_role (obj) == ATK_ROLE_TREE_TABLE)
117             {
118               expander_column = _find_expander_column (ATK_TABLE (obj));
119               if (expander_column == -1)
120                 {
121                   g_warning ("Expander column not found\n");
122                   return;
123                 }
124             }
125           _runtest(obj);
126         }
127       else
128         g_warning ("Table does not support AtkTable interface\n");
129     }
130   else 
131     {
132       /*
133        * We do not call these functions at the same time as we set the 
134        * signals as the GtkTreeView may not be displayed yet.
135        */
136       gint x, y, width, height, first_x, last_x, last_y;
137       gint first_row, last_row, first_column, last_column;
138       gint index;
139       AtkObject *first_child, *last_child, *header;
140       AtkComponent *component = ATK_COMPONENT (obj);
141       AtkTable *table = ATK_TABLE (obj);
142
143       atk_component_get_extents (component, 
144                                  &x, &y, &width, &height, ATK_XY_WINDOW);
145       g_print ("WINDOW: x: %d y: %d width: %d height: %d\n",
146                x, y, width, height);
147       atk_component_get_extents (component, 
148                                  &x, &y, &width, &height, ATK_XY_SCREEN);
149       g_print ("SCREEN: x: %d y: %d width: %d height: %d\n",
150                x, y, width, height);
151       last_x = x + width - 1;
152       last_y = y + height - 1;
153       first_x = x; 
154       header = atk_table_get_column_header (table, 0);
155       if (header)
156         {
157           atk_component_get_extents (ATK_COMPONENT (header), 
158                                      &x, &y, &width, &height, ATK_XY_SCREEN);
159           g_print ("Got column header: x: %d y: %d width: %d height: %d\n",
160                    x, y, width, height);
161           y += height;
162         }
163       first_child = atk_component_ref_accessible_at_point (component, 
164                                              first_x, y, ATK_XY_SCREEN);
165       atk_component_get_extents (ATK_COMPONENT (first_child), 
166                                  &x, &y, &width, &height, ATK_XY_SCREEN);
167       g_print ("first_child: x: %d y: %d width: %d height: %d\n",
168                x, y, width, height);
169       index = atk_object_get_index_in_parent (ATK_OBJECT (first_child));
170       first_row = atk_table_get_row_at_index (table, index);
171       first_column = atk_table_get_column_at_index (table, index);
172       g_print ("first_row: %d first_column: %d index: %d\n",
173                first_row, first_column, index);
174       g_assert (index == atk_table_get_index_at (table, first_row, first_column));
175       last_child = atk_component_ref_accessible_at_point (component, 
176                                      last_x, last_y, ATK_XY_SCREEN);
177       if (last_child == NULL)
178         {
179           /* The TreeView may be bigger than the data */
180           gint n_children;
181
182           n_children = atk_object_get_n_accessible_children (obj);
183           last_child = atk_object_ref_accessible_child (obj, n_children - 1);
184         }
185       atk_component_get_extents (ATK_COMPONENT (last_child), 
186                                  &x, &y, &width, &height, ATK_XY_SCREEN);
187       g_print ("last_child: x: %d y: %d width: %d height: %d\n",
188                x, y, width, height);
189       index = atk_object_get_index_in_parent (ATK_OBJECT (last_child));
190       last_row = atk_table_get_row_at_index (table, index);
191       last_column = atk_table_get_column_at_index (table, index);
192       g_print ("last_row: %d last_column: %d index: %d\n",
193                last_row, last_column, index);
194       g_assert (index == atk_table_get_index_at (table, last_row, last_column));
195       g_object_unref (first_child);
196       g_object_unref (last_child);
197
198       if (expander_column >= 0)
199         {
200           gint n_rows, i;
201           gint x, y, width, height;
202
203           n_rows = atk_table_get_n_rows (table);
204           for (i = 0; i < n_rows; i++)
205             {
206               AtkObject *child_obj;
207               AtkStateSet *state_set;
208               gboolean showing;
209
210               child_obj = atk_table_ref_at (table, i, expander_column);
211               state_set = atk_object_ref_state_set (child_obj);
212               showing =  atk_state_set_contains_state (state_set, 
213                                                        ATK_STATE_SHOWING);
214               g_object_unref (state_set);
215               atk_component_get_extents (ATK_COMPONENT (child_obj), 
216                                          &x, &y, &width, &height, 
217                                          ATK_XY_SCREEN);
218               g_object_unref (child_obj);
219               if (showing)
220                 g_print ("Row: %d Column: %d x: %d y: %d width: %d height: %d\n", 
221                          i, expander_column, x, y, width, height);
222             }
223         }
224     }
225 }
226
227 static void 
228 _check_cell_actions (AtkObject *in_obj)
229 {
230   AtkRole role;
231   AtkAction *action;
232   gint n_actions, i;
233
234   role = atk_object_get_role (in_obj);
235   if (role != ATK_ROLE_TABLE_CELL)
236     return;
237
238   if (!ATK_IS_ACTION (in_obj))
239     return;
240
241   if (editing_cell)
242     return;
243
244   action = ATK_ACTION (in_obj);
245
246   n_actions = atk_action_get_n_actions (action);
247
248   for (i = 0; i < n_actions; i++)
249     {
250       const gchar* name;
251
252       name = atk_action_get_name (action, i);
253       g_print ("Action %d is %s\n", i, name);
254 #if 0
255       if (strcmp (name, "edit") == 0)
256         {
257           editing_cell = TRUE;
258           atk_action_do_action (action, i);
259         }
260 #endif
261     }
262   return;
263 }
264
265 static gint 
266 _find_expander_column (AtkTable *table)
267 {
268   gint n_columns, i;
269   gint retval = -1;
270
271   n_columns = atk_table_get_n_columns (table);
272   for (i = 0; i < n_columns; i++)
273     {
274       AtkObject *cell;
275       AtkRelationSet *relation_set;
276
277       cell = atk_table_ref_at (table, 0, i);
278       relation_set =  atk_object_ref_relation_set (cell);
279       if (atk_relation_set_contains (relation_set, 
280                                      ATK_RELATION_NODE_CHILD_OF))
281         retval = i;
282       g_object_unref (relation_set);
283       g_object_unref (cell);
284       if (retval >= 0)
285         break;
286     }
287   return retval;
288 }
289
290 static void
291 _check_expanders (AtkTable *table,
292                   gint     expander_column)
293 {
294   gint n_rows, i;
295
296   n_rows = atk_table_get_n_rows (table);
297
298   for (i = 0; i < n_rows; i++)
299     {
300       AtkObject *cell;
301       AtkRelationSet *relation_set;
302       AtkRelation *relation;
303       GPtrArray *target;
304       gint j;
305
306       cell = atk_table_ref_at (table, i, expander_column);
307
308       relation_set =  atk_object_ref_relation_set (cell);
309       relation = atk_relation_set_get_relation_by_type (relation_set, 
310                                      ATK_RELATION_NODE_CHILD_OF);
311       g_assert (relation);
312       target = atk_relation_get_target (relation);
313       g_assert (target->len == 1);
314       for (j = 0; j < target->len; j++)
315         {
316           AtkObject *target_obj;
317           AtkRole role;
318           gint target_index, target_row;
319
320           target_obj = g_ptr_array_index (target, j);
321           role = atk_object_get_role (target_obj);
322
323           switch (role)
324             {
325             case ATK_ROLE_TREE_TABLE:
326               g_print ("Row %d is top level\n", i);
327               break;
328             case ATK_ROLE_TABLE_CELL:
329               target_index = atk_object_get_index_in_parent (target_obj);
330               target_row = atk_table_get_row_at_index (table, target_index);
331               g_print ("Row %d has parent at %d\n", i, target_row);
332               break;
333             default:
334               g_assert_not_reached ();
335             } 
336         }
337       g_object_unref (relation_set);
338       g_object_unref (cell);
339     }
340 }
341
342 static void
343 _create_event_watcher (void)
344 {
345   atk_add_focus_tracker (_check_table);
346 }
347
348 int
349 gtk_module_init (gint argc, 
350                  char *argv[])
351 {
352   g_print ("testtreetable Module loaded\n");
353
354   _create_event_watcher ();
355
356   return 0;
357 }
358
359 static void
360 _runtest (AtkObject *obj)
361 {
362   AtkObject *child_obj;
363   AtkTable *table;
364   AtkObject *caption;
365   gint i;
366   gint n_cols, n_rows, n_children; 
367
368   table = ATK_TABLE (obj);
369   n_children = atk_object_get_n_accessible_children (ATK_OBJECT (obj));
370   n_cols = atk_table_get_n_columns (table);
371   n_rows = atk_table_get_n_rows (table);
372   g_print ("n_children: %d n_rows: %d n_cols: %d\n", 
373             n_children, n_rows, n_cols);
374   
375   for (i = 0; i < n_rows; i++)
376     {
377       gint index = atk_table_get_index_at (table, i, expander_column);
378       gint index_in_parent;
379
380       child_obj = atk_table_ref_at (table, i, expander_column);
381       index_in_parent = atk_object_get_index_in_parent (child_obj);
382       g_print ("index: %d %d row %d column %d\n", index, index_in_parent, i, expander_column);
383       
384       g_object_unref (child_obj);
385     }
386   caption = atk_table_get_caption (table);
387   if (caption)
388     {
389       const gchar *caption_name = atk_object_get_name (caption);
390
391       g_print ("Caption: %s\n", caption_name ? caption_name : "<null>");
392     }
393   for (i = 0; i < n_cols; i++)
394     {
395       AtkObject *header;
396
397       header = atk_table_get_column_header (table, i);
398       g_print ("Header for column %d is %p\n", i, header);
399       if (header)
400         {
401           const gchar *name;
402           AtkRole role;
403           AtkObject *parent;
404           AtkObject *child;
405           gint index;
406
407           name = atk_object_get_name (header);
408           role = atk_object_get_role (header);
409           parent = atk_object_get_parent (header);
410
411           if (parent)
412             {
413               index = atk_object_get_index_in_parent (header);
414               g_print ("Parent: %s index: %d\n", G_OBJECT_TYPE_NAME (parent), index);
415               child = atk_object_ref_accessible_child (parent, 0);
416               g_print ("Child: %s %p\n", G_OBJECT_TYPE_NAME (child), child);
417               if (index >= 0)
418                 {
419                   child = atk_object_ref_accessible_child (parent, index);
420                   g_print ("Index: %d child: %s\n", index, G_OBJECT_TYPE_NAME (child));
421                   g_object_unref (child);
422                 }
423             }
424           else
425             g_print ("Parent of header is NULL\n");
426           g_print ("%s %s %s\n", G_OBJECT_TYPE_NAME (header), name ? name: "<null>", atk_role_get_name (role));
427         }
428     }
429 }
430
431 static void 
432 row_inserted (AtkObject *obj,
433               gint      row,
434               gint      count)
435 {
436 #if 0
437   GtkWidget *widget;
438   GtkTreeView *tree_view;
439   GtkTreeModel *tree_model;
440 #endif
441   gint index;
442
443   g_print ("row_inserted: row: %d count: %d\n", row, count);
444   index = atk_table_get_index_at (ATK_TABLE (obj), row+1, 0);
445   g_print ("index for first column of next row is %d\n", index);
446
447 #if 0
448   widget = GTK_ACCESSIBLE (obj)->widget;
449   tree_view = GTK_TREE_VIEW (widget);
450   tree_model = gtk_tree_view_get_model (tree_view);
451   if (GTK_IS_TREE_STORE (tree_model))
452     {
453       GtkTreeStore *tree_store;
454       GtkTreePath *tree_path;
455       GtkTreeIter tree_iter;
456
457       tree_store = GTK_TREE_STORE (tree_model);
458       tree_path = gtk_tree_path_new_from_string ("3:0");
459       gtk_tree_model_get_iter (tree_model, &tree_iter, tree_path);
460       gtk_tree_path_free (tree_path);
461       gtk_tree_store_remove (tree_store, &tree_iter);
462     }
463 #endif
464 }
465
466 static void 
467 row_deleted (AtkObject *obj,
468              gint      row,
469              gint      count)
470 {
471 #if 0
472   GtkWidget *widget;
473   GtkTreeView *tree_view;
474   GtkTreeModel *tree_model;
475 #endif
476   gint index;
477
478   g_print ("row_deleted: row: %d count: %d\n", row, count);
479   index = atk_table_get_index_at (ATK_TABLE (obj), row+1, 0);
480   g_print ("index for first column of next row is %d\n", index);
481
482 #if 0
483   widget = GTK_ACCESSIBLE (obj)->widget;
484   tree_view = GTK_TREE_VIEW (widget);
485   tree_model = gtk_tree_view_get_model (tree_view);
486   if (GTK_IS_TREE_STORE (tree_model))
487     {
488       GtkTreeStore *tree_store;
489       GtkTreePath *tree_path;
490       GtkTreeIter tree_iter, new_iter;
491
492       tree_store = GTK_TREE_STORE (tree_model);
493       tree_path = gtk_tree_path_new_from_string ("2");
494       gtk_tree_model_get_iter (tree_model, &tree_iter, tree_path);
495       gtk_tree_path_free (tree_path);
496       gtk_tree_store_insert_before (tree_store, &new_iter, NULL, &tree_iter);
497     }
498 #endif
499 }