[evolution-patches] gal, e-table accessiblity, handle of row-inserted and row-deleted signal, HEAD
- From: Yuedong Du <yuedong du sun com>
- To: Mike Kestner <mkestner ximian com>, evolution-patches ximian com
- Subject: [evolution-patches] gal, e-table accessiblity, handle of row-inserted and row-deleted signal, HEAD
- Date: Fri, 07 Nov 2003 11:47:46 +0800
Hi Mike and all,
The patch is mainly for handle the model's row-inserted and deleted signal.
after the patch, when insert expand a collapsed tree, you can find the new
added tree-cells in at-poke. Please review.
I use an arrary to cache the previously ref-ed a11y object in table.
In table's ref_at method, the object will be ref-ed one more time if it
is found
in cache. And all returned a11y object is weak refed. when it is destoryed
the listener update the cache correspondingly.
After rows-inserted signal is received , it will realloc the array and
then deprecate
cells below the place where rows are inserted. Then send a11y of table item
"row-inserted" and "children_changed:add" signal.
When rows-deleted signal is received, deprecate the rows below where rows
are deleted. Then send row-deleted signal to table's a11y object.
The patch add ref_state_set implementation in cell's a11y object. The idea
is largely copied from gailcell.c.
The patch also has a trival change that modify the the previous miss
prefixed
functions in gal-a11y-e-cell.c.
Regards
York
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gal/ChangeLog,v
retrieving revision 1.818
diff -u -r1.818 ChangeLog
--- ChangeLog 3 Nov 2003 06:55:14 -0000 1.818
+++ ChangeLog 7 Nov 2003 02:50:47 -0000
@@ -1,3 +1,25 @@
+2003-11-07 Yuedong Du <yuedong du sun com>
+
+ * gal/a11y/e-table/gal-a11y-e-cell-text.c: (ect_get_text): sanity test
+ on the text.
+ * gal/a11y/e-table/gal-a11y-e-cell.c: (gal_a11y_e_cell_dispose),
+ (gal_a11y_e_cell_get_parent),
+ (gal_a11y_e_cell_get_index_in_parent),
+ (gal_a11y_e_cell_get_extents), (gal_a11y_e_cell_grab_focus),
+ (gal_a11y_e_cell_atk_component_iface_init),
+ (gal_a11y_e_cell_ref_state_set), implement the ref_state_set method.
+ (gal_a11y_e_cell_class_init),
+ (gal_a11y_e_cell_init), (gal_a11y_e_cell_remove_state),
+ (gal_a11y_e_cell_get_type):
+ Change the prefix of these functions from 'eti' to 'gal_a11y_e_cell'.
+ * gal/a11y/e-table/gal-a11y-e-cell.h:
+ * gal/a11y/e-table/gal-a11y-e-table-item.c: (eti_dispose),
+ (cell_destroyed), (eti_ref_at), (eti_rows_inserted), handle the
+ rows-inserted sigal
+ (eti_rows_deleted), handle the rows-deleted signal.
+ (eti_real_initialize), (eti_class_init),
+ (gal_a11y_e_table_item_new):
+
2003-11-03 Bolian Yin <bolian yin sun com>
* gal/a11y/e-table/gal-a11y-e-table-item: defunct widget checking, selection interface
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.2
diff -u -r1.2 gal-a11y-e-cell-text.c
--- gal/a11y/e-table/gal-a11y-e-cell-text.c 3 May 2003 17:05:29 -0000 1.2
+++ gal/a11y/e-table/gal-a11y-e-cell-text.c 7 Nov 2003 02:50:47 -0000
@@ -34,6 +34,9 @@
char *full_text =
e_cell_text_get_text (ect, gaec->item->table_model, gaec->model_col, gaec->row);
+ if (full_text == NULL)
+ return NULL;
+
if (end_offset == -1)
end_offset = strlen (full_text);
else
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.4
diff -u -r1.4 gal-a11y-e-cell.c
--- gal/a11y/e-table/gal-a11y-e-cell.c 3 Nov 2003 04:20:10 -0000 1.4
+++ gal/a11y/e-table/gal-a11y-e-cell.c 7 Nov 2003 02:50:47 -0000
@@ -38,7 +38,7 @@
#endif
static void
-eti_dispose (GObject *object)
+gal_a11y_e_cell_dispose (GObject *object)
{
GalA11yECell *a11y = GAL_A11Y_E_CELL (object);
@@ -57,20 +57,23 @@
a11y->view_col = -1;
a11y->row = -1;
+ if (a11y->state_set)
+ g_object_unref (a11y->state_set);
+
if (parent_class->dispose)
parent_class->dispose (object);
}
/* Static functions */
static AtkObject*
-eti_get_parent (AtkObject *accessible)
+gal_a11y_e_cell_get_parent (AtkObject *accessible)
{
GalA11yECell *a11y = GAL_A11Y_E_CELL (accessible);
return a11y->parent;
}
static gint
-eti_get_index_in_parent (AtkObject *accessible)
+gal_a11y_e_cell_get_index_in_parent (AtkObject *accessible)
{
GalA11yECell *a11y = GAL_A11Y_E_CELL (accessible);
@@ -80,7 +83,7 @@
/* Component IFace */
static void
-eti_get_extents (AtkComponent *component,
+gal_a11y_e_cell_get_extents (AtkComponent *component,
gint *x,
gint *y,
gint *width,
@@ -114,7 +117,7 @@
}
static gboolean
-eti_grab_focus (AtkComponent *component)
+gal_a11y_e_cell_grab_focus (AtkComponent *component)
{
GalA11yECell *a11y;
gint view_row;
@@ -136,28 +139,41 @@
/* Table IFace */
static void
-eti_atk_component_iface_init (AtkComponentIface *iface)
+gal_a11y_e_cell_atk_component_iface_init (AtkComponentIface *iface)
+{
+ iface->get_extents = gal_a11y_e_cell_get_extents;
+ iface->grab_focus = gal_a11y_e_cell_grab_focus;
+}
+
+
+static AtkStateSet *
+gal_a11y_e_cell_ref_state_set (AtkObject *obj)
{
- iface->get_extents = eti_get_extents;
- iface->grab_focus = eti_grab_focus;
+ GalA11yECell *cell = GAL_A11Y_E_CELL (obj);
+ g_return_val_if_fail (cell->state_set, NULL);
+
+ g_object_ref(cell->state_set);
+ return cell->state_set;
}
+
static void
-eti_class_init (GalA11yECellClass *klass)
+gal_a11y_e_cell_class_init (GalA11yECellClass *klass)
{
AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
GObjectClass *object_class = G_OBJECT_CLASS (klass);
parent_class = g_type_class_ref (PARENT_TYPE);
- object_class->dispose = eti_dispose;
+ object_class->dispose = gal_a11y_e_cell_dispose;
- atk_object_class->get_parent = eti_get_parent;
- atk_object_class->get_index_in_parent = eti_get_index_in_parent;
+ atk_object_class->get_parent = gal_a11y_e_cell_get_parent;
+ atk_object_class->get_index_in_parent = gal_a11y_e_cell_get_index_in_parent;
+ atk_object_class->ref_state_set = gal_a11y_e_cell_ref_state_set;
}
static void
-eti_init (GalA11yECell *a11y)
+gal_a11y_e_cell_init (GalA11yECell *a11y)
{
a11y->item = NULL;
a11y->cell_view = NULL;
@@ -165,6 +181,9 @@
a11y->model_col = -1;
a11y->view_col = -1;
a11y->row = -1;
+ 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);
}
@@ -410,6 +429,34 @@
}
}
+gboolean
+gal_a11y_e_cell_remove_state (GalA11yECell *cell,
+ AtkStateType state_type,
+ gboolean emit_signal)
+{
+ if (atk_state_set_contains_state (cell->state_set, state_type))
+ {
+ gboolean rc;
+ AtkObject *parent;
+
+ rc = atk_state_set_remove_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, FALSE); /* If state_type is ATK_STATE_VISIBLE, additional notification */
+ if (state_type == ATK_STATE_VISIBLE)
+ g_signal_emit_by_name (cell, "visible_data_changed");
+ }
+ }
+ else
+ return FALSE;
+}
+
/**
* gal_a11y_e_cell_get_type:
@@ -430,17 +477,17 @@
sizeof (GalA11yECellClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
- (GClassInitFunc) eti_class_init,
+ (GClassInitFunc) gal_a11y_e_cell_class_init,
(GClassFinalizeFunc) NULL,
NULL, /* class_data */
sizeof (GalA11yECell),
0,
- (GInstanceInitFunc) eti_init,
+ (GInstanceInitFunc) gal_a11y_e_cell_init,
NULL /* value_cell */
};
static const GInterfaceInfo atk_component_info = {
- (GInterfaceInitFunc) eti_atk_component_iface_init,
+ (GInterfaceInitFunc) gal_a11y_e_cell_atk_component_iface_init,
(GInterfaceFinalizeFunc) NULL,
NULL
};
Index: gal/a11y/e-table/gal-a11y-e-cell.h
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/gal-a11y-e-cell.h,v
retrieving revision 1.2
diff -u -r1.2 gal-a11y-e-cell.h
--- gal/a11y/e-table/gal-a11y-e-cell.h 28 Oct 2003 05:41:03 -0000 1.2
+++ gal/a11y/e-table/gal-a11y-e-cell.h 7 Nov 2003 02:50:47 -0000
@@ -87,5 +87,9 @@
gboolean gal_a11y_e_cell_remove_action_by_name (GalA11yECell *cell,
const gchar *action_name);
+gboolean gal_a11y_e_cell_add_state (GalA11yECell *cell,
+ AtkStateType state_type,
+ gboolean emit_signal);
+
#endif /* ! __GAL_A11Y_E_CELL_H__ */
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.2
diff -u -r1.2 gal-a11y-e-table-item.c
--- gal/a11y/e-table/gal-a11y-e-table-item.c 3 Nov 2003 06:40:50 -0000 1.2
+++ gal/a11y/e-table/gal-a11y-e-table-item.c 7 Nov 2003 02:50:48 -0000
@@ -10,6 +10,7 @@
#include <config.h>
#include "gal-a11y-e-table-item.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>
@@ -32,6 +33,7 @@
struct _GalA11yETableItemPrivate {
AtkObject *parent;
gint index_in_parent;
+ gpointer *cell_data;
};
#if 0
@@ -74,16 +76,13 @@
static void
eti_dispose (GObject *object)
{
+ gint i,j;
GalA11yETableItem *a11y = GAL_A11Y_E_TABLE_ITEM (object);
GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y);
-#if 0
- if (priv->item)
- g_object_weak_unref (G_OBJECT (priv->item), unref_accessible, a11y);
+ g_free (priv->cell_data);
+ priv->cell_data = NULL;
- if (priv->parent)
- g_object_unref (priv->parent);
-#endif
priv->parent = NULL;
if (parent_class->dispose)
@@ -223,11 +222,33 @@
/* atk table */
+static void
+cell_destroyed (gpointer data)
+{
+ AtkObject *parent;
+ gint index, n_cols;
+ GalA11yETableItem * item;
+ GalA11yECell * cell;
+
+ g_return_if_fail (GAL_A11Y_IS_E_CELL (data));
+
+ parent = atk_object_get_parent (ATK_OBJECT (data));
+
+ item = GAL_A11Y_E_TABLE_ITEM(parent);
+ if (item == NULL)
+ return;
+
+ index = cell->row * cell->item->cols + cell->view_col;
+
+ if (GET_PRIVATE (item)->cell_data [index])
+ GET_PRIVATE (item)->cell_data [index] = NULL;
+}
static AtkObject*
eti_ref_at (AtkTable *table, gint row, gint column)
{
ETableItem *item;
+ AtkObject* ret;
item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
if (!item)
@@ -240,13 +261,30 @@
item->cell_views_realized) {
ECellView *cell_view = item->cell_views[column];
ETableCol *ecol = e_table_header_get_column (item->header, column);
- return gal_a11y_e_cell_registry_get_object (NULL,
+ gpointer * cell_data;
+
+ cell_data = GET_PRIVATE (table)->cell_data;
+
+ if (cell_data[row*item->cols + column] == NULL) {
+ ret = gal_a11y_e_cell_registry_get_object (NULL,
item,
cell_view,
ATK_OBJECT (table),
ecol->col_idx,
column,
row);
+ cell_data[row*item->cols + column] = ret;
+ g_object_weak_ref (G_OBJECT (ret),
+ (GWeakNotify) cell_destroyed,
+ ret);
+
+ } else {
+ ret = (AtkObject *) cell_data[row*item->cols + column];
+ g_object_ref (ret);
+ }
+
+
+ return ret;
}
return NULL;
@@ -524,6 +562,101 @@
}
static void
+eti_rows_inserted (ETableModel * model, int row, int count,
+ AtkObject * table_item)
+{
+ gint n_cols,n_rows,i,j;
+ gint size;
+ gpointer *cell_data;
+ ETableItem *item = E_TABLE_ITEM (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (table_item)));
+
+ n_cols = atk_table_get_n_columns (ATK_TABLE(table_item));
+ n_rows = atk_table_get_n_rows (ATK_TABLE(table_item));
+
+ g_return_if_fail (n_cols > 0 && n_rows > 0);
+
+ cell_data = GET_PRIVATE(table_item)->cell_data;
+ GET_PRIVATE(table_item)->cell_data = g_realloc (cell_data, sizeof(gpointer)*(n_rows*n_cols));
+ cell_data = GET_PRIVATE(table_item)->cell_data;
+ /* Initialize new added mem to 0s. */
+ for (i = 0 ; i < count; i ++) {
+ for (j = 0 ; j < n_cols; j ++) {
+ cell_data [(n_rows-i-1)*n_cols+j] = NULL;
+ }
+ }
+
+ for (i = row; i < (n_rows-count); i ++) {
+ for (j = 0; j < n_cols; j ++)
+ if (cell_data[i*n_cols + j] != NULL) {
+ AtkObject * a11y;
+
+ a11y = ATK_OBJECT(cell_data[i*n_cols + j]);
+ gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL(a11y), ATK_STATE_STALE, TRUE);
+ cell_data[i*n_cols + j] = NULL;
+ }
+ }
+
+ for (i = row; i < (row + count); i ++) {
+ for (j = 0; j < n_cols; j ++) {
+ g_signal_emit_by_name (table_item,
+ "children_changed::add",
+ ( (i*n_cols) + j), NULL, NULL);
+ }
+ }
+
+ g_signal_emit_by_name (table_item, "visible-data-changed");
+}
+
+static void
+eti_rows_deleted (ETableModel * model, int row, int count,
+ AtkObject * table_item)
+{
+ gint i,j, n_rows,n_cols;
+ gpointer *cell_data;
+ ETableItem *item = E_TABLE_ITEM (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (table_item)));
+
+ n_rows = atk_table_get_n_rows (ATK_TABLE(table_item));
+ n_cols = atk_table_get_n_columns (ATK_TABLE(table_item));
+
+ cell_data = GET_PRIVATE(table_item)->cell_data;
+
+ for (i = row; i < (n_rows + count); i ++) {
+ for (j = 0; j < n_cols; j ++)
+ if (cell_data[i*n_cols + j] != NULL) {
+ AtkObject * a11y;
+
+ a11y = ATK_OBJECT(cell_data[i*n_cols + j]);
+ gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL(a11y), ATK_STATE_STALE, TRUE);
+ cell_data[i*n_cols + j] = NULL;
+ }
+ }
+
+ g_signal_emit_by_name (table_item, "row-deleted", row,
+ count, NULL);
+ g_signal_emit_by_name (table_item, "visible-data-changed");
+}
+
+static void
+eti_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ ETableItem * eti;
+ ETableModel * model;
+
+ ATK_OBJECT_CLASS (parent_class)->initialize (obj, data);
+ eti = E_TABLE_ITEM (data);
+
+ model = eti->table_model;
+
+ g_signal_connect (model, "model-rows-inserted",
+ G_CALLBACK (eti_rows_inserted),
+ obj);
+ g_signal_connect (model, "model-rows-deleted",
+ G_CALLBACK (eti_rows_deleted),
+ obj);
+}
+
+static void
eti_class_init (GalA11yETableItemClass *klass)
{
AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
@@ -539,6 +672,7 @@
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;
}
static void
@@ -633,6 +767,7 @@
int index_in_parent)
{
GalA11yETableItem *a11y;
+ int n;
a11y = g_object_new (gal_a11y_e_table_item_get_type (), NULL);
@@ -640,6 +775,10 @@
GET_PRIVATE (a11y)->parent = parent;
GET_PRIVATE (a11y)->index_in_parent = index_in_parent;
+
+ /* Initialize cell data. */
+ n = item->cols * item->rows;
+ GET_PRIVATE (a11y)->cell_data = g_malloc0(n*sizeof(gpointer));
if (parent)
g_object_ref (parent);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]