From f7b0e26b427f42d312dc84c4197181a364da88f0 Mon Sep 17 00:00:00 2001 From: Mike Gorse Date: Thu, 8 Nov 2018 10:26:02 -0600 Subject: [PATCH] A11y: Add support for AtkTableCell --- gtk/a11y/gtkcellaccessible.c | 88 ++++++++++++++++++++++++++++- gtk/a11y/gtkcellaccessibleparent.c | 66 ++++++++++++++++++++++ gtk/a11y/gtkcellaccessibleparent.h | 19 +++++++ gtk/a11y/gtktreeviewaccessible.c | 52 +++++++++++++++++ testsuite/a11y/accessibility-dump.c | 51 +++++++++++++++++ 5 files changed, 275 insertions(+), 1 deletion(-) diff --git a/gtk/a11y/gtkcellaccessible.c b/gtk/a11y/gtkcellaccessible.c index ad7601405f..ebbf096b3b 100644 --- a/gtk/a11y/gtkcellaccessible.c +++ b/gtk/a11y/gtkcellaccessible.c @@ -46,11 +46,13 @@ static const struct { static GtkCellRendererState gtk_cell_accessible_get_state (GtkCellAccessible *cell); static void atk_action_interface_init (AtkActionIface *iface); static void atk_component_interface_init (AtkComponentIface *iface); +static void atk_table_cell_interface_init (AtkTableCellIface *iface); G_DEFINE_TYPE_WITH_CODE (GtkCellAccessible, gtk_cell_accessible, GTK_TYPE_ACCESSIBLE, G_ADD_PRIVATE (GtkCellAccessible) G_IMPLEMENT_INTERFACE (ATK_TYPE_ACTION, atk_action_interface_init) - G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init)) + G_IMPLEMENT_INTERFACE (ATK_TYPE_COMPONENT, atk_component_interface_init) + G_IMPLEMENT_INTERFACE (ATK_TYPE_TABLE_CELL, atk_table_cell_interface_init)) static gint gtk_cell_accessible_get_index_in_parent (AtkObject *obj) @@ -366,6 +368,90 @@ atk_component_interface_init (AtkComponentIface *iface) iface->grab_focus = gtk_cell_accessible_grab_focus; } +static gboolean +gtk_cell_accessible_get_column_span (AtkTableCell *table_cell) +{ + return 1; +} + +static GPtrArray * +gtk_cell_accessible_get_column_header_cells (AtkTableCell *table_cell) +{ + GtkCellAccessible *cell; + AtkObject *parent; + + cell = GTK_CELL_ACCESSIBLE (table_cell); + parent = gtk_widget_get_accessible (gtk_accessible_get_widget (GTK_ACCESSIBLE (cell))); + + return gtk_cell_accessible_parent_get_column_header_cells (GTK_CELL_ACCESSIBLE_PARENT (parent), + cell); +} + +static gboolean +gtk_cell_accessible_get_position (AtkTableCell *table_cell, + gint *row, + gint *column) +{ + GtkCellAccessible *cell; + AtkObject *parent; + + cell = GTK_CELL_ACCESSIBLE (table_cell); + parent = gtk_widget_get_accessible (gtk_accessible_get_widget (GTK_ACCESSIBLE (cell))); + + gtk_cell_accessible_parent_get_cell_position (GTK_CELL_ACCESSIBLE_PARENT (parent), + cell, + row, column); + return ((row && *row > 0) || (column && *column > 0)); +} + +static gboolean +gtk_cell_accessible_get_row_span (AtkTableCell *table_cell) +{ + return 1; +} + +static GPtrArray * +gtk_cell_accessible_get_row_header_cells (AtkTableCell *table_cell) +{ + GtkCellAccessible *cell; + AtkObject *parent; + + cell = GTK_CELL_ACCESSIBLE (table_cell); + parent = gtk_widget_get_accessible (gtk_accessible_get_widget (GTK_ACCESSIBLE (cell))); + + return gtk_cell_accessible_parent_get_row_header_cells (GTK_CELL_ACCESSIBLE_PARENT (parent), + cell); +} + +static gboolean +gtk_cell_accessible_get_table (AtkTableCell *table_cell) +{ + AtkObject *obj; + + obj = ATK_OBJECT (table_cell); + do + { + AtkRole role; + obj = atk_object_get_parent (obj); + role = atk_object_get_role (obj); + if (role == ATK_ROLE_TABLE || role == ATK_ROLE_TREE_TABLE) + break; + } + while (obj); + return obj; +} + +static void +atk_table_cell_interface_init (AtkTableCellIface *iface) +{ + iface->get_column_span = gtk_cell_accessible_get_column_span; + iface->get_column_header_cells = gtk_cell_accessible_get_column_header_cells; + iface->get_position = gtk_cell_accessible_get_position; + iface->get_row_span = gtk_cell_accessible_get_row_span; + iface->get_row_header_cells = gtk_cell_accessible_get_row_header_cells; + iface->get_table = gtk_cell_accessible_get_table; +} + static GtkCellRendererState gtk_cell_accessible_get_state (GtkCellAccessible *cell) { diff --git a/gtk/a11y/gtkcellaccessibleparent.c b/gtk/a11y/gtkcellaccessibleparent.c index e4ad784a27..1f9dcd75f9 100644 --- a/gtk/a11y/gtkcellaccessibleparent.c +++ b/gtk/a11y/gtkcellaccessibleparent.c @@ -187,3 +187,69 @@ gtk_cell_accessible_parent_update_relationset (GtkCellAccessibleParent *parent, if (iface->update_relationset) (iface->update_relationset) (parent, cell, relationset); } + +void +gtk_cell_accessible_parent_get_cell_position (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell, + gint *row, + gint *column) +{ + GtkCellAccessibleParentIface *iface; + + g_return_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent)); + g_return_if_fail (GTK_IS_CELL_ACCESSIBLE (cell)); + + iface = GTK_CELL_ACCESSIBLE_PARENT_GET_IFACE (parent); + + if (iface->get_cell_position) + (iface->get_cell_position) (parent, cell, row, column); + else + { + if (row) + *row = -1; + if (column) + *column = -1; + } +} + +/** + * gtk_cell_accessible_parent_get_column_header_cells: + * Returns: (transfer full) (element-type AtkObject) + */ +GPtrArray * +gtk_cell_accessible_parent_get_column_header_cells (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell) +{ + GtkCellAccessibleParentIface *iface; + + g_return_val_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent), NULL); + g_return_val_if_fail (GTK_IS_CELL_ACCESSIBLE (cell), NULL); + + iface = GTK_CELL_ACCESSIBLE_PARENT_GET_IFACE (parent); + + if (iface->get_column_header_cells) + return (iface->get_column_header_cells) (parent, cell); + else + return NULL; +} + +/** + * gtk_cell_accessible_parent_get_row_header_cells: + * Returns: (transfer full) (element-type AtkObject) + */ +GPtrArray * +gtk_cell_accessible_parent_get_row_header_cells (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell) +{ + GtkCellAccessibleParentIface *iface; + + g_return_val_if_fail (GTK_IS_CELL_ACCESSIBLE_PARENT (parent), NULL); + g_return_val_if_fail (GTK_IS_CELL_ACCESSIBLE (cell), NULL); + + iface = GTK_CELL_ACCESSIBLE_PARENT_GET_IFACE (parent); + + if (iface->get_row_header_cells) + return (iface->get_row_header_cells) (parent, cell); + else + return NULL; +} diff --git a/gtk/a11y/gtkcellaccessibleparent.h b/gtk/a11y/gtkcellaccessibleparent.h index 7cece0e778..a773f37288 100644 --- a/gtk/a11y/gtkcellaccessibleparent.h +++ b/gtk/a11y/gtkcellaccessibleparent.h @@ -75,6 +75,14 @@ struct _GtkCellAccessibleParentIface void ( *update_relationset) (GtkCellAccessibleParent *parent, GtkCellAccessible *cell, AtkRelationSet *relationset); + void ( *get_cell_position) (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell, + gint *row, + gint *column); + GPtrArray * ( *get_column_header_cells) (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell); + GPtrArray * ( *get_row_header_cells) (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell); }; GDK_AVAILABLE_IN_ALL @@ -115,6 +123,17 @@ GDK_AVAILABLE_IN_ALL void gtk_cell_accessible_parent_update_relationset (GtkCellAccessibleParent *parent, GtkCellAccessible *cell, AtkRelationSet *relationset); +GDK_AVAILABLE_IN_ALL +void gtk_cell_accessible_parent_get_cell_position(GtkCellAccessibleParent *parent, + GtkCellAccessible *cell, + gint *row, + gint *column); + +GPtrArray *gtk_cell_accessible_parent_get_column_header_cells (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell); + +GPtrArray *gtk_cell_accessible_parent_get_row_header_cells (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell); G_END_DECLS diff --git a/gtk/a11y/gtktreeviewaccessible.c b/gtk/a11y/gtktreeviewaccessible.c index f32acee10b..37339ceb14 100644 --- a/gtk/a11y/gtktreeviewaccessible.c +++ b/gtk/a11y/gtktreeviewaccessible.c @@ -1391,6 +1391,56 @@ gtk_tree_view_accessible_update_relationset (GtkCellAccessibleParent *parent, } } +static void +gtk_tree_view_accessible_get_cell_position (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell, + gint *row, + gint *column) +{ + GtkWidget *widget; + GtkTreeView *tree_view; + GtkTreeViewAccessibleCellInfo *cell_info; + GtkTreeViewAccessible *accessible; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)); + if (widget == NULL) + return; + + tree_view = GTK_TREE_VIEW (widget); + accessible = GTK_TREE_VIEW_ACCESSIBLE (parent); + cell_info = find_cell_info (accessible, cell); + if (!cell_info) + return; + + if (row) + (*row) = _gtk_rbtree_node_get_index (cell_info->tree, cell_info->node); + if (column) + (*column) = get_column_number (tree_view, cell_info->cell_col_ref); +} + +static GPtrArray * +gtk_tree_view_accessible_get_column_header_cells (GtkCellAccessibleParent *parent, + GtkCellAccessible *cell) +{ + GtkWidget *widget; + GtkTreeViewAccessibleCellInfo *cell_info; + GtkTreeViewAccessible *accessible; + GPtrArray *array; + + widget = gtk_accessible_get_widget (GTK_ACCESSIBLE (parent)); + if (widget == NULL) + return NULL; + + accessible = GTK_TREE_VIEW_ACCESSIBLE (parent); + cell_info = find_cell_info (accessible, cell); + if (!cell_info) + return NULL; + + array = g_ptr_array_new_full (1, g_object_unref); + g_ptr_array_add (array, g_object_ref (get_header_from_column ( (cell_info->cell_col_ref)))); + return array; +} + static void gtk_cell_accessible_parent_interface_init (GtkCellAccessibleParentIface *iface) { @@ -1403,6 +1453,8 @@ gtk_cell_accessible_parent_interface_init (GtkCellAccessibleParentIface *iface) iface->activate = gtk_tree_view_accessible_activate; iface->edit = gtk_tree_view_accessible_edit; iface->update_relationset = gtk_tree_view_accessible_update_relationset; + iface->get_cell_position = gtk_tree_view_accessible_get_cell_position; + iface->get_column_header_cells = gtk_tree_view_accessible_get_column_header_cells; } void diff --git a/testsuite/a11y/accessibility-dump.c b/testsuite/a11y/accessibility-dump.c index 5f848fb96a..96da1af98b 100644 --- a/testsuite/a11y/accessibility-dump.c +++ b/testsuite/a11y/accessibility-dump.c @@ -626,6 +626,54 @@ G_GNUC_END_IGNORE_DEPRECATIONS } } +static void +dump_atk_table_cell (AtkTableCell *table_cell, + guint depth, + GString *string) +{ + gint i; + AtkObject *obj; + GPtrArray *cells; + gint row = -1, column = -1; + + g_string_append_printf (string, "%*s\n", depth, ""); + + obj = atk_table_cell_get_table (table_cell); + if (obj) + g_string_append_printf (string, "%*stable: %s\n", depth, "", get_name (obj)); + + cells = atk_table_cell_get_column_header_cells (table_cell); + if (cells) + { + for (i = 0; i < cells->len; i++) + { + obj = g_ptr_array_index (cells, i); + if (obj) + g_string_append_printf (string, "%*scolumn-header[%d]: %s\n", depth, "", i, get_name (obj)); + } + g_ptr_array_free (cells, TRUE); + } + + cells = atk_table_cell_get_row_header_cells (table_cell); + if (cells) + { + for (i = 0; i < cells->len; i++) + { + obj = g_ptr_array_index (cells, i); + if (obj) + g_string_append_printf (string, "%*srow-header[%d]: %s\n", depth, "", i, get_name (obj)); + } + g_ptr_array_free (cells, TRUE); + } + + g_string_append_printf (string, "%*scolumn-span: %d\n", depth, "", atk_table_cell_get_column_span (table_cell)); + g_string_append_printf (string, "%*srow-span: %d\n", depth, "", atk_table_cell_get_row_span (table_cell)); + if (atk_table_cell_get_position (table_cell, &row, &column)) + { + g_string_append_printf (string, "%*sposition: %d %d\n", depth, "", row, column); + } +} + static void dump_accessible (AtkObject *accessible, guint depth, @@ -679,6 +727,9 @@ dump_accessible (AtkObject *accessible, if (ATK_IS_TABLE (accessible)) dump_atk_table (ATK_TABLE (accessible), depth, string); + if (ATK_IS_TABLE_CELL (accessible)) + dump_atk_table_cell (ATK_TABLE_CELL (accessible), depth, string); + for (i = 0; i < atk_object_get_n_accessible_children (accessible); i++) { AtkObject *child = atk_object_ref_accessible_child (accessible, i); diff --git a/testsuite/a11y/tree.txt b/testsuite/a11y/tree.txt index 4b0bb681db..c26c1a9c84 100644 --- a/testsuite/a11y/tree.txt +++ b/testsuite/a11y/tree.txt @@ -59,6 +59,11 @@ window1 action 1 description: Creates a widget in which the contents of the cell can be edited action 2 name: activate action 2 description: Activates the cell + + table: tv + column-header[0]: unnamed-GtkButtonAccessible-0 + column-span: 1 + row-span: 1 tv "table cell" parent: tv @@ -103,6 +108,11 @@ window1 action 1 description: Creates a widget in which the contents of the cell can be edited action 2 name: activate action 2 description: Activates the cell + + table: tv + column-header[0]: unnamed-GtkButtonAccessible-0 + column-span: 1 + row-span: 1 tv "table cell" parent: tv @@ -147,6 +157,11 @@ window1 action 1 description: Creates a widget in which the contents of the cell can be edited action 2 name: activate action 2 description: Activates the cell + + table: tv + column-header[0]: unnamed-GtkButtonAccessible-0 + column-span: 1 + row-span: 1 tv "table cell" parent: tv @@ -162,6 +177,12 @@ window1 action 1 description: Creates a widget in which the contents of the cell can be edited action 2 name: activate action 2 description: Activates the cell + + table: tv + column-header[0]: unnamed-GtkButtonAccessible-0 + column-span: 1 + row-span: 1 + position: 1 0 tv "table cell" parent: tv @@ -206,6 +227,12 @@ window1 action 1 description: Creates a widget in which the contents of the cell can be edited action 2 name: activate action 2 description: Activates the cell + + table: tv + column-header[0]: unnamed-GtkButtonAccessible-0 + column-span: 1 + row-span: 1 + position: 1 0 tv "table cell" parent: tv @@ -250,6 +277,12 @@ window1 action 1 description: Creates a widget in which the contents of the cell can be edited action 2 name: activate action 2 description: Activates the cell + + table: tv + column-header[0]: unnamed-GtkButtonAccessible-0 + column-span: 1 + row-span: 1 + position: 1 0 tv "table cell" parent: tv @@ -265,6 +298,12 @@ window1 action 1 description: Creates a widget in which the contents of the cell can be edited action 2 name: activate action 2 description: Activates the cell + + table: tv + column-header[0]: unnamed-GtkButtonAccessible-0 + column-span: 1 + row-span: 1 + position: 2 0 tv "table cell" parent: tv @@ -309,6 +348,12 @@ window1 action 1 description: Creates a widget in which the contents of the cell can be edited action 2 name: activate action 2 description: Activates the cell + + table: tv + column-header[0]: unnamed-GtkButtonAccessible-0 + column-span: 1 + row-span: 1 + position: 2 0 tv "table cell" parent: tv @@ -353,3 +398,9 @@ window1 action 1 description: Creates a widget in which the contents of the cell can be edited action 2 name: activate action 2 description: Activates the cell + + table: tv + column-header[0]: unnamed-GtkButtonAccessible-0 + column-span: 1 + row-span: 1 + position: 2 0 -- 2.18.0