aboutsummaryrefslogtreecommitdiffstats
path: root/a11y/e-table
diff options
context:
space:
mode:
Diffstat (limited to 'a11y/e-table')
-rw-r--r--a11y/e-table/gal-a11y-e-cell-popup.c5
-rw-r--r--a11y/e-table/gal-a11y-e-cell-text.c223
-rw-r--r--a11y/e-table/gal-a11y-e-cell-text.h2
-rw-r--r--a11y/e-table/gal-a11y-e-cell-toggle.c17
-rw-r--r--a11y/e-table/gal-a11y-e-cell-tree.c9
-rw-r--r--a11y/e-table/gal-a11y-e-cell-vbox.c214
-rw-r--r--a11y/e-table/gal-a11y-e-cell-vbox.h64
-rw-r--r--a11y/e-table/gal-a11y-e-cell.c158
-rw-r--r--a11y/e-table/gal-a11y-e-table-click-to-add.c52
-rw-r--r--a11y/e-table/gal-a11y-e-table-item-factory.c2
-rw-r--r--a11y/e-table/gal-a11y-e-table-item.c527
-rw-r--r--a11y/e-table/gal-a11y-e-table-item.h6
-rw-r--r--a11y/e-table/gal-a11y-e-table.c151
-rw-r--r--a11y/e-table/gal-a11y-e-tree.c12
14 files changed, 990 insertions, 452 deletions
diff --git a/a11y/e-table/gal-a11y-e-cell-popup.c b/a11y/e-table/gal-a11y-e-cell-popup.c
index a3de45afb3..15cae2effb 100644
--- a/a11y/e-table/gal-a11y-e-cell-popup.c
+++ b/a11y/e-table/gal-a11y-e-cell-popup.c
@@ -31,6 +31,7 @@
#include <atk/atkobject.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtkwidget.h>
+#include <glib/gi18n.h>
static AtkObjectClass *parent_class = NULL;
#define PARENT_TYPE (gal_a11y_e_cell_get_type ())
@@ -118,8 +119,8 @@ gal_a11y_e_cell_popup_new (ETableItem *item,
g_return_val_if_fail (a11y != NULL, NULL);
cell = GAL_A11Y_E_CELL(a11y);
gal_a11y_e_cell_add_action (cell,
- "popup", /* action name*/
- "popup a child", /* action description */
+ _("popup"), /* action name*/
+ _("popup a child"), /* action description */
"<Alt>Down", /* action keybinding */
popup_cell_action);
diff --git a/a11y/e-table/gal-a11y-e-cell-text.c b/a11y/e-table/gal-a11y-e-cell-text.c
index d94a3640a3..89c1b3a813 100644
--- a/a11y/e-table/gal-a11y-e-cell-text.c
+++ b/a11y/e-table/gal-a11y-e-cell-text.c
@@ -15,18 +15,84 @@
#include <atk/atktext.h>
#include <atk/atkeditabletext.h>
#include <atk/atkaction.h>
+#include <atk/atkstateset.h>
+#include <glib/gi18n.h>
#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yECellTextClass))
static AtkObjectClass *parent_class;
#define PARENT_TYPE (gal_a11y_e_cell_get_type ())
/* Static functions */
+static void
+ect_dispose (GObject *object)
+{
+ GObjectClass *g_class;
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (object);
+ GalA11yECellText *gaet = GAL_A11Y_E_CELL_TEXT (object);
+
+ if (gaet->inserted_id != 0) {
+ ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+
+ if (ect) {
+ g_signal_handler_disconnect (ect, gaet->inserted_id);
+ g_signal_handler_disconnect (ect, gaet->deleted_id);
+ }
+
+ gaet->inserted_id = 0;
+ gaet->deleted_id = 0;
+ }
+
+ g_class = (GObjectClass *)parent_class;
+ if (g_class->dispose)
+ g_class->dispose (object);
+
+}
+
+static gboolean
+ect_check (gpointer a11y)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y);
+ ETableItem *item = gaec->item;
+
+ g_return_val_if_fail ((gaec->item != NULL), FALSE);
+ g_return_val_if_fail ((gaec->cell_view != NULL), FALSE);
+ g_return_val_if_fail ((gaec->cell_view->ecell != NULL), FALSE);
+
+ if (atk_state_set_contains_state (gaec->state_set, ATK_STATE_DEFUNCT))
+ return FALSE;
+
+ if (gaec->row < 0 || gaec->row >= item->rows
+ || gaec->view_col <0 || gaec->view_col >= item->cols
+ || gaec->model_col <0 || gaec->model_col >= e_table_model_column_count (item->table_model))
+ return FALSE;
+
+ if (!E_IS_CELL_TEXT (gaec->cell_view->ecell))
+ return FALSE;
+
+ return TRUE;
+}
+
static G_CONST_RETURN gchar*
ect_get_name (AtkObject * a11y)
{
- GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y);
- ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
- return e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+ GalA11yECell *gaec;
+ char *name;
+
+ if (!ect_check (a11y))
+ return NULL;
+
+ gaec = GAL_A11Y_E_CELL (a11y);
+ name = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+ if (name != NULL) {
+ ATK_OBJECT_CLASS (parent_class)->set_name (a11y, name);
+ g_free (name);
+ }
+
+ if (a11y->name != NULL && strcmp (a11y->name, "")) {
+ return a11y->name;
+ } else {
+ return parent_class->get_name (a11y);
+ }
}
static gchar *
@@ -35,9 +101,13 @@ ect_get_text (AtkText *text,
gint end_offset)
{
GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
- ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+ gchar *full_text;
gchar *ret_val;
- gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+
+ if (!ect_check (text))
+ return NULL;
+
+ full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
if (end_offset == -1)
end_offset = strlen (full_text);
@@ -48,7 +118,7 @@ ect_get_text (AtkText *text,
ret_val = g_strndup (full_text + start_offset, end_offset - start_offset);
- e_cell_text_free_text (ect, full_text);
+ g_free (full_text);
return ret_val;
}
@@ -80,13 +150,16 @@ ect_get_character_at_offset (AtkText *text,
gint offset)
{
GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
- ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
gunichar ret_val;
gchar *at_offset;
- gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+
+ if (!ect_check (text))
+ return -1;
+
+ gchar *full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
at_offset = g_utf8_offset_to_pointer (full_text, offset);
ret_val = g_utf8_get_char_validated (at_offset, -1);
- e_cell_text_free_text (ect, full_text);
+ g_free (full_text);
return ret_val;
}
@@ -108,18 +181,17 @@ static gint
ect_get_caret_offset (AtkText *text)
{
GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
- ECellText *ect = NULL;
gint start, end;
- g_return_val_if_fail (gaec && gaec->cell_view && gaec->cell_view->ecell && E_IS_CELL_TEXT (gaec->cell_view->ecell), -1);
- ect = E_CELL_TEXT (gaec->cell_view->ecell);
+ if (!ect_check (text))
+ return -1;
if (e_cell_text_get_selection (gaec->cell_view,
gaec->view_col, gaec->row,
&start, &end)) {
- gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+ gchar *full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
end = g_utf8_pointer_to_offset (full_text, full_text + end);
- e_cell_text_free_text (ect, full_text);
+ g_free (full_text);
return end;
}
@@ -163,13 +235,15 @@ static gint
ect_get_character_count (AtkText *text)
{
GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
- ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
gint ret_val;
- gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+ if (!ect_check (text))
+ return -1;
+
+ gchar *full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
ret_val = g_utf8_strlen (full_text, -1);
- e_cell_text_free_text (ect, full_text);
+ g_free (full_text);
return ret_val;
}
@@ -190,6 +264,10 @@ ect_get_n_selections (AtkText *text)
{
GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
gint selection_start, selection_end;
+
+ if (!ect_check (text))
+ return 0;
+
if (e_cell_text_get_selection (gaec->cell_view,
gaec->view_col, gaec->row,
&selection_start,
@@ -207,7 +285,6 @@ ect_get_selection (AtkText *text,
gint *end_offset)
{
GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
- ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
gchar *ret_val;
gint selection_start, selection_end;
@@ -218,7 +295,7 @@ ect_get_selection (AtkText *text,
&selection_end)
&& selection_start != selection_end) {
gint real_start, real_end, len;
- gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+ gchar *full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
len = strlen (full_text);
real_start = MIN (selection_start, selection_end);
real_end = MAX (selection_start, selection_end);
@@ -234,7 +311,7 @@ ect_get_selection (AtkText *text,
*start_offset = real_start;
if (end_offset)
*end_offset = real_end;
- e_cell_text_free_text (ect, full_text);
+ g_free (full_text);
} else {
if (start_offset)
*start_offset = 0;
@@ -253,12 +330,11 @@ ect_add_selection (AtkText *text,
gint end_offset)
{
GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
- ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
if (start_offset != end_offset) {
gint real_start, real_end, len;
gchar *full_text =
- e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+ e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
len = g_utf8_strlen (full_text, -1);
if (end_offset == -1)
@@ -272,7 +348,7 @@ ect_add_selection (AtkText *text,
real_start = g_utf8_offset_to_pointer (full_text, real_start) - full_text;
real_end = g_utf8_offset_to_pointer (full_text, real_end) - full_text;
- e_cell_text_free_text (ect, full_text);
+ g_free (full_text);
if (e_cell_text_set_selection (gaec->cell_view,
gaec->view_col, gaec->row,
@@ -330,11 +406,10 @@ ect_set_caret_offset (AtkText *text,
gint offset)
{
GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
- ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
gchar *full_text;
gint len;
- full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+ full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
len = g_utf8_strlen (full_text, -1);
if (offset == -1)
@@ -344,7 +419,7 @@ ect_set_caret_offset (AtkText *text,
offset = g_utf8_offset_to_pointer (full_text, offset) - full_text;
- e_cell_text_free_text (ect, full_text);
+ g_free (full_text);
return e_cell_text_set_selection (gaec->cell_view,
gaec->view_col, gaec->row,
@@ -382,7 +457,7 @@ ect_insert_text (AtkEditableText *text,
GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
- gchar *full_text = e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+ gchar *full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
gchar *result = g_strdup_printf ("%.*s%.*s%s", *position, full_text, length, string, full_text + *position);
e_cell_text_set_value (ect, gaec->item->table_model, gaec->model_col, gaec->row, result);
@@ -390,7 +465,7 @@ ect_insert_text (AtkEditableText *text,
*position += length;
g_free (result);
- e_cell_text_free_text (ect, full_text);
+ g_free (full_text);
}
static void
@@ -443,7 +518,43 @@ static void
ect_do_action_edit (AtkAction *action)
{
GalA11yECell *a11y = GAL_A11Y_E_CELL (action);
- e_table_item_enter_edit (a11y->item, a11y->view_col, a11y->row);
+ ETableModel *e_table_model = a11y->item->table_model;
+
+ if (e_table_model_is_cell_editable(e_table_model, a11y->model_col, a11y->row)) {
+ e_table_item_enter_edit (a11y->item, a11y->view_col, a11y->row);
+ }
+}
+
+/* text signal handlers */
+static void
+ect_text_inserted_cb (ECellText *text, ECellView *cell_view, int pos, int len, int row, int model_col, gpointer data)
+{
+ GalA11yECellText *gaet;
+ GalA11yECell *gaec;
+
+ if (!ect_check (data))
+ return;
+ gaet = GAL_A11Y_E_CELL_TEXT (data);
+ gaec = GAL_A11Y_E_CELL (data);
+
+ if (cell_view == gaec->cell_view && row == gaec->row && model_col == gaec->model_col) {
+ g_signal_emit_by_name (gaet, "text_changed::insert", pos, len);
+
+ }
+}
+
+static void
+ect_text_deleted_cb (ECellText *text, ECellView *cell_view, int pos, int len, int row, int model_col, gpointer data)
+{
+ GalA11yECellText *gaet;
+ GalA11yECell *gaec;
+ if (!ect_check (data))
+ return;
+ gaet = GAL_A11Y_E_CELL_TEXT (data);
+ gaec = GAL_A11Y_E_CELL (data);
+ if (cell_view == gaec->cell_view && row == gaec->row && model_col == gaec->model_col) {
+ g_signal_emit_by_name (gaet, "text_changed::delete", pos, len);
+ }
}
static void
@@ -483,19 +594,25 @@ ect_atk_editable_text_iface_init (AtkEditableTextIface *iface)
static void
ect_class_init (GalA11yECellTextClass *klass)
{
- AtkObjectClass *a11y = ATK_OBJECT_CLASS (klass);
+ AtkObjectClass *a11y = ATK_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
parent_class = g_type_class_ref (PARENT_TYPE);
a11y->get_name = ect_get_name;
+ object_class->dispose = ect_dispose;
}
static void
-ect_init (GalA11yECellText *a11y)
+ect_action_init (GalA11yECellText *a11y)
{
- gal_a11y_e_cell_add_action (GAL_A11Y_E_CELL (a11y),
- "edit",
- "begin editing this cell",
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y);
+ ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+ if (ect->editable && e_table_model_is_cell_editable (gaec->cell_view->e_table_model, gaec->model_col, gaec->row))
+ gal_a11y_e_cell_add_action (gaec,
+ _("edit"),
+ _("begin editing this cell"),
NULL,
- (ACTION_FUNC)ect_do_action_edit);
+ (ACTION_FUNC) ect_do_action_edit);
}
/**
@@ -522,7 +639,7 @@ gal_a11y_e_cell_text_get_type (void)
NULL, /* class_data */
sizeof (GalA11yECellText),
0,
- (GInstanceInitFunc) ect_init,
+ (GInstanceInitFunc) NULL,
NULL /* value_cell_text */
};
@@ -547,6 +664,14 @@ gal_a11y_e_cell_text_get_type (void)
return type;
}
+static void
+cell_text_destroyed (gpointer data)
+{
+ g_return_if_fail (GAL_A11Y_IS_E_CELL_TEXT (data));
+
+ g_object_unref (data);
+}
+
AtkObject *
gal_a11y_e_cell_text_new (ETableItem *item,
ECellView *cell_view,
@@ -556,6 +681,9 @@ gal_a11y_e_cell_text_new (ETableItem *item,
int row)
{
AtkObject *a11y;
+ GalA11yECell *gaec;
+ GalA11yECellText *gaet;
+ ECellText *ect;
a11y = g_object_new (gal_a11y_e_cell_text_get_type (), NULL);
@@ -566,5 +694,28 @@ gal_a11y_e_cell_text_new (ETableItem *item,
model_col,
view_col,
row);
+ gaet = GAL_A11Y_E_CELL_TEXT (a11y);
+
+ /* will be unrefed in cell_text_destroyed */
+ g_object_ref (a11y);
+
+ gaet->inserted_id = g_signal_connect (E_CELL_TEXT (((ECellView *)cell_view)->ecell),
+ "text_inserted", G_CALLBACK (ect_text_inserted_cb), a11y);
+ gaet->deleted_id = g_signal_connect (E_CELL_TEXT (((ECellView *)cell_view)->ecell),
+ "text_deleted", G_CALLBACK (ect_text_deleted_cb), a11y);
+
+ g_object_weak_ref (G_OBJECT (((ECellView *)cell_view)->ecell),
+ (GWeakNotify) cell_text_destroyed,
+ a11y);
+
+ ect_action_init (gaet);
+
+ ect = E_CELL_TEXT (cell_view->ecell);
+ gaec = GAL_A11Y_E_CELL (a11y);
+ if (ect->editable && e_table_model_is_cell_editable (gaec->cell_view->e_table_model, gaec->model_col, gaec->row))
+ gal_a11y_e_cell_add_state (gaec, ATK_STATE_EDITABLE, FALSE);
+ else
+ gal_a11y_e_cell_remove_state (gaec, ATK_STATE_EDITABLE, FALSE);
+
return a11y;
}
diff --git a/a11y/e-table/gal-a11y-e-cell-text.h b/a11y/e-table/gal-a11y-e-cell-text.h
index 3d9a4447be..50056476c3 100644
--- a/a11y/e-table/gal-a11y-e-cell-text.h
+++ b/a11y/e-table/gal-a11y-e-cell-text.h
@@ -29,6 +29,8 @@ typedef struct _GalA11yECellTextPrivate GalA11yECellTextPrivate;
**/
struct _GalA11yECellText {
GalA11yECell object;
+ gint inserted_id;
+ gint deleted_id;
};
struct _GalA11yECellTextClass {
diff --git a/a11y/e-table/gal-a11y-e-cell-toggle.c b/a11y/e-table/gal-a11y-e-cell-toggle.c
index 0d01028cc9..21f4955d1d 100644
--- a/a11y/e-table/gal-a11y-e-cell-toggle.c
+++ b/a11y/e-table/gal-a11y-e-cell-toggle.c
@@ -2,6 +2,8 @@
#include "gal-a11y-e-cell-toggle.h"
#include <gal/e-table/e-cell-toggle.h>
#include <gal/e-table/e-table-model.h>
+#include <atk/atkcomponent.h>
+#include <glib/gi18n.h>
#define PARENT_TYPE (gal_a11y_e_cell_get_type ())
static GObjectClass *parent_class;
@@ -15,8 +17,10 @@ gal_a11y_e_cell_toggle_dispose (GObject *object)
ETableModel *e_table_model = GAL_A11Y_E_CELL (a11y)->item->table_model;
- if (e_table_model)
+ if (e_table_model && a11y->model_id > 0) {
g_signal_handler_disconnect (e_table_model, a11y->model_id);
+ a11y->model_id = 0;
+ }
if (parent_class->dispose)
parent_class->dispose (object);
@@ -91,8 +95,8 @@ toggle_cell_action (GalA11yECell *cell)
static void
model_change_cb (ETableModel *etm,
- gint row,
gint col,
+ gint row,
GalA11yECell *cell)
{
gint value;
@@ -101,7 +105,10 @@ model_change_cb (ETableModel *etm,
value = GPOINTER_TO_INT (
e_table_model_value_at (cell->cell_view->e_table_model,
- cell->model_col, cell->row));
+ cell->model_col, cell->row));
+ /* Cheat gnopernicus, or it will ignore the state change signal */
+ atk_focus_tracker_notify (ATK_OBJECT (cell));
+
if (value)
gal_a11y_e_cell_add_state (cell, ATK_STATE_CHECKED, TRUE);
else
@@ -140,8 +147,8 @@ gal_a11y_e_cell_toggle_new (ETableItem *item,
row);
gal_a11y_e_cell_add_action (cell,
- "toggle", /* action name*/
- "toggle the cell", /* action description */
+ _("toggle"), /* action name*/
+ _("toggle the cell"), /* action description */
NULL, /* action keybinding */
toggle_cell_action);
diff --git a/a11y/e-table/gal-a11y-e-cell-tree.c b/a11y/e-table/gal-a11y-e-cell-tree.c
index ae833d9150..126bbcfbe5 100644
--- a/a11y/e-table/gal-a11y-e-cell-tree.c
+++ b/a11y/e-table/gal-a11y-e-cell-tree.c
@@ -14,6 +14,7 @@
#include "gal/e-table/e-cell-tree.h"
#include "gal/e-table/e-table.h"
#include "gal/e-table/e-tree-table-adapter.h"
+#include <glib/gi18n.h>
#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yECellTreeClass))
static AtkObjectClass *a11y_parent_class;
@@ -164,14 +165,14 @@ gal_a11y_e_cell_tree_new (ETableItem *item,
view_col,
row);
gal_a11y_e_cell_add_action (GAL_A11Y_E_CELL (subcell_a11y),
- "expand",
- "expands the row in the ETree containing this cell",
+ _("expand"),
+ _("expands the row in the ETree containing this cell"),
NULL,
(ACTION_FUNC)ectr_do_action_expand);
gal_a11y_e_cell_add_action (GAL_A11Y_E_CELL (subcell_a11y),
- "collapse",
- "collapses the row in the ETree containing this cell",
+ _("collapse"),
+ _("collapses the row in the ETree containing this cell"),
NULL,
(ACTION_FUNC)ectr_do_action_collapse);
diff --git a/a11y/e-table/gal-a11y-e-cell-vbox.c b/a11y/e-table/gal-a11y-e-cell-vbox.c
new file mode 100644
index 0000000000..4f2c156da8
--- /dev/null
+++ b/a11y/e-table/gal-a11y-e-cell-vbox.c
@@ -0,0 +1,214 @@
+/* Evolution Accessibility: gal-a11y-e-cell-vbox.c
+ *
+ * Copyright (C) 2004 Sun Microsystem, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Eric Zhao <eric.zhao@sun.com> Sun Microsystem Inc., 2004
+ *
+ */
+#include "gal-a11y-e-cell-vbox.h"
+#include "gal-a11y-e-cell-registry.h"
+#include <gal/e-table/e-cell-vbox.h>
+#include <atk/atkcomponent.h>
+
+static GObjectClass *parent_class;
+static AtkComponentIface *component_parent_iface;
+#define PARENT_TYPE (gal_a11y_e_cell_get_type ())
+
+static gint
+ecv_get_n_children (AtkObject *a11y)
+{
+ g_return_val_if_fail (GAL_A11Y_IS_E_CELL_VBOX (a11y), 0);
+ GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (a11y);
+ return (gaev->a11y_subcell_count);
+}
+
+static void
+subcell_destroyed (gpointer data)
+{
+ GalA11yECell *cell;
+ AtkObject *parent;
+ GalA11yECellVbox *gaev;
+
+ g_return_if_fail (GAL_A11Y_IS_E_CELL (data));
+ cell = GAL_A11Y_E_CELL (data);
+
+ parent = atk_object_get_parent (ATK_OBJECT (cell));
+ g_return_if_fail (GAL_A11Y_IS_E_CELL_VBOX (parent));
+ gaev = GAL_A11Y_E_CELL_VBOX (parent);
+
+ if (cell->view_col < gaev->a11y_subcell_count)
+ gaev->a11y_subcells[cell->view_col] = NULL;
+}
+
+static AtkObject*
+ecv_ref_child (AtkObject *a11y, gint i)
+{
+ GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (a11y);
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y);
+ ECellVboxView *ecvv = (ECellVboxView *) (gaec->cell_view);
+ AtkObject *ret;
+ if (i < gaev->a11y_subcell_count) {
+ if (gaev->a11y_subcells[i] == NULL) {
+ gint model_col, row;
+ row = gaec->row;
+ model_col = ecvv->model_cols[i];
+ ECellView *subcell_view = ecvv->subcell_views[i];
+ ret = gal_a11y_e_cell_registry_get_object (NULL,
+ gaec->item,
+ subcell_view,
+ a11y,
+ model_col,
+ gaec->view_col, /* FIXME should the view column use a fake one or the same as its parent? */
+ row);
+ gaev->a11y_subcells[i] = ret;
+ g_object_ref (ret);
+ g_object_weak_ref (G_OBJECT (ret),
+ (GWeakNotify) subcell_destroyed,
+ ret);
+ } else {
+ ret = (AtkObject *) gaev->a11y_subcells[i];
+ if (ATK_IS_OBJECT (ret))
+ g_object_ref (ret);
+ else
+ ret = NULL;
+ }
+ } else {
+ ret = NULL;
+ }
+
+ return ret;
+}
+
+static void
+ecv_dispose (GObject *object)
+{
+ GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (object);
+ if (gaev->a11y_subcells)
+ g_free (gaev->a11y_subcells);
+
+ if (parent_class->dispose)
+ parent_class->dispose (object);
+}
+
+/* AtkComponet interface */
+static AtkObject*
+ecv_ref_accessible_at_point (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type)
+{
+ gint x0, y0, width, height;
+ int subcell_height, i;
+
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (component);
+ ECellVboxView *ecvv = (ECellVboxView *) (gaec->cell_view);
+
+ atk_component_get_extents (component, &x0, &y0, &width, &height, coord_type);
+ x -= x0;
+ y -= y0;
+ if (x < 0 || x > width || y < 0 || y > height)
+ return NULL;
+
+ for (i = 0; i < ecvv->subcell_view_count; i++) {
+ subcell_height = e_cell_height (ecvv->subcell_views[i], ecvv->model_cols[i], gaec->view_col, gaec->row);
+ if ( 0 <= y && y <= subcell_height) {
+ return ecv_ref_child ((AtkObject *)component, i);
+ } else
+ y -= subcell_height;
+ }
+
+ return NULL;
+}
+
+static void
+ecv_class_init (GalA11yECellVboxClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *a11y_class = ATK_OBJECT_CLASS (klass);
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ object_class->dispose = ecv_dispose;
+
+ a11y_class->get_n_children = ecv_get_n_children;
+ a11y_class->ref_child = ecv_ref_child;
+}
+
+static void
+ecv_init (GalA11yECellVbox *a11y)
+{
+}
+
+static void
+ecv_atk_component_iface_init (AtkComponentIface *iface)
+{
+ component_parent_iface = g_type_interface_peek_parent (iface);
+
+ iface->ref_accessible_at_point = ecv_ref_accessible_at_point;
+}
+
+GType
+gal_a11y_e_cell_vbox_get_type (void)
+{
+ static GType type = 0;
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yECellVboxClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ecv_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yECellVbox),
+ 0,
+ (GInstanceInitFunc) ecv_init,
+ NULL /* value_cell */
+ };
+
+ static const GInterfaceInfo atk_component_info = {
+ (GInterfaceInitFunc) ecv_atk_component_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yECellVbox", &info, 0);
+ gal_a11y_e_cell_type_add_action_interface (type);
+ g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info);
+ }
+
+ return type;
+}
+
+AtkObject *gal_a11y_e_cell_vbox_new (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row)
+{
+ AtkObject *a11y;
+
+ a11y = g_object_new (gal_a11y_e_cell_vbox_get_type (), NULL);
+
+ gal_a11y_e_cell_construct (a11y, item, cell_view, parent, model_col, view_col, row);
+
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y);
+ GalA11yECellVbox *gaev = GAL_A11Y_E_CELL_VBOX (a11y);
+ ECellVboxView *ecvv = (ECellVboxView *) (gaec->cell_view);
+ gaev->a11y_subcell_count = ecvv->subcell_view_count;
+ gaev->a11y_subcells = g_malloc0 (sizeof(AtkObject *)*gaev->a11y_subcell_count);
+ return a11y;
+}
diff --git a/a11y/e-table/gal-a11y-e-cell-vbox.h b/a11y/e-table/gal-a11y-e-cell-vbox.h
new file mode 100644
index 0000000000..ea0c9d8dc9
--- /dev/null
+++ b/a11y/e-table/gal-a11y-e-cell-vbox.h
@@ -0,0 +1,64 @@
+/* Evolution Accessibility: gal-a11y-e-cell-vbox.h
+ *
+ * Copyright (C) 2004 Sun Microsystem, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Eric Zhao <eric.zhao@sun.com> Sun Microsystem Inc., 2004
+ *
+ */
+#ifndef __GAL_A11Y_E_CELL_VBOX_H__
+#define __GAL_A11Y_E_CELL_VBOX_H__
+
+#include "gal-a11y-e-cell.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GAL_A11Y_TYPE_E_CELL_VBOX (gal_a11y_e_cell_vbox_get_type ())
+#define GAL_A11Y_E_CELL_VBOX(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_VBOX, GalA11yECellVbox))
+#define GAL_A11Y_E_CELL_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_E_CELL_VBOX, GalA11yECellVboxClass))
+#define GAL_A11Y_IS_E_CELL_VBOX(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_VBOX))
+#define GAL_A11Y_IS_E_CELL_VBOX_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_VBOX))
+#define GAL_A11Y_E_CELL_VBOX_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GAL_A11Y_TYPE_E_CELL_VBOX, GalA11yECellVboxClass))
+
+typedef struct _GalA11yECellVbox GalA11yECellVbox;
+typedef struct _GalA11yECellVboxClass GalA11yECellVboxClass;
+
+struct _GalA11yECellVbox
+{
+ GalA11yECell object;
+ int a11y_subcell_count;
+ gpointer *a11y_subcells;
+};
+
+struct _GalA11yECellVboxClass
+{
+ GalA11yECellClass parent_class;
+};
+
+GType gal_a11y_e_cell_vbox_get_type (void);
+AtkObject *gal_a11y_e_cell_vbox_new (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __GAL_A11Y_E_CELL_VBOX_H__ */
diff --git a/a11y/e-table/gal-a11y-e-cell.c b/a11y/e-table/gal-a11y-e-cell.c
index 9df3568e6c..f22b8f6b44 100644
--- a/a11y/e-table/gal-a11y-e-cell.c
+++ b/a11y/e-table/gal-a11y-e-cell.c
@@ -7,7 +7,10 @@
*/
#include <config.h>
+#include <string.h>
#include "gal/e-table/e-table.h"
+#include "gal/e-table/e-tree.h"
+#include "gal-a11y-e-table-item.h"
#include "gal-a11y-e-cell.h"
#include "gal-a11y-util.h"
#include <atk/atkobject.h>
@@ -15,6 +18,7 @@
#include <atk/atkaction.h>
#include <atk/atkstateset.h>
#include <gtk/gtkwindow.h>
+#include <glib/gi18n.h>
#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yECellClass))
static GObjectClass *parent_class;
@@ -39,8 +43,28 @@ unref_cell (gpointer user_data, GObject *obj_loc)
}
#endif
+static gboolean
+is_valid (AtkObject *cell)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (cell);
+ GalA11yETableItem *a11yItem = GAL_A11Y_E_TABLE_ITEM (a11y->parent);
+ AtkStateSet *item_ss;
+ gboolean ret = TRUE;
+
+ item_ss = atk_object_ref_state_set (ATK_OBJECT (a11yItem));
+ if (atk_state_set_contains_state (item_ss, ATK_STATE_DEFUNCT))
+ ret = FALSE;
+
+ g_object_unref (item_ss);
+
+ if (ret && atk_state_set_contains_state (a11y->state_set, ATK_STATE_DEFUNCT))
+ ret = FALSE;
+
+ return ret;
+}
+
static void
-eti_dispose (GObject *object)
+gal_a11y_e_cell_dispose (GObject *object)
{
GalA11yECell *a11y = GAL_A11Y_E_CELL (object);
@@ -53,43 +77,69 @@ eti_dispose (GObject *object)
g_object_unref (a11y->parent);
#endif
- if (a11y->state_set)
+ if (a11y->state_set) {
g_object_unref (a11y->state_set);
+ a11y->state_set = NULL;
+ }
if (parent_class->dispose)
parent_class->dispose (object);
+
}
/* Static functions */
+static G_CONST_RETURN gchar*
+gal_a11y_e_cell_get_name (AtkObject * a11y)
+{
+ GalA11yECell *cell = GAL_A11Y_E_CELL (a11y);
+ ETableCol *ecol;
+
+ if (a11y->name != NULL && strcmp (a11y->name, ""))
+ return a11y->name;
+
+ if (cell->item != NULL) {
+ ecol = e_table_header_get_column (cell->item->header, cell->view_col);
+ if (ecol != NULL)
+ return ecol->text;
+ }
+
+ return _("Table Cell");
+}
+
static AtkStateSet *
-eti_ref_state_set (AtkObject *accessible)
+gal_a11y_e_cell_ref_state_set (AtkObject *accessible)
{
GalA11yECell *cell = GAL_A11Y_E_CELL (accessible);
- g_return_val_if_fail (cell->state_set, NULL);
+ g_return_val_if_fail (cell->state_set, NULL);
+
g_object_ref(cell->state_set);
+
return cell->state_set;
}
static AtkObject*
-eti_get_parent (AtkObject *accessible)
+gal_a11y_e_cell_get_parent (AtkObject *accessible)
{
GalA11yECell *a11y = GAL_A11Y_E_CELL (accessible);
return a11y->parent;
}
static gint
-eti_get_index_in_parent (AtkObject *accessible)
+gal_a11y_e_cell_get_index_in_parent (AtkObject *accessible)
{
GalA11yECell *a11y = GAL_A11Y_E_CELL (accessible);
+ if (!is_valid (accessible))
+ return -1;
+
return a11y->row * a11y->item->cols + a11y->view_col;
}
/* Component IFace */
static void
-eti_get_extents (AtkComponent *component,
+gal_a11y_e_cell_get_extents (AtkComponent *component,
gint *x,
gint *y,
gint *width,
@@ -97,6 +147,7 @@ eti_get_extents (AtkComponent *component,
AtkCoordType coord_type)
{
GalA11yECell *a11y = GAL_A11Y_E_CELL (component);
+ GtkWidget *tableOrTree;
int row;
int col;
int xval;
@@ -105,14 +156,16 @@ eti_get_extents (AtkComponent *component,
row = a11y->row;
col = a11y->view_col;
-
- e_table_item_get_cell_geometry (a11y->item,
- &row,
- &col,
- &xval,
- &yval,
- width,
- height);
+ tableOrTree = gtk_widget_get_parent (GTK_WIDGET (a11y->item->parent.canvas));
+ if (E_IS_TREE (tableOrTree)) {
+ e_tree_get_cell_geometry (E_TREE (tableOrTree),
+ row, col, &xval, &yval,
+ width, height);
+ } else {
+ e_table_get_cell_geometry (E_TABLE (tableOrTree),
+ row, col, &xval, &yval,
+ width, height);
+ }
atk_component_get_position (ATK_COMPONENT (a11y->parent),
x, y, coord_type);
@@ -123,22 +176,23 @@ eti_get_extents (AtkComponent *component,
}
static gboolean
-eti_grab_focus (AtkComponent *component)
+gal_a11y_e_cell_grab_focus (AtkComponent *component)
{
GalA11yECell *a11y;
- gint view_row;
- GtkWidget *e_table, *toplevel;
+ gint index;
+ GtkWidget *toplevel;
+ GalA11yETableItem *a11yTableItem;
a11y = GAL_A11Y_E_CELL (component);
- e_table = gtk_widget_get_parent (GTK_WIDGET (GNOME_CANVAS_ITEM (a11y->item)->canvas));
- view_row = e_table_view_to_model_row (E_TABLE (e_table), a11y->row);
-
- e_selection_model_select_single_row (a11y->item->selection, view_row);
- e_selection_model_change_cursor (a11y->item->selection, view_row, a11y->view_col);
-
- gtk_widget_grab_focus (e_table);
- toplevel = gtk_widget_get_toplevel (e_table);
- if (GTK_WIDGET_TOPLEVEL (toplevel))
+ a11yTableItem = GAL_A11Y_E_TABLE_ITEM (a11y->parent);
+ index = atk_object_get_index_in_parent (ATK_OBJECT (a11y));
+
+ atk_selection_clear_selection (ATK_SELECTION (a11yTableItem));
+ atk_selection_add_selection (ATK_SELECTION (a11yTableItem), index);
+
+ gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (a11y->item)->canvas));
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (GNOME_CANVAS_ITEM (a11y->item)->canvas));
+ if (toplevel && GTK_WIDGET_TOPLEVEL (toplevel))
gtk_window_present (GTK_WINDOW (toplevel));
return TRUE;
@@ -147,29 +201,30 @@ eti_grab_focus (AtkComponent *component)
/* Table IFace */
static void
-eti_atk_component_iface_init (AtkComponentIface *iface)
+gal_a11y_e_cell_atk_component_iface_init (AtkComponentIface *iface)
{
- iface->get_extents = eti_get_extents;
- iface->grab_focus = eti_grab_focus;
+ iface->get_extents = gal_a11y_e_cell_get_extents;
+ iface->grab_focus = gal_a11y_e_cell_grab_focus;
}
static void
-eti_class_init (GalA11yECellClass *klass)
+gal_a11y_e_cell_class_init (GalA11yECellClass *klass)
{
AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_ref (PARENT_TYPE);
- object_class->dispose = eti_dispose;
+ object_class->dispose = gal_a11y_e_cell_dispose;
- atk_object_class->get_parent = eti_get_parent;
- atk_object_class->get_index_in_parent = eti_get_index_in_parent;
- atk_object_class->ref_state_set = eti_ref_state_set;
+ atk_object_class->get_parent = gal_a11y_e_cell_get_parent;
+ atk_object_class->get_index_in_parent = gal_a11y_e_cell_get_index_in_parent;
+ atk_object_class->ref_state_set = gal_a11y_e_cell_ref_state_set;
+ atk_object_class->get_name = gal_a11y_e_cell_get_name;
}
static void
-eti_init (GalA11yECell *a11y)
+gal_a11y_e_cell_init (GalA11yECell *a11y)
{
a11y->item = NULL;
a11y->cell_view = NULL;
@@ -181,6 +236,11 @@ eti_init (GalA11yECell *a11y)
a11y->state_set = atk_state_set_new ();
atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT);
atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_VISIBLE);
}
@@ -350,6 +410,10 @@ idle_do_action (gpointer data)
GalA11yECell *cell;
cell = GAL_A11Y_E_CELL (data);
+
+ if (!is_valid (ATK_OBJECT (cell)))
+ return FALSE;
+
cell->action_idle_handler = 0;
cell->action_func (cell);
@@ -363,6 +427,9 @@ gal_a11y_e_cell_action_do_action (AtkAction *action,
GalA11yECell *cell = GAL_A11Y_E_CELL(action);
ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index);
+ if (!is_valid (ATK_OBJECT (action)))
+ return FALSE;
+
if (info == NULL)
return FALSE;
g_return_val_if_fail (info->do_action_func, FALSE);
@@ -477,17 +544,17 @@ gal_a11y_e_cell_get_type (void)
sizeof (GalA11yECellClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
- (GClassInitFunc) eti_class_init,
+ (GClassInitFunc) gal_a11y_e_cell_class_init,
(GClassFinalizeFunc) NULL,
NULL, /* class_data */
sizeof (GalA11yECell),
0,
- (GInstanceInitFunc) eti_init,
+ (GInstanceInitFunc) gal_a11y_e_cell_init,
NULL /* value_cell */
};
static const GInterfaceInfo atk_component_info = {
- (GInterfaceInitFunc) eti_atk_component_iface_init,
+ (GInterfaceInitFunc) gal_a11y_e_cell_atk_component_iface_init,
(GInterfaceFinalizeFunc) NULL,
NULL
};
@@ -539,17 +606,16 @@ gal_a11y_e_cell_construct (AtkObject *object,
a11y->row = row;
ATK_OBJECT (a11y) ->role = ATK_ROLE_TABLE_CELL;
+ if (item)
+ g_object_ref (G_OBJECT (item));
+
#if 0
if (parent)
g_object_ref (parent);
- if (item)
- g_object_ref (G_OBJECT (item)); /*,
- unref_item,
- a11y);*/
if (cell_view)
- g_object_ref (G_OBJECT (cell_view)); /*,
- unref_cell,
- a11y);*/
+ g_object_ref (G_OBJECT (cell_view));
+
+
#endif
}
diff --git a/a11y/e-table/gal-a11y-e-table-click-to-add.c b/a11y/e-table/gal-a11y-e-table-click-to-add.c
index 13214a7ddd..c7c84d9deb 100644
--- a/a11y/e-table/gal-a11y-e-table-click-to-add.c
+++ b/a11y/e-table/gal-a11y-e-table-click-to-add.c
@@ -13,6 +13,7 @@
#include <gal/e-table/e-table-click-to-add.h>
#include <atk/atkcomponent.h>
#include <atk/atkaction.h>
+#include <glib/gi18n.h>
static AtkObjectClass *parent_class;
static GType parent_type;
@@ -37,7 +38,7 @@ etcta_get_description (AtkAction *action,
gint i)
{
if (i == 0)
- return "click to add";
+ return _("click to add");
return NULL;
}
@@ -46,7 +47,7 @@ static G_CONST_RETURN gchar*
etcta_action_get_name (AtkAction *action, gint i)
{
if (i == 0)
- return "click";
+ return _("click");
return NULL;
}
@@ -104,9 +105,15 @@ atk_action_interface_init (AtkActionIface *iface)
static G_CONST_RETURN gchar *
etcta_get_name (AtkObject *obj)
{
+ ETableClickToAdd * etcta;
+
g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD (obj), NULL);
- return "click to add";
+ etcta = E_TABLE_CLICK_TO_ADD (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(obj)));
+ if (etcta && etcta->message != NULL)
+ return etcta->message;
+
+ return _("click to add");
}
static gint
@@ -140,6 +147,20 @@ etcta_ref_child (AtkObject *accessible,
return atk_obj;
}
+static AtkStateSet *
+etcta_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet * state_set = NULL;
+
+ state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible);
+ if (state_set != NULL) {
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+ }
+
+ return state_set;
+}
+
static void
etcta_class_init (GalA11yETableClickToAddClass *klass)
{
@@ -150,6 +171,7 @@ etcta_class_init (GalA11yETableClickToAddClass *klass)
atk_object_class->get_name = etcta_get_name;
atk_object_class->get_n_children = etcta_get_n_children;
atk_object_class->ref_child = etcta_ref_child;
+ atk_object_class->ref_state_set = etcta_ref_state_set;
}
static void
@@ -241,6 +263,27 @@ etcta_event (GnomeCanvasItem *item, GdkEvent *e, gpointer data)
return TRUE;
}
+static void
+etcta_selection_cursor_changed (ESelectionModel *esm, gint row, gint col,
+ GalA11yETableClickToAdd *a11y)
+{
+ ETableClickToAdd *etcta;
+ AtkObject *row_a11y;
+
+ etcta = E_TABLE_CLICK_TO_ADD (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(a11y)));
+
+ if (etcta == NULL || etcta->row == NULL)
+ return;
+
+ row_a11y = atk_gobject_accessible_for_object (G_OBJECT(etcta->row));
+ if (row_a11y) {
+ AtkObject *cell_a11y = g_object_get_data (G_OBJECT(row_a11y), "gail-focus-object");
+ if (cell_a11y) {
+ atk_focus_tracker_notify (cell_a11y);
+ }
+ }
+}
+
AtkObject *
gal_a11y_e_table_click_to_add_new (GObject *widget)
{
@@ -265,5 +308,8 @@ gal_a11y_e_table_click_to_add_new (GObject *widget)
g_signal_connect_after (G_OBJECT(widget), "event",
G_CALLBACK (etcta_event), a11y);
+ g_signal_connect (etcta->selection, "cursor_changed",
+ G_CALLBACK (etcta_selection_cursor_changed), a11y);
+
return ATK_OBJECT (a11y);
}
diff --git a/a11y/e-table/gal-a11y-e-table-item-factory.c b/a11y/e-table/gal-a11y-e-table-item-factory.c
index 12cb978fde..3c8e60a4bb 100644
--- a/a11y/e-table/gal-a11y-e-table-item-factory.c
+++ b/a11y/e-table/gal-a11y-e-table-item-factory.c
@@ -31,7 +31,7 @@ gal_a11y_e_table_item_factory_create_accessible (GObject *obj)
AtkObject *accessible;
g_return_val_if_fail (E_IS_TABLE_ITEM(obj), NULL);
- accessible = gal_a11y_e_table_item_new(NULL, E_TABLE_ITEM (obj), 0);
+ accessible = gal_a11y_e_table_item_new (E_TABLE_ITEM (obj));
return accessible;
}
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 ());
+}
diff --git a/a11y/e-table/gal-a11y-e-table-item.h b/a11y/e-table/gal-a11y-e-table-item.h
index f3a447131d..0317132804 100644
--- a/a11y/e-table/gal-a11y-e-table-item.h
+++ b/a11y/e-table/gal-a11y-e-table-item.h
@@ -37,8 +37,8 @@ struct _GalA11yETableItemClass {
/* Standard Glib function */
GType gal_a11y_e_table_item_get_type (void);
-AtkObject *gal_a11y_e_table_item_new (AtkObject *parent,
- ETableItem *item,
- int index_in_parent);
+AtkObject *gal_a11y_e_table_item_new (ETableItem *item);
+
+void gal_a11y_e_table_item_init (void);
#endif /* ! __GAL_A11Y_E_TABLE_ITEM_H__ */
diff --git a/a11y/e-table/gal-a11y-e-table.c b/a11y/e-table/gal-a11y-e-table.c
index 8f4f246e70..16fef97c9d 100644
--- a/a11y/e-table/gal-a11y-e-table.c
+++ b/a11y/e-table/gal-a11y-e-table.c
@@ -12,6 +12,7 @@
#include "gal-a11y-util.h"
#include <gal/e-table/e-table.h>
#include <gal/e-table/e-table-group.h>
+#include <gal/e-table/e-table-group-container.h>
#include <gal/e-table/e-table-group-leaf.h>
#include <gal/e-table/e-table-click-to-add.h>
@@ -27,16 +28,80 @@ struct _GalA11yETablePrivate {
};
/* Static functions */
+static ETableItem *
+find_first_table_item (ETableGroup *group)
+{
+ GnomeCanvasGroup *cgroup;
+ GList *l;
-static void
+ cgroup = GNOME_CANVAS_GROUP (group);
+
+ for (l = cgroup->item_list; l; l = l->next) {
+ GnomeCanvasItem *i;
+
+ i = GNOME_CANVAS_ITEM (l->data);
+
+ if (E_IS_TABLE_GROUP (i))
+ return find_first_table_item (E_TABLE_GROUP (i));
+ else if (E_IS_TABLE_ITEM (i)) {
+ return E_TABLE_ITEM (i);
+ }
+ }
+
+ return NULL;
+}
+
+static AtkObject*
+eti_get_accessible (ETableItem *eti, AtkObject *parent)
+{
+ AtkObject *a11y = NULL;
+
+ g_return_val_if_fail (eti, NULL);
+
+ a11y = atk_gobject_accessible_for_object (G_OBJECT (eti));
+ g_return_val_if_fail (a11y, NULL);
+
+ return a11y;
+}
+
+static ETableItem *
+find_table_item (ETable *table)
+{
+ if (e_table_model_row_count(table->model) < 1)
+ return NULL;
+ else {
+ if (table->group)
+ return find_first_table_item (table->group);
+ }
+
+ return NULL;
+}
+
+static gboolean
init_child_item (GalA11yETable *a11y)
{
- GalA11yETablePrivate *priv = GET_PRIVATE (a11y);
- ETable *table = E_TABLE (GTK_ACCESSIBLE (a11y)->widget);
- if (priv->child_item == NULL) {
- priv->child_item = atk_gobject_accessible_for_object (G_OBJECT(E_TABLE_GROUP_LEAF (table->group)->item));
- priv->child_item->role = ATK_ROLE_TABLE;
+ ETable *table;
+
+ if (!a11y || !GTK_IS_ACCESSIBLE (a11y))
+ return FALSE;
+
+ table = E_TABLE (GTK_ACCESSIBLE (a11y)->widget);
+ if (table && GTK_WIDGET_MAPPED (GTK_WIDGET (table)) && table->group && E_IS_TABLE_GROUP_CONTAINER(table->group)) {
+ ETableGroupContainer *etgc = (ETableGroupContainer *)table->group;
+ GList *list;
+
+ for (list = etgc->children; list; list = g_list_next (list)) {
+ ETableGroupContainerChildNode *child_node = list->data;
+ ETableGroup *child = child_node->child;
+ ETableItem *eti = find_first_table_item (child);
+
+ eti_get_accessible (eti, ATK_OBJECT (a11y));
+ }
}
+ g_object_unref (a11y);
+ g_object_unref (table);
+
+ return FALSE;
}
static AtkObject*
@@ -46,7 +111,8 @@ et_ref_accessible_at_point (AtkComponent *component,
AtkCoordType coord_type)
{
GalA11yETable *a11y = GAL_A11Y_E_TABLE (component);
- init_child_item (a11y);
+ if (GET_PRIVATE (a11y)->child_item)
+ g_object_ref (GET_PRIVATE (a11y)->child_item);
return GET_PRIVATE (a11y)->child_item;
}
@@ -55,13 +121,23 @@ et_get_n_children (AtkObject *accessible)
{
GalA11yETable *a11y = GAL_A11Y_E_TABLE (accessible);
ETable * et;
+ int n = 0;
et = E_TABLE(GTK_ACCESSIBLE (a11y)->widget);
- if (et && et->use_click_to_add) {
- return 2;
- }
- return 1;
+ if (et->group) {
+ if (E_IS_TABLE_GROUP_LEAF (et->group))
+ n = 1;
+ else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
+ ETableGroupContainer *etgc = (ETableGroupContainer *)et->group;
+ n = g_list_length (etgc->children);
+ }
+ }
+
+ if (et && et->use_click_to_add && et->click_to_add) {
+ n++;
+ }
+ return n;
}
static AtkObject*
@@ -70,24 +146,40 @@ et_ref_child (AtkObject *accessible,
{
GalA11yETable *a11y = GAL_A11Y_E_TABLE (accessible);
ETable * et;
+ gint child_no;
et = E_TABLE(GTK_ACCESSIBLE (a11y)->widget);
- if (i == 0) {
- init_child_item (a11y);
- g_object_ref (GET_PRIVATE (a11y)->child_item);
- return GET_PRIVATE (a11y)->child_item;
- } else if (i == 1) {
+ child_no = et_get_n_children (accessible);
+ if (i == 0 || i < child_no - 1) {
+ if (E_IS_TABLE_GROUP_LEAF (et->group)) {
+ ETableItem *eti = find_first_table_item (et->group);
+ AtkObject *aeti = eti_get_accessible (eti, accessible);
+ if (aeti)
+ g_object_ref (aeti);
+ return aeti;
+
+ } else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
+ ETableGroupContainer *etgc = (ETableGroupContainer *) et->group;
+ ETableGroupContainerChildNode *child_node = g_list_nth_data (etgc->children, i);
+ if (child_node) {
+ ETableGroup *child = child_node->child;
+ ETableItem * eti = find_first_table_item (child);
+ AtkObject *aeti = eti_get_accessible (eti, accessible);
+ if (aeti)
+ g_object_ref (aeti);
+ return aeti;
+ }
+ }
+ } else if (i == child_no -1) {
AtkObject * accessible;
ETableClickToAdd * etcta;
if (et && et->use_click_to_add && et->click_to_add) {
etcta = E_TABLE_CLICK_TO_ADD(et->click_to_add);
- if (etcta->rect) {
- accessible = atk_gobject_accessible_for_object (G_OBJECT(etcta));
- } else {
- accessible = atk_gobject_accessible_for_object (G_OBJECT(etcta->row));
- }
+ accessible = atk_gobject_accessible_for_object (G_OBJECT(etcta));
+ if (accessible)
+ g_object_ref (accessible);
return accessible;
}
}
@@ -95,6 +187,12 @@ et_ref_child (AtkObject *accessible,
return NULL;
}
+static AtkLayer
+et_get_layer (AtkComponent *component)
+{
+ return ATK_LAYER_WIDGET;
+}
+
static void
et_class_init (GalA11yETableClass *klass)
{
@@ -110,6 +208,7 @@ static void
et_atk_component_iface_init (AtkComponentIface *iface)
{
iface->ref_accessible_at_point = et_ref_accessible_at_point;
+ iface->get_layer = et_get_layer;
}
static void
@@ -181,5 +280,15 @@ gal_a11y_e_table_new (GObject *widget)
GTK_ACCESSIBLE (a11y)->widget = GTK_WIDGET (widget);
+ /* we need to init all the children for multiple table items */
+ if (table && GTK_WIDGET_MAPPED (GTK_WIDGET (table)) && table->group && E_IS_TABLE_GROUP_CONTAINER (table->group)) {
+ /* Ref it here so that it is still valid in the idle function */
+ /* It will be unrefed in the idle function */
+ g_object_ref (a11y);
+ g_object_ref (widget);
+
+ g_idle_add ((GSourceFunc)init_child_item, a11y);
+ }
+
return ATK_OBJECT (a11y);
}
diff --git a/a11y/e-table/gal-a11y-e-tree.c b/a11y/e-table/gal-a11y-e-tree.c
index 9bb49496d4..9f371729ae 100644
--- a/a11y/e-table/gal-a11y-e-tree.c
+++ b/a11y/e-table/gal-a11y-e-tree.c
@@ -35,11 +35,6 @@ init_child_item (GalA11yETree *a11y)
eti = e_tree_get_item (tree);
if (priv->child_item == NULL) {
priv->child_item = atk_gobject_accessible_for_object (G_OBJECT (eti));
- if (!priv->child_item)
- priv->child_item = gal_a11y_e_table_item_new (ATK_OBJECT (a11y),eti, 0);
-
- g_return_if_fail (priv->child_item);
- priv->child_item->role = ATK_ROLE_TREE_TABLE;
}
}
@@ -72,6 +67,12 @@ et_ref_child (AtkObject *accessible,
return GET_PRIVATE (a11y)->child_item;
}
+static AtkLayer
+et_get_layer (AtkComponent *component)
+{
+ return ATK_LAYER_WIDGET;
+}
+
static void
et_class_init (GalA11yETreeClass *klass)
{
@@ -87,6 +88,7 @@ static void
et_atk_component_iface_init (AtkComponentIface *iface)
{
iface->ref_accessible_at_point = et_ref_accessible_at_point;
+ iface->get_layer = et_get_layer;
}
static void