[evolution-patches] gal, gnopernicus can't read the cell in settings dialog's left navigation pane.



Hi,
   The attachment is a patch for bug #61688,  which is a accessibility related bug.
Steps to reproduce the problem:
1. start evolution with accessibility enabled;
2. Click Tools->Settings;
3. Start gnopernicus, then click the left navigation pane's cell to read
its text.

Actual Results:
gnopernicus can only read "TAB".

Expected Results:
gnopernicus should read the cell's text, such as "Mail Accounts".

The bug's reason is that the navigation pane's e-cell is an e-cell-vbox,
which consists of several subcells. So it can't be treated as a generic e-cell, and
the corresponding AtkObject of e-cell-vbox should be implemented.

In the attachment, I implemented the a11y of e-cell-vbox and modified some relevant
files, please help review, thanks.

Regards,
Eric
-- 
Eric Zhao <eric zhao sun com>

Public Key: http://pgp.mit.edu:11371/pks/lookup?op=get&search=0xE3225516
Key fingerprint = EA12 D205 D359 A98D E63E  CAC3 C2A7 30B1 E322 5516
Index: a11y/e-table/Makefile.am
===================================================================
RCS file: /cvs/gnome/gal/gal/a11y/e-table/Makefile.am,v
retrieving revision 1.7
diff -u -p -r1.7 Makefile.am
--- a11y/e-table/Makefile.am	17 Dec 2003 02:35:20 -0000	1.7
+++ a11y/e-table/Makefile.am	17 Jul 2004 13:27:38 -0000
@@ -19,6 +19,7 @@ libgal_a11y_etable_la_SOURCES =			\
 	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 @@ libgal_a11y_etableinclude_HEADERS =		\
 	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: e-table/e-cell-vbox.c
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-vbox.c,v
retrieving revision 1.4
diff -u -p -r1.4 e-cell-vbox.c
--- e-table/e-cell-vbox.c	17 Nov 2002 00:02:53 -0000	1.4
+++ e-table/e-cell-vbox.c	17 Jul 2004 13:27:38 -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 @@ e_cell_vbox_class_init (GObjectClass *ob
 #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-table/e-cell-vbox.h
===================================================================
RCS file: /cvs/gnome/gal/gal/e-table/e-cell-vbox.h,v
retrieving revision 1.3
diff -u -p -r1.3 e-cell-vbox.h
--- e-table/e-cell-vbox.h	17 Nov 2002 00:02:53 -0000	1.3
+++ e-table/e-cell-vbox.h	17 Jul 2004 13:27:38 -0000
@@ -50,6 +50,13 @@ typedef struct {
 } ECellVbox;
 
 typedef struct {
+	ECellView     cell_view;
+	int           subcell_view_count;
+	ECellView   **subcell_views;
+	int          *model_cols;
+} ECellVboxView;
+
+typedef struct {
 	ECellClass parent_class;
 } ECellVboxClass;
 
/* 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 AtkObjectClass *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,
				i, /* FIXME should the view column use a fake one or the same as its parent? */
				row);
			gaev->a11y_subcells[i] = 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);
}

/* 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;
}
/* 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__ */


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