diff options
add gal-a11y-e-cell-vbox.h and gal-a11y-e-cell-vbox.c
2005-01-27 Li Yuan <li.yuan@sun.com>
* gal/a11y/e-table/Makefile.am:
add gal-a11y-e-cell-vbox.h and gal-a11y-e-cell-vbox.c
* gal/a11y/e-table/gal-a11y-e-cell-popup.c:
(gal_a11y_e_cell_popup_new):
add i18n support to strings.
Fixes #70261
* gal/a11y/e-table/gal-a11y-e-cell-text.c:
(ect_dispose): disconnect the insert and the delete signal.
(ect_check):do some check works.
(ect_get_name), (ect_get_text),
(ect_get_character_at_offset), (ect_get_caret_offset),
(ect_get_character_count), (ect_get_n_selections),
(ect_get_selection), (ect_add_selection), (ect_set_caret_offset),
(ect_insert_text): use e_cell_text_get_text_by_view instead of
e_cell_text_get_text. make get_name work well when e-cell-text
is being edited.
(ect_do_action_edit): call e_table_item_enter_edit only when
the cell is editable.
(ect_text_inserted_cb), (ect_text_deleted_cb):
emit the text_changed::insert(delete) signal. make gnopernicus
know the text_changed.
(ect_class_init): add dispose function.
(ect_action_init): add the edit action.
(gal_a11y_e_cell_text_get_type): no ect_init function now.
(cell_text_destroyed): unref the atkobject.
(gal_a11y_e_cell_text_new): connect text_inserted and text_deleted
singals and make sure the state of editable is right.
* gal/a11y/e-table/gal-a11y-e-cell-text.h:
add two signal handler id.
* gal/a11y/e-table/gal-a11y-e-cell-toggle.c:
(gal_a11y_e_cell_toggle_dispose): fix #70261.
(model_change_cb): make gnopernicus to report state change signal.
(gal_a11y_e_cell_toggle_new):add i18n support to strings.
* gal/a11y/e-table/gal-a11y-e-cell-tree.c:
(gal_a11y_e_cell_tree_new):
add i18n support to strings.
Fixes #61688
* gal/a11y/e-table/gal-a11y-e-cell-vbox.c: (ecv_get_n_children),
(subcell_destroyed), (ecv_ref_child), (ecv_dispose),
(ecv_ref_accessible_at_point), (ecv_class_init), (ecv_init),
(ecv_atk_component_iface_init), (gal_a11y_e_cell_vbox_get_type),
(gal_a11y_e_cell_vbox_new):
* gal/a11y/e-table/gal-a11y-e-cell-vbox.h:
implement a11y object of ECellVbox.
Fixes #48976
* gal/a11y/e-table/gal-a11y-e-cell.c:
function name are changed form eti_* to gal_a11y_e_cell_*
(is_valid): check if the cell is valid.
(gal_a11y_e_cell_dispose): make sure state_set is null.
(gal_a11y_e_cell_get_name): implement the get_name function.
(gal_a11y_e_cell_ref_state_set): add VISIBLE state.
(gal_a11y_e_cell_get_parent),
(gal_a11y_e_cell_get_index_in_parent),
(gal_a11y_e_cell_get_extents): use e_tree_get_cell_geometry and
e_table_get_cell_geometry instead of e_table_item_get_cell_geometry.
(gal_a11y_e_cell_grab_focus): make grab_focus work with e-tree also.
(gal_a11y_e_cell_atk_component_iface_init),
(gal_a11y_e_cell_class_init): add get_name function.
(gal_a11y_e_cell_init): add some state to cell.
(idle_do_action): check if cell is valid.
(gal_a11y_e_cell_action_do_action): check if cell is valid.
(gal_a11y_e_cell_get_type), (gal_a11y_e_cell_construct):
ref e-table-item.
* gal/a11y/e-table/gal-a11y-e-table-click-to-add.c:
(etcta_get_description), (etcta_action_get_name): add i18n support to strings.
(etcta_get_name): if etcta has message, return it.
(etcta_ref_state_set): implement the ref_state_set function,
add SENSITIVE and SHOWING state.
(etcta_class_init):add ref_state_set function.
(etcta_selection_cursor_changed): call atk_focus_tracker_notify
to a11y-e-cell
(gal_a11y_e_table_click_to_add_new): connect
etcta_selection_cursor_changed to cursor_changed signal.
* gal/a11y/e-table/gal-a11y-e-table-item-factory.c:
(gal_a11y_e_table_item_factory_create_accessible):
parameters of gal_a11y_e_table_item_new have been changed.
Fixes #68675
Fixes #70324
Fixes #68681
Fixes #68627
* gal/a11y/e-table/gal-a11y-e-table-item.c:
remove the cell_data support.
(item_destroyed): add ATK_STATE_DEFUNCT state and unref selection.
(eti_ref_state_set): just ref state_set.
(eti_dispose): we have unref selection in item_destroyed.
remove the cell_data support.
(eti_ref_child): remove support for column header. use eti_ref_at
instead of atk_table_ref_at.
(eti_get_extents): add support for click to add.
(eti_ref_accessible_at_point): e-tree and e-table are different here.
(cell_destroyed): add a check and unref item. remove the cell_data support.
(eti_ref_at): if e-table-item has DEFUNCT state, return NULL.
remove the cell_data support.
(eti_get_column_header): use column name as the a11y name. set it role
as ATK_ROLE_TABLE_COLUMN_HEADER.
(table_is_row_selected): use view_to_model_row to convert row when
uses source model.
(table_get_selected_rows): if e-table-item has DEFUNCT state, return 0.
(table_remove_row_selection): use view_to_model_row to convert row
when uses source model.
(eti_rows_inserted), (eti_rows_deleted): remove the cell_data support.
(eti_tree_model_node_changed_cb): emit visible-data-changed signal. for
the eti_clear_rows have been removed.
(eti_header_structure_changed): remove the cell_data support.
(eti_class_init): add eti_ref_state_set, remove eti_get_parent
and eti_get_index_in_parent.
(eti_init): init parent and index_in_parent.
(gal_a11y_e_table_item_new): add some states. get name form parents.
init role correctly. add FOCUSED state to focused cell.
remove the cell_data support.
(eti_a11y_selection_changed_cb): if e-table-item has DEFUNCT state,
just return.
(eti_a11y_cursor_changed_cb): remove the FOCUESD state form the old cell.
(selection_add_selection): if it has been focused already, just return.
if another row was focused, clear it first.
(selection_ref_selection): use eti_ref_at instead of atk_table_ref_at.
(gal_a11y_e_table_item_init): add this function.
* gal/a11y/e-table/gal-a11y-e-table-item.h:
add gal_a11y_e_table_item_init and change the parameters of
gal_a11y_e_table_item_new.
* gal/a11y/e-table/gal-a11y-e-table.c:
(find_first_table_item): find the first item of the group.
(eti_get_accessible), (find_table_item): find the first table item.
(init_child_item): ref every group's first item.
(et_ref_accessible_at_point): no need to call init_child_item here.
just ref the item.
(et_get_n_children): add support for multiple ETableItems.
(et_ref_child): add support for multiple ETableItems.
(et_get_layer): Set AtkLayer as ATK_LAYER_WIDGET for e-table.
(et_atk_component_iface_init): add et_get_layer function.
(gal_a11y_e_table_new):ref the a11y and widget, and unref it in
the idle function to avoid crash.
Fixes #71158
* gal/a11y/e-table/gal-a11y-e-tree.c:
(init_child_item): just get the a11y object of the child item.
(et_get_layer): Set AtkLayer as ATK_LAYER_WIDGET for etree.
(et_atk_component_iface_init): add et_get_layer function.
* gal/util/e-marshal.list:
add support for the text_inserted and text_deleted signal.
svn path=/trunk/; revision=28572
Diffstat (limited to 'a11y/e-table/gal-a11y-e-table-item.c')
-rw-r--r-- | a11y/e-table/gal-a11y-e-table-item.c | 527 |
1 files changed, 201 insertions, 326 deletions
diff --git a/a11y/e-table/gal-a11y-e-table-item.c b/a11y/e-table/gal-a11y-e-table-item.c index 627735ba04..2cf407c772 100644 --- a/a11y/e-table/gal-a11y-e-table-item.c +++ b/a11y/e-table/gal-a11y-e-table-item.c @@ -10,11 +10,16 @@ #include <config.h> #include <string.h> #include "gal-a11y-e-table-item.h" +#include "gal-a11y-e-table-item-factory.h" +#include "gal-a11y-e-table-click-to-add.h" #include "gal-a11y-e-cell-registry.h" #include "gal-a11y-e-cell.h" #include "gal-a11y-util.h" #include <gal/e-table/e-table-subset.h> +#include <gal/widgets/e-selection-model.h> +#include <gal/widgets/e-canvas.h> #include <gal/e-table/e-table.h> +#include <gal/e-table/e-table-click-to-add.h> #include <gal/e-table/e-tree.h> #include <atk/atkobject.h> @@ -34,15 +39,13 @@ static GQuark quark_accessible_object = 0; #define PARENT_TYPE (parent_type) struct _GalA11yETableItemPrivate { - AtkObject *parent; - gint index_in_parent; gint cols; gint rows; - gpointer *cell_data; int selection_change_id; int cursor_change_id; ETableCol ** columns; ESelectionModel *selection; + AtkStateSet *state_set; GtkWidget *widget; }; @@ -50,17 +53,31 @@ static gboolean gal_a11y_e_table_item_ref_selection (GalA11yETableItem *a11y, ESelectionModel *selection); static gboolean gal_a11y_e_table_item_unref_selection (GalA11yETableItem *a11y); -static gpointer *eti_reinit_data (AtkTable *table, ETableItem *item); +static AtkObject* eti_ref_at (AtkTable *table, gint row, gint column); -#if 0 static void -unref_accessible (gpointer user_data, GObject *obj_loc) +item_destroyed (GtkObject *item, gpointer user_data) { GalA11yETableItem *a11y = GAL_A11Y_E_TABLE_ITEM (user_data); - GET_PRIVATE (a11y)->item = NULL; - g_object_unref (a11y); + GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y); + + atk_state_set_add_state (priv->state_set, ATK_STATE_DEFUNCT); + atk_object_notify_state_change (ATK_OBJECT (a11y), ATK_STATE_DEFUNCT, TRUE); + + if (priv->selection) + gal_a11y_e_table_item_unref_selection (a11y); + +} + +static AtkStateSet * +eti_ref_state_set (AtkObject *accessible) +{ + GalA11yETableItemPrivate *priv = GET_PRIVATE (accessible); + + g_object_ref(priv->state_set); + + return priv->state_set; } -#endif inline static gint view_to_model_row(ETableItem *eti, int row) @@ -131,13 +148,6 @@ eti_dispose (GObject *object) GalA11yETableItem *a11y = GAL_A11Y_E_TABLE_ITEM (object); GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y); - priv->parent = NULL; - - if ( priv->cell_data != NULL ) { - g_free(priv->cell_data); - priv->cell_data = NULL; - } - if (priv->columns) { g_free(priv->columns); priv->columns = NULL; @@ -145,25 +155,9 @@ eti_dispose (GObject *object) if (parent_class->dispose) parent_class->dispose (object); - if (priv->selection) - gal_a11y_e_table_item_unref_selection (a11y); } /* Static functions */ -static AtkObject * -eti_get_parent (AtkObject *accessible) -{ - GalA11yETableItem *a11y; - - g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (accessible), NULL); - if (!eti_a11y_get_gobject (accessible)) - /* defunct */ - return NULL; - - a11y = GAL_A11Y_E_TABLE_ITEM (accessible); - return GET_PRIVATE (a11y)->parent; -} - static gint eti_get_n_children (AtkObject *accessible) { @@ -186,34 +180,12 @@ eti_ref_child (AtkObject *accessible, gint index) if (!item) return NULL; - if (index < item->cols) { - AtkObject *child; - - /* A column header is required */ - child = atk_table_get_column_header (ATK_TABLE (accessible), index); - if (child) - g_object_ref (child); - return child; - } + /* don't support column header now */ - index -= item->cols; col = index % item->cols; row = index / item->cols; - return atk_table_ref_at (ATK_TABLE (accessible), row, col); -} - -static gint -eti_get_index_in_parent (AtkObject *accessible) -{ - GalA11yETableItem *a11y; - - g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (accessible), -1); - if (!eti_a11y_get_gobject (accessible)) - return -1; - - a11y = GAL_A11Y_E_TABLE_ITEM (accessible); - return GET_PRIVATE (a11y)->index_in_parent; + return eti_ref_at (ATK_TABLE (accessible), row, col); } static void @@ -225,33 +197,25 @@ eti_get_extents (AtkComponent *component, AtkCoordType coord_type) { ETableItem *item; - double real_width; - double real_height; - int fake_width; - int fake_height; + AtkObject *parent; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (component))); if (!item) return; - if (component_parent_iface && - component_parent_iface->get_extents) - component_parent_iface->get_extents (component, - x, - y, - &fake_width, - &fake_height, - coord_type); - - gtk_object_get (GTK_OBJECT (item), - "width", &real_width, - "height", &real_height, - NULL); - - if (width) - *width = real_width; - if (height) - *height = real_height; + parent = ATK_OBJECT (component)->accessible_parent; + if (parent && ATK_IS_COMPONENT (parent)) + atk_component_get_extents (ATK_COMPONENT (parent), x, y, + width, height, + coord_type); + + if (parent && GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD (parent)) { + ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (parent))); + if (etcta) { + *width = etcta->width; + *height = etcta->height; + } + } } static AtkObject* @@ -264,6 +228,7 @@ eti_ref_accessible_at_point (AtkComponent *component, int col = -1; int x_origin, y_origin; ETableItem *item; + GtkWidget *tableOrTree; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (component))); if (!item) @@ -276,11 +241,15 @@ eti_ref_accessible_at_point (AtkComponent *component, x -= x_origin; y -= y_origin; - e_table_item_compute_location (item, &x, &y, - &row, &col); + tableOrTree = gtk_widget_get_parent (GTK_WIDGET (item->parent.canvas)); + + if (E_IS_TREE(tableOrTree)) + e_tree_get_cell_at (E_TREE (tableOrTree), x, y, &row, &col); + else + e_table_get_cell_at (E_TABLE (tableOrTree), x, y, &row, &col); if (row != -1 && col != -1) { - return atk_table_ref_at (ATK_TABLE (component), row, col); + return eti_ref_at (ATK_TABLE (component), row, col); } else { return NULL; } @@ -290,23 +259,18 @@ eti_ref_accessible_at_point (AtkComponent *component, static void cell_destroyed (gpointer data) { - gint index; - GalA11yETableItem * item; GalA11yECell * cell; g_return_if_fail (GAL_A11Y_IS_E_CELL (data)); cell = GAL_A11Y_E_CELL (data); - - item = GAL_A11Y_E_TABLE_ITEM (atk_gobject_accessible_for_object (G_OBJECT (GAL_A11Y_E_CELL(data)->item))); - g_return_if_fail (item && GAL_A11Y_IS_E_TABLE_ITEM (item)); + g_return_if_fail (cell->item && G_IS_OBJECT (cell->item)); - g_return_if_fail (cell->row < GET_PRIVATE(item)->rows && cell->view_col < GET_PRIVATE(item)->cols); + if (cell->item) { + g_object_unref (cell->item); + cell->item = NULL; + } - index = cell->row * cell->item->cols + cell->view_col; - - if (GET_PRIVATE (item)->cell_data && GET_PRIVATE (item)->cell_data [index] == data) - GET_PRIVATE (item)->cell_data [index] = NULL; } /* atk table */ @@ -315,6 +279,11 @@ eti_ref_at (AtkTable *table, gint row, gint column) { ETableItem *item; AtkObject* ret; + GalA11yETableItemPrivate *priv = GET_PRIVATE (table); + + if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) + return NULL; + item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); if (!item) @@ -327,38 +296,23 @@ eti_ref_at (AtkTable *table, gint row, gint column) item->cell_views_realized) { ECellView *cell_view = item->cell_views[column]; ETableCol *ecol = e_table_header_get_column (item->header, column); - gpointer * cell_data; - - cell_data = eti_reinit_data (table, item); - if (cell_data == NULL) - return NULL; - - if (cell_data[row*item->cols + column] == NULL) { - ret = gal_a11y_e_cell_registry_get_object (NULL, + ret = gal_a11y_e_cell_registry_get_object (NULL, item, cell_view, ATK_OBJECT (table), ecol->col_idx, column, - row); - cell_data[row*item->cols + column] = ret; - if (ATK_IS_OBJECT (ret)) { - gal_a11y_e_cell_add_state(ret, ATK_STATE_SHOWING, FALSE); - gal_a11y_e_cell_add_state(ret, ATK_STATE_VISIBLE, FALSE); - g_object_weak_ref (G_OBJECT (ret), - (GWeakNotify) cell_destroyed, - ret); - } else - ret = NULL; - } else { - ret = (AtkObject *) cell_data[row*item->cols + column]; - if (ATK_IS_OBJECT (ret)) { - g_object_ref (ret); - } else { - ret = NULL; - } - } - + row); + if (ATK_IS_OBJECT (ret)) { + g_object_weak_ref (G_OBJECT (ret), + (GWeakNotify) cell_destroyed, + ret); + /* if current cell is focused, add FOCUSED state */ + if (e_selection_model_cursor_row (item->selection) == GAL_A11Y_E_CELL (ret)->row && + e_selection_model_cursor_col (item->selection) == GAL_A11Y_E_CELL (ret)->model_col) + gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL (ret), ATK_STATE_FOCUSED, FALSE); + } else + ret = NULL; return ret; } @@ -501,16 +455,21 @@ eti_get_column_header (AtkTable *table, gint column) ETableItem *item; ETableCol *ecol; AtkObject *atk_obj = NULL; - ECell *ecell; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); if (!item) return NULL; ecol = e_table_header_get_column (item->header, column); - ecell = ecol->ecell; - if (ecell) - atk_obj = atk_gobject_accessible_for_object (G_OBJECT (ecell)); + if (ecol) { + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (ecol)); + if (atk_obj) { + if (ecol->text) + atk_object_set_name (atk_obj, ecol->text); + atk_object_set_role (atk_obj, ATK_ROLE_TABLE_COLUMN_HEADER); + } + } + return atk_obj; } @@ -541,12 +500,16 @@ static gboolean table_is_row_selected (AtkTable *table, gint row) { ETableItem *item; + GalA11yETableItemPrivate *priv = GET_PRIVATE (table); + + if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) + return FALSE; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); if (!item) return FALSE; - return e_selection_model_is_row_selected(item->selection, row); + return e_selection_model_is_row_selected(item->selection, view_to_model_row (item, row)); } static gboolean @@ -560,6 +523,10 @@ table_get_selected_rows (AtkTable *table, gint **rows_selected) { ETableItem *item; gint n_selected, row, index_selected; + GalA11yETableItemPrivate *priv = GET_PRIVATE (table); + + if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) + return 0; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); if (!item) @@ -601,6 +568,10 @@ static gboolean table_remove_row_selection (AtkTable *table, gint row) { ETableItem *item; + GalA11yETableItemPrivate *priv = GET_PRIVATE (table); + + if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) + return FALSE; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table))); if (!item) @@ -608,7 +579,7 @@ table_remove_row_selection (AtkTable *table, gint row) if (!atk_table_is_row_selected (table, row)) return TRUE; - e_selection_model_toggle_single_row (item->selection, row); + e_selection_model_toggle_single_row (item->selection, view_to_model_row (item, row)); return TRUE; } @@ -651,7 +622,6 @@ eti_rows_inserted (ETableModel * model, int row, int count, AtkObject * table_item) { gint n_cols,n_rows,i,j; - gpointer *cell_data; GalA11yETableItem * item_a11y; gint old_nrows; @@ -666,34 +636,8 @@ eti_rows_inserted (ETableModel * model, int row, int count, g_return_if_fail (n_cols > 0 && n_rows > 0); g_return_if_fail (old_nrows == n_rows - count); - cell_data = GET_PRIVATE(table_item)->cell_data; - GET_PRIVATE(table_item)->cell_data = g_realloc (cell_data, (n_rows*n_cols) * sizeof(gpointer)); - cell_data = GET_PRIVATE(table_item)->cell_data; - GET_PRIVATE(table_item)->rows = n_rows; - /* If rows are insert in the middle of a table. */ - if (row + count < n_rows ) { - memmove(&cell_data[(row+count)*n_cols], &cell_data[row*n_cols], - (old_nrows-row)*n_cols*sizeof(gpointer)); - - /* Update cell's index. */ - for (i = row + count; i < n_rows; i ++) { - for (j = 0; j < n_cols; j ++) - if (cell_data[i*n_cols + j] != NULL) { - AtkObject * a11y; - - a11y = ATK_OBJECT(cell_data[i*n_cols + j]); - GAL_A11Y_E_CELL(a11y)->row = i; - } - } - } - - /* Clear cache for the new added rows. */ - for (i = row ; i < row+count; i ++) - for (j = 0 ; j < n_cols; j ++) - cell_data [i*n_cols + j] = NULL; - g_signal_emit_by_name (table_item, "row-inserted", row, count, NULL); @@ -708,132 +652,21 @@ eti_rows_inserted (ETableModel * model, int row, int count, g_signal_emit_by_name (table_item, "visible-data-changed"); } -/* - * reinit the eti's private data - * make sure it is synchronized with the gal-e-table-item - */ -static gpointer * -eti_reinit_data (AtkTable *table, ETableItem *item) -{ - gpointer * cell_data; - - int oldsize, newsize; - cell_data = GET_PRIVATE (table)->cell_data; - if (GET_PRIVATE (table)->rows != item->rows - || GET_PRIVATE (table)->cols != item->cols ) { /* reinit cell_data */ - oldsize = GET_PRIVATE (table)->cols * GET_PRIVATE (table)->rows; - newsize = item->cols*item->rows; - GET_PRIVATE (table)->cols = item->cols; - GET_PRIVATE (table)->rows = item->rows; - - cell_data = g_realloc(cell_data, newsize*sizeof(gpointer)); - if (newsize > oldsize) - memset(&cell_data[oldsize], 0, (newsize-oldsize)*sizeof(gpointer)); - - GET_PRIVATE (table)->cell_data = cell_data; - } - return cell_data; -} - -/* - * clear all the AtkObjects stored in the cell_data - * doesn't free the cell_data or resize it. - */ -static void -eti_clear_rows (ETableModel * model, AtkObject * table_item, int row, int count) -{ - gint i,j, n_rows, n_cols; - gpointer *cell_data; - - g_return_if_fail (model && table_item); - - cell_data = GET_PRIVATE (table_item)->cell_data; - g_return_if_fail (cell_data); - - n_rows = GET_PRIVATE (table_item)->rows; - n_cols = GET_PRIVATE (table_item)->cols; - - g_return_if_fail( row >= 0 && count > 0 && row+count <= n_rows); - - /* DEFUNCT the deleted cells. */ - for (i = row; i < row+count; i ++) { - for (j = 0; j < n_cols; j ++) { - if (cell_data[i*n_cols + j] != NULL) { - AtkObject * a11y; - - a11y = ATK_OBJECT(cell_data[i*n_cols + j]); - gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL(a11y), ATK_STATE_DEFUNCT, TRUE); - cell_data[i*n_cols + j] = NULL; - } - } - } - - g_signal_emit_by_name (table_item, "row-deleted", row, - count, NULL); - - for (i = row; i < row+count; i ++) { - for (j = 0; j < n_cols; j ++) { - g_signal_emit_by_name (table_item, - "children_changed::remove", - ( (i*n_cols) + j), NULL, NULL); - } - } - g_signal_emit_by_name (table_item, "visible-data-changed"); -} - static void eti_rows_deleted (ETableModel * model, int row, int count, AtkObject * table_item) { gint i,j, n_rows, n_cols, old_nrows; - gpointer *cell_data; n_rows = atk_table_get_n_rows (ATK_TABLE(table_item)); n_cols = atk_table_get_n_columns (ATK_TABLE(table_item)); - cell_data = GET_PRIVATE(table_item)->cell_data; old_nrows = GET_PRIVATE(table_item)->rows; g_return_if_fail ( row+count <= old_nrows); g_return_if_fail (old_nrows == n_rows + count); GET_PRIVATE(table_item)->rows = n_rows; - /* DEFUNCT the deleted cells. */ - for (i = row; i < row+count; i ++) { - for (j = 0; j < n_cols; j ++) { - if (cell_data[i*n_cols + j] != NULL) { - AtkObject * a11y; - - a11y = ATK_OBJECT(cell_data[i*n_cols + j]); - gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL(a11y), ATK_STATE_DEFUNCT, TRUE); - cell_data[i*n_cols + j] = NULL; - } - } - } - - /* If more rows left, update the a11y object. */ - if (old_nrows > row + count) { - - /* Remove the defunct cells in cache. */ - memmove (&cell_data[row*n_cols], &cell_data[(row+count)*n_cols], - ( old_nrows-row-count)*n_cols*sizeof(gpointer)); - - GET_PRIVATE(table_item)->cell_data = g_realloc (cell_data, n_rows*n_cols*sizeof(gpointer)); - cell_data = GET_PRIVATE(table_item)->cell_data; - - /* Update index of cells below the deleted rows. */ - for (i = row; i < n_rows; i ++) { - for (j = 0; j < n_cols; j ++) { - if (cell_data[i*n_cols + j] != NULL) { - AtkObject * a11y; - - a11y = ATK_OBJECT(cell_data[i*n_cols + j]); - GAL_A11Y_E_CELL(a11y)->row = i; - } - } - } - } - g_signal_emit_by_name (table_item, "row-deleted", row, count, NULL); @@ -858,9 +691,9 @@ eti_tree_model_node_changed_cb (ETreeModel *model, ETreePath node, ETableItem *e atk_obj = atk_gobject_accessible_for_object (G_OBJECT (eti)); a11y = GAL_A11Y_E_TABLE_ITEM (atk_obj); - /* we can't figure out which rows are changed, so just clear all of them ... */ + /* we can't figure out which rows are changed, so just send out a signal ... */ if (GET_PRIVATE (a11y)->rows > 0) - eti_clear_rows (eti->table_model, atk_obj, 0, GET_PRIVATE (a11y)->rows); + g_signal_emit_by_name (a11y, "visible-data-changed"); } enum { @@ -885,14 +718,10 @@ eti_header_structure_changed (ETableHeader *eth, AtkObject *a11y) GalA11yETableItemPrivate *priv; gint *state = NULL, *prev_state = NULL, *reorder = NULL; gint i,j,n_rows,n_cols, prev_n_cols; - gpointer * cell_data, * tmp; a11y_item = GAL_A11Y_E_TABLE_ITEM (a11y); priv = GET_PRIVATE (a11y_item); - g_return_if_fail (priv && priv->cell_data); - cell_data = priv->cell_data ; - /* Assume rows do not changed. */ n_rows = priv->rows; @@ -949,26 +778,6 @@ eti_header_structure_changed (ETableHeader *eth, AtkObject *a11y) if (!reorder_found && !added_found && !removed_found) return; - /* Now update our cache. */ - tmp = g_malloc0 (n_rows*n_cols*sizeof(gpointer)); - g_return_if_fail (tmp); - - for (i = 0 ; i < n_rows; i ++) { - for ( j = 0 ; j < n_cols; j ++ ) { - if ( state[j] == ETI_HEADER_REORDERED ) { - tmp [i*n_cols+j] = cell_data[i*prev_n_cols+reorder[j]]; - if (tmp[i*n_cols+j] && ATK_IS_OBJECT(tmp[i*n_cols+j])) { - GAL_A11Y_E_CELL(tmp[i*n_cols+j])->view_col = j; - } - } else if (state[j] == ETI_HEADER_UNCHANGED) { - tmp [i*n_cols+j] = cell_data[i*prev_n_cols+j]; - } /* else: new added, keep NULL. */ - } - } - - g_free (cell_data); - priv->cell_data = tmp; - /* Emit signals */ if (reorder_found) g_signal_emit_by_name (G_OBJECT(a11y_item), "column_reordered"); @@ -1040,11 +849,10 @@ eti_class_init (GalA11yETableItemClass *klass) object_class->dispose = eti_dispose; - atk_object_class->get_parent = eti_get_parent; atk_object_class->get_n_children = eti_get_n_children; atk_object_class->ref_child = eti_ref_child; - atk_object_class->get_index_in_parent = eti_get_index_in_parent; atk_object_class->initialize = eti_real_initialize; + atk_object_class->ref_state_set = eti_ref_state_set; } static void @@ -1054,8 +862,6 @@ eti_init (GalA11yETableItem *a11y) priv = GET_PRIVATE (a11y); - priv->parent = NULL; - priv->index_in_parent = -1; priv->selection_change_id = 0; priv->cursor_change_id = 0; priv->selection = NULL; @@ -1149,37 +955,36 @@ gal_a11y_e_table_item_get_type (void) } AtkObject * -gal_a11y_e_table_item_new (AtkObject *parent, - ETableItem *item, - int index_in_parent) +gal_a11y_e_table_item_new (ETableItem *item) { GalA11yETableItem *a11y; AtkObject *accessible; int n; + ESelectionModel * esm; + AtkObject * cell; + AtkObject *parent; + const char *name; g_return_val_if_fail (item && item->cols >= 0 && item->rows >= 0, NULL); a11y = g_object_new (gal_a11y_e_table_item_get_type (), NULL); atk_object_initialize (ATK_OBJECT (a11y), item); - GET_PRIVATE (a11y)->parent = parent; - GET_PRIVATE (a11y)->index_in_parent = index_in_parent; + GET_PRIVATE (a11y)->state_set = atk_state_set_new (); + + atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_TRANSIENT); + atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_ENABLED); + atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_SENSITIVE); + atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_SHOWING); + atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_VISIBLE); + accessible = ATK_OBJECT(a11y); - accessible->role = ATK_ROLE_TREE_TABLE; /* Initialize cell data. */ n = item->cols * item->rows; GET_PRIVATE (a11y)->cols = item->cols; GET_PRIVATE (a11y)->rows = item->rows; - if (n > 0) { - GET_PRIVATE (a11y)->cell_data = g_malloc0(n*sizeof(gpointer)); - /* memory error. */ - if ( GET_PRIVATE (a11y)->cell_data == NULL) - return NULL; - } else - GET_PRIVATE (a11y)->cell_data = NULL; - GET_PRIVATE (a11y)->columns = e_table_header_get_columns (item->header); if ( GET_PRIVATE (a11y)->columns == NULL) @@ -1196,22 +1001,49 @@ gal_a11y_e_table_item_new (AtkObject *parent, /* find the TableItem's parent: table or tree */ GET_PRIVATE (a11y)->widget = gtk_widget_get_parent (GTK_WIDGET (item->parent.canvas)); + parent = gtk_widget_get_accessible (GET_PRIVATE (a11y)->widget); + name = atk_object_get_name (parent); + if (name) + atk_object_set_name (accessible, name); + atk_object_set_parent (accessible, parent); + if (E_IS_TREE (GET_PRIVATE (a11y)->widget)) { ETreeModel *model; model = e_tree_get_model (E_TREE (GET_PRIVATE (a11y)->widget)); g_signal_connect (G_OBJECT(model), "node_changed", G_CALLBACK (eti_tree_model_node_changed_cb), item); + accessible->role = ATK_ROLE_TREE_TABLE; + } else if (E_IS_TABLE (GET_PRIVATE (a11y)->widget)) { + accessible->role = ATK_ROLE_TABLE; } } - if (parent) - g_object_ref (parent); -#if 0 if (item) - g_object_weak_ref (G_OBJECT (item), - unref_accessible, + g_signal_connect (G_OBJECT (item), "destroy", + G_CALLBACK (item_destroyed), a11y); -#endif + esm = item->selection; + + if (esm != NULL) { + int cursor_row, cursor_col, view_row, view_col; + + cursor_row = e_selection_model_cursor_row(esm); + cursor_col = e_selection_model_cursor_col(esm); + + view_row = model_to_view_row (item, cursor_row); + view_col = model_to_view_col (item, cursor_col); + + if (view_row == -1) + view_row = 0; + if (view_col == -1) + view_col = 0; + + cell = eti_ref_at (ATK_TABLE (a11y), view_row, view_col); + if (cell != NULL) { + g_object_set_data (G_OBJECT(a11y), "gail-focus-object", cell); + gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL (cell), ATK_STATE_FOCUSED, FALSE); + } + } return ATK_OBJECT (a11y); } @@ -1304,6 +1136,11 @@ eti_a11y_selection_model_added_cb (ETableItem *eti, ESelectionModel *selection, static void eti_a11y_selection_changed_cb (ESelectionModel *selection, GalA11yETableItem *a11y) { + GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y); + + if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) + return; + g_return_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (a11y)); g_signal_emit_by_name (a11y, "selection_changed"); @@ -1316,27 +1153,39 @@ eti_a11y_cursor_changed_cb (ESelectionModel *selection, AtkObject * cell; int view_row, view_col; ETableItem *item; + GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y); g_return_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (a11y)); - g_signal_emit_by_name (a11y, "selection_changed"); + if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT)) + return; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (a11y))); g_return_if_fail (item); + if (row == -1 && col == -1) + return; + view_row = model_to_view_row (item, row); view_col = model_to_view_col (item, col); - cell = atk_table_ref_at (ATK_TABLE (a11y), view_row, view_col); + if (view_col == -1) + view_col = 0; + cell = eti_ref_at (ATK_TABLE (a11y), view_row, view_col); if (cell != NULL) { - gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL (cell), ATK_STATE_FOCUSED, FALSE); + AtkObject *old_cell = (AtkObject *)g_object_get_data (G_OBJECT(a11y), "gail-focus-object"); + if (old_cell && GAL_A11Y_IS_E_CELL (old_cell)) + gal_a11y_e_cell_remove_state (GAL_A11Y_E_CELL (old_cell), ATK_STATE_FOCUSED, FALSE); + if (old_cell) + g_object_unref (old_cell); + + g_object_set_data (G_OBJECT(a11y), "gail-focus-object", cell); if (ATK_IS_OBJECT (cell)) g_signal_emit_by_name (a11y, "active-descendant-changed", cell); - atk_focus_tracker_notify (cell); } } @@ -1357,7 +1206,7 @@ static gboolean selection_add_selection (AtkSelection *selection, gint index) { AtkTable *table; - gint row, col; + gint row, col, cursor_row, cursor_col, model_row, model_col; ETableItem *item; item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (selection))); @@ -1367,18 +1216,36 @@ selection_add_selection (AtkSelection *selection, gint index) table = ATK_TABLE (selection); row = atk_table_get_row_at_index (table, index); - atk_table_add_row_selection (table, row); - col = atk_table_get_column_at_index (table, index); + + model_row = view_to_model_row (item, row); + model_col = view_to_model_col (item, col); + + cursor_row = e_selection_model_cursor_row (item->selection); + cursor_col = e_selection_model_cursor_col (item->selection); + + /* check whether is selected already */ + if (model_row == cursor_row && model_col == cursor_col) + return TRUE; + + if (model_row != cursor_row) { + /* we need to make the item get focus */ + e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (item), TRUE); + + /* FIXME, currently we only support single row selection */ + atk_selection_clear_selection (selection); + atk_table_add_row_selection (table, row); + } + e_selection_model_change_cursor (item->selection, - view_to_model_row (item, row), - view_to_model_col (item, col)); + model_row, + model_col); e_selection_model_cursor_changed (item->selection, - view_to_model_row (item, row), - view_to_model_col (item, col)); + model_row, + model_col); e_selection_model_cursor_activated (item->selection, - view_to_model_row (item, row), - view_to_model_col (item, col)); + model_row, + model_col); return TRUE; } @@ -1407,7 +1274,7 @@ selection_ref_selection (AtkSelection *selection, gint index) if (!atk_table_is_row_selected (table, row)) return NULL; - return atk_table_ref_at (table, row, col); + return eti_ref_at (table, row, col); } static gint @@ -1431,3 +1298,11 @@ selection_is_child_selected (AtkSelection *selection, gint i) row = atk_table_get_row_at_index (ATK_TABLE (selection), i); return atk_table_is_row_selected (ATK_TABLE (selection), row); } + +void +gal_a11y_e_table_item_init (void) +{ + atk_registry_set_factory_type (atk_get_default_registry (), + E_TABLE_ITEM_TYPE, + gal_a11y_e_table_item_factory_get_type ()); +} |