[evolution-patches] gal , a11y e-cell-toggle, HEAD



Hi Mike and all,

The patch is for a11y of toggle cell. After the patch I can toggle the the new mail toggle
in message list with at-poke. Please review.

First, the patch introduce a a11y object for e-cell-toggle in gal-a11y-e-cell-toggle.[ch] (a11y.diff).
toggle.diff just register the atk object in e-cell-toggle.c.

And we also introduce a collection of helper funtion in gal-a11y-e-cell.c:
gal_a11y_e_cell_type_add_action_interface ();
gal_a11y_e_cell_add_action    ();
gal_a11y_e_cell_remove_action ();
gal_a11y_e_cell_remove_action_by_name ();

The toggle's action interface is actually added by these helper functions.

The idea and code is actually stealed from gailcell.c. Because many cell may have an action interface, to write an action interface for each cell involve a lot of similiar code. The help
function is here to resolve the problem.

gal_a11y_e_cell_type_add_action_interface () just add an action interface,
which query a internal link list for available action. when intial the link list is empty, so there is actually no actions. Later gal_a11y_e_cell_add_action () add info into the
internal link list, so the actuall action is added into the list.

The action of toggle, is just emulate a mouse click event on the cell.


Regards
York







Index: e-cell-toggle.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-toggle.c,v
retrieving revision 1.38
diff -u -r1.38 e-cell-toggle.c
--- e-cell-toggle.c	12 Aug 2003 22:39:49 -0000	1.38
+++ e-cell-toggle.c	26 Oct 2003 03:48:34 -0000
@@ -32,6 +32,7 @@
 #include "gal/util/e-util.h"
 #include "gal/widgets/e-hsv-utils.h"
 #include "e-table-item.h"
+#include "gal/a11y/e-table/gal-a11y-e-cell-toggle.h"
 
 #define PARENT_TYPE e_cell_get_type ()
 
@@ -414,6 +415,9 @@
 	ecc->style_set  = etog_style_set;
 
 	parent_class = g_type_class_ref (PARENT_TYPE);
+	gal_a11y_e_cell_registry_add_cell_type (NULL,
+                                                E_CELL_TOGGLE_TYPE,
+                                                gal_a11y_e_cell_toggle_new);
 }
 
 static void
Index: Makefile.am
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/Makefile.am,v
retrieving revision 1.3
diff -u -r1.3 Makefile.am
--- Makefile.am	11 Oct 2003 02:59:24 -0000	1.3
+++ Makefile.am	26 Oct 2003 03:53:38 -0000
@@ -15,6 +15,7 @@
 	gal-a11y-e-tree-factory.c		\
 	gal-a11y-e-cell.c			\
 	gal-a11y-e-cell-text.c			\
+	gal-a11y-e-cell-toggle.c		\
 	gal-a11y-e-cell-registry.c		\
 	gal-a11y-e-table.c			\
 	gal-a11y-e-table-item.c			\
@@ -28,6 +29,7 @@
 	gal-a11y-e-tree-factory.h		\
 	gal-a11y-e-cell.h			\
 	gal-a11y-e-cell-text.h			\
+	gal-a11y-e-cell-toggle.h		\
 	gal-a11y-e-cell-registry.h		\
 	gal-a11y-e-table.h			\
 	gal-a11y-e-table-item.h			\
Index: gal-a11y-e-cell-toggle.c
===================================================================
RCS file: gal-a11y-e-cell-toggle.c
diff -N gal-a11y-e-cell-toggle.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gal-a11y-e-cell-toggle.c	26 Oct 2003 03:53:38 -0000
@@ -0,0 +1,105 @@
+#include <gtk/gtk.h>
+#include "gal-a11y-e-cell-toggle.h"
+#include <gal/e-table/e-cell-toggle.h>
+#include <gal/e-table/e-table-model.h>
+
+static void gal_a11y_e_cell_toggle_class_init (GalA11yECellToggleClass *klass);
+
+GType
+gal_a11y_e_cell_toggle_get_type (void)
+{
+  static GType type = 0;
+
+  if (!type)
+    {
+      static const GTypeInfo tinfo =
+      {
+        sizeof (GalA11yECellToggleClass),
+        (GBaseInitFunc) NULL, /* base init */
+        (GBaseFinalizeFunc) NULL, /* base finalize */
+        (GClassInitFunc) gal_a11y_e_cell_toggle_class_init, /* class init */
+        (GClassFinalizeFunc) NULL, /* class finalize */
+        NULL, /* class data */
+        sizeof (GalA11yECellToggle), /* instance size */
+        0, /* nb preallocs */
+        NULL, /* instance init */
+        NULL /* value table */
+      };
+                                                                                
+
+      type = g_type_register_static (GAL_A11Y_TYPE_E_CELL,
+                                     "GalA11yECellToggle", &tinfo, 0);
+      gal_a11y_e_cell_type_add_action_interface (type);
+	
+    }
+  return type;
+}
+
+
+static void 
+gal_a11y_e_cell_toggle_class_init (GalA11yECellToggleClass *klass)
+{
+}
+
+static void
+toggle_cell_action (GalA11yECell *cell)
+{
+	ECellToggle * ect;
+	gint finished;
+	GdkEventButton event;
+	gint x, y, width, height;
+	gint row, col;
+
+	row = cell->row;
+	col = cell->view_col;
+
+	e_table_item_get_cell_geometry (cell->item, &row, &col,
+					&x, &y, &width, &height);
+	event.x = x ;
+	event.y = y ;
+	event.type = GDK_BUTTON_PRESS;
+	event.window = GTK_LAYOUT(GNOME_CANVAS_ITEM(cell->item)->canvas)->bin_window;
+        event.button = 1;
+        event.send_event = TRUE;
+        event.time = GDK_CURRENT_TIME;
+        event.axes = NULL;
+
+	g_signal_emit_by_name (cell->item, "event", &event, &finished);
+}
+
+AtkObject* 
+gal_a11y_e_cell_toggle_new (ETableItem *item,
+			    ECellView  *cell_view,
+			    AtkObject  *parent,
+			    int         model_col,
+			    int         view_col,
+			    int         row)
+{
+	AtkObject *a11y;
+	GalA11yECell *cell;
+	GalA11yECellToggle *toggle_cell;
+
+	a11y = ATK_OBJECT(g_object_new (GAL_A11Y_TYPE_E_CELL_TOGGLE, NULL));
+
+	g_return_val_if_fail (a11y != NULL, NULL);
+
+	cell = GAL_A11Y_E_CELL(a11y);
+	toggle_cell = GAL_A11Y_E_CELL_TOGGLE(a11y);
+	a11y->role  = ATK_ROLE_TABLE_CELL;
+
+        gal_a11y_e_cell_construct (a11y,
+                                   item,
+                                   cell_view,
+                                   parent,
+                                   model_col,
+                                   view_col,
+                                   row);
+
+	gal_a11y_e_cell_add_action (cell, 
+				    "toggle",	       /* action name*/
+				    "toggle the cell", /* action description */
+				    NULL,              /* action keybinding */
+				    toggle_cell_action);
+
+	return a11y;
+}
Index: gal-a11y-e-cell-toggle.h
===================================================================
RCS file: gal-a11y-e-cell-toggle.h
diff -N gal-a11y-e-cell-toggle.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ gal-a11y-e-cell-toggle.h	26 Oct 2003 03:53:38 -0000
@@ -0,0 +1,47 @@
+#ifndef __GAL_A11Y_E_CELL_TOGGLE_H__
+#define __GAL_A11Y_E_CELL_TOGGLE_H__
+
+#include <atk/atk.h>
+#include "gal-a11y-e-cell.h"
+#include "gal-a11y-e-cell-toggle.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GAL_A11Y_TYPE_E_CELL_TOGGLE            (gal_a11y_e_cell_toggle_get_type ())
+#define GAL_A11Y_E_CELL_TOGGLE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_TOGGLE, GalA11yECellToggle))
+#define GAL_A11Y_E_CELL_TOGGLE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_E_CELL_TOGGLE, GalA11yECellToggleClass))
+#define GAL_A11Y_IS_E_CELL_TOGGLE(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_TOGGLE))
+#define GAL_A11Y_IS_E_CELL_TOGGLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_TOGGLE))
+#define GAL_A11Y_E_CELL_TOGGLE_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GAL_A11Y_TYPE_E_CELL_TOGGLE, GalA11yECellToggleClass))
+
+typedef struct _GalA11yECellToggle                  GalA11yECellToggle;
+typedef struct _GalA11yECellToggleClass             GalA11yECellToggleClass;
+
+struct _GalA11yECellToggle
+{
+  GalA11yECell parent;
+  gboolean cell_value;
+};
+
+GType gal_a11y_e_cell_toggle_get_type (void);
+
+struct _GalA11yECellToggleClass
+{
+  GalA11yECellClass parent_class;
+};
+
+AtkObject *gal_a11y_e_cell_toggle_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_TOGGLE_H__ */
Index: gal-a11y-e-cell.c
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell.c,v
retrieving revision 1.2
diff -u -r1.2 gal-a11y-e-cell.c
--- gal-a11y-e-cell.c	11 Oct 2003 02:59:24 -0000	1.2
+++ gal-a11y-e-cell.c	26 Oct 2003 03:53:38 -0000
@@ -11,6 +11,7 @@
 #include "gal-a11y-util.h"
 #include <atk/atkobject.h>
 #include <atk/atkcomponent.h>
+#include <atk/atkaction.h>
 
 #define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yECellClass))
 static GObjectClass *parent_class;
@@ -143,6 +144,250 @@
 	a11y->view_col = -1;
 	a11y->row = -1;
 }
+
+
+static ActionInfo *
+_gal_a11y_e_cell_get_action_info (GalA11yECell *cell,
+                            gint     index)
+{
+	GList *list_node;
+                                                                                
+	g_return_val_if_fail (GAL_A11Y_IS_E_CELL (cell), NULL);
+	if (cell->action_list == NULL)
+		return NULL;
+	list_node = g_list_nth (cell->action_list, index);
+	if (!list_node)
+		return NULL;
+	return (ActionInfo *) (list_node->data);
+}
+
+static void
+_gal_a11y_e_cell_destroy_action_info (gpointer action_info,
+				      gpointer user_data)
+{
+	ActionInfo *info = (ActionInfo *)action_info;
+
+	g_return_if_fail (info != NULL);
+	g_free (info->name);
+	g_free (info->description);
+	g_free (info->keybinding);
+	g_free (info);
+}
+
+
+gboolean
+gal_a11y_e_cell_add_action ( GalA11yECell * cell,
+			     const gchar *action_name,
+			     const gchar *action_description,
+			     const gchar *action_keybinding,
+			     ACTION_FUNC action_func)
+{
+	ActionInfo *info;
+	g_return_val_if_fail (GAL_A11Y_IS_E_CELL (cell), FALSE);
+	info = g_new (ActionInfo, 1);
+                                                                              
+	if (action_name != NULL)
+		info->name = g_strdup (action_name);
+	else
+		info->name = NULL;
+
+	if (action_description != NULL)
+		info->description = g_strdup (action_description);
+	else
+		info->description = NULL;
+	if (action_keybinding != NULL)
+		info->keybinding = g_strdup (action_keybinding);
+	else
+		info->keybinding = NULL;
+	info->do_action_func = action_func;
+
+	cell->action_list = g_list_append (cell->action_list, (gpointer) info);
+	return TRUE;
+}
+
+gboolean
+gal_a11y_e_cell_remove_action (GalA11yECell *cell,
+			       gint     action_index)
+{
+	GList *list_node;
+
+	g_return_val_if_fail (GAL_A11Y_IS_E_CELL (cell), FALSE);
+	list_node = g_list_nth (cell->action_list, action_index);
+	if (!list_node)
+		return FALSE;
+	g_return_val_if_fail (list_node->data != NULL, FALSE);
+	_gal_a11y_e_cell_destroy_action_info (list_node->data, NULL);
+	cell->action_list = g_list_remove_link (cell->action_list, list_node);
+
+	return TRUE;
+}
+
+gboolean
+gal_a11y_e_cell_remove_action_by_name (GalA11yECell *cell,
+				       const gchar *action_name)
+{
+	GList *list_node;
+	gboolean action_found= FALSE;
+                                                                               
+	g_return_val_if_fail (GAL_A11Y_IS_E_CELL (cell), FALSE);
+	for (list_node = cell->action_list; list_node && !action_found;
+          	          list_node = list_node->next) {
+		if (!g_strcasecmp (((ActionInfo *)(list_node->data))->name, action_name)) {
+			action_found = TRUE;
+			break;
+		}
+	}
+
+	g_return_val_if_fail (action_found, FALSE);
+	_gal_a11y_e_cell_destroy_action_info (list_node->data, NULL);
+	cell->action_list = g_list_remove_link (cell->action_list, list_node);
+
+	return TRUE;
+}
+
+static gint
+gal_a11y_e_cell_action_get_n_actions (AtkAction *action)
+{
+	GalA11yECell *cell = GAL_A11Y_E_CELL(action);
+	if (cell->action_list != NULL)
+		return g_list_length (cell->action_list);
+	else
+		return 0;
+}
+
+static G_CONST_RETURN gchar *
+gal_a11y_e_cell_action_get_name (AtkAction *action,
+                           gint      index)
+{
+	GalA11yECell *cell = GAL_A11Y_E_CELL(action);
+	ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index);
+                                                                                
+	if (info == NULL)
+		return NULL;
+	return info->name;
+}
+
+static G_CONST_RETURN gchar *
+gal_a11y_e_cell_action_get_description (AtkAction *action,
+					gint      index)
+{
+	GalA11yECell *cell = GAL_A11Y_E_CELL(action);
+	ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index);
+
+	if (info == NULL)
+		return NULL;
+	return info->description;
+}
+
+static gboolean
+gal_a11y_e_cell_action_set_description (AtkAction   *action,
+					gint        index,
+					const gchar *desc)
+{
+	GalA11yECell *cell = GAL_A11Y_E_CELL(action);
+	ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index);
+                                                                                
+	if (info == NULL)
+		return FALSE;
+	g_free (info->description);
+	info->description = g_strdup (desc);
+	return TRUE;
+}
+
+static G_CONST_RETURN gchar *
+gal_a11y_e_cell_action_get_keybinding (AtkAction *action,
+				       gint      index)
+{
+	GalA11yECell *cell = GAL_A11Y_E_CELL(action);
+	ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index);
+	if (info == NULL)
+		return NULL;
+
+	return info->keybinding;
+}
+                                                                                
+static gboolean
+idle_do_action (gpointer data)
+{
+	GalA11yECell *cell;
+
+	cell = GAL_A11Y_E_CELL (data);
+	cell->action_idle_handler = 0;
+	cell->action_func (cell);
+                                                                                
+	return FALSE;
+}
+
+static gboolean
+gal_a11y_e_cell_action_do_action (AtkAction *action,
+				  gint      index)
+{
+	GalA11yECell *cell = GAL_A11Y_E_CELL(action);
+	ActionInfo *info = _gal_a11y_e_cell_get_action_info (cell, index);
+
+	if (info == NULL)
+		return FALSE;
+	g_return_val_if_fail (info->do_action_func, FALSE);
+	if (cell->action_idle_handler)
+		return FALSE;
+	cell->action_func = info->do_action_func;
+	cell->action_idle_handler = g_idle_add (idle_do_action, cell);
+
+	return TRUE;
+}
+
+static void
+gal_a11y_e_cell_atk_action_interface_init (AtkActionIface *iface)
+{
+  g_return_if_fail (iface != NULL);
+                                                                                
+  iface->get_n_actions = gal_a11y_e_cell_action_get_n_actions;
+  iface->do_action = gal_a11y_e_cell_action_do_action;
+  iface->get_name = gal_a11y_e_cell_action_get_name;
+  iface->get_description = gal_a11y_e_cell_action_get_description;
+  iface->set_description = gal_a11y_e_cell_action_set_description;
+  iface->get_keybinding = gal_a11y_e_cell_action_get_keybinding;
+}
+
+void
+gal_a11y_e_cell_type_add_action_interface (GType type)
+{
+	static const GInterfaceInfo atk_action_info =
+	{
+	(GInterfaceInitFunc) gal_a11y_e_cell_atk_action_interface_init,
+	(GInterfaceFinalizeFunc) NULL,
+	NULL
+	};
+
+	g_type_add_interface_static (type, ATK_TYPE_ACTION,
+				     &atk_action_info);
+}
+
+gboolean
+gal_a11y_e_cell_add_state (GalA11yECell     *cell,
+			   AtkStateType state_type,
+			   gboolean     emit_signal)
+{
+	if (!atk_state_set_contains_state (cell->state_set, state_type)) {
+		gboolean rc;
+                                                                                
+		rc = atk_state_set_add_state (cell->state_set, state_type);
+		/*
+		 * The signal should only be generated if the value changed,
+		 * not when the cell is set up.  So states that are set
+		 * initially should pass FALSE as the emit_signal argument.
+		 */
+                                                                                
+		if (emit_signal) {
+			atk_object_notify_state_change (ATK_OBJECT (cell), state_type, TRUE);
+			/* If state_type is ATK_STATE_VISIBLE, additional 
+			   notification */
+			if (state_type == ATK_STATE_VISIBLE)
+				g_signal_emit_by_name (cell, "visible_data_changed");
+		}
+	}
+}
+
 
 /**
  * gal_a11y_e_cell_get_type:
Index: gal-a11y-e-cell.h
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell.h,v
retrieving revision 1.1
diff -u -r1.1 gal-a11y-e-cell.h
--- gal-a11y-e-cell.h	30 Nov 2002 07:54:15 -0000	1.1
+++ gal-a11y-e-cell.h	26 Oct 2003 03:53:39 -0000
@@ -22,6 +22,9 @@
 typedef struct _GalA11yECell GalA11yECell;
 typedef struct _GalA11yECellClass GalA11yECellClass;
 typedef struct _GalA11yECellPrivate GalA11yECellPrivate;
+typedef struct _ActionInfo ActionInfo;
+typedef void (*ACTION_FUNC) (GalA11yECell *cell);
+
 
 /* This struct should actually be larger as this isn't what we derive from.
  * The GalA11yECellPrivate comes right after the parent class structure.
@@ -35,12 +38,24 @@
 	int         model_col;
 	int         view_col;
 	int         row;
+	AtkStateSet *state_set;
+	GList       *action_list;
+	gint         action_idle_handler;
+	ACTION_FUNC  action_func;
 };
 
 struct _GalA11yECellClass {
 	AtkObjectClass parent_class;
 };
 
+struct _ActionInfo {
+	gchar *name;
+	gchar *description;
+	gchar *keybinding;
+	ACTION_FUNC do_action_func;
+};
+
+
 
 /* Standard Glib function */
 GType      gal_a11y_e_cell_get_type   (void);
@@ -57,5 +72,20 @@
 				       int         model_col,
 				       int         view_col,
 				       int         row);
+
+void	gal_a11y_e_cell_type_add_action_interface (GType type);
+                                                                                
+gboolean gal_a11y_e_cell_add_action	(GalA11yECell	*cell,
+				         const gchar     *action_name,
+					 const gchar     *action_description,
+					 const gchar     *action_keybinding,
+					 ACTION_FUNC     action_func);
+                                                                                
+gboolean gal_a11y_e_cell_remove_action	(GalA11yECell	*cell,
+                                         gint           action_id);
+                                                                                
+gboolean gal_a11y_e_cell_remove_action_by_name (GalA11yECell        *cell,
+                                          	const gchar     *action_name);
+
 
 #endif /* ! __GAL_A11Y_E_CELL_H__ */
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gal/ChangeLog,v
retrieving revision 1.812
diff -u -r1.812 ChangeLog
--- ChangeLog	14 Oct 2003 18:20:17 -0000	1.812
+++ ChangeLog	26 Oct 2003 12:58:32 -0000
@@ -1,3 +1,32 @@
+2003-10-26  Yuedong Du  <yuedong du sun com>
+
+	* gal/a11y/e-table/Makefile.am: add new file for toggle cell a11y 
+	 object.
+	* gal/a11y/e-table/gal-a11y-e-cell-toggle.c: new a11y object toggle cell
+	(gal_a11y_e_cell_toggle_get_type),
+	(gal_a11y_e_cell_toggle_class_init), (toggle_cell_action), the
+	implementation of toggle cell action.
+	(gal_a11y_e_cell_toggle_new):
+	* gal/a11y/e-table/gal-a11y-e-cell-toggle.h: ditto
+	* gal/a11y/e-table/gal-a11y-e-cell.c:
+	(_gal_a11y_e_cell_get_action_info),
+	(_gal_a11y_e_cell_destroy_action_info),
+	(gal_a11y_e_cell_add_action), (gal_a11y_e_cell_remove_action),
+	(gal_a11y_e_cell_remove_action_by_name),
+	(gal_a11y_e_cell_action_get_n_actions),
+	(gal_a11y_e_cell_action_get_name),
+	(gal_a11y_e_cell_action_get_description),
+	(gal_a11y_e_cell_action_set_description),
+	(gal_a11y_e_cell_action_get_keybinding), (idle_do_action),
+	(gal_a11y_e_cell_action_do_action),
+	(gal_a11y_e_cell_atk_action_interface_init),
+	(gal_a11y_e_cell_type_add_action_interface),
+	(gal_a11y_e_cell_add_state): helper functions for add a action, 
+	stealed from gailcell.c
+	* gal/a11y/e-table/gal-a11y-e-cell.h:
+	* gal/e-table/e-cell-toggle.c: (e_cell_toggle_class_init): register
+	toggle's a11y object.
+
 2003-10-14  Suresh Chandrasekharan  <suresh chandrasekharan sun com>
 	
 	* Support for preedit in e-text widgets.


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