2 * Copyright 2008 Codethink Ltd.
3 * Copyright (c) 2015 Samsung Electronics Co., Ltd.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
25 #include "my-atk-object.h"
26 #include "my-atk-table.h"
27 #include "my-atk-table-cell.h"
29 typedef struct _MyAtkTableInfo MyAtkTableInfo;
31 static void GDestroyNotifyGPTRARRAYptrArray (gpointer data);
32 static void atk_table_interface_init (AtkTableIface *iface);
34 G_DEFINE_TYPE_WITH_CODE (MyAtkTable,
37 G_IMPLEMENT_INTERFACE (ATK_TYPE_TABLE,
38 atk_table_interface_init));
42 my_atk_table_get_index_at (AtkTable *obj, gint row, gint column)
44 MyAtkTable *self = MY_ATK_TABLE (obj);
45 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), -1);
46 gint i, all_child, index_first_cell = -1;
49 all_child = MY_ATK_OBJECT (self)->children->len;
50 AtkObject *child = NULL;
52 MyAtkTableCell *cell = NULL;
53 for (i = 0; i < all_child; i++) {
54 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
55 if (atk_object_get_role (child) == ATK_ROLE_TABLE_CELL) {
56 if (index_first_cell == -1) {
59 cell = MY_ATK_TABLE_CELL (child);
60 if (cell->x == column && cell->y == row) {
61 ret = i-index_first_cell;
69 my_atk_table_get_column_at_index (AtkTable *obj, gint index)
71 MyAtkTable *table = MY_ATK_TABLE (obj);
72 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), -1);
77 columns = atk_table_get_n_columns (ATK_TABLE (table));
78 rows = atk_table_get_n_rows (ATK_TABLE (table));
80 for (i = 0; i < rows; i++) {
81 for (j = 0; j < columns; j++) {
82 if (index == my_atk_table_get_index_at (obj, i, j))
90 my_atk_table_get_row_at_index (AtkTable *obj, gint index)
92 MyAtkTable *table = MY_ATK_TABLE (obj);
93 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), -1);
98 columns = atk_table_get_n_columns (ATK_TABLE (table));
99 rows = atk_table_get_n_rows (ATK_TABLE (table));
101 for (i = 0; i < rows; i++) {
102 for (j = 0; j < columns; j++) {
103 if (index == my_atk_table_get_index_at (obj, i, j))
112 my_atk_table_get_n_columns (AtkTable *obj)
114 MyAtkTable *self = MY_ATK_TABLE (obj);
115 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), -1);
116 gint i, all_child, ret=0;
118 all_child = MY_ATK_OBJECT (self)->children->len;
119 AtkObject *child = NULL;
120 for (i = 0; i < all_child; i++) {
121 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
122 if (atk_object_get_role (child) == ATK_ROLE_TABLE_COLUMN_HEADER)
129 my_atk_table_get_n_rows (AtkTable *obj)
131 MyAtkTable *self = MY_ATK_TABLE (obj);
132 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), -1);
133 gint i, all_child, ret=0;
135 all_child = MY_ATK_OBJECT (self)->children->len;
136 AtkObject *child = NULL;
137 for (i = 0; i < all_child; i++) {
138 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
139 if (atk_object_get_role (child) == ATK_ROLE_TABLE_ROW_HEADER)
146 my_atk_table_get_caption (AtkTable *obj)
148 MyAtkTable *self = MY_ATK_TABLE (obj);
150 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), NULL);
152 AtkObject *caption = NULL;
154 all_child = MY_ATK_OBJECT (self)->children->len;
155 AtkObject *child = NULL;
156 for (i = 0; i < all_child; i++) {
157 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
158 if (atk_object_get_role (child) == ATK_ROLE_CAPTION)
161 return caption ? caption : NULL;
165 my_atk_table_ref_at (AtkTable *obj, gint row, gint column)
167 MyAtkTable *self = MY_ATK_TABLE (obj);
168 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), NULL);
170 AtkObject *ret = NULL;
172 all_child = MY_ATK_OBJECT (self)->children->len;
173 AtkObject *child = NULL;
175 MyAtkTableCell *cell = NULL;
176 for (i = 0; i < all_child; i++) {
177 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
178 if (atk_object_get_role (child) == ATK_ROLE_TABLE_CELL) {
179 cell = MY_ATK_TABLE_CELL (child);
180 if (cell->x == column && cell->y == row)
181 ret = ATK_OBJECT (cell);
184 return ret ? ret : NULL;
188 my_atk_table_get_row_description (AtkTable *obj, gint index)
190 MyAtkTable *self = MY_ATK_TABLE (obj);
191 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), NULL);
193 GPtrArray *ret = g_ptr_array_new_full ( my_atk_table_get_n_rows (obj),
196 all_child = MY_ATK_OBJECT (self)->children->len;
197 AtkObject *child = NULL;
199 for (i = 0; i < all_child; i++) {
200 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
201 if (atk_object_get_role (child) == ATK_ROLE_TABLE_ROW_HEADER)
202 g_ptr_array_add (ret, child);
204 child = g_ptr_array_index (ret, index);
206 return g_strdup (atk_object_get_description (child));
210 my_atk_table_get_column_description (AtkTable *obj, gint index)
212 MyAtkTable *self = MY_ATK_TABLE (obj);
213 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), NULL);
215 GPtrArray *ret = g_ptr_array_new_full (my_atk_table_get_n_columns (obj), g_object_unref);
217 all_child = MY_ATK_OBJECT(self)->children->len;
218 AtkObject *child = NULL;
220 for (i = 0; i < all_child; i++) {
221 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
222 if (atk_object_get_role (child) == ATK_ROLE_TABLE_COLUMN_HEADER)
223 g_ptr_array_add (ret, child);
225 child = g_ptr_array_index (ret, index);
227 return g_strdup (atk_object_get_description (child));
231 my_atk_table_test_table_get_row_extent_at (AtkTable *obj, gint row, gint col)
233 AtkObject *cell = my_atk_table_ref_at (obj, row, col);
235 MyAtkTableCell *self = MY_ATK_TABLE_CELL (cell);
237 return self->row_span;
241 my_atk_table_test_table_get_column_extent_at (AtkTable *obj, gint row, gint col)
243 AtkObject *cell = my_atk_table_ref_at (obj, row, col);
245 MyAtkTableCell *self = MY_ATK_TABLE_CELL (cell);
247 return self->column_span;
251 my_atk_table_get_row_header (AtkTable *obj, gint row)
253 MyAtkTable *self = MY_ATK_TABLE (obj);
254 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), NULL);
256 GPtrArray *ret = g_ptr_array_new_full (my_atk_table_get_n_rows (obj), g_object_unref);
258 all_child = MY_ATK_OBJECT (self)->children->len;
259 AtkObject *child = NULL;
262 for (i = 0; i < all_child; i++) {
263 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
264 if (atk_object_get_role (child) == ATK_ROLE_TABLE_ROW_HEADER)
265 g_ptr_array_add (ret, child);
267 c = ATK_OBJECT (g_ptr_array_index (ret, row));
269 return atk_object_ref_accessible_child (c, 0);
273 my_atk_table_get_column_header (AtkTable *obj, gint col)
275 MyAtkTable *self = MY_ATK_TABLE (obj);
276 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), NULL);
278 GPtrArray *ret = g_ptr_array_new_full (my_atk_table_get_n_rows (obj), g_object_unref);
280 all_child = MY_ATK_OBJECT (self)->children->len;
281 AtkObject *child = NULL;
284 for (i = 0; i < all_child; i++) {
285 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
286 if (atk_object_get_role (child) == ATK_ROLE_TABLE_COLUMN_HEADER)
287 g_ptr_array_add (ret, child);
289 c = g_ptr_array_index (ret, col);
291 return atk_object_ref_accessible_child (c, 0);
295 my_atk_table_get_selected_rows (AtkTable *obj, gint **selected)
297 MyAtkTable *self = MY_ATK_TABLE (obj);
298 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), -1);
299 gint i, all_child, row = 0, ret = 0;
300 AtkObject *child = NULL;
301 AtkStateSet *ss = NULL;
303 GArray *array = g_array_new (FALSE, FALSE, sizeof (gint));
305 all_child = MY_ATK_OBJECT (self)->children->len;
306 for (i=0; i<all_child; i++) {
307 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
308 if (atk_object_get_role (child) == ATK_ROLE_TABLE_ROW_HEADER) {
309 ss = atk_object_ref_state_set (child);
310 if (atk_state_set_contains_state (ss, ATK_STATE_SELECTED)) {
312 g_array_append_val (array, row);
318 *selected = (gint *) g_array_free (array, FALSE);
323 my_atk_table_get_selected_columns (AtkTable *obj, gint **selected)
325 MyAtkTable *self = MY_ATK_TABLE (obj);
326 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), -1);
327 gint i, all_child, column = 0, ret = 0;
328 AtkObject *child = NULL;
329 AtkStateSet *ss = NULL;
331 GArray *array = g_array_new (FALSE, FALSE, sizeof (gint));
333 all_child = MY_ATK_OBJECT (self)->children->len;
334 for (i=0; i<all_child; i++) {
335 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
336 if (atk_object_get_role (child) == ATK_ROLE_TABLE_COLUMN_HEADER) {
337 ss = atk_object_ref_state_set (child);
338 if (atk_state_set_contains_state (ss, ATK_STATE_SELECTED)) {
340 g_array_append_val (array, column);
346 *selected = (gint *) g_array_free (array, FALSE);
351 my_atk_table_is_row_selected (AtkTable *obj, gint row)
353 MyAtkTable *self = MY_ATK_TABLE (obj);
354 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), FALSE);
356 AtkObject *child = NULL;
358 AtkStateSet *ss = NULL;
359 GPtrArray *ret = g_ptr_array_new_full (my_atk_table_get_n_rows (obj), g_object_unref);
361 all_child = MY_ATK_OBJECT (self)->children->len;
362 for (i = 0; i < all_child; i++) {
363 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
364 if (atk_object_get_role (child) == ATK_ROLE_TABLE_ROW_HEADER)
365 g_ptr_array_add (ret, child);
367 c = g_ptr_array_index (ret, row);
368 ss = atk_object_ref_state_set (c);
369 if (atk_state_set_contains_state (ss, ATK_STATE_SELECTED))
375 my_atk_table_is_column_selected (AtkTable *obj, gint col)
377 MyAtkTable *self = MY_ATK_TABLE (obj);
378 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), FALSE);
380 AtkObject *child = NULL;
382 AtkStateSet *ss = NULL;
383 GPtrArray *ret = g_ptr_array_new_full (my_atk_table_get_n_columns (obj), g_object_unref);
385 all_child = MY_ATK_OBJECT (self)->children->len;
386 for (i = 0; i < all_child; i++) {
387 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
388 if (atk_object_get_role (child) == ATK_ROLE_TABLE_COLUMN_HEADER)
389 g_ptr_array_add (ret, child);
391 c = g_ptr_array_index (ret, col);
392 ss = atk_object_ref_state_set (c);
393 if (atk_state_set_contains_state (ss, ATK_STATE_SELECTED))
399 my_atk_table_is_selected (AtkTable *obj, gint row, gint col)
401 AtkObject *cell = atk_table_ref_at (obj, row, col);
402 AtkStateSet *ss = atk_object_ref_state_set (cell);
403 gboolean ret = FALSE;
405 if (atk_state_set_contains_state (ss, ATK_STATE_SELECTED))
411 my_atk_table_add_column_selection (AtkTable *obj, gint col)
413 MyAtkTable *self = MY_ATK_TABLE (obj);
414 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), FALSE);
415 gint i, all_child, counter = 0;
416 AtkObject *child = NULL;
417 AtkStateSet *ss = NULL;
419 all_child = MY_ATK_OBJECT (self)->children->len;
420 for (i = 0; i < all_child; i++) {
421 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
422 if (atk_object_get_role (child) == ATK_ROLE_TABLE_COLUMN_HEADER) {
423 if (col == counter) {
424 ss = atk_object_ref_state_set (child);
425 if (!atk_state_set_contains_state (ss, ATK_STATE_SELECTED)) {
426 atk_state_set_add_state (ss, ATK_STATE_SELECTED);
437 my_atk_table_add_row_selection (AtkTable *obj, gint row)
439 MyAtkTable *self = MY_ATK_TABLE (obj);
440 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), FALSE);
441 gint i, all_child, counter = 0;
442 AtkObject *child = NULL;
443 AtkStateSet *ss = NULL;
445 all_child = MY_ATK_OBJECT (self)->children->len;
446 for (i = 0; i < all_child; i++) {
447 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
448 if (atk_object_get_role (child) == ATK_ROLE_TABLE_ROW_HEADER) {
449 if (row == counter) {
450 ss = atk_object_ref_state_set (child);
451 if (!atk_state_set_contains_state (ss, ATK_STATE_SELECTED)) {
452 atk_state_set_add_state (ss, ATK_STATE_SELECTED);
463 my_atk_table_remove_column_selection (AtkTable *obj, gint col)
465 MyAtkTable *self = MY_ATK_TABLE (obj);
466 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), FALSE);
467 gint i, all_child, counter = 0;
468 AtkObject *child = NULL;
469 AtkStateSet *ss = NULL;
471 all_child = MY_ATK_OBJECT (self)->children->len;
472 for (i = 0; i < all_child; i++) {
473 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
474 if (atk_object_get_role (child) == ATK_ROLE_TABLE_COLUMN_HEADER) {
475 if (col == counter) {
476 ss = atk_object_ref_state_set (child);
477 if (atk_state_set_contains_state (ss, ATK_STATE_SELECTED)) {
478 atk_state_set_remove_state (ss, ATK_STATE_SELECTED);
489 my_atk_table_remove_row_selection (AtkTable *obj, gint row)
491 MyAtkTable *self = MY_ATK_TABLE (obj);
492 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), FALSE);
493 gint i, all_child, counter = 0;
494 AtkObject *child = NULL;
495 AtkStateSet *ss = NULL;
497 all_child = MY_ATK_OBJECT (self)->children->len;
498 for (i = 0; i < all_child; i++) {
499 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
500 if (atk_object_get_role (child) == ATK_ROLE_TABLE_ROW_HEADER) {
501 if (row == counter) {
502 ss = atk_object_ref_state_set (child);
503 if (atk_state_set_contains_state (ss, ATK_STATE_SELECTED)) {
504 atk_state_set_remove_state (ss, ATK_STATE_SELECTED);
515 my_atk_table_get_summary (AtkTable *obj)
517 MyAtkTable *self = MY_ATK_TABLE (obj);
518 g_return_val_if_fail (MY_IS_ATK_TABLE (obj), NULL);
520 AtkObject *summary = NULL;
522 all_child = MY_ATK_OBJECT(self)->children->len;
523 AtkObject *child = NULL;
524 for (i=0; i<all_child; i++) {
525 child = atk_object_ref_accessible_child (ATK_OBJECT (obj), i);
526 if (atk_object_get_role (child) == ATK_ROLE_HEADING)
529 return summary ? summary : NULL;
533 my_atk_table_set_column_header (AtkTable *obj, gint column, AtkObject *header)
538 my_atk_table_set_column_description (AtkTable *obj, gint column, const gchar *desc)
543 my_atk_table_set_caption (AtkTable *obj, AtkObject *caption)
548 my_atk_table_set_row_description (AtkTable *obj, gint row, const gchar *desc)
553 my_atk_table_set_row_header (AtkTable *obj, gint column, AtkObject *header)
558 my_atk_table_set_summary (AtkTable *table, AtkObject *accessible)
563 my_atk_table_row_inserted (AtkTable *table, gint row, gint num_inserted)
568 my_atk_table_column_inserted (AtkTable *table, gint column, gint num_inserted)
573 my_atk_table_row_deleted (AtkTable *table, gint row, gint num_deleted)
578 my_atk_table_column_deleted (AtkTable *table, gint column, gint num_deleted)
583 my_atk_table_row_reordered (AtkTable *table)
588 my_atk_table_column_reordered (AtkTable *table)
593 my_atk_table_model_changed (AtkTable *table)
598 atk_table_interface_init (AtkTableIface *iface)
603 iface->ref_at = my_atk_table_ref_at;
605 /* DEPRICATED BUT NOT IN ATSPI */
606 iface->get_index_at = my_atk_table_get_index_at;
607 iface->get_column_at_index = my_atk_table_get_column_at_index;
608 iface->get_row_at_index = my_atk_table_get_row_at_index;
611 iface->get_n_columns = my_atk_table_get_n_columns;
612 iface->get_n_rows = my_atk_table_get_n_rows;
613 iface->get_column_extent_at = my_atk_table_test_table_get_column_extent_at;
614 iface->get_row_extent_at = my_atk_table_test_table_get_row_extent_at;
615 iface->get_caption = my_atk_table_get_caption;
616 iface->get_column_description = my_atk_table_get_column_description;
617 iface->get_column_header = my_atk_table_get_column_header;
618 iface->get_row_description = my_atk_table_get_row_description;
619 iface->get_row_header = my_atk_table_get_row_header;
620 iface->get_summary = my_atk_table_get_summary;
621 iface->set_caption = my_atk_table_set_caption;
622 iface->set_column_description = my_atk_table_set_column_description;
623 iface->set_column_header = my_atk_table_set_column_header;
624 iface->set_row_description = my_atk_table_set_row_description;
625 iface->set_row_header = my_atk_table_set_row_header;
626 iface->set_summary = my_atk_table_set_summary;
627 iface->get_selected_columns = my_atk_table_get_selected_columns;
628 iface->get_selected_rows = my_atk_table_get_selected_rows;
629 iface->is_column_selected = my_atk_table_is_column_selected;
630 iface->is_row_selected = my_atk_table_is_row_selected;
631 iface->is_selected = my_atk_table_is_selected;
632 iface->add_row_selection = my_atk_table_add_row_selection;
633 iface->remove_row_selection = my_atk_table_remove_row_selection;
634 iface->add_column_selection = my_atk_table_add_column_selection;
635 iface->remove_column_selection = my_atk_table_remove_column_selection;
636 iface->row_inserted = my_atk_table_row_inserted;
637 iface->column_inserted = my_atk_table_column_inserted;
638 iface->row_deleted = my_atk_table_row_deleted;
639 iface->column_deleted = my_atk_table_column_deleted;
640 iface->row_reordered = my_atk_table_row_reordered;
641 iface->column_reordered = my_atk_table_column_reordered;
642 iface->model_changed = my_atk_table_model_changed;
646 my_atk_table_init (MyAtkTable *self)
648 self->parent_table = NULL;
649 self->table = g_ptr_array_new_with_free_func (GDestroyNotifyGPTRARRAYptrArray);
650 self->row_header = g_ptr_array_new_with_free_func (GDestroyNotifyGPTRARRAYptrArray);
651 self->column_headers = g_ptr_array_new_with_free_func (GDestroyNotifyGPTRARRAYptrArray);
652 self->selected = FALSE;
653 self->col_desc = NULL;
658 GDestroyNotifyGPTRARRAYptrArray (gpointer data)
660 g_ptr_array_free (data, TRUE);
664 my_atk_table_class_initialize (AtkObject *obj, gpointer data)
669 my_atk_table_class_finalize (GObject *obj)
674 my_atk_table_class_init (MyAtkTableClass *my_class)
676 AtkObjectClass *atk_class = ATK_OBJECT_CLASS (my_class);
677 GObjectClass *gobject_class = G_OBJECT_CLASS (my_class);
679 gobject_class->finalize = my_atk_table_class_finalize;
681 atk_class->initialize = my_atk_table_class_initialize;