diff options
-rw-r--r-- | a11y/e-table/gal-a11y-e-cell-toggle.c | 105 | ||||
-rw-r--r-- | a11y/e-table/gal-a11y-e-cell-toggle.h | 47 | ||||
-rw-r--r-- | a11y/e-table/gal-a11y-e-cell.c | 245 | ||||
-rw-r--r-- | a11y/e-table/gal-a11y-e-cell.h | 30 | ||||
-rw-r--r-- | widgets/table/e-cell-toggle.c | 4 |
5 files changed, 431 insertions, 0 deletions
diff --git a/a11y/e-table/gal-a11y-e-cell-toggle.c b/a11y/e-table/gal-a11y-e-cell-toggle.c new file mode 100644 index 0000000000..2daa7e7271 --- /dev/null +++ b/a11y/e-table/gal-a11y-e-cell-toggle.c @@ -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; +} diff --git a/a11y/e-table/gal-a11y-e-cell-toggle.h b/a11y/e-table/gal-a11y-e-cell-toggle.h new file mode 100644 index 0000000000..9a740d7d84 --- /dev/null +++ b/a11y/e-table/gal-a11y-e-cell-toggle.h @@ -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__ */ diff --git a/a11y/e-table/gal-a11y-e-cell.c b/a11y/e-table/gal-a11y-e-cell.c index a4ad363533..db4135bf1d 100644 --- a/a11y/e-table/gal-a11y-e-cell.c +++ b/a11y/e-table/gal-a11y-e-cell.c @@ -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; @@ -144,6 +145,250 @@ eti_init (GalA11yECell *a11y) 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: * @void: diff --git a/a11y/e-table/gal-a11y-e-cell.h b/a11y/e-table/gal-a11y-e-cell.h index ff9e5162d8..81f5f147ca 100644 --- a/a11y/e-table/gal-a11y-e-cell.h +++ b/a11y/e-table/gal-a11y-e-cell.h @@ -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 @@ struct _GalA11yECell { 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); @@ -58,4 +73,19 @@ void gal_a11y_e_cell_construct (AtkObject *object, 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__ */ diff --git a/widgets/table/e-cell-toggle.c b/widgets/table/e-cell-toggle.c index fbb68ac951..de113488e3 100644 --- a/widgets/table/e-cell-toggle.c +++ b/widgets/table/e-cell-toggle.c @@ -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 @@ e_cell_toggle_class_init (GtkObjectClass *object_class) 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 |