[evolution-patches] gal, accessiblity, etable, handle the columns change (add/delete/reorder)
- From: Yuedong Du <yuedong du sun com>
- To: Evolution Patches <evolution-patches ximian com>, Mike Kestner <mkestner ximian com>
- Subject: [evolution-patches] gal, accessiblity, etable, handle the columns change (add/delete/reorder)
- Date: Mon, 24 Nov 2003 14:25:45 +0800
Hi Mike,
The patch fix bug 49594.
It work by listen to table header's structure change signal.
By comparing table header with previously saved one, we know what
actually happened.
column insert or delete or reorder. Then we manipulate the cache to
reflect the new conditions.
Regards
York
Index: 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.2
diff -u -r1.2 gal-a11y-e-cell-toggle.c
--- gal-a11y-e-cell-toggle.c 21 Nov 2003 04:28:04 -0000 1.2
+++ gal-a11y-e-cell-toggle.c 24 Nov 2003 06:14:59 -0000
@@ -13,11 +13,6 @@
{
GalA11yECellToggle *a11y = GAL_A11Y_E_CELL_TOGGLE (object);
- ETableModel *e_table_model = GAL_A11Y_E_CELL (a11y)->cell_view->e_table_model;
-
- if (e_table_model)
- g_signal_handler_disconnect (e_table_model, a11y->model_id);
-
if (parent_class->dispose)
parent_class->dispose (object);
}
Index: 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.5
diff -u -r1.5 gal-a11y-e-table-item.c
--- gal-a11y-e-table-item.c 21 Nov 2003 04:28:04 -0000 1.5
+++ gal-a11y-e-table-item.c 24 Nov 2003 06:15:00 -0000
@@ -38,6 +38,7 @@
gpointer *cell_data;
int selection_change_id;
int cursor_change_id;
+ ETableCol ** columns;
};
#if 0
@@ -91,6 +92,11 @@
priv->cell_data = NULL;
}
+ if (priv->columns) {
+ g_free(priv->columns);
+ priv->columns = NULL;
+ }
+
if (parent_class->dispose)
parent_class->dispose (object);
}
@@ -706,6 +712,151 @@
g_signal_emit_by_name (table_item, "visible-data-changed");
}
+enum {
+ ETI_HEADER_UNCHANGED = 0,
+ ETI_HEADER_REORDERED,
+ ETI_HEADER_NEW_ADDED,
+ ETI_HEADER_REMOVED,
+};
+
+/*
+ * 1. Check what actually happened: column reorder, remove or add
+ * 2. Update cache
+ * 3. Emit signals
+ */
+static void
+eti_header_structure_changed (ETableHeader *eth, AtkObject *a11y)
+{
+
+ gboolean reorder_found=FALSE, added_found=FALSE, removed_found=FALSE;
+ GalA11yETableItem * a11y_item;
+ ETableCol ** cols, **prev_cols;
+ GalA11yETableItemPrivate *priv;
+ gint *state = NULL, *prev_state = NULL, *reorder = NULL;
+ gint i,j,n_rows,n_cols, prev_n_cols;
+ gpointer * cell_data, * tmp;
+
+ a11y_item = GAL_A11Y_E_TABLE_ITEM (a11y);
+ priv = GET_PRIVATE (a11y_item);
+
+ g_return_if_fail (priv && priv->cell_data);
+ cell_data = priv->cell_data ;
+
+ /* Assume rows do not changed. */
+ n_rows = priv->rows;
+
+ prev_n_cols = priv->cols;
+ prev_cols = priv->columns;
+
+ cols = e_table_header_get_columns (eth);
+ n_cols = eth->col_count;
+
+ g_return_if_fail (cols && prev_cols && n_cols > 0);
+
+ /* Init to ETI_HEADER_UNCHANGED. */
+ state = g_malloc0 (sizeof (gint) * n_cols);
+ prev_state = g_malloc0 (sizeof (gint) * prev_n_cols);
+ reorder = g_malloc0 (sizeof (gint) * n_cols);
+ g_return_if_fail (state && reorder && prev_state);
+
+ /* Compare with previously saved column headers. */
+ for ( i = 0 ; i < n_cols && cols[i]; i ++ ) {
+ for ( j = 0 ; j < prev_n_cols && prev_cols[j]; j ++ ) {
+ if ( prev_cols [j] == cols[i] && i != j ) {
+
+ reorder_found = TRUE;
+ state [i] = ETI_HEADER_REORDERED;
+ reorder [i] = j;
+
+ break;
+ } else if (prev_cols[j] == cols[i]) {
+ /* OK, this column is not changed. */
+ break;
+ }
+ }
+
+ /* cols[i] is new added column. */
+ if ( j == prev_n_cols ) {
+ gint row;
+
+ added_found = TRUE;
+ state[i] = ETI_HEADER_NEW_ADDED;
+ }
+ }
+
+ /* Now try to find if there are removed columns. */
+ for (i = 0 ; i < prev_n_cols && prev_cols[i]; i ++) {
+ for (j = 0 ; j < n_cols && cols[j]; j ++)
+ if ( prev_cols [j] == cols[i] )
+ break;
+
+ /* Removed columns found. */
+ if ( j == n_cols ) {
+ removed_found = TRUE;
+ prev_state[j] = ETI_HEADER_REMOVED;
+ }
+ }
+
+ /* If nothing interesting just return. */
+ if (!reorder_found && !added_found && !removed_found)
+ return;
+
+ /* Now update our cache. */
+ tmp = g_malloc0 (n_rows*n_cols*sizeof(gpointer));
+ g_return_if_fail (tmp);
+
+ for (i = 0 ; i < n_rows; i ++) {
+ for ( j = 0 ; j < n_cols; j ++ ) {
+ if ( state[j] == ETI_HEADER_REORDERED ) {
+ tmp [i*n_cols+j] = cell_data[i*prev_n_cols+reorder[j]];
+ if (tmp[i*n_cols+j] && ATK_IS_OBJECT(tmp[i*n_cols+j])) {
+ GAL_A11Y_E_CELL(tmp[i*n_cols+j])->view_col = j;
+ }
+ } else if (state[j] == ETI_HEADER_UNCHANGED) {
+ tmp [i*n_cols+j] = cell_data[i*prev_n_cols+j];
+ } /* else: new added, keep NULL. */
+ }
+ }
+
+ g_free (cell_data);
+ priv->cell_data = tmp;
+
+ /* Emit signals */
+ if (reorder_found)
+ g_signal_emit_by_name (G_OBJECT(a11y_item), "column_reordered");
+
+
+ if (removed_found) {
+ for (i = 0; i < prev_n_cols; i ++ ) {
+ if (prev_state[i] == ETI_HEADER_REMOVED) {
+ g_signal_emit_by_name (G_OBJECT(a11y_item), "column-deleted", i, 1);
+ for (j = 0 ; j < n_rows; j ++)
+ g_signal_emit_by_name (G_OBJECT(a11y_item), "children_changed::remove", (j*prev_n_cols+i), NULL, NULL);
+ }
+ }
+ }
+
+ if (added_found) {
+ for ( i = 0; i < n_cols; i ++ ) {
+ if (state[i] == ETI_HEADER_NEW_ADDED) {
+ g_signal_emit_by_name (G_OBJECT(a11y_item), "column-inserted", i, 1);
+ for (j = 0 ; j < n_rows; j ++)
+ g_signal_emit_by_name (G_OBJECT(a11y_item), "children_changed::add", (j*n_cols+i), NULL, NULL);
+ }
+ }
+ }
+
+ priv->cols = n_cols;
+
+ g_free (state);
+ g_free (reorder);
+ g_free (prev_state);
+
+ g_free (priv->columns);
+ priv->columns = cols;
+}
+
+
static void
eti_real_initialize (AtkObject *obj,
gpointer data)
@@ -724,6 +875,9 @@
g_signal_connect (model, "model-rows-deleted",
G_CALLBACK (eti_rows_deleted),
obj);
+ g_signal_connect (G_OBJECT (eti->header), "structure_change",
+ G_CALLBACK (eti_header_structure_changed), obj);
+
}
static void
@@ -868,6 +1022,10 @@
/* memory error. */
if ( GET_PRIVATE (a11y) == NULL)
return NULL;
+
+ GET_PRIVATE (a11y)->columns = e_table_header_get_columns (item->header);
+ if ( GET_PRIVATE (a11y)->columns == NULL)
+ return NULL;
if (item) {
g_signal_connect (G_OBJECT(item), "selection_model_removed",
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]