[evolution-patches] gal e-table patches about a11y bugs



Hi JP,

Attachments are two gal patches for e-table which fix some a11y bugs.
They have passed our internal test. The patches will work if you patch
all of them into the code.

Please spend a little time to review these patches.

Thank you very much.

Regards,
Li
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gal/ChangeLog,v
retrieving revision 1.902
diff -u -r1.902 ChangeLog
--- ChangeLog	28 Nov 2004 20:32:01 -0000	1.902
+++ ChangeLog	8 Dec 2004 08:27:32 -0000
@@ -1,3 +1,129 @@
+2004-12-06  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.
+	
+	* gal/a11y/e-table/gal-a11y-e-cell-text.c: 
+	(ect_do_action_edit):check the cell's editable property when 
+	enter_edit,fixes crash when UI grab the cell.
+	(ect_action_init):add i18n support to strings.
+	(ect_action_init), (gal_a11y_e_cell_text_get_type), 
+	(gal_a11y_e_cell_text_new):
+	only add action interface if the cell is editable.
+	(ect_dispose), (ect_get_name), (ect_get_text),
+	(ect_get_character_at_offset), (ect_get_caret_offset),
+	(ect_get_character_count), (ect_get_selection),
+	(ect_add_selection), (ect_set_caret_offset),
+	(ect_insert_text), (ect_text_inserted_cb),(ect_text_deleted_cb), 
+	(ect_class_init),  (gal_a11y_e_cell_text_new):
+	connect to "text_inserted" and "text_deleted" signal of e-text-cell
+	to send "text_changed" signal. use e_cell_text_get_text_by_view
+	instead of e_cell_text_get_text.
+	(ect_get_name):if the name is NULL or "", return the column's title.
+	(ect_dispose), (ect_check), (ect_get_name), (ect_get_text),
+	(ect_get_character_at_offset), (ect_get_character_count),
+	(ect_get_n_selections),(gal_a11y_e_cell_text_new):
+	add ect_check to fix a crash.
+	(gal_a11y_e_cell_text_new): add ATK_EDITABLE_STATE if needed.
+	(ect_get_name):If e-cell-text's name is empty, use the column's 
+	name as the atk name.
+	
+	* gal/a11y/e-table/gal-a11y-e-cell-text.h:
+	fix a crash.
+	
+	* 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.
+
+	* 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.
+
+	* gal/a11y/e-table/gal-a11y-e-cell.c: 	
+	(gal_a11y_e_cell_get_name), (eti_class_init):
+	impl the get_name method for cell.
+	(eti_grab_focus):Use add_selection to implement grab_focus.
+	(eti_dispose):fix a crash.
+	(eti_dispose), (gal_a11y_e_cell_construct):
+	fix #70261.
+	(eti_init):Add ATK_STATE_SELECTABLE to cell's state.
+	(gal_a11y_e_cell_get_name): If e-cell-text's name is empty,
+	use the column's name as the atk name.
+	(gal_a11y_e_cell_ref_state_set): make the cell always visible.
+	(eti_init):Add FOCUSABLE state to the stateset.
+	(is_valid), (idle_do_action), (gal_a11y_e_cell_action_do_action):
+	add is_valid check.
+
+	* 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_ref_state_set), (etcta_class_init):
+	add ref_state_set function.
+	(etcta_get_name):Use the messaage as the name.
+	(etcta_selection_cursor_changed), (gal_a11y_e_table_click_to_add_new):
+	fix #70261.
+	(etcta_selection_cursor_changed): add more check here.
+	(etcta_ref_state_set):Add SHOWING state to the stateset.
+	
+	* gal/a11y/e-table/gal-a11y-e-table-item-factory.c:
+	(gal_a11y_e_table_item_factory_create_accessible):
+	
+	* gal/a11y/e-table/gal-a11y-e-table-item.c: 
+	(eti_ref_state_set), (eti_class_init), (gal_a11y_e_table_item_new):
+	add function eti_ref_state_set and add some states.
+	(eti_ref_child): Don't support table header column for now.
+	(gal_a11y_e_table_item_new):
+	make gnopernicus can read the first item.
+	(eti_ref_accessible_at_point):
+	return NULL to fix a crash.
+	(gal_a11y_e_table_item_new), (eti_a11y_cursor_changed_cb):
+	fix a crash.
+	(item_destroyed), (cell_destroyed), (eti_ref_at),
+	(table_is_row_selected), (table_get_selected_rows), 
+	(table_add_row_selection), (table_remove_row_selection), 
+	(gal_a11y_e_table_item_new), (eti_a11y_selection_changed_cb), 
+	(eti_a11y_cursor_changed_cb):fix #70261.
+	(eti_get_column_header), (gal_a11y_e_table_item_new), 
+	(eti_a11y_cursor_changed_cb), (selection_add_selection):
+	Make e-table only support single selection now.
+	(eti_a11y_selection_changed_cb):
+	remove focused state from old cell and don't send out focus event.
+	(gal_a11y_e_table_item_new):no need to notify focus change here.
+	(eti_ref_child), (eti_ref_accessible_at_point), 
+	(table_is_row_selected), (table_add_row_selection), 
+	(table_remove_row_selection), (eti_class_init), (eti_init),
+	(gal_a11y_e_table_item_new), (eti_a11y_cursor_changed_cb),
+	(selection_add_selection),(selection_ref_selection):
+	Add support for multiple ETableItems.
+	
+	* gal/a11y/e-table/gal-a11y-e-table-item.h:
+	
+	* gal/a11y/e-table/gal-a11y-e-table.c: 
+	(init_child_item): set the tableItem's name according to the 
+	table's name.
+	(eti_ref_accessible), (init_child_item), (et_ref_accessible_at_point),
+	(et_get_n_children), (et_ref_child), (gal_a11y_e_table_new):
+	Add support for multiple ETableItems.
+
+	* gal/a11y/e-table/gal-a11y-e-tree.c: (init_child_item):
+	set the tableItem's name according to the table's name.
+	Add support for multiple ETableItems.
+
+
 2004-11-28  JP Rosevear  <jpr novell com>
 
 	* configure.in: bump version

Index: gal/a11y/e-table/Makefile.am
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/Makefile.am,v
retrieving revision 1.7
diff -u -r1.7 Makefile.am
--- gal/a11y/e-table/Makefile.am	17 Dec 2003 02:35:20 -0000	1.7
+++ gal/a11y/e-table/Makefile.am	8 Dec 2004 08:28:00 -0000
@@ -19,6 +19,7 @@
 	gal-a11y-e-cell-toggle.c		\
 	gal-a11y-e-cell-popup.c			\
 	gal-a11y-e-cell-registry.c		\
+	gal-a11y-e-cell-vbox.c			\
 	gal-a11y-e-table.c			\
 	gal-a11y-e-table-item.c			\
 	gal-a11y-e-table-item-factory.c		\
@@ -37,6 +38,7 @@
 	gal-a11y-e-cell-toggle.h		\
 	gal-a11y-e-cell-popup.h			\
 	gal-a11y-e-cell-registry.h		\
+	gal-a11y-e-cell-vbox.h			\
 	gal-a11y-e-table.h			\
 	gal-a11y-e-table-item.h			\
 	gal-a11y-e-table-click-to-add-factory.h	\
Index: gal/a11y/e-table/gal-a11y-e-cell-popup.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell-popup.c,v
retrieving revision 1.3
diff -u -r1.3 gal-a11y-e-cell-popup.c
--- gal/a11y/e-table/gal-a11y-e-cell-popup.c	10 Jun 2004 17:00:45 -0000	1.3
+++ gal/a11y/e-table/gal-a11y-e-cell-popup.c	8 Dec 2004 08:28:00 -0000
@@ -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 @@
 	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);
 
Index: gal/a11y/e-table/gal-a11y-e-cell-text.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell-text.c,v
retrieving revision 1.6
diff -u -r1.6 gal-a11y-e-cell-text.c
--- gal/a11y/e-table/gal-a11y-e-cell-text.c	10 Jun 2004 17:00:45 -0000	1.6
+++ gal/a11y/e-table/gal-a11y-e-cell-text.c	8 Dec 2004 08:28:02 -0000
@@ -15,18 +15,89 @@
 #include <atk/atktext.h>
 #include <atk/atkeditabletext.h>
 #include <atk/atkaction.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;
+	GalA11yECellText *gaet = GAL_A11Y_E_CELL_TEXT (object);
+
+	if (gaet->inserted_id != 0) {
+		ECellText *ect = E_CELL_TEXT (gaet->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);
+	GalA11yECellText *gaet = GAL_A11Y_E_CELL_TEXT (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 (gaet->ecell != gaec->cell_view->ecell) {
+		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;
+	ECellText *ect;
+	char *name;
+
+	if (!ect_check (a11y))
+		return NULL;
+
+	gaec = GAL_A11Y_E_CELL (a11y);
+	ect = E_CELL_TEXT (gaec->cell_view->ecell);
+	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 +106,15 @@
 	      gint end_offset)
 {
 	GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
-	ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+	ECellText *ect ;
+	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;
+
+	ect = E_CELL_TEXT (gaec->cell_view->ecell);
+	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 +125,7 @@
 
 	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 +157,18 @@
 			     gint offset)
 {
 	GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
-	ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+	ECellText *ect;
 	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;
+
+	ect = E_CELL_TEXT (gaec->cell_view->ecell);
+	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;
 }
@@ -111,15 +193,17 @@
 	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);
+	if (!ect_check (text))
+		return -1;
+
 	ect = E_CELL_TEXT (gaec->cell_view->ecell);
 
 	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 +247,17 @@
 ect_get_character_count (AtkText *text)
 {
 	GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
-	ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+	ECellText *ect;
 	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;
+
+	ect = E_CELL_TEXT (gaec->cell_view->ecell);
+	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 +278,10 @@
 {
 	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,
@@ -218,7 +310,7 @@
 					  &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 +326,7 @@
 			*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;
@@ -258,7 +350,7 @@
 	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 +364,7 @@
 
 		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,
@@ -334,7 +426,7 @@
 	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 +436,7 @@
 	
 	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 +474,7 @@
 	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 +482,7 @@
 	*position += length;
 
 	g_free (result);
-	e_cell_text_free_text (ect, full_text);
+	g_free (full_text);
 }
 
 static void
@@ -443,7 +535,33 @@
 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, gpointer data)
+{
+	GalA11yECellText *gaet = GAL_A11Y_E_CELL_TEXT (data);
+	GalA11yECell *gaec = GAL_A11Y_E_CELL (data);
+	if (cell_view == gaec->cell_view) {
+		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, gpointer data)
+{
+	GalA11yECellText *gaet = GAL_A11Y_E_CELL_TEXT (data);
+	GalA11yECell *gaec = GAL_A11Y_E_CELL (data);
+	if (cell_view == gaec->cell_view) {
+		g_signal_emit_by_name (gaet, "text_changed::delete", pos, len);
+	 }
 }
 
 static void
@@ -483,19 +601,25 @@
 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 +646,7 @@
 			NULL, /* class_data */
 			sizeof (GalA11yECellText),
 			0,
-			(GInstanceInitFunc) ect_init,
+			(GInstanceInitFunc) NULL,
 			NULL /* value_cell_text */
 		};
 
@@ -556,6 +680,9 @@
 			  int         row)
 {
 	AtkObject *a11y;
+	GalA11yECell *gaec;
+	GalA11yECellText *gaet;
+	ECellText *ect; 
 
 	a11y = g_object_new (gal_a11y_e_cell_text_get_type (), NULL);
 
@@ -566,5 +693,22 @@
 				   model_col,
 				   view_col,
 				   row);
+	gaet = GAL_A11Y_E_CELL_TEXT (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);
+
+	ect_action_init (gaet);
+	gaet->ecell = cell_view->ecell;
+
+	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;
 }
Index: gal/a11y/e-table/gal-a11y-e-cell-text.h
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell-text.h,v
retrieving revision 1.1
diff -u -r1.1 gal-a11y-e-cell-text.h
--- gal/a11y/e-table/gal-a11y-e-cell-text.h	30 Nov 2002 07:54:15 -0000	1.1
+++ gal/a11y/e-table/gal-a11y-e-cell-text.h	8 Dec 2004 08:28:02 -0000
@@ -29,6 +29,9 @@
  **/
 struct _GalA11yECellText {
 	GalA11yECell object;
+	ECell *ecell;
+	gint inserted_id;
+	gint deleted_id;
 };
 
 struct _GalA11yECellTextClass {
Index: gal/a11y/e-table/gal-a11y-e-cell-toggle.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell-toggle.c,v
retrieving revision 1.4
diff -u -r1.4 gal-a11y-e-cell-toggle.c
--- gal/a11y/e-table/gal-a11y-e-cell-toggle.c	10 Jun 2004 17:00:45 -0000	1.4
+++ gal/a11y/e-table/gal-a11y-e-cell-toggle.c	8 Dec 2004 08:28:02 -0000
@@ -2,6 +2,7 @@
 #include "gal-a11y-e-cell-toggle.h"
 #include <gal/e-table/e-cell-toggle.h>
 #include <gal/e-table/e-table-model.h>
+#include <glib/gi18n.h>
 
 #define PARENT_TYPE  (gal_a11y_e_cell_get_type ())
 static GObjectClass *parent_class;
@@ -15,8 +16,10 @@
 
 	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);
@@ -101,7 +104,10 @@
 
 	        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 (cell);
+
 		if (value)
 			gal_a11y_e_cell_add_state (cell, ATK_STATE_CHECKED, TRUE);
 		else
@@ -140,8 +146,8 @@
                                    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);
 
Index: gal/a11y/e-table/gal-a11y-e-cell-tree.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell-tree.c,v
retrieving revision 1.3
diff -u -r1.3 gal-a11y-e-cell-tree.c
--- gal/a11y/e-table/gal-a11y-e-cell-tree.c	10 Jun 2004 17:00:45 -0000	1.3
+++ gal/a11y/e-table/gal-a11y-e-cell-tree.c	8 Dec 2004 08:28:02 -0000
@@ -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 @@
 								    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);
 
Index: gal/a11y/e-table/gal-a11y-e-cell-vbox.c
===================================================================
RCS file: gal/a11y/e-table/gal-a11y-e-cell-vbox.c
diff -N gal/a11y/e-table/gal-a11y-e-cell-vbox.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gal/a11y/e-table/gal-a11y-e-cell-vbox.c	8 Dec 2004 08:28:02 -0000
@@ -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;
+}
Index: gal/a11y/e-table/gal-a11y-e-cell-vbox.h
===================================================================
RCS file: gal/a11y/e-table/gal-a11y-e-cell-vbox.h
diff -N gal/a11y/e-table/gal-a11y-e-cell-vbox.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gal/a11y/e-table/gal-a11y-e-cell-vbox.h	8 Dec 2004 08:28:02 -0000
@@ -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__ */
Index: gal/a11y/e-table/gal-a11y-e-cell.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell.c,v
retrieving revision 1.8
diff -u -r1.8 gal-a11y-e-cell.c
--- gal/a11y/e-table/gal-a11y-e-cell.c	10 Jun 2004 17:00:45 -0000	1.8
+++ gal/a11y/e-table/gal-a11y-e-cell.c	8 Dec 2004 08:28:03 -0000
@@ -8,6 +8,8 @@
 
 #include <config.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 +17,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,6 +42,26 @@
 }
 #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)
 {
@@ -53,21 +76,48 @@
 		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)
 {
 	GalA11yECell *cell = GAL_A11Y_E_CELL (accessible);
+	AtkObject *parent;
+	gint x, y, width, height;
+	gint parent_x, parent_y, parent_width, parent_height;
+
 	g_return_val_if_fail (cell->state_set, NULL);
 
+	gal_a11y_e_cell_add_state (cell, ATK_STATE_VISIBLE, TRUE);
+                                                                              
 	g_object_ref(cell->state_set);
+
 	return cell->state_set;
 }
 
@@ -97,6 +147,7 @@
 		AtkCoordType coord_type)
 {
 	GalA11yECell *a11y = GAL_A11Y_E_CELL (component);
+	GtkWidget *tableOrTree;
 	int row;
 	int col;
 	int xval;
@@ -105,14 +156,16 @@
 	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);
@@ -126,19 +179,20 @@
 eti_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;
@@ -166,6 +220,7 @@
 	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_name            = gal_a11y_e_cell_get_name;
 }
 
 static void
@@ -181,6 +236,10 @@
 	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);
 }
 
 
@@ -350,6 +409,10 @@
 	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 +426,9 @@
 	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);
@@ -539,17 +605,16 @@
 	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
 }
Index: gal/a11y/e-table/gal-a11y-e-table-click-to-add.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-table-click-to-add.c,v
retrieving revision 1.2
diff -u -r1.2 gal-a11y-e-table-click-to-add.c
--- gal/a11y/e-table/gal-a11y-e-table-click-to-add.c	10 Jun 2004 17:00:45 -0000	1.2
+++ gal/a11y/e-table/gal-a11y-e-table-click-to-add.c	8 Dec 2004 08:28:03 -0000
@@ -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 @@
                              gint      i)
 {
 	if (i == 0)
-		return "click to add";
+		return _("click to add");
 
 	return NULL;
 }
@@ -46,7 +47,7 @@
 etcta_action_get_name (AtkAction *action, gint      i)
 {
 	if (i == 0)
-		return "click";
+		return _("click");
 
 	return NULL;
 }
@@ -104,9 +105,15 @@
 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 @@
 	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 @@
 	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 @@
 	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)
 {
@@ -264,6 +307,9 @@
 
 	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);
 }
Index: gal/a11y/e-table/gal-a11y-e-table-item-factory.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-table-item-factory.c,v
retrieving revision 1.3
diff -u -r1.3 gal-a11y-e-table-item-factory.c
--- gal/a11y/e-table/gal-a11y-e-table-item-factory.c	10 Jun 2004 17:00:45 -0000	1.3
+++ gal/a11y/e-table/gal-a11y-e-table-item-factory.c	8 Dec 2004 08:28:03 -0000
@@ -31,7 +31,7 @@
 	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;
 }
Index: gal/a11y/e-table/gal-a11y-e-table-item.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-table-item.c,v
retrieving revision 1.14
diff -u -r1.14 gal-a11y-e-table-item.c
--- gal/a11y/e-table/gal-a11y-e-table-item.c	21 Jun 2004 12:02:31 -0000	1.14
+++ gal/a11y/e-table/gal-a11y-e-table-item.c	8 Dec 2004 08:28:07 -0000
@@ -10,11 +10,14 @@
 #include <config.h>
 #include <string.h>
 #include "gal-a11y-e-table-item.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/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>
@@ -32,10 +35,9 @@
 static GQuark		quark_accessible_object = 0;
 #define GET_PRIVATE(object) ((GalA11yETableItemPrivate *) (((char *) object) + priv_offset))
 #define PARENT_TYPE (parent_type)
+static gpointer * eti_reinit_data (AtkTable *table, ETableItem *item);
 
 struct _GalA11yETableItemPrivate {
-	AtkObject *parent;
-	gint index_in_parent;
 	gint cols;
 	gint rows;
 	gpointer *cell_data;
@@ -43,6 +45,7 @@
 	int cursor_change_id;
 	ETableCol ** columns;
 	ESelectionModel *selection;
+	AtkStateSet *state_set;
 	GtkWidget *widget;
 };
 
@@ -52,15 +55,28 @@
 
 static gpointer *eti_reinit_data (AtkTable *table, ETableItem *item);
 
-#if 0
+static AtkObject* eti_ref_at (AtkTable *table, gint row, gint column);
+
 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);
+
+}
+
+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,8 +147,6 @@
 	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;
@@ -150,20 +164,6 @@
 }
 
 /* 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 +186,12 @@
 	if (!item)
 		return NULL;
 
-	if (index < item->cols) {
-		AtkObject *child;
+	/* don't support column header now */
 
-		/* A column header is required */
-		child = atk_table_get_column_header (ATK_TABLE (accessible), index);
-		if (child)
-			g_object_ref (child);
-		return child;
-	}
-
-	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
@@ -229,29 +207,25 @@
 	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 +238,7 @@
 	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 +251,15 @@
 	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;
 	}
@@ -296,7 +275,8 @@
 
 	g_return_if_fail (GAL_A11Y_IS_E_CELL (data));
 	cell = GAL_A11Y_E_CELL (data);
-		
+
+	g_return_if_fail (cell->item && G_IS_OBJECT (cell->item));
 	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));
@@ -307,6 +287,11 @@
                                                                    
 	if (GET_PRIVATE (item)->cell_data && GET_PRIVATE (item)->cell_data [index] == data)
 		GET_PRIVATE (item)->cell_data [index] = NULL;
+
+        if (cell->item) {
+                g_object_unref (G_OBJECT (cell->item));  
+                cell->item = NULL;
+        }
 }
 
 /* atk table */
@@ -315,6 +300,11 @@
 {
 	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)
@@ -343,8 +333,7 @@
 							    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_ref (ret);
 				g_object_weak_ref (G_OBJECT (ret),
 						   (GWeakNotify) cell_destroyed,
 						   ret);
@@ -508,9 +497,15 @@
 		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 +536,16 @@
 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 +559,10 @@
 {
 	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,14 +604,20 @@
 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)
 		return FALSE;
+	/* we need to make the item get focus */
+	e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (item), TRUE);
 
 	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;
 }
 
@@ -655,6 +664,7 @@
 	GalA11yETableItem * item_a11y;
 	gint old_nrows;
 
+
 	g_return_if_fail (table_item);
  	item_a11y = GAL_A11Y_E_TABLE_ITEM (table_item);
 
@@ -1040,11 +1050,10 @@
 
 	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 +1063,6 @@
 
 	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,24 +1156,31 @@
 }
 
 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;
@@ -1196,22 +1210,49 @@
 
 		/* 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 +1345,11 @@
 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 +1362,38 @@
 	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);
+	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);
+		gal_a11y_e_cell_add_state(GAL_A11Y_E_CELL (cell), ATK_STATE_FOCUSED, FALSE);
 
         	if (ATK_IS_OBJECT (cell))
                 	g_signal_emit_by_name  (a11y,
                                         "active-descendant-changed",
                                         cell);
-		atk_focus_tracker_notify (cell);
 	}
 
 }
@@ -1357,7 +1414,7 @@
 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 +1424,33 @@
 	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) {
+		/* 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 +1479,7 @@
 	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
@@ -1430,4 +1502,12 @@
 
 	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 ());
 }
Index: gal/a11y/e-table/gal-a11y-e-table-item.h
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-table-item.h,v
retrieving revision 1.2
diff -u -r1.2 gal-a11y-e-table-item.h
--- gal/a11y/e-table/gal-a11y-e-table-item.h	3 Nov 2003 06:40:50 -0000	1.2
+++ gal/a11y/e-table/gal-a11y-e-table-item.h	8 Dec 2004 08:28:07 -0000
@@ -37,8 +37,8 @@
 
 /* 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__ */
Index: gal/a11y/e-table/gal-a11y-e-table.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-table.c,v
retrieving revision 1.3
diff -u -r1.3 gal-a11y-e-table.c
--- gal/a11y/e-table/gal-a11y-e-table.c	17 Dec 2003 02:35:20 -0000	1.3
+++ gal/a11y/e-table/gal-a11y-e-table.c	8 Dec 2004 08:28:08 -0000
@@ -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 @@
 };
 
 /* 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_ref_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);
+
+	g_object_ref (a11y);
+	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) || !GTK_ACCESSIBLE (a11y)->widget)
+		return FALSE;
+
+	table = E_TABLE (GTK_ACCESSIBLE (a11y)->widget);
+	if (table && table->group && E_IS_TABLE_GROUP_CONTAINER (table->group)) {
+		/* we need to init all the children for multiple table items */
+		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_ref_accessible (eti, ATK_OBJECT (a11y));
+		}
 	}
+
+	return FALSE;
 }
 
 static AtkObject*
@@ -46,7 +111,8 @@
 			     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 @@
 {
 	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,34 @@
 {
 	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);
+			return eti_ref_accessible (eti, accessible);
+
+		} 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);
+				return eti_ref_accessible (eti, accessible);
+			}
+		}
+	} 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;
 		}
 	}
@@ -180,6 +266,8 @@
 	a11y = g_object_new (gal_a11y_e_table_get_type (), NULL);
 
 	GTK_ACCESSIBLE (a11y)->widget = GTK_WIDGET (widget);
+
+	g_idle_add ((GSourceFunc)init_child_item, a11y);
 
 	return ATK_OBJECT (a11y);
 }
Index: gal/a11y/e-table/gal-a11y-e-tree.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-tree.c,v
retrieving revision 1.4
diff -u -r1.4 gal-a11y-e-tree.c
--- gal/a11y/e-table/gal-a11y-e-tree.c	10 Jun 2004 17:00:45 -0000	1.4
+++ gal/a11y/e-table/gal-a11y-e-tree.c	8 Dec 2004 08:28:09 -0000
@@ -35,11 +35,6 @@
 	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;
 	}
 }

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/ChangeLog,v
retrieving revision 1.942
diff -u -r1.942 ChangeLog
--- ChangeLog	24 Nov 2004 10:34:55 -0000	1.942
+++ ChangeLog	8 Dec 2004 09:04:06 -0000
@@ -1,3 +1,54 @@
+2004-12-06  Li Yuan  <li yuan sun com>
+
+	* e-cell-combo.c: (e_cell_combo_init)
+	(e_cell_combo_do_popup),
+	(e_cell_combo_list_button_press), (e_cell_combo_button_press),
+	(e_cell_combo_button_release), (e_cell_combo_key_press):
+	add an a11y name for the popup list.
+	make shortcut key ALT+Arrow work.
+	* e-cell-text.c: 
+	(e_cell_text_class_init),
+	(_delete_selection), (_insert), (e_cell_text_delete_selection):
+	add "text_inserted" and "text_deleted" signals to notify the 
+	text has been changed.
+	(e_cell_text_get_text_by_view):
+	new helper function to get the text being editted.
+	* e-cell-text.h:
+	add signal declaration.
+	* e-cell-toggle.c: (etog_draw):
+	add range check for negative values.
+	* e-cell-vbox.c: (e_cell_vbox_class_init):
+	* e-cell-vbox.h:
+	make ECellVboxView public since it will be used in a11y part.
+	* e-table-click-to-add.c: (etcta_style_set),
+	(create_rect_and_text), (etcta_realize), (etcta_class_init),
+	(e_table_click_to_add_commit):
+	add "style_set" signal to click_to_add and implement
+	the style_set function.
+	(etcta_init):
+	add a11y name to click to add.
+	* e-table-click-to-add.h:
+	add "style_set" signal to click_to_add and implement
+	the style_set function.
+	* e-table-config.c: 
+	(config_button_up), (config_button_down):
+	check whether the columns are empty.
+	* e-table-group-container.c:
+	* e-table-group-container.h:
+	make ETableGroupContainerChildNode public since it 
+	will be used in a11y part
+	* e-table-item.c: (eti_init): 
+	init eti->cols
+	(eti_event):
+	at GDK_KEY_PRESS event and GDK_Down key pressed, we check 
+	view_col value before we pass it to eti_e_cell_event.
+	(eti_class_init):
+	call the new initialize function
+	* e-table.c: (table_canvas_focus_event_cb):
+	if canvas has a focused item but the etable does not 
+	have a cursor row, just focus the first item after check
+        whether the click_to_add should get the focus.	
+
 2004-11-24  Li Yuan  <li yuan sun com>
 
 	* e-table.c: (e_table_get_cell_geometry):
Index: e-cell-combo.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-combo.c,v
retrieving revision 1.17
diff -u -r1.17 e-cell-combo.c
--- e-cell-combo.c	12 Aug 2004 05:10:42 -0000	1.17
+++ e-cell-combo.c	8 Dec 2004 09:04:09 -0000
@@ -56,6 +56,7 @@
 #include <string.h> /* strcmp() */
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtk.h>
+#include <glib/gi18n.h>
 #include "gal/util/e-util.h"
 #include "gal/widgets/e-unicode.h"
 #include "e-table-item.h"
@@ -135,6 +136,7 @@
 e_cell_combo_init			(ECellCombo	*ecc)
 {
 	GtkWidget *frame;
+	AtkObject *a11y;
 
 	/* We create one popup window for the ECell, since there will only
 	   ever be one popup in use at a time. */
@@ -167,6 +169,9 @@
 					     gtk_scrolled_window_get_hadjustment (GTK_SCROLLED_WINDOW (ecc->popup_scrolled_window)));
 	gtk_widget_show (ecc->popup_list);
 
+	a11y = gtk_widget_get_accessible (ecc->popup_list);
+	atk_object_set_name (a11y, _("popup list"));
+
 	g_signal_connect (ecc->popup_list,
 			  "selection_changed",
 			  G_CALLBACK (e_cell_combo_selection_changed),
@@ -291,6 +296,7 @@
 	if (error_code != 0)
 		g_warning ("Failed to get pointer grab (%i)", error_code);
 	gtk_grab_add (ecc->popup_window);
+	gdk_keyboard_grab (ecc->popup_list->window, TRUE, time);
 
 	return TRUE;
 }
@@ -522,6 +528,7 @@
 	e_cell_combo_update_cell (ecc);
 	gtk_grab_remove (ecc->popup_window);
 	gdk_pointer_ungrab (event->button.time);
+	gdk_keyboard_ungrab (event->button.time);
 	gtk_widget_hide (ecc->popup_window);
 
 	e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE);
@@ -561,6 +568,7 @@
 
 	gtk_grab_remove (ecc->popup_window);
 	gdk_pointer_ungrab (event->button.time);
+	gdk_keyboard_ungrab (event->button.time);
 	gtk_widget_hide (ecc->popup_window);
 
 	e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE);
@@ -602,6 +610,7 @@
 	   update the cell to reflect the new selection. */
 	gtk_grab_remove (ecc->popup_window);
 	gdk_pointer_ungrab (event->time);
+	gdk_keyboard_ungrab (event->time);
 	gtk_widget_hide (ecc->popup_window);
 
 	e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE);
@@ -631,6 +640,7 @@
 
 	gtk_grab_remove (ecc->popup_window);
 	gdk_pointer_ungrab (event->time);
+	gdk_keyboard_ungrab (event->time);
 	gtk_widget_hide (ecc->popup_window);
 
 	e_cell_popup_set_shown (E_CELL_POPUP (ecc), FALSE);
Index: e-cell-text.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-text.c,v
retrieving revision 1.137
diff -u -r1.137 e-cell-text.c
--- e-cell-text.c	10 Jun 2004 15:29:14 -0000	1.137
+++ e-cell-text.c	8 Dec 2004 09:04:25 -0000
@@ -59,6 +59,7 @@
 
 #define d(x)
 #define DO_SELECTION 1
+#define VIEW_TO_CELL(view) E_CELL_TEXT (((ECellView *)view)->ecell)
 
 #if d(!)0
 #define e_table_item_leave_edit_(x) (e_table_item_leave_edit((x)), g_print ("%s: e_table_item_leave_edit\n", __FUNCTION__))
@@ -94,6 +95,15 @@
 	E_SELECTION_CLIPBOARD
 };
 
+/* signals */
+enum {
+	TEXT_INSERTED,
+	TEXT_DELETED,
+	LAST_SIGNAL
+};
+
+static guint signals [LAST_SIGNAL] = { 0 };
+
 static GdkAtom clipboard_atom = GDK_NONE;
 
 #define PARENT_TYPE e_cell_get_type ()
@@ -1698,6 +1708,28 @@
 
 	parent_class = g_type_class_ref (PARENT_TYPE);
 
+	signals [TEXT_INSERTED] = 
+		g_signal_new ("text_inserted",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (ECellTextClass, text_inserted),
+			      NULL, NULL,
+			      e_marshal_VOID__POINTER_INT_INT,
+			      G_TYPE_NONE, 3,
+			      G_TYPE_POINTER, G_TYPE_INT, G_TYPE_INT);
+
+	signals [TEXT_DELETED] = 
+		g_signal_new ("text_deleted",
+			      G_TYPE_FROM_CLASS (object_class),
+			      G_SIGNAL_RUN_FIRST,
+			      G_STRUCT_OFFSET (ECellTextClass, text_deleted),
+			      NULL, NULL,
+			      e_marshal_VOID__POINTER_INT_INT,
+			      G_TYPE_NONE, 3,
+			      G_TYPE_POINTER, G_TYPE_INT, G_TYPE_INT);
+
+
+
 	g_object_class_install_property (object_class, PROP_STRIKEOUT_COLUMN,
 					 g_param_spec_int ("strikeout_column",
 							   _("Strikeout Column"),
@@ -2182,6 +2214,8 @@
 	memmove (sp, ep, length);
 
 	edit->selection_end = edit->selection_start;
+
+	g_signal_emit (VIEW_TO_CELL (text_view), signals[TEXT_DELETED], 0, text_view, edit->selection_start, ep-sp);
 }
 
 /* fixme: */
@@ -2209,6 +2243,8 @@
 
 	edit->selection_start += value;
 	edit->selection_end = edit->selection_start;
+
+	 g_signal_emit (VIEW_TO_CELL (text_view), signals[TEXT_INSERTED], 0, text_view, edit->selection_end-value, value);
 }
 
 static void
@@ -2778,3 +2814,39 @@
 	command.position = E_TEP_SELECTION;
 	e_cell_text_view_command (edit->tep, &command, edit);
 }
+
+/**
+ * e_cell_text_get_text_by_view:
+ * @cell_view: the given cell view
+ * @col: column of the given cell in the model
+ * @row: row of the given cell in the model
+ * 
+ * Get the cell's text directly from CellEdit,
+ * during editting this cell, the cell's text value maybe inconsistant
+ * with the text got from table_model.
+ * The caller should free the text after using it.
+ *
+ * This API is most likely to be used by a11y implementations.
+ */
+char *
+e_cell_text_get_text_by_view (ECellView *cell_view, gint col, gint row)
+{
+	ECellTextView *ectv;
+	CellEdit *edit;
+	gchar	*ret, *model_text;
+
+	ectv = (ECellTextView *)cell_view;
+	edit = ectv->edit;
+	
+	if (edit) { /* being editted now */
+		ret = g_strdup (edit->text);
+	} else{
+		model_text = e_cell_text_get_text (E_CELL_TEXT (cell_view->ecell), 
+					     cell_view->e_table_model, col, row);
+		ret = g_strdup (model_text);
+		e_cell_text_free_text (E_CELL_TEXT (cell_view->ecell), model_text);
+	}
+
+	return ret;
+
+}
Index: e-cell-text.h
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-text.h,v
retrieving revision 1.32
diff -u -r1.32 e-cell-text.h
--- e-cell-text.h	2 Dec 2003 07:20:04 -0000	1.32
+++ e-cell-text.h	8 Dec 2004 09:04:26 -0000
@@ -84,6 +84,9 @@
 	char *(*get_text)  (ECellText *cell, ETableModel *model, int col, int row);
 	void  (*free_text) (ECellText *cell, char *text);
 	void  (*set_value) (ECellText *cell, ETableModel *model, int col, int row, const char *text);
+	/* signal handlers */
+	void (*text_inserted) (ECellText *cell, ECellView *cell_view, int pos, int len);
+	void (*text_deleted)  (ECellText *cell, ECellView *cell_view, int pos, int len);
 } ECellTextClass;
 
 GType      e_cell_text_get_type (void);
@@ -116,6 +119,9 @@
 /* Deletes selected text */
 void e_cell_text_delete_selection (ECellView *cell_view, gint col, gint row);
 
+/* get text directly from view, both col and row are model format */
+char *e_cell_text_get_text_by_view (ECellView *cell_view, gint col, gint row);
+
 G_END_DECLS
 
 #endif /* _E_CELL_TEXT_H_ */
Index: e-cell-toggle.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-toggle.c,v
retrieving revision 1.40
diff -u -r1.40 e-cell-toggle.c
--- e-cell-toggle.c	10 Jun 2004 15:29:14 -0000	1.40
+++ e-cell-toggle.c	8 Dec 2004 09:04:27 -0000
@@ -201,7 +201,7 @@
 	
 	selected = flags & E_CELL_SELECTED;
 
-	if (value >= toggle->n_states){
+	if (value < 0 || value >= toggle->n_states){
 		g_warning ("Value from the table model is %d, the states we support are [0..%d)\n",
 			   value, toggle->n_states);
 		return;
Index: e-cell-vbox.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-vbox.c,v
retrieving revision 1.4
diff -u -r1.4 e-cell-vbox.c
--- e-cell-vbox.c	17 Nov 2002 00:02:53 -0000	1.4
+++ e-cell-vbox.c	8 Dec 2004 09:04:31 -0000
@@ -42,18 +42,13 @@
 #include <gdk/gdkkeysyms.h>
 
 #include "gal/util/e-util.h"
+#include "gal/a11y/e-table/gal-a11y-e-cell-registry.h"
+#include "gal/a11y/e-table/gal-a11y-e-cell-vbox.h"
 #include "e-table-item.h"
 #include "e-cell-vbox.h"
 
 #define PARENT_TYPE e_cell_get_type ()
 
-typedef struct {
-	ECellView     cell_view;
-	int           subcell_view_count;
-	ECellView   **subcell_views;
-	int          *model_cols;
-} ECellVboxView;
-
 static ECellClass *parent_class;
 
 #define INDENT_AMOUNT 16
@@ -443,6 +438,8 @@
 #endif
 
 	parent_class = g_type_class_ref (PARENT_TYPE);
+
+	gal_a11y_e_cell_registry_add_cell_type (NULL, E_CELL_VBOX_TYPE, gal_a11y_e_cell_vbox_new);
 }
 
 static void
Index: e-cell-vbox.h
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-vbox.h,v
retrieving revision 1.3
diff -u -r1.3 e-cell-vbox.h
--- e-cell-vbox.h	17 Nov 2002 00:02:53 -0000	1.3
+++ e-cell-vbox.h	8 Dec 2004 09:04:31 -0000
@@ -50,6 +50,13 @@
 } ECellVbox;
 
 typedef struct {
+	ECellView     cell_view;
+	int           subcell_view_count;
+	ECellView   **subcell_views;
+	int          *model_cols;
+} ECellVboxView;
+
+typedef struct {
 	ECellClass parent_class;
 } ECellVboxClass;
 
Index: e-table-click-to-add.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-click-to-add.c,v
retrieving revision 1.39
diff -u -r1.39 e-table-click-to-add.c
--- e-table-click-to-add.c	10 Jun 2004 15:29:14 -0000	1.39
+++ e-table-click-to-add.c	8 Dec 2004 09:04:37 -0000
@@ -27,6 +27,8 @@
 #include <libgnomecanvas/gnome-canvas.h>
 #include <libgnomecanvas/gnome-canvas-util.h>
 #include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
+#include <atk/atkobject.h>
+#include <glib/gi18n.h>
 #include <gdk-pixbuf/gdk-pixbuf.h>
 #include <atk/atkregistry.h>
 
@@ -44,6 +46,7 @@
 
 enum {
 	CURSOR_CHANGE,
+	STYLE_SET,
 	LAST_SIGNAL
 };
 
@@ -73,6 +76,26 @@
 }
 
 static void
+etcta_style_set (ETableClickToAdd *etcta, GtkStyle *previous_style)
+{
+	GtkWidget *widget = GTK_WIDGET(GNOME_CANVAS_ITEM(etcta)->canvas);
+
+	if (etcta->rect) {
+		gnome_canvas_item_set (etcta->rect,
+					"outline_color_gdk", &widget->style->fg[GTK_STATE_NORMAL], 
+					"fill_color_gdk", &widget->style->bg[GTK_STATE_NORMAL],
+					NULL );
+
+	}
+
+	if (etcta->text)
+		gnome_canvas_item_set (etcta->text,
+					"fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL],
+					NULL);
+
+}
+
+static void
 etcta_add_table_header (ETableClickToAdd *etcta, ETableHeader *header)
 {
 	etcta->eth = header;
@@ -215,6 +238,33 @@
 }
 
 static void
+create_rect_and_text (ETableClickToAdd *etcta)
+{
+	GtkWidget *widget = GTK_WIDGET (GNOME_CANVAS_ITEM(etcta)->canvas);
+
+	if (!etcta->rect)
+		etcta->rect = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etcta),
+					    gnome_canvas_rect_get_type(),
+					    "x1", (double) 0,
+					    "y1", (double) 0,
+					    "x2", (double) etcta->width - 1,
+					    "y2", (double) etcta->height - 1,
+					    "outline_color_gdk", &widget->style->fg[GTK_STATE_NORMAL], 
+					    "fill_color_gdk", &widget->style->bg[GTK_STATE_NORMAL],
+					    NULL);
+
+	if (!etcta->text)
+		etcta->text = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etcta),
+					    e_text_get_type(),
+					    "text", etcta->message ? etcta->message : "",
+					    "anchor", GTK_ANCHOR_NW,
+					    "width", etcta->width - 4,
+					    "draw_background", FALSE,
+					    "fill_color_gdk", &widget->style->text[GTK_STATE_NORMAL],
+					    NULL);
+}
+
+static void
 etcta_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
 {
 	ETableClickToAdd *etcta;
@@ -248,23 +298,7 @@
 {
 	ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
 
-	etcta->rect = gnome_canvas_item_new(GNOME_CANVAS_GROUP(item),
-					    gnome_canvas_rect_get_type(),
-					    "x1", (double) 0,
-					    "y1", (double) 0,
-					    "x2", (double) etcta->width - 1,
-					    "y2", (double) etcta->height - 1,
-					    "outline_color", "black", 
-					    "fill_color", "white",
-					    NULL);
-
-	etcta->text = gnome_canvas_item_new(GNOME_CANVAS_GROUP(item),
-					    e_text_get_type(),
-					    "text", etcta->message ? etcta->message : "",
-					    "anchor", GTK_ANCHOR_NW,
-					    "width", etcta->width - 4,
-					    "draw_background", FALSE,
-					    NULL);
+	create_rect_and_text (etcta);
 	e_canvas_item_move_absolute (etcta->text, 2, 2);
 
 	if (GNOME_CANVAS_ITEM_CLASS (etcta_parent_class)->realize)
@@ -448,6 +482,7 @@
 	etcta_parent_class = g_type_class_ref (PARENT_OBJECT_TYPE);
 
 	klass->cursor_change = NULL;
+	klass->style_set     = etcta_style_set;
 
 	object_class->dispose      = etcta_dispose;
 	object_class->set_property = etcta_set_property;
@@ -501,6 +536,16 @@
 			      e_marshal_VOID__INT_INT,
 			      G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_INT);
 
+	etcta_signals [STYLE_SET] =
+		g_signal_new ("style_set",
+			      G_OBJECT_CLASS_TYPE (object_class),
+			      G_SIGNAL_RUN_LAST,
+			      G_STRUCT_OFFSET (ETableClickToAddClass, style_set),
+			      NULL, NULL,
+			      e_marshal_NONE__OBJECT,
+			      G_TYPE_NONE, 1, GTK_TYPE_STYLE);
+
+
 	atk_registry_set_factory_type (atk_get_default_registry (),
 					E_TABLE_CLICK_TO_ADD_TYPE,
 					gal_a11y_e_table_click_to_add_factory_get_type ());
@@ -511,6 +556,7 @@
 etcta_init (GnomeCanvasItem *item)
 {
 	ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
+	AtkObject *a11y;
 
 	etcta->one = NULL;
 	etcta->model = NULL;
@@ -527,6 +573,12 @@
 			 G_CALLBACK (etcta_cursor_change), etcta);
 
 	e_canvas_item_set_reflow_callback(item, etcta_reflow);
+
+	/* create its a11y object at this time if accessibility is enabled*/
+	if (atk_get_root () != NULL) {
+        	atk_gobject_accessible_for_object (etcta);
+		atk_object_set_name (a11y, _("click to add"));
+	}
 }
 
 E_MAKE_TYPE(e_table_click_to_add, "ETableClickToAdd", ETableClickToAdd, etcta_class_init, etcta_init, PARENT_OBJECT_TYPE)
@@ -549,25 +601,6 @@
 		gtk_object_destroy(GTK_OBJECT (etcta->row));
 		etcta->row = NULL;
 	}
-	if (!etcta->rect) {
-		etcta->rect = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etcta),
-						    gnome_canvas_rect_get_type(),
-						    "x1", (double) 0,
-						    "y1", (double) 0,
-						    "x2", (double) etcta->width - 1,
-						    "y2", (double) etcta->height - 1,
-						    "outline_color", "black",
-						    "fill_color", "white",
-						    NULL);
-	}
-	if (!etcta->text) {
-		etcta->text = gnome_canvas_item_new(GNOME_CANVAS_GROUP(etcta),
-						    e_text_get_type(),
-						    "text", etcta->message ? etcta->message : "",
-						    "anchor", GTK_ANCHOR_NW,
-						    "width", etcta->width - 4,
-						    "draw_background", FALSE,
-						    NULL);
-		e_canvas_item_move_absolute (etcta->text, 3, 3);
-	}
+	create_rect_and_text (etcta);
+	e_canvas_item_move_absolute (etcta->text, 3, 3);
 }
Index: e-table-click-to-add.h
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-click-to-add.h,v
retrieving revision 1.9
diff -u -r1.9 e-table-click-to-add.h
--- e-table-click-to-add.h	15 Nov 2002 02:22:00 -0000	1.9
+++ e-table-click-to-add.h	8 Dec 2004 09:04:37 -0000
@@ -66,6 +66,7 @@
 	 * signals
 	 */
 	void (*cursor_change) (ETableClickToAdd *etcta, gint row, gint col);
+	void (*style_set) (ETableClickToAdd *etcta, GtkStyle *previous_style);
 } ETableClickToAddClass;
 
 GType      e_table_click_to_add_get_type (void);
Index: e-table-config.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-config.c,v
retrieving revision 1.66
diff -u -r1.66 e-table-config.c
--- e-table-config.c	4 Aug 2004 09:16:19 -0000	1.66
+++ e-table-config.c	8 Dec 2004 09:05:16 -0000
@@ -947,6 +947,11 @@
 	int i;
 
 	e_table_selected_row_foreach (config->shown, add_column, &columns);
+
+	/* if no columns left, just return */
+	if (columns == NULL)
+		return;
+
 	columns = g_list_reverse (columns);
 
 	new_shown = g_new (int, config->temp_state->col_count);
@@ -998,6 +1003,11 @@
 
 	e_table_selected_row_foreach (config->shown, add_column, &columns);
 
+	/* if no columns left, just return */
+	if (columns == NULL)
+		return;
+
+
 	new_shown = g_new (int, config->temp_state->col_count);
 	new_expansions = g_new (double, config->temp_state->col_count);
 
Index: e-table-group-container.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-group-container.c,v
retrieving revision 1.66
diff -u -r1.66 e-table-group-container.c
--- e-table-group-container.c	8 Apr 2003 14:36:55 -0000	1.66
+++ e-table-group-container.c	8 Dec 2004 09:05:44 -0000
@@ -59,6 +59,7 @@
 	PROP_UNIFORM_ROW_HEIGHT
 };
 
+/*
 typedef struct {
 	ETableGroup *child;
 	void *key;
@@ -67,6 +68,7 @@
 	GnomeCanvasItem *rect;
 	gint count;
 } ETableGroupContainerChildNode;
+*/
 
 static EPrintable *
 etgc_get_printable (ETableGroup *etg);
Index: e-table-group-container.h
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-group-container.h,v
retrieving revision 1.19
diff -u -r1.19 e-table-group-container.h
--- e-table-group-container.h	17 Nov 2002 00:02:53 -0000	1.19
+++ e-table-group-container.h	8 Dec 2004 09:05:44 -0000
@@ -84,6 +84,16 @@
 	ETableGroupClass parent_class;
 } ETableGroupContainerClass;
 
+typedef struct {
+        ETableGroup *child;
+        void *key;
+        char *string;
+        GnomeCanvasItem *text;
+        GnomeCanvasItem *rect;
+        gint count;
+} ETableGroupContainerChildNode;
+
+
 ETableGroup *e_table_group_container_new       (GnomeCanvasGroup *parent, ETableHeader *full_header, ETableHeader     *header,
 						ETableModel *model, ETableSortInfo *sort_info, int n);
 void         e_table_group_container_construct (GnomeCanvasGroup *parent, ETableGroupContainer *etgc,
Index: e-table-item.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table-item.c,v
retrieving revision 1.237
diff -u -r1.237 e-table-item.c
--- e-table-item.c	10 Jun 2004 15:29:14 -0000	1.237
+++ e-table-item.c	8 Dec 2004 09:06:12 -0000
@@ -44,6 +44,7 @@
 #include "gal/widgets/e-canvas.h"
 #include "gal/widgets/e-canvas-utils.h"
 #include "gal/util/e-util.h"
+#include "gal/a11y/e-table/gal-a11y-e-table-item.h"
 #include "gal/util/e-i18n.h"
 #include <string.h>
 #include <stdlib.h>
@@ -1647,6 +1648,7 @@
 	eti->cursor_y2                 = -1;
 
 	eti->rows                      = -1;
+	eti->cols                      = -1;
 
 	eti->frozen_count              = 0;
 	eti->queue_show_cursor         = FALSE;
@@ -2669,9 +2671,10 @@
 		case GDK_KP_Down:
 			if ((e->key.state & GDK_MOD1_MASK)
 			    && ((e->key.keyval == GDK_Down ) || (e->key.keyval == GDK_KP_Down))) {
-				gint view_col = model_to_view_col(eti, cursor_col);
-				if (eti_e_cell_event (eti, eti->cell_views [view_col], e, ((GdkEventKey *)e)->time, cursor_col, view_col, model_to_view_row(eti, cursor_row),  E_CELL_CURSOR))
-					return TRUE;
+				gint view_col = model_to_view_col(eti, cursor_col);				
+				if ((view_col >= 0) && (view_col < eti->cols))
+					if (eti_e_cell_event (eti, eti->cell_views [view_col], e, ((GdkEventKey *)e)->time, cursor_col, view_col, model_to_view_row(eti, cursor_row),  E_CELL_CURSOR))
+						return TRUE;
 			} else
 			return_val = e_selection_model_key_press(E_SELECTION_MODEL (eti->selection), (GdkEventKey *) e);
 			break;
@@ -3124,10 +3127,8 @@
 			      G_TYPE_NONE, 1,
 			      G_TYPE_POINTER);
 
-        atk_registry_set_factory_type (atk_get_default_registry (),
-				       E_TABLE_ITEM_TYPE,
-				       gal_a11y_e_table_item_factory_get_type ());
-
+	/* A11y Init */
+	gal_a11y_e_table_item_init ();
 }
 
 E_MAKE_TYPE (e_table_item,
Index: e-table.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-table.c,v
retrieving revision 1.232
diff -u -r1.232 e-table.c
--- e-table.c	24 Nov 2004 10:34:55 -0000	1.232
+++ e-table.c	8 Dec 2004 09:06:47 -0000
@@ -1126,6 +1126,14 @@
         	focus_first_etable_item (etable->group);
 	} else if (canvas->focused_item) {
 		ESelectionModel *selection = (ESelectionModel *)etable->selection;
+
+		/* check whether click_to_add already got the focus */
+		if (etable->click_to_add) {
+			GnomeCanvasItem *row = E_TABLE_CLICK_TO_ADD(etable->click_to_add)->row;
+			if (canvas->focused_item == row)
+				return TRUE;
+		}
+
 		if (e_selection_model_cursor_row (selection) == -1)
 			focus_first_etable_item (etable->group);
 	}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]