aboutsummaryrefslogtreecommitdiffstats
path: root/widgets
diff options
context:
space:
mode:
authorMilan Crha <mcrha@redhat.com>2009-05-20 22:50:00 +0800
committerMilan Crha <mcrha@redhat.com>2009-05-20 22:50:00 +0800
commitf4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81 (patch)
tree1c0228db536f5fa0efc6e0f779bb86df610989d0 /widgets
parent3acc45b10c9849aa5385a762b4d139472916dca1 (diff)
downloadgsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.tar.gz
gsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.tar.zst
gsoc2013-evolution-f4cf9af33ccde3142a3011e8b2dbcfb4cbc9ae81.zip
Use -no-undefined on Linux too
There still left two things opened, search for KILL-BONOBO to find them. One is in calendar's Makefile.am, one in composer.
Diffstat (limited to 'widgets')
-rw-r--r--widgets/Makefile.am4
-rw-r--r--widgets/menus/gal-view-collection.c2
-rw-r--r--widgets/menus/gal-view-instance.c2
-rw-r--r--widgets/menus/gal-view-new-dialog.c2
-rw-r--r--widgets/misc/Makefile.am43
-rw-r--r--widgets/misc/a11y/ea-calendar-cell.c387
-rw-r--r--widgets/misc/a11y/ea-calendar-cell.h90
-rw-r--r--widgets/misc/a11y/ea-calendar-item.c1314
-rw-r--r--widgets/misc/a11y/ea-calendar-item.h72
-rw-r--r--widgets/misc/a11y/ea-widgets.c32
-rw-r--r--widgets/misc/a11y/ea-widgets.h32
-rw-r--r--widgets/misc/e-calendar-item.c2
-rw-r--r--widgets/misc/e-search-bar.c2
-rw-r--r--widgets/misc/e-unicode.c2052
-rw-r--r--widgets/misc/e-unicode.h113
-rw-r--r--widgets/table/Makefile.am52
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-popup.c144
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-popup.h62
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-registry.c149
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-registry.h72
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-text.c737
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-text.h64
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-toggle.c191
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-toggle.h68
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-tree.c260
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-tree.h64
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-vbox.c225
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell-vbox.h67
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell.c644
-rw-r--r--widgets/table/a11y/gal-a11y-e-cell.h113
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-click-to-add-factory.c106
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-click-to-add-factory.h50
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-click-to-add.c344
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-click-to-add.h55
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-column-header.c229
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-column-header.h55
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-factory.c99
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-factory.h51
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-item-factory.c105
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-item-factory.h50
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-item.c1327
-rw-r--r--widgets/table/a11y/gal-a11y-e-table-item.h59
-rw-r--r--widgets/table/a11y/gal-a11y-e-table.c308
-rw-r--r--widgets/table/a11y/gal-a11y-e-table.h59
-rw-r--r--widgets/table/a11y/gal-a11y-e-tree-factory.c98
-rw-r--r--widgets/table/a11y/gal-a11y-e-tree-factory.h50
-rw-r--r--widgets/table/a11y/gal-a11y-e-tree.c191
-rw-r--r--widgets/table/a11y/gal-a11y-e-tree.h58
-rw-r--r--widgets/table/e-cell-combo.c2
-rw-r--r--widgets/table/e-cell-date-edit.c (renamed from widgets/misc/e-cell-date-edit.c)6
-rw-r--r--widgets/table/e-cell-date-edit.h (renamed from widgets/misc/e-cell-date-edit.h)0
-rw-r--r--widgets/table/e-cell-date.c2
-rw-r--r--widgets/table/e-cell-hbox.c4
-rw-r--r--widgets/table/e-cell-percent.c (renamed from widgets/misc/e-cell-percent.c)0
-rw-r--r--widgets/table/e-cell-percent.h (renamed from widgets/misc/e-cell-percent.h)0
-rw-r--r--widgets/table/e-cell-popup.c4
-rw-r--r--widgets/table/e-cell-text.c6
-rw-r--r--widgets/table/e-cell-toggle.c4
-rw-r--r--widgets/table/e-cell-tree.c4
-rw-r--r--widgets/table/e-cell-vbox.c4
-rw-r--r--widgets/table/e-table-click-to-add.c2
-rw-r--r--widgets/table/e-table-config.c2
-rw-r--r--widgets/table/e-table-group-container.c2
-rw-r--r--widgets/table/e-table-header-utils.c2
-rw-r--r--widgets/table/e-table-item.c4
-rw-r--r--widgets/table/e-table-utils.c2
-rw-r--r--widgets/table/e-table.c4
-rw-r--r--widgets/table/e-tree.c2
-rw-r--r--widgets/text/Makefile.am21
-rw-r--r--widgets/text/a11y/gal-a11y-e-text-factory.c101
-rw-r--r--widgets/text/a11y/gal-a11y-e-text-factory.h50
-rw-r--r--widgets/text/a11y/gal-a11y-e-text.c1134
-rw-r--r--widgets/text/a11y/gal-a11y-e-text.h57
-rw-r--r--widgets/text/e-reflow-model.c (renamed from widgets/misc/e-reflow-model.c)0
-rw-r--r--widgets/text/e-reflow-model.h (renamed from widgets/misc/e-reflow-model.h)0
-rw-r--r--widgets/text/e-reflow.c (renamed from widgets/misc/e-reflow.c)8
-rw-r--r--widgets/text/e-reflow.h (renamed from widgets/misc/e-reflow.h)2
-rw-r--r--widgets/text/e-text.c4
78 files changed, 9534 insertions, 2254 deletions
diff --git a/widgets/Makefile.am b/widgets/Makefile.am
index 347c0f7c66..99305b844e 100644
--- a/widgets/Makefile.am
+++ b/widgets/Makefile.am
@@ -1,9 +1,9 @@
SUBDIRS = \
- table \
- text \
misc \
+ text \
e-timezone-dialog \
+ table \
menus
EXTRA_DIST = \
diff --git a/widgets/menus/gal-view-collection.c b/widgets/menus/gal-view-collection.c
index 890ee3ea7f..9541f0fb9c 100644
--- a/widgets/menus/gal-view-collection.c
+++ b/widgets/menus/gal-view-collection.c
@@ -33,7 +33,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "e-util/e-xml-utils.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "gal-view-collection.h"
diff --git a/widgets/menus/gal-view-instance.c b/widgets/menus/gal-view-instance.c
index 19ec402fa3..40a9e5262a 100644
--- a/widgets/menus/gal-view-instance.c
+++ b/widgets/menus/gal-view-instance.c
@@ -38,7 +38,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "e-util/e-xml-utils.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "gal-define-views-dialog.h"
#include "gal-view-instance.h"
diff --git a/widgets/menus/gal-view-new-dialog.c b/widgets/menus/gal-view-new-dialog.c
index 061c04b71a..8716764c49 100644
--- a/widgets/menus/gal-view-new-dialog.c
+++ b/widgets/menus/gal-view-new-dialog.c
@@ -27,7 +27,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "e-util/e-util-private.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "gal-define-views-model.h"
#include "gal-view-new-dialog.h"
diff --git a/widgets/misc/Makefile.am b/widgets/misc/Makefile.am
index 212d67557b..bd2c9f9f36 100644
--- a/widgets/misc/Makefile.am
+++ b/widgets/misc/Makefile.am
@@ -1,10 +1,5 @@
-if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libfilter.la
-endif
-
INCLUDES = \
-I$(top_srcdir) \
- -I$(top_srcdir)/a11y/widgets \
-I$(top_srcdir)/filter \
-I$(top_srcdir)/widgets \
-DEVOLUTION_IMAGES=\""$(imagesdir)"\" \
@@ -50,13 +45,10 @@ widgetsinclude_HEADERS = \
e-attachment-view.h \
e-calendar.h \
e-calendar-item.h \
- e-camel-activity.h \
e-canvas.h \
e-canvas-background.h \
e-canvas-utils.h \
e-canvas-vbox.h \
- e-cell-date-edit.h \
- e-cell-percent.h \
e-cell-renderer-combo.h \
e-charset-picker.h \
e-colors.h \
@@ -75,8 +67,6 @@ widgetsinclude_HEADERS = \
e-popup-menu.h \
e-preferences-window.h \
e-printable.h \
- e-reflow.h \
- e-reflow-model.h \
e-search-bar.h \
e-selection-model.h \
e-selection-model-array.h \
@@ -91,8 +81,10 @@ widgetsinclude_HEADERS = \
e-spinner.c \
e-spinner.h \
e-timeout-activity.h \
- e-unicode.h \
- e-url-entry.h
+ e-url-entry.h \
+ a11y/ea-calendar-cell.h \
+ a11y/ea-calendar-item.h \
+ a11y/ea-widgets.h
libemiscwidgets_la_SOURCES = \
$(widgetsinclude_HEADERS) \
@@ -115,13 +107,10 @@ libemiscwidgets_la_SOURCES = \
e-attachment-view.c \
e-calendar.c \
e-calendar-item.c \
- e-camel-activity.c \
e-canvas.c \
e-canvas-background.c \
e-canvas-utils.c \
e-canvas-vbox.c \
- e-cell-date-edit.c \
- e-cell-percent.c \
e-cell-renderer-combo.c \
e-charset-picker.c \
e-colors.c \
@@ -140,8 +129,6 @@ libemiscwidgets_la_SOURCES = \
e-popup-menu.c \
e-preferences-window.c \
e-printable.c \
- e-reflow-model.c \
- e-reflow.c \
e-search-bar.c \
e-selection-model.c \
e-selection-model-array.c \
@@ -154,20 +141,20 @@ libemiscwidgets_la_SOURCES = \
e-signature-script-dialog.c \
e-signature-tree-view.c \
e-timeout-activity.c \
- e-unicode.c \
- e-url-entry.c
+ e-url-entry.c \
+ a11y/ea-calendar-cell.c \
+ a11y/ea-calendar-item.c \
+ a11y/ea-widgets.c
libemiscwidgets_la_LDFLAGS = $(NO_UNDEFINED)
-libemiscwidgets_la_LIBADD = \
- $(top_builddir)/e-util/libeutil.la \
- $(top_builddir)/filter/libfilter.la \
- $(top_builddir)/widgets/table/libetable.la \
- $(top_builddir)/widgets/text/libetext.la \
- $(top_builddir)/a11y/widgets/libevolution-widgets-a11y.la \
- $(top_builddir)/a11y/libevolution-a11y.la \
- $(EVOLUTION_MAIL_LIBS) \
- $(GNOME_PLATFORM_LIBS) \
+libemiscwidgets_la_LIBADD = \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/filter/libfilter.la \
+ $(top_builddir)/a11y/libevolution-a11y.la \
+ $(EVOLUTION_MAIL_LIBS) \
+ $(GNOME_PLATFORM_LIBS) \
+ $(MATH_LIB) \
$(ICONV_LIBS)
noinst_PROGRAMS = \
diff --git a/widgets/misc/a11y/ea-calendar-cell.c b/widgets/misc/a11y/ea-calendar-cell.c
new file mode 100644
index 0000000000..8173d6d25f
--- /dev/null
+++ b/widgets/misc/a11y/ea-calendar-cell.c
@@ -0,0 +1,387 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Bolian Yin <bolian.yin@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <gtk/gtk.h>
+#include <e-util/e-util.h>
+#include "ea-calendar-cell.h"
+#include "ea-calendar-item.h"
+#include "a11y/ea-factory.h"
+
+/* ECalendarCell */
+
+static void e_calendar_cell_class_init (ECalendarCellClass *class);
+
+EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_CELL, ea_calendar_cell, ea_calendar_cell_new)
+
+GType
+e_calendar_cell_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static GTypeInfo tinfo = {
+ sizeof (ECalendarCellClass),
+ (GBaseInitFunc) NULL, /* base init */
+ (GBaseFinalizeFunc) NULL, /* base finalize */
+ (GClassInitFunc) e_calendar_cell_class_init, /* class init */
+ (GClassFinalizeFunc) NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (ECalendarCell), /* instance size */
+ 0, /* nb preallocs */
+ (GInstanceInitFunc) NULL, /* instance init */
+ NULL /* value table */
+ };
+
+ type = g_type_register_static (G_TYPE_OBJECT,
+ "ECalendarCell", &tinfo, 0);
+ }
+
+ return type;
+}
+
+static void
+e_calendar_cell_class_init (ECalendarCellClass *class)
+{
+ EA_SET_FACTORY (e_calendar_cell_get_type (), ea_calendar_cell);
+}
+
+ECalendarCell *
+e_calendar_cell_new (ECalendarItem *calitem, gint row, gint column)
+{
+ GObject *object;
+ ECalendarCell *cell;
+
+ g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), NULL);
+
+ object = g_object_new (E_TYPE_CALENDAR_CELL, NULL);
+ cell = E_CALENDAR_CELL (object);
+ cell->calitem = calitem;
+ cell->row = row;
+ cell->column = column;
+
+#ifdef ACC_DEBUG
+ g_print ("EvoAcc: e_calendar_cell created %p\n", (void *)cell);
+#endif
+
+ return cell;
+}
+
+/* EaCalendarCell */
+
+static void ea_calendar_cell_class_init (EaCalendarCellClass *klass);
+static void ea_calendar_cell_init (EaCalendarCell *a11y);
+
+static G_CONST_RETURN gchar* ea_calendar_cell_get_name (AtkObject *accessible);
+static G_CONST_RETURN gchar* ea_calendar_cell_get_description (AtkObject *accessible);
+static AtkObject * ea_calendar_cell_get_parent (AtkObject *accessible);
+static gint ea_calendar_cell_get_index_in_parent (AtkObject *accessible);
+static AtkStateSet *ea_calendar_cell_ref_state_set (AtkObject *accessible);
+
+/* component interface */
+static void atk_component_interface_init (AtkComponentIface *iface);
+static void component_interface_get_extents (AtkComponent *component,
+ gint *x, gint *y,
+ gint *width, gint *height,
+ AtkCoordType coord_type);
+static gboolean component_interface_grab_focus (AtkComponent *component);
+
+static gpointer parent_class = NULL;
+
+#ifdef ACC_DEBUG
+static gint n_ea_calendar_cell_created = 0, n_ea_calendar_cell_destroyed = 0;
+static void ea_calendar_cell_finalize (GObject *object);
+#endif
+
+GType
+ea_calendar_cell_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ static GTypeInfo tinfo = {
+ sizeof (EaCalendarCellClass),
+ (GBaseInitFunc) NULL, /* base init */
+ (GBaseFinalizeFunc) NULL, /* base finalize */
+ (GClassInitFunc) ea_calendar_cell_class_init, /* class init */
+ (GClassFinalizeFunc) NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (EaCalendarCell), /* instance size */
+ 0, /* nb preallocs */
+ (GInstanceInitFunc) ea_calendar_cell_init, /* instance init */
+ NULL /* value table */
+ };
+
+ static const GInterfaceInfo atk_component_info = {
+ (GInterfaceInitFunc) atk_component_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ type = g_type_register_static (ATK_TYPE_GOBJECT_ACCESSIBLE,
+ "EaCalendarCell", &tinfo, 0);
+ g_type_add_interface_static (type, ATK_TYPE_COMPONENT,
+ &atk_component_info);
+ }
+
+ return type;
+}
+
+static void
+ea_calendar_cell_class_init (EaCalendarCellClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+#ifdef ACC_DEBUG
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = ea_calendar_cell_finalize;
+#endif
+
+ parent_class = g_type_class_peek_parent (klass);
+
+ class->get_name = ea_calendar_cell_get_name;
+ class->get_description = ea_calendar_cell_get_description;
+
+ class->get_parent = ea_calendar_cell_get_parent;
+ class->get_index_in_parent = ea_calendar_cell_get_index_in_parent;
+ class->ref_state_set = ea_calendar_cell_ref_state_set;
+}
+
+static void
+ea_calendar_cell_init (EaCalendarCell *a11y)
+{
+ 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);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE);
+}
+
+AtkObject*
+ea_calendar_cell_new (GObject *obj)
+{
+ gpointer object;
+ AtkObject *atk_object;
+
+ g_return_val_if_fail (E_IS_CALENDAR_CELL (obj), NULL);
+ object = g_object_new (EA_TYPE_CALENDAR_CELL, NULL);
+ atk_object = ATK_OBJECT (object);
+ atk_object_initialize (atk_object, obj);
+ atk_object->role = ATK_ROLE_TABLE_CELL;
+
+#ifdef ACC_DEBUG
+ ++n_ea_calendar_cell_created;
+ g_print ("ACC_DEBUG: n_ea_calendar_cell_created = %d\n",
+ n_ea_calendar_cell_created);
+#endif
+ return atk_object;
+}
+
+#ifdef ACC_DEBUG
+static void ea_calendar_cell_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+
+ ++n_ea_calendar_cell_destroyed;
+ g_print ("ACC_DEBUG: n_ea_calendar_cell_destroyed = %d\n",
+ n_ea_calendar_cell_destroyed);
+}
+#endif
+
+static G_CONST_RETURN gchar*
+ea_calendar_cell_get_name (AtkObject *accessible)
+{
+ GObject *g_obj;
+
+ g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL);
+
+ g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible));
+ if (!g_obj)
+ /* defunct object*/
+ return NULL;
+
+ if (!accessible->name) {
+ AtkObject *atk_obj;
+ EaCalendarItem *ea_calitem;
+ ECalendarCell *cell;
+ gint day_index;
+ gint year, month, day;
+ gchar buffer[128];
+
+ cell = E_CALENDAR_CELL (g_obj);
+ atk_obj = ea_calendar_cell_get_parent (accessible);
+ ea_calitem = EA_CALENDAR_ITEM (atk_obj);
+ day_index = atk_table_get_index_at (ATK_TABLE (ea_calitem),
+ cell->row, cell->column);
+ e_calendar_item_get_date_for_offset (cell->calitem, day_index,
+ &year, &month, &day);
+
+ g_snprintf (buffer, 128, "%d-%d-%d", year, month + 1, day);
+ ATK_OBJECT_CLASS (parent_class)->set_name (accessible, buffer);
+ }
+ return accessible->name;
+}
+
+static G_CONST_RETURN gchar*
+ea_calendar_cell_get_description (AtkObject *accessible)
+{
+ return ea_calendar_cell_get_name (accessible);
+}
+
+static AtkObject *
+ea_calendar_cell_get_parent (AtkObject *accessible)
+{
+ GObject *g_obj;
+ ECalendarCell *cell;
+ ECalendarItem *calitem;
+
+ g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), NULL);
+
+ g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible));
+ if (!g_obj)
+ /* defunct object*/
+ return NULL;
+
+ cell = E_CALENDAR_CELL (g_obj);
+ calitem = cell->calitem;
+ return atk_gobject_accessible_for_object (G_OBJECT (calitem));
+}
+
+static gint
+ea_calendar_cell_get_index_in_parent (AtkObject *accessible)
+{
+ GObject *g_obj;
+ ECalendarCell *cell;
+ AtkObject *parent;
+
+ g_return_val_if_fail (EA_IS_CALENDAR_CELL (accessible), -1);
+
+ g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible));
+ if (!g_obj)
+ return -1;
+ cell = E_CALENDAR_CELL (g_obj);
+ parent = atk_object_get_parent (accessible);
+ return atk_table_get_index_at (ATK_TABLE (parent),
+ cell->row, cell->column);
+}
+
+static AtkStateSet *
+ea_calendar_cell_ref_state_set (AtkObject *accessible)
+{
+ EaCalendarCell *atk_cell = EA_CALENDAR_CELL (accessible);
+
+ g_return_val_if_fail (atk_cell->state_set, NULL);
+
+ g_object_ref(atk_cell->state_set);
+
+ return atk_cell->state_set;
+
+}
+
+/* Atk Component Interface */
+
+static void
+atk_component_interface_init (AtkComponentIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->get_extents = component_interface_get_extents;
+ iface->grab_focus = component_interface_grab_focus;
+}
+
+static void
+component_interface_get_extents (AtkComponent *component,
+ gint *x, gint *y, gint *width, gint *height,
+ AtkCoordType coord_type)
+{
+ GObject *g_obj;
+ AtkObject *atk_obj, *atk_canvas;
+ ECalendarCell *cell;
+ ECalendarItem *calitem;
+ EaCalendarItem *ea_calitem;
+ gint day_index;
+ gint year, month, day;
+ gint canvas_x, canvas_y, canvas_width, canvas_height;
+
+ *x = *y = *width = *height = 0;
+
+ g_return_if_fail (EA_IS_CALENDAR_CELL (component));
+
+
+ g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component));
+ if (!g_obj)
+ /* defunct object*/
+ return;
+
+ cell = E_CALENDAR_CELL (g_obj);
+ calitem = cell->calitem;
+ atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem));
+ ea_calitem = EA_CALENDAR_ITEM (atk_obj);
+ day_index = atk_table_get_index_at (ATK_TABLE (ea_calitem),
+ cell->row, cell->column);
+ e_calendar_item_get_date_for_offset (calitem, day_index,
+ &year, &month, &day);
+
+ if (!e_calendar_item_get_day_extents (calitem,
+ year, month, day,
+ x, y, width, height))
+ return;
+ atk_canvas = atk_object_get_parent (ATK_OBJECT (ea_calitem));
+ atk_component_get_extents (ATK_COMPONENT (atk_canvas),
+ &canvas_x, &canvas_y,
+ &canvas_width, &canvas_height,
+ coord_type);
+ *x += canvas_x;
+ *y += canvas_y;
+}
+
+static gboolean
+component_interface_grab_focus (AtkComponent *component)
+{
+ GObject *g_obj;
+ GtkWidget *toplevel;
+ AtkObject *ea_calitem;
+ ECalendarItem *calitem;
+ EaCalendarCell *a11y;
+ gint index;
+
+ a11y = EA_CALENDAR_CELL (component);
+ ea_calitem = ea_calendar_cell_get_parent (ATK_OBJECT (a11y));
+
+ g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(ea_calitem));
+ calitem = E_CALENDAR_ITEM (g_obj);
+
+ index = atk_object_get_index_in_parent (ATK_OBJECT (a11y));
+
+ atk_selection_clear_selection (ATK_SELECTION (ea_calitem));
+ atk_selection_add_selection (ATK_SELECTION (ea_calitem), index);
+
+ gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas));
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (GNOME_CANVAS_ITEM (calitem)->canvas));
+ if (toplevel && GTK_WIDGET_TOPLEVEL (toplevel))
+ gtk_window_present (GTK_WINDOW (toplevel));
+
+ return TRUE;
+
+}
diff --git a/widgets/misc/a11y/ea-calendar-cell.h b/widgets/misc/a11y/ea-calendar-cell.h
new file mode 100644
index 0000000000..a07b7e8bbc
--- /dev/null
+++ b/widgets/misc/a11y/ea-calendar-cell.h
@@ -0,0 +1,90 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Bolian Yin <bolian.yin@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EA_CALENDAR_CELL_H__
+#define __EA_CALENDAR_CELL_H__
+
+#include <atk/atkgobjectaccessible.h>
+#include "misc/e-calendar-item.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define E_TYPE_CALENDAR_CELL (e_calendar_cell_get_type ())
+#define E_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_CALENDAR_CELL, ECalendarCell))
+#define E_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_CALENDAR_CELL, ECalendarCellClass))
+#define E_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_CALENDAR_CELL))
+#define E_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_CALENDAR_CELL))
+#define E_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_CALENDAR_CELL, ECalendarCellClass))
+
+typedef struct _ECalendarCell ECalendarCell;
+typedef struct _ECalendarCellClass ECalendarCellClass;
+
+struct _ECalendarCell
+{
+ GObject parent;
+ ECalendarItem *calitem;
+ gint row;
+ gint column;
+};
+
+GType e_calendar_cell_get_type (void);
+
+struct _ECalendarCellClass
+{
+ GObjectClass parent_class;
+};
+
+ECalendarCell * e_calendar_cell_new (ECalendarItem *calitem,
+ gint row, gint column);
+
+#define EA_TYPE_CALENDAR_CELL (ea_calendar_cell_get_type ())
+#define EA_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCell))
+#define EA_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass))
+#define EA_IS_CALENDAR_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_CELL))
+#define EA_IS_CALENDAR_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_CELL))
+#define EA_CALENDAR_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_CELL, EaCalendarCellClass))
+
+typedef struct _EaCalendarCell EaCalendarCell;
+typedef struct _EaCalendarCellClass EaCalendarCellClass;
+
+struct _EaCalendarCell
+{
+ AtkGObjectAccessible parent;
+ AtkStateSet *state_set;
+};
+
+GType ea_calendar_cell_get_type (void);
+
+struct _EaCalendarCellClass
+{
+ AtkGObjectAccessibleClass parent_class;
+};
+
+AtkObject* ea_calendar_cell_new (GObject *gobj);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __EA_CALENDAR_CELL_H__ */
diff --git a/widgets/misc/a11y/ea-calendar-item.c b/widgets/misc/a11y/ea-calendar-item.c
new file mode 100644
index 0000000000..66f40a92a0
--- /dev/null
+++ b/widgets/misc/a11y/ea-calendar-item.c
@@ -0,0 +1,1314 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Bolian Yin <bolian.yin@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <stdio.h>
+#include <time.h>
+#include <string.h>
+#include <libgnomecanvas/gnome-canvas.h>
+#include <glib.h>
+#include <e-util/e-util.h>
+#include <glib/gi18n.h>
+#include <libedataserver/e-data-server-util.h>
+#include "ea-calendar-item.h"
+#include "ea-calendar-cell.h"
+#include "a11y/ea-cell-table.h"
+
+#define EA_CALENDAR_COLUMN_NUM E_CALENDAR_COLS_PER_MONTH
+
+/* EaCalendarItem */
+static void ea_calendar_item_class_init (EaCalendarItemClass *klass);
+static void ea_calendar_item_finalize (GObject *object);
+
+static G_CONST_RETURN gchar* ea_calendar_item_get_name (AtkObject *accessible);
+static G_CONST_RETURN gchar* ea_calendar_item_get_description (AtkObject *accessible);
+static gint ea_calendar_item_get_n_children (AtkObject *accessible);
+static AtkObject *ea_calendar_item_ref_child (AtkObject *accessible, gint index);
+static AtkStateSet* ea_calendar_item_ref_state_set (AtkObject *accessible);
+
+/* atk table interface */
+static void atk_table_interface_init (AtkTableIface *iface);
+static gint table_interface_get_index_at (AtkTable *table,
+ gint row,
+ gint column);
+static gint table_interface_get_column_at_index (AtkTable *table,
+ gint index);
+static gint table_interface_get_row_at_index (AtkTable *table,
+ gint index);
+static AtkObject* table_interface_ref_at (AtkTable *table,
+ gint row,
+ gint column);
+static gint table_interface_get_n_rows (AtkTable *table);
+static gint table_interface_get_n_columns (AtkTable *table);
+static gint table_interface_get_column_extent_at (AtkTable *table,
+ gint row,
+ gint column);
+static gint table_interface_get_row_extent_at (AtkTable *table,
+ gint row,
+ gint column);
+
+static gboolean table_interface_is_row_selected (AtkTable *table,
+ gint row);
+static gboolean table_interface_is_column_selected (AtkTable *table,
+ gint row);
+static gboolean table_interface_is_selected (AtkTable *table,
+ gint row,
+ gint column);
+static gint table_interface_get_selected_rows (AtkTable *table,
+ gint **rows_selected);
+static gint table_interface_get_selected_columns (AtkTable *table,
+ gint **columns_selected);
+static gboolean table_interface_add_row_selection (AtkTable *table, gint row);
+static gboolean table_interface_remove_row_selection (AtkTable *table,
+ gint row);
+static gboolean table_interface_add_column_selection (AtkTable *table,
+ gint column);
+static gboolean table_interface_remove_column_selection (AtkTable *table,
+ gint column);
+static AtkObject* table_interface_get_row_header (AtkTable *table, gint row);
+static AtkObject* table_interface_get_column_header (AtkTable *table,
+ gint in_col);
+static AtkObject* table_interface_get_caption (AtkTable *table);
+
+static G_CONST_RETURN gchar*
+table_interface_get_column_description (AtkTable *table, gint in_col);
+
+static G_CONST_RETURN gchar*
+table_interface_get_row_description (AtkTable *table, gint row);
+
+static AtkObject* table_interface_get_summary (AtkTable *table);
+
+/* atk selection interface */
+static void atk_selection_interface_init (AtkSelectionIface *iface);
+static gboolean selection_interface_add_selection (AtkSelection *selection,
+ gint i);
+static gboolean selection_interface_clear_selection (AtkSelection *selection);
+static AtkObject* selection_interface_ref_selection (AtkSelection *selection,
+ gint i);
+static gint selection_interface_get_selection_count (AtkSelection *selection);
+static gboolean selection_interface_is_child_selected (AtkSelection *selection,
+ gint i);
+
+/* callbacks */
+static void selection_preview_change_cb (ECalendarItem *calitem);
+static void date_range_changed_cb (ECalendarItem *calitem);
+
+/* helpers */
+static EaCellTable *ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem);
+static void ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem);
+static gboolean ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem,
+ gint column,
+ gchar *buffer,
+ gint buffer_size);
+static gboolean ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem,
+ gint row,
+ gchar *buffer,
+ gint buffer_size);
+static gboolean e_calendar_item_get_offset_for_date (ECalendarItem *calitem,
+ gint year, gint month, gint day,
+ gint *offset);
+static void ea_calendar_set_focus_object (EaCalendarItem *ea_calitem,
+ AtkObject *item_cell);
+
+#ifdef ACC_DEBUG
+static gint n_ea_calendar_item_created = 0;
+static gint n_ea_calendar_item_destroyed = 0;
+#endif
+
+static gpointer parent_class = NULL;
+
+GType
+ea_calendar_item_get_type (void)
+{
+ static GType type = 0;
+ AtkObjectFactory *factory;
+ GTypeQuery query;
+ GType derived_atk_type;
+
+ if (!type) {
+ static GTypeInfo tinfo = {
+ sizeof (EaCalendarItemClass),
+ (GBaseInitFunc) NULL, /* base init */
+ (GBaseFinalizeFunc) NULL, /* base finalize */
+ (GClassInitFunc) ea_calendar_item_class_init, /* class init */
+ (GClassFinalizeFunc) NULL, /* class finalize */
+ NULL, /* class data */
+ sizeof (EaCalendarItem), /* instance size */
+ 0, /* nb preallocs */
+ (GInstanceInitFunc) NULL, /* instance init */
+ NULL /* value table */
+ };
+
+ static const GInterfaceInfo atk_table_info = {
+ (GInterfaceInitFunc) atk_table_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+ static const GInterfaceInfo atk_selection_info = {
+ (GInterfaceInitFunc) atk_selection_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ /*
+ * Figure out the size of the class and instance
+ * we are run-time deriving from (GailCanvasItem, in this case)
+ */
+
+ factory = atk_registry_get_factory (atk_get_default_registry (),
+ GNOME_TYPE_CANVAS_ITEM);
+ derived_atk_type = atk_object_factory_get_accessible_type (factory);
+ g_type_query (derived_atk_type, &query);
+
+ tinfo.class_size = query.class_size;
+ tinfo.instance_size = query.instance_size;
+
+ type = g_type_register_static (derived_atk_type,
+ "EaCalendarItem", &tinfo, 0);
+ g_type_add_interface_static (type, ATK_TYPE_TABLE,
+ &atk_table_info);
+ g_type_add_interface_static (type, ATK_TYPE_SELECTION,
+ &atk_selection_info);
+ }
+
+ return type;
+}
+
+static void
+ea_calendar_item_class_init (EaCalendarItemClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+
+ gobject_class->finalize = ea_calendar_item_finalize;
+ parent_class = g_type_class_peek_parent (klass);
+
+ class->get_name = ea_calendar_item_get_name;
+ class->get_description = ea_calendar_item_get_description;
+ class->ref_state_set = ea_calendar_item_ref_state_set;
+
+ class->get_n_children = ea_calendar_item_get_n_children;
+ class->ref_child = ea_calendar_item_ref_child;
+}
+
+AtkObject*
+ea_calendar_item_new (GObject *obj)
+{
+ gpointer object;
+ AtkObject *atk_object;
+ AtkObject *item_cell;
+
+ g_return_val_if_fail (E_IS_CALENDAR_ITEM (obj), NULL);
+ object = g_object_new (EA_TYPE_CALENDAR_ITEM, NULL);
+ atk_object = ATK_OBJECT (object);
+ atk_object_initialize (atk_object, obj);
+ atk_object->role = ATK_ROLE_CALENDAR;
+
+ item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_object),
+ 0);
+ if (item_cell)
+ ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_object), item_cell);
+
+#ifdef ACC_DEBUG
+ ++n_ea_calendar_item_created;
+ g_print ("ACC_DEBUG: n_ea_calendar_item_created = %d\n",
+ n_ea_calendar_item_created);
+#endif
+ /* connect signal handlers */
+ g_signal_connect (obj, "selection_preview_changed",
+ G_CALLBACK (selection_preview_change_cb),
+ atk_object);
+ g_signal_connect (obj, "date_range_changed",
+ G_CALLBACK (date_range_changed_cb),
+ atk_object);
+
+ return atk_object;
+}
+
+static void
+ea_calendar_item_finalize (GObject *object)
+{
+ EaCalendarItem *ea_calitem;
+
+ g_return_if_fail (EA_IS_CALENDAR_ITEM (object));
+
+ ea_calitem = EA_CALENDAR_ITEM (object);
+
+ /* Free the allocated cell data */
+ ea_calendar_item_destory_cell_data (ea_calitem);
+
+ G_OBJECT_CLASS (parent_class)->finalize (object);
+#ifdef ACC_DEBUG
+ ++n_ea_calendar_item_destroyed;
+ printf ("ACC_DEBUG: n_ea_calendar_item_destroyed = %d\n",
+ n_ea_calendar_item_destroyed);
+#endif
+}
+
+static G_CONST_RETURN gchar*
+ea_calendar_item_get_name (AtkObject *accessible)
+{
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ gint start_year, start_month, start_day;
+ gint end_year, end_month, end_day;
+ gchar *name_str = NULL;
+ gchar buffer_start[128] = "";
+ gchar buffer_end[128] = "";
+ struct tm day_start = { 0 };
+ struct tm day_end = { 0 };
+
+ g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL);
+
+ g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible));
+ if (!g_obj)
+ return NULL;
+ g_return_val_if_fail (E_IS_CALENDAR_ITEM (g_obj), NULL);
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ if (e_calendar_item_get_date_range (calitem,
+ &start_year, &start_month, &start_day,
+ &end_year, &end_month, &end_day)) {
+
+ day_start.tm_year = start_year - 1900;
+ day_start.tm_mon = start_month;
+ day_start.tm_mday = start_day;
+ day_start.tm_isdst = -1;
+ e_utf8_strftime (buffer_start, sizeof (buffer_start), _("%d %B %Y"), &day_start);
+
+ day_end.tm_year = end_year - 1900;
+ day_end.tm_mon = end_month;
+ day_end.tm_mday = end_day;
+ day_end.tm_isdst = -1;
+ e_utf8_strftime (buffer_end, sizeof (buffer_end), _("%d %B %Y"), &day_end);
+
+ name_str = g_strdup_printf (_("Calendar: from %s to %s"), buffer_start, buffer_end);
+ }
+
+#if 0
+ if (e_calendar_item_get_selection (calitem, &select_start, &select_end)) {
+ GDate select_start, select_end;
+ gint year1, year2, month1, month2, day1, day2;
+
+ year1 = g_date_get_year (&select_start);
+ month1 = g_date_get_month (&select_start);
+ day1 = g_date_get_day (&select_start);
+
+ year2 = g_date_get_year (&select_end);
+ month2 = g_date_get_month (&select_end);
+ day2 = g_date_get_day (&select_end);
+
+ sprintf (new_name + strlen (new_name),
+ " : current selection: from %d-%d-%d to %d-%d-%d.",
+ year1, month1, day1,
+ year2, month2, day2);
+ }
+#endif
+
+ ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str);
+ g_free (name_str);
+
+ return accessible->name;
+}
+
+static G_CONST_RETURN gchar*
+ea_calendar_item_get_description (AtkObject *accessible)
+{
+ if (accessible->description)
+ return accessible->description;
+
+ return _("evolution calendar item");
+}
+
+static AtkStateSet*
+ea_calendar_item_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet *state_set;
+ GObject *g_obj;
+
+ state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible);
+ g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible));
+ if (!g_obj)
+ return state_set;
+
+ atk_state_set_add_state (state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+
+ return state_set;
+}
+
+static gint
+ea_calendar_item_get_n_children (AtkObject *accessible)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ gint n_children = 0;
+ gint start_year, start_month, start_day;
+ gint end_year, end_month, end_day;
+ GDate *start_date, *end_date;
+
+ g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), -1);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return -1;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ if (!e_calendar_item_get_date_range (calitem, &start_year,
+ &start_month, &start_day,
+ &end_year, &end_month,
+ &end_day))
+ return 0;
+
+ start_date = g_date_new_dmy (start_day, start_month + 1, start_year);
+ end_date = g_date_new_dmy (end_day, end_month + 1, end_year);
+
+ n_children = g_date_days_between (start_date, end_date) + 1;
+ g_free (start_date);
+ g_free (end_date);
+ return n_children;
+}
+
+static AtkObject *
+ea_calendar_item_ref_child (AtkObject *accessible, gint index)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ gint n_children;
+ ECalendarCell *cell;
+ EaCellTable *cell_data;
+ EaCalendarItem *ea_calitem;
+
+ g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return NULL;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+
+ n_children = ea_calendar_item_get_n_children (accessible);
+ if (index < 0 || index >= n_children)
+ return NULL;
+
+ ea_calitem = EA_CALENDAR_ITEM (accessible);
+ cell_data = ea_calendar_item_get_cell_data (ea_calitem);
+ if (!cell_data)
+ return NULL;
+
+ cell = ea_cell_table_get_cell_at_index (cell_data, index);
+ if (!cell) {
+ cell = e_calendar_cell_new (calitem,
+ index / EA_CALENDAR_COLUMN_NUM,
+ index % EA_CALENDAR_COLUMN_NUM);
+ ea_cell_table_set_cell_at_index (cell_data, index, cell);
+ g_object_unref (cell);
+ }
+
+#ifdef ACC_DEBUG
+ g_print ("AccDebug: ea_calendar_item children[%d]=%p\n", index,
+ (gpointer)cell);
+#endif
+ return g_object_ref (atk_gobject_accessible_for_object (G_OBJECT(cell)));
+}
+
+/* atk table interface */
+
+static void
+atk_table_interface_init (AtkTableIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->ref_at = table_interface_ref_at;
+
+ iface->get_n_rows = table_interface_get_n_rows;
+ iface->get_n_columns = table_interface_get_n_columns;
+ iface->get_index_at = table_interface_get_index_at;
+ iface->get_column_at_index = table_interface_get_column_at_index;
+ iface->get_row_at_index = table_interface_get_row_at_index;
+ iface->get_column_extent_at = table_interface_get_column_extent_at;
+ iface->get_row_extent_at = table_interface_get_row_extent_at;
+
+ iface->is_selected = table_interface_is_selected;
+ iface->get_selected_rows = table_interface_get_selected_rows;
+ iface->get_selected_columns = table_interface_get_selected_columns;
+ iface->is_row_selected = table_interface_is_row_selected;
+ iface->is_column_selected = table_interface_is_column_selected;
+ iface->add_row_selection = table_interface_add_row_selection;
+ iface->remove_row_selection = table_interface_remove_row_selection;
+ iface->add_column_selection = table_interface_add_column_selection;
+ iface->remove_column_selection = table_interface_remove_column_selection;
+
+ iface->get_row_header = table_interface_get_row_header;
+ iface->get_column_header = table_interface_get_column_header;
+ iface->get_caption = table_interface_get_caption;
+ iface->get_summary = table_interface_get_summary;
+ iface->get_row_description = table_interface_get_row_description;
+ iface->get_column_description = table_interface_get_column_description;
+}
+
+static AtkObject*
+table_interface_ref_at (AtkTable *table,
+ gint row,
+ gint column)
+{
+ gint index;
+
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+ index = EA_CALENDAR_COLUMN_NUM * row + column;
+ return ea_calendar_item_ref_child (ATK_OBJECT (ea_calitem), index);
+}
+
+static gint
+table_interface_get_n_rows (AtkTable *table)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+ gint n_children;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return -1;
+
+ n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem));
+ return (n_children - 1) / EA_CALENDAR_COLUMN_NUM + 1;
+}
+
+static gint
+table_interface_get_n_columns (AtkTable *table)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return -1;
+
+ return EA_CALENDAR_COLUMN_NUM;
+}
+
+static gint
+table_interface_get_index_at (AtkTable *table,
+ gint row,
+ gint column)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return -1;
+
+ return row * EA_CALENDAR_COLUMN_NUM + column;
+}
+
+static gint
+table_interface_get_column_at_index (AtkTable *table,
+ gint index)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+ gint n_children;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return -1;
+
+ n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem));
+ if (index >= 0 && index < n_children)
+ return index % EA_CALENDAR_COLUMN_NUM;
+ return -1;
+}
+
+static gint
+table_interface_get_row_at_index (AtkTable *table,
+ gint index)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+ gint n_children;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return -1;
+
+ n_children = ea_calendar_item_get_n_children (ATK_OBJECT (ea_calitem));
+ if (index >= 0 && index < n_children)
+ return index / EA_CALENDAR_COLUMN_NUM;
+ return -1;
+}
+
+static gint
+table_interface_get_column_extent_at (AtkTable *table,
+ gint row,
+ gint column)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return FALSE;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ return calitem->cell_width;
+}
+
+static gint
+table_interface_get_row_extent_at (AtkTable *table,
+ gint row, gint column)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return FALSE;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ return calitem->cell_height;
+}
+
+/* any day in the row is selected, the row is selected */
+static gboolean
+table_interface_is_row_selected (AtkTable *table,
+ gint row)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ gint n_rows;
+ ECalendarItem *calitem;
+ gint row_index_start, row_index_end;
+ gint sel_index_start, sel_index_end;
+
+ GDate start_date, end_date;
+
+ g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (table);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return FALSE;
+
+ n_rows = table_interface_get_n_rows (table);
+ if (row < 0 || row >= n_rows)
+ return FALSE;
+
+ row_index_start = row * EA_CALENDAR_COLUMN_NUM;
+ row_index_end = row_index_start + EA_CALENDAR_COLUMN_NUM - 1;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ if (!e_calendar_item_get_selection (calitem, &start_date, &end_date))
+ return FALSE;
+
+ e_calendar_item_get_offset_for_date (calitem,
+ g_date_get_year (&start_date),
+ g_date_get_month (&start_date),
+ g_date_get_day (&start_date),
+ &sel_index_start);
+ e_calendar_item_get_offset_for_date (calitem,
+ g_date_get_year (&end_date),
+ g_date_get_month (&end_date),
+ g_date_get_day (&end_date),
+ &sel_index_end);
+
+ if ((sel_index_start < row_index_start &&
+ sel_index_end >= row_index_start) ||
+ (sel_index_start >= row_index_start &&
+ sel_index_start <= row_index_end))
+ return TRUE;
+ return FALSE;
+}
+
+static gboolean
+table_interface_is_selected (AtkTable *table,
+ gint row,
+ gint column)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ gint n_rows, n_columns;
+ ECalendarItem *calitem;
+ gint index;
+ gint sel_index_start, sel_index_end;
+
+ GDate start_date, end_date;
+
+ g_return_val_if_fail (EA_IS_CALENDAR_ITEM (table), FALSE);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (table);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return FALSE;
+
+ n_rows = table_interface_get_n_rows (table);
+ if (row < 0 || row >= n_rows)
+ return FALSE;
+ n_columns = table_interface_get_n_columns (table);
+ if (column < 0 || column >= n_columns)
+ return FALSE;
+
+ index = table_interface_get_index_at (table, row, column);
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ if (!e_calendar_item_get_selection (calitem, &start_date, &end_date))
+ return FALSE;
+
+ e_calendar_item_get_offset_for_date (calitem,
+ g_date_get_year (&start_date),
+ g_date_get_month (&start_date),
+ g_date_get_day (&start_date),
+ &sel_index_start);
+ e_calendar_item_get_offset_for_date (calitem,
+ g_date_get_year (&end_date),
+ g_date_get_month (&end_date),
+ g_date_get_day (&end_date), &sel_index_end);
+
+ if (sel_index_start <= index && sel_index_end >= index)
+ return TRUE;
+ return FALSE;
+}
+
+static gboolean
+table_interface_is_column_selected (AtkTable *table,
+ gint column)
+{
+ return FALSE;
+}
+
+static gint
+table_interface_get_selected_rows (AtkTable *table,
+ gint **rows_selected)
+{
+ *rows_selected = NULL;
+ return -1;
+}
+
+static gint
+table_interface_get_selected_columns (AtkTable *table,
+ gint **columns_selected)
+{
+ *columns_selected = NULL;
+ return -1;
+}
+
+static gboolean
+table_interface_add_row_selection (AtkTable *table,
+ gint row)
+{
+ return FALSE;
+}
+
+static gboolean
+table_interface_remove_row_selection (AtkTable *table,
+ gint row)
+{
+ return FALSE;
+}
+
+static gboolean
+table_interface_add_column_selection (AtkTable *table,
+ gint column)
+{
+ return FALSE;
+}
+
+static gboolean
+table_interface_remove_column_selection (AtkTable *table,
+ gint column)
+{
+ /* FIXME: NOT IMPLEMENTED */
+ return FALSE;
+}
+
+static AtkObject*
+table_interface_get_row_header (AtkTable *table,
+ gint row)
+{
+ /* FIXME: NOT IMPLEMENTED */
+ return NULL;
+}
+
+static AtkObject*
+table_interface_get_column_header (AtkTable *table,
+ gint in_col)
+{
+ /* FIXME: NOT IMPLEMENTED */
+ return NULL;
+}
+
+static AtkObject*
+table_interface_get_caption (AtkTable *table)
+{
+ /* FIXME: NOT IMPLEMENTED */
+ return NULL;
+}
+
+static G_CONST_RETURN gchar*
+table_interface_get_column_description (AtkTable *table, gint in_col)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+ const gchar *description = NULL;
+ EaCellTable *cell_data;
+ gint n_columns;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return NULL;
+
+ n_columns = table_interface_get_n_columns (table);
+ if (in_col < 0 || in_col >= n_columns)
+ return NULL;
+ cell_data = ea_calendar_item_get_cell_data (ea_calitem);
+ if (!cell_data)
+ return NULL;
+
+ description = ea_cell_table_get_column_label (cell_data, in_col);
+ if (!description) {
+ gchar buffer[128] = "column description";
+ ea_calendar_item_get_column_label (ea_calitem, in_col,
+ buffer, sizeof (buffer));
+ ea_cell_table_set_column_label (cell_data, in_col, buffer);
+ description = ea_cell_table_get_column_label (cell_data,
+ in_col);
+ }
+ return description;
+}
+
+static G_CONST_RETURN gchar*
+table_interface_get_row_description (AtkTable *table, gint row)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (table);
+ const gchar *description = NULL;
+ EaCellTable *cell_data;
+ gint n_rows;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return NULL;
+
+ n_rows = table_interface_get_n_rows (table);
+ if (row < 0 || row >= n_rows)
+ return NULL;
+ cell_data = ea_calendar_item_get_cell_data (ea_calitem);
+ if (!cell_data)
+ return NULL;
+
+ description = ea_cell_table_get_row_label (cell_data, row);
+ if (!description) {
+ gchar buffer[128] = "row description";
+ ea_calendar_item_get_row_label (ea_calitem, row,
+ buffer, sizeof (buffer));
+ ea_cell_table_set_row_label (cell_data, row, buffer);
+ description = ea_cell_table_get_row_label (cell_data,
+ row);
+ }
+ return description;
+}
+
+static AtkObject*
+table_interface_get_summary (AtkTable *table)
+{
+ /* FIXME: NOT IMPLEMENTED */
+ return NULL;
+}
+
+/* atkselection interface */
+
+static void
+atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->add_selection = selection_interface_add_selection;
+ iface->clear_selection = selection_interface_clear_selection;
+ iface->ref_selection = selection_interface_ref_selection;
+ iface->get_selection_count = selection_interface_get_selection_count;
+ iface->is_child_selected = selection_interface_is_child_selected;
+}
+
+static gboolean
+selection_interface_add_selection (AtkSelection *selection, gint index)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection);
+ gint year, month, day;
+ GDate start_date, end_date;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return FALSE;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ if (!e_calendar_item_get_date_for_offset (calitem, index,
+ &year, &month, &day))
+ return FALSE;
+
+ /* FIXME: not support mulit-selection */
+ g_date_set_dmy (&start_date, day, month + 1, year);
+ end_date = start_date;
+ e_calendar_item_set_selection (calitem, &start_date, &end_date);
+ return TRUE;
+}
+
+static gboolean
+selection_interface_clear_selection (AtkSelection *selection)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return FALSE;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ e_calendar_item_set_selection (calitem, NULL, NULL);
+
+ return TRUE;
+}
+
+static AtkObject*
+selection_interface_ref_selection (AtkSelection *selection, gint i)
+{
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection);
+ gint count, sel_offset;
+ GDate start_date, end_date;
+
+ count = selection_interface_get_selection_count (selection);
+ if (i < 0 || i >= count)
+ return NULL;
+
+ g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_calitem));
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ if (!e_calendar_item_get_selection (calitem, &start_date, &end_date))
+ return NULL;
+ if (!e_calendar_item_get_offset_for_date (calitem,
+ g_date_get_year (&start_date),
+ g_date_get_month (&start_date) - 1,
+ g_date_get_day (&start_date),
+ &sel_offset))
+ return NULL;
+
+ return ea_calendar_item_ref_child (ATK_OBJECT (selection), sel_offset + i);
+}
+
+static gint
+selection_interface_get_selection_count (AtkSelection *selection)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection);
+ GDate start_date, end_date;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return 0;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ if (e_calendar_item_get_selection (calitem, &start_date, &end_date))
+ return g_date_days_between (&start_date, &end_date) + 1;
+ else
+ return 0;
+}
+
+static gboolean
+selection_interface_is_child_selected (AtkSelection *selection, gint index)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ EaCalendarItem* ea_calitem = EA_CALENDAR_ITEM (selection);
+ gint row, column, n_children;
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return FALSE;
+
+ n_children = atk_object_get_n_accessible_children (ATK_OBJECT (selection));
+ if (index < 0 || index >= n_children)
+ return FALSE;
+
+ row = index / EA_CALENDAR_COLUMN_NUM;
+ column = index % EA_CALENDAR_COLUMN_NUM;
+
+ return table_interface_is_selected (ATK_TABLE (selection), row, column);
+}
+
+/* callbacks */
+
+static void
+selection_preview_change_cb (ECalendarItem *calitem)
+{
+ AtkObject *atk_obj;
+ AtkObject *item_cell;
+
+ g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
+ atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem));
+ ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj));
+
+ /* only deal with the first selected child, for now */
+ item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_obj),
+ 0);
+
+ if (item_cell)
+ ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell);
+
+ g_signal_emit_by_name (atk_obj,
+ "active-descendant-changed",
+ item_cell);
+ g_signal_emit_by_name (atk_obj, "selection_changed");
+}
+
+static void
+date_range_changed_cb (ECalendarItem *calitem)
+{
+ AtkObject *atk_obj;
+ AtkObject *item_cell;
+
+ g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
+ atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem));
+ ea_calendar_item_destory_cell_data (EA_CALENDAR_ITEM (atk_obj));
+
+ item_cell = atk_selection_ref_selection (ATK_SELECTION (atk_obj),
+ 0);
+ if (item_cell)
+ ea_calendar_set_focus_object (EA_CALENDAR_ITEM (atk_obj), item_cell);
+
+ g_signal_emit_by_name (atk_obj, "model_changed");
+}
+
+/* helpers */
+
+static EaCellTable *
+ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ EaCellTable *cell_data;
+
+ g_return_val_if_fail (ea_calitem, NULL);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return NULL;
+
+ cell_data = g_object_get_data (G_OBJECT(ea_calitem),
+ "ea-calendar-cell-table");
+
+ if (!cell_data) {
+ gint n_cells = ea_calendar_item_get_n_children (ATK_OBJECT(ea_calitem));
+ cell_data = ea_cell_table_create (n_cells/EA_CALENDAR_COLUMN_NUM,
+ EA_CALENDAR_COLUMN_NUM,
+ FALSE);
+ g_object_set_data (G_OBJECT(ea_calitem),
+ "ea-calendar-cell-table", cell_data);
+ }
+ return cell_data;
+}
+
+static void
+ea_calendar_item_destory_cell_data (EaCalendarItem *ea_calitem)
+{
+ EaCellTable *cell_data;
+
+ g_return_if_fail (ea_calitem);
+
+ cell_data = g_object_get_data (G_OBJECT(ea_calitem),
+ "ea-calendar-cell-table");
+ if (cell_data) {
+ g_object_set_data (G_OBJECT(ea_calitem),
+ "ea-calendar-cell-table", NULL);
+ ea_cell_table_destroy (cell_data);
+ }
+}
+
+static gboolean
+ea_calendar_item_get_row_label (EaCalendarItem *ea_calitem, gint row,
+ gchar *buffer, gint buffer_size)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ gint index, week_num;
+ gint year, month, day;
+
+ g_return_val_if_fail (ea_calitem, FALSE);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return FALSE;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+
+ index = atk_table_get_index_at (ATK_TABLE (ea_calitem), row, 0);
+ if (!e_calendar_item_get_date_for_offset (calitem, index,
+ &year, &month, &day))
+ return FALSE;
+
+ week_num = e_calendar_item_get_week_number (calitem,
+ day, month, year);
+
+ g_snprintf (buffer, buffer_size, "week number : %d", week_num);
+ return TRUE;
+}
+
+static gboolean
+ea_calendar_item_get_column_label (EaCalendarItem *ea_calitem, gint column,
+ gchar *buffer, gint buffer_size)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ const gchar *abbr_name;
+
+ g_return_val_if_fail (ea_calitem, FALSE);
+
+ atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_calitem);
+ g_obj = atk_gobject_accessible_get_object (atk_gobj);
+ if (!g_obj)
+ return FALSE;
+
+ /* Columns are 0 = Monday ... 6 = Sunday */
+ calitem = E_CALENDAR_ITEM (g_obj);
+ abbr_name = e_get_weekday_name (column + 1, TRUE);
+ g_strlcpy (buffer, abbr_name, buffer_size);
+
+ return TRUE;
+}
+
+/* the coordinate the e-calendar canvas coord */
+gboolean
+e_calendar_item_get_day_extents (ECalendarItem *calitem,
+ gint year, gint month, gint date,
+ gint *x, gint *y,
+ gint *width, gint *height)
+{
+ GnomeCanvasItem *item;
+ GtkWidget *widget;
+ GtkStyle *style;
+ PangoFontDescription *font_desc;
+ PangoContext *pango_context;
+ PangoFontMetrics *font_metrics;
+ gint char_height, xthickness, ythickness, text_y;
+ gint new_year, new_month, num_months, months_offset;
+ gint month_x, month_y, month_cell_x, month_cell_y;
+ gint month_row, month_col;
+ gint day_row, day_col;
+ gint days_from_week_start;
+
+ g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE);
+
+ item = GNOME_CANVAS_ITEM (calitem);
+ widget = GTK_WIDGET (item->canvas);
+ style = widget->style;
+
+ /* Set up Pango prerequisites */
+ font_desc = calitem->font_desc;
+ if (!font_desc)
+ font_desc = style->font_desc;
+ pango_context = gtk_widget_get_pango_context (widget);
+ font_metrics = pango_context_get_metrics (pango_context, font_desc,
+ pango_context_get_language (pango_context));
+
+ char_height =
+ PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) +
+ PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics));
+
+ xthickness = style->xthickness;
+ ythickness = style->ythickness;
+
+ new_year = year;
+ new_month = month;
+ e_calendar_item_normalize_date (calitem, &new_year, &new_month);
+ num_months = calitem->rows * calitem->cols;
+ months_offset = (new_year - calitem->year) * 12
+ + new_month - calitem->month;
+
+ if (months_offset > num_months || months_offset < 0)
+ return FALSE;
+
+ month_row = months_offset / calitem->cols;
+ month_col = months_offset % calitem->cols;
+
+ month_x = item->x1 + xthickness + calitem->x_offset
+ + month_col * calitem->month_width;
+ month_y = item->y1 + ythickness + month_row * calitem->month_height;
+
+ month_cell_x = month_x + E_CALENDAR_ITEM_XPAD_BEFORE_WEEK_NUMBERS
+ + calitem->month_lpad + E_CALENDAR_ITEM_XPAD_BEFORE_CELLS;
+ text_y = month_y + ythickness * 2
+ + E_CALENDAR_ITEM_YPAD_ABOVE_MONTH_NAME
+ + char_height + E_CALENDAR_ITEM_YPAD_BELOW_MONTH_NAME
+ + E_CALENDAR_ITEM_YPAD_ABOVE_DAY_LETTERS + calitem->month_tpad;
+
+ month_cell_y = text_y + char_height
+ + E_CALENDAR_ITEM_YPAD_BELOW_DAY_LETTERS + 1
+ + E_CALENDAR_ITEM_YPAD_ABOVE_CELLS;
+
+ days_from_week_start =
+ e_calendar_item_get_n_days_from_week_start (calitem, new_year,
+ new_month);
+ day_row = (date + days_from_week_start - 1) / EA_CALENDAR_COLUMN_NUM;
+ day_col = (date + days_from_week_start - 1) % EA_CALENDAR_COLUMN_NUM;
+
+ *x = month_cell_x + day_col * calitem->cell_width;
+ *y = month_cell_y + day_row * calitem->cell_height;
+ *width = calitem->cell_width;
+ *height = calitem->cell_height;
+
+ return TRUE;
+}
+
+/* month is from 0 to 11 */
+gboolean
+e_calendar_item_get_date_for_offset (ECalendarItem *calitem, gint day_offset,
+ gint *year, gint *month, gint *day)
+{
+ gint start_year, start_month, start_day;
+ gint end_year, end_month, end_day;
+ GDate *start_date;
+
+ g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE);
+
+ if (!e_calendar_item_get_date_range (calitem, &start_year,
+ &start_month, &start_day,
+ &end_year, &end_month,
+ &end_day))
+ return FALSE;
+
+ start_date = g_date_new_dmy (start_day, start_month + 1, start_year);
+
+ g_date_add_days (start_date, day_offset);
+
+ *year = g_date_get_year (start_date);
+ *month = g_date_get_month (start_date) - 1;
+ *day = g_date_get_day (start_date);
+
+ return TRUE;
+}
+
+/* the arg month is from 0 to 11 */
+static gboolean
+e_calendar_item_get_offset_for_date (ECalendarItem *calitem,
+ gint year, gint month, gint day,
+ gint *offset)
+{
+ gint start_year, start_month, start_day;
+ gint end_year, end_month, end_day;
+ GDate *start_date, *end_date;
+
+ *offset = 0;
+ g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), FALSE);
+
+ if (!e_calendar_item_get_date_range (calitem, &start_year,
+ &start_month, &start_day,
+ &end_year, &end_month,
+ &end_day))
+ return FALSE;
+
+ start_date = g_date_new_dmy (start_day, start_month + 1, start_year);
+ end_date = g_date_new_dmy (day, month + 1, year);
+
+ *offset = g_date_days_between (start_date, end_date);
+ g_free (start_date);
+ g_free (end_date);
+
+ return TRUE;
+}
+
+gint
+e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem,
+ gint year, gint month)
+{
+ struct tm tmp_tm;
+ gint start_weekday, days_from_week_start;
+
+ memset (&tmp_tm, 0, sizeof (tmp_tm));
+ tmp_tm.tm_year = year - 1900;
+ tmp_tm.tm_mon = month;
+ tmp_tm.tm_mday = 1;
+ tmp_tm.tm_isdst = -1;
+ mktime (&tmp_tm);
+ start_weekday = (tmp_tm.tm_wday + 6) % 7; /* 0 to 6 */
+ days_from_week_start = (start_weekday + 7 - calitem->week_start_day)
+ % 7;
+ return days_from_week_start;
+}
+
+static void
+ea_calendar_set_focus_object (EaCalendarItem *ea_calitem, AtkObject *item_cell)
+{
+ AtkStateSet *state_set, *old_state_set;
+ AtkObject *old_cell;
+
+ old_cell = (AtkObject *)g_object_get_data (G_OBJECT(ea_calitem), "gail-focus-object");
+ if (old_cell && EA_IS_CALENDAR_CELL (old_cell)) {
+ old_state_set = atk_object_ref_state_set (old_cell);
+ atk_state_set_remove_state (old_state_set, ATK_STATE_FOCUSED);
+ g_object_unref (old_state_set);
+ }
+ if (old_cell)
+ g_object_unref (old_cell);
+
+ state_set = atk_object_ref_state_set (item_cell);
+ atk_state_set_add_state (state_set, ATK_STATE_FOCUSED);
+ g_object_set_data (G_OBJECT(ea_calitem), "gail-focus-object", item_cell);
+ g_object_unref (state_set);
+}
diff --git a/widgets/misc/a11y/ea-calendar-item.h b/widgets/misc/a11y/ea-calendar-item.h
new file mode 100644
index 0000000000..87b825b479
--- /dev/null
+++ b/widgets/misc/a11y/ea-calendar-item.h
@@ -0,0 +1,72 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Bolian Yin <bolian.yin@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __EA_CALENDAR_ITEM_H__
+#define __EA_CALENDAR_ITEM_H__
+
+#include <atk/atkgobjectaccessible.h>
+#include <misc/e-calendar-item.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define EA_TYPE_CALENDAR_ITEM (ea_calendar_item_get_type ())
+#define EA_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItem))
+#define EA_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass))
+#define EA_IS_CALENDAR_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CALENDAR_ITEM))
+#define EA_IS_CALENDAR_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CALENDAR_ITEM))
+#define EA_CALENDAR_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CALENDAR_ITEM, EaCalendarItemClass))
+
+typedef struct _EaCalendarItem EaCalendarItem;
+typedef struct _EaCalendarItemClass EaCalendarItemClass;
+
+struct _EaCalendarItem
+{
+ AtkGObjectAccessible parent;
+};
+
+GType ea_calendar_item_get_type (void);
+
+struct _EaCalendarItemClass
+{
+ AtkGObjectAccessibleClass parent_class;
+};
+
+AtkObject *ea_calendar_item_new (GObject *obj);
+gboolean e_calendar_item_get_day_extents (ECalendarItem *calitem,
+ gint year, gint month, gint date,
+ gint *x, gint *y,
+ gint *width, gint *height);
+gboolean e_calendar_item_get_date_for_offset (ECalendarItem *calitem,
+ gint day_offset,
+ gint *year, gint *month,
+ gint *day);
+gint e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem,
+ gint year, gint month);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __EA_CALENDAR_ITEM_H__ */
diff --git a/widgets/misc/a11y/ea-widgets.c b/widgets/misc/a11y/ea-widgets.c
new file mode 100644
index 0000000000..239299da0b
--- /dev/null
+++ b/widgets/misc/a11y/ea-widgets.c
@@ -0,0 +1,32 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Bolian Yin <bolian.yin@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include "a11y/ea-factory.h"
+#include "ea-calendar-item.h"
+#include "ea-widgets.h"
+
+EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_ITEM, ea_calendar_item, ea_calendar_item_new)
+
+void e_calendar_item_a11y_init (void)
+{
+ EA_SET_FACTORY (e_calendar_item_get_type (), ea_calendar_item);
+}
diff --git a/widgets/misc/a11y/ea-widgets.h b/widgets/misc/a11y/ea-widgets.h
new file mode 100644
index 0000000000..d19c908293
--- /dev/null
+++ b/widgets/misc/a11y/ea-widgets.h
@@ -0,0 +1,32 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Bolian Yin <bolian.yin@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+/* Evolution Accessibility
+*/
+
+#ifndef _EA_WIDGETS_H__
+#define _EA_WIDGETS_H__
+
+void e_calendar_item_a11y_init (void);
+
+#endif /* _EA_WIDGETS_H__ */
diff --git a/widgets/misc/e-calendar-item.c b/widgets/misc/e-calendar-item.c
index 32e74dd535..d5f5efd462 100644
--- a/widgets/misc/e-calendar-item.c
+++ b/widgets/misc/e-calendar-item.c
@@ -26,7 +26,7 @@
#endif
#include "e-calendar-item.h"
-#include "ea-widgets.h"
+#include "a11y/ea-widgets.h"
#include <time.h>
#include <string.h>
diff --git a/widgets/misc/e-search-bar.c b/widgets/misc/e-search-bar.c
index 050f840fa8..a588b73b0c 100644
--- a/widgets/misc/e-search-bar.c
+++ b/widgets/misc/e-search-bar.c
@@ -31,11 +31,11 @@
#include <glib/gi18n.h>
#include <gdk/gdkkeysyms.h>
#include <e-util/e-util.h>
+#include <e-util/e-unicode.h>
#include <e-action-combo-box.h>
#include <e-gui-utils.h>
#include <e-icon-entry.h>
-#include <e-unicode.h>
#define E_SEARCH_BAR_GET_PRIVATE(obj) \
(G_TYPE_INSTANCE_GET_PRIVATE \
diff --git a/widgets/misc/e-unicode.c b/widgets/misc/e-unicode.c
deleted file mode 100644
index 9d660b6600..0000000000
--- a/widgets/misc/e-unicode.c
+++ /dev/null
@@ -1,2052 +0,0 @@
-/*
- * e-unicode.c - utf-8 support functions for gal
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Lauris Kaplinski <lauris@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-/*
- * TODO: Break simple ligatures in e_utf8_strstrcasedecomp
- */
-
-#include <config.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <iconv.h>
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-#include <libxml/xmlmemory.h>
-
-#include <camel/camel-iconv.h>
-
-#include <glib/gi18n.h>
-#include "e-unicode.h"
-
-#define d(x)
-
-#define FONT_TESTING
-#define MAX_DECOMP 8
-
-static gint e_canonical_decomposition (gunichar ch, gunichar * buf);
-static gunichar e_stripped_char (gunichar ch);
-
-/* FIXME: this has not been ported fully yet - non ASCII people beware. */
-
-/*
- * This my favourite
- *
- * strstr doing case insensitive, decomposing search
- *
- * Lauris
- */
-
-const gchar *
-e_utf8_strstrcasedecomp (const gchar *haystack, const gchar *needle)
-{
- gunichar *nuni;
- gunichar unival;
- gint nlen;
- const gchar *o, *p;
-
- if (haystack == NULL) return NULL;
- if (needle == NULL) return NULL;
- if (strlen (needle) == 0) return haystack;
- if (strlen (haystack) == 0) return NULL;
-
- nuni = alloca (sizeof (gunichar) * strlen (needle));
-
- nlen = 0;
- for (p = e_unicode_get_utf8 (needle, &unival); p && unival; p = e_unicode_get_utf8 (p, &unival)) {
- gint sc;
- sc = e_stripped_char (unival);
- if (sc) {
- nuni[nlen++] = sc;
- }
- }
- /* NULL means there was illegal utf-8 sequence */
- if (!p) return NULL;
- /* If everything is correct, we have decomposed, lowercase, stripped needle */
- if (nlen < 1) return haystack;
-
- o = haystack;
- for (p = e_unicode_get_utf8 (o, &unival); p && unival; p = e_unicode_get_utf8 (p, &unival)) {
- gint sc;
- sc = e_stripped_char (unival);
- if (sc) {
- /* We have valid stripped char */
- if (sc == nuni[0]) {
- const gchar *q = p;
- gint npos = 1;
- while (npos < nlen) {
- q = e_unicode_get_utf8 (q, &unival);
- if (!q || !unival) return NULL;
- sc = e_stripped_char (unival);
- if ((!sc) || (sc != nuni[npos])) break;
- npos++;
- }
- if (npos == nlen) {
- return o;
- }
- }
- }
- o = p;
- }
-
- return NULL;
-}
-
-const gchar *
-e_utf8_strstrcase (const gchar *haystack, const gchar *needle)
-{
- gunichar *nuni;
- gunichar unival;
- gint nlen;
- const gchar *o, *p;
-
- if (haystack == NULL) return NULL;
- if (needle == NULL) return NULL;
- if (strlen (needle) == 0) return haystack;
- if (strlen (haystack) == 0) return NULL;
-
- nuni = alloca (sizeof (gunichar) * strlen (needle));
-
- nlen = 0;
- for (p = e_unicode_get_utf8 (needle, &unival); p && unival; p = e_unicode_get_utf8 (p, &unival)) {
- nuni[nlen++] = g_unichar_tolower (unival);
- }
- /* NULL means there was illegal utf-8 sequence */
- if (!p) return NULL;
-
- o = haystack;
- for (p = e_unicode_get_utf8 (o, &unival); p && unival; p = e_unicode_get_utf8 (p, &unival)) {
- gint sc;
- sc = g_unichar_tolower (unival);
- /* We have valid stripped char */
- if (sc == nuni[0]) {
- const gchar *q = p;
- gint npos = 1;
- while (npos < nlen) {
- q = e_unicode_get_utf8 (q, &unival);
- if (!q || !unival) return NULL;
- sc = g_unichar_tolower (unival);
- if (sc != nuni[npos]) break;
- npos++;
- }
- if (npos == nlen) {
- return o;
- }
- }
- o = p;
- }
-
- return NULL;
-}
-
-#if 0
-const gchar *
-e_utf8_strstrcase (const gchar *haystack, const gchar *needle)
-{
- gchar *p;
- gunichar *huni, *nuni;
- gunichar unival;
- gint hlen, nlen, hp, np;
-
- if (haystack == NULL) return NULL;
- if (needle == NULL) return NULL;
- if (strlen (needle) == 0) return haystack;
-
- huni = alloca (sizeof (gunichar) * strlen (haystack));
-
- for (hlen = 0, p = e_unicode_get_utf8 (haystack, &unival); p && unival; hlen++, p = e_unicode_get_utf8 (p, &unival)) {
- huni[hlen] = g_unichar_tolower (unival);
- }
-
- if (!p) return NULL;
- if (hlen == 0) return NULL;
-
- nuni = alloca (sizeof (gunichar) * strlen (needle));
-
- for (nlen = 0, p = e_unicode_get_utf8 (needle, &unival); p && unival; nlen++, p = e_unicode_get_utf8 (p, &unival)) {
- nuni[nlen] = g_unichar_tolower (unival);
- }
-
- if (!p) return NULL;
- if (nlen == 0) return NULL;
-
- if (hlen < nlen) return NULL;
-
- for (hp = 0; hp <= hlen - nlen; hp++) {
- for (np = 0; np < nlen; np++) {
- if (huni[hp + np] != nuni[np]) break;
- }
- if (np == nlen) return haystack + unicode_offset_to_index (haystack, hp);
- }
-
- return NULL;
-}
-#endif
-
-gchar *
-e_utf8_from_gtk_event_key (GtkWidget *widget, guint keyval, const gchar *string)
-{
- gint unival;
- gchar *utf;
- gint unilen;
-
- if (keyval == GDK_VoidSymbol) {
- utf = e_utf8_from_locale_string (string);
- } else {
- unival = gdk_keyval_to_unicode (keyval);
-
- if (unival < ' ') return NULL;
-
- utf = g_new (gchar, 7);
-
- unilen = e_unichar_to_utf8 (unival, utf);
-
- utf[unilen] = '\0';
- }
-
- return utf;
-}
-
-gchar *
-e_utf8_from_iconv_string_sized (iconv_t ic, const gchar *string, gint bytes)
-{
- char *new, *ob;
- const char *ib;
- size_t ibl, obl;
-
- if (!string) return NULL;
-
- if (ic == (iconv_t) -1) {
- gint i;
- /* iso-8859-1 */
- ib = (char *) string;
- new = ob = (char *)g_new (unsigned char, bytes * 2 + 1);
- for (i = 0; i < (bytes); i ++) {
- ob += e_unichar_to_utf8 (ib[i], ob);
- }
- *ob = '\0';
- return new;
- }
-
- ib = string;
- ibl = bytes;
- new = ob = g_new (gchar, ibl * 6 + 1);
- obl = ibl * 6;
-
- while (ibl > 0) {
- camel_iconv (ic, &ib, &ibl, &ob, &obl);
- if (ibl > 0) {
- gint len;
- if ((*ib & 0x80) == 0x00) len = 1;
- else if ((*ib &0xe0) == 0xc0) len = 2;
- else if ((*ib &0xf0) == 0xe0) len = 3;
- else if ((*ib &0xf8) == 0xf0) len = 4;
- else {
- g_warning ("Invalid UTF-8 sequence");
- break;
- }
- ib += len;
- ibl = bytes - (ib - string);
- if (ibl > bytes) ibl = 0;
- *ob++ = '_';
- obl--;
- }
- }
-
- *ob = '\0';
-
- return new;
-}
-
-gchar *
-e_utf8_from_iconv_string (iconv_t ic, const gchar *string)
-{
- if (!string) return NULL;
- return e_utf8_from_iconv_string_sized (ic, string, strlen (string));
-}
-
-gchar *
-e_utf8_to_iconv_string_sized (iconv_t ic, const gchar *string, gint bytes)
-{
- char *new, *ob;
- const char *ib;
- size_t ibl, obl;
-
- if (!string) return NULL;
-
- if (ic == (iconv_t) -1) {
- gint len;
- const gchar *u;
- gunichar uc;
-
- new = (char *)g_new (unsigned char, bytes * 4 + 1);
- u = string;
- len = 0;
-
- while ((u) && (u - string < bytes)) {
- u = e_unicode_get_utf8 (u, &uc);
- new[len++] = uc & 0xff;
- }
- new[len] = '\0';
- return new;
- }
-
- ib = string;
- ibl = bytes;
- new = ob = g_new (char, ibl * 4 + 4);
- obl = ibl * 4;
-
- while (ibl > 0) {
- camel_iconv (ic, &ib, &ibl, &ob, &obl);
- if (ibl > 0) {
- gint len;
- if ((*ib & 0x80) == 0x00) len = 1;
- else if ((*ib &0xe0) == 0xc0) len = 2;
- else if ((*ib &0xf0) == 0xe0) len = 3;
- else if ((*ib &0xf8) == 0xf0) len = 4;
- else {
- g_warning ("Invalid UTF-8 sequence");
- break;
- }
- ib += len;
- ibl = bytes - (ib - string);
- if (ibl > bytes) ibl = 0;
-
- /* FIXME: this is wrong... what if the destination charset is 16 or 32 bit? */
- *ob++ = '_';
- obl--;
- }
- }
-
- /* Make sure to terminate with plenty of padding */
- memset (ob, 0, 4);
-
- return new;
-}
-
-gchar *
-e_utf8_to_iconv_string (iconv_t ic, const gchar *string)
-{
- if (!string) return NULL;
- return e_utf8_to_iconv_string_sized (ic, string, strlen (string));
-}
-
-gchar *
-e_utf8_from_charset_string_sized (const gchar *charset, const gchar *string, gint bytes)
-{
- iconv_t ic;
- char *ret;
-
- if (!string) return NULL;
-
- ic = camel_iconv_open("utf-8", charset);
- ret = e_utf8_from_iconv_string_sized (ic, string, bytes);
- camel_iconv_close(ic);
-
- return ret;
-}
-
-gchar *
-e_utf8_from_charset_string (const gchar *charset, const gchar *string)
-{
- if (!string) return NULL;
- return e_utf8_from_charset_string_sized (charset, string, strlen (string));
-}
-
-gchar *
-e_utf8_to_charset_string_sized (const gchar *charset, const gchar *string, gint bytes)
-{
- iconv_t ic;
- char *ret;
-
- if (!string) return NULL;
-
- ic = camel_iconv_open(charset, "utf-8");
- ret = e_utf8_to_iconv_string_sized (ic, string, bytes);
- camel_iconv_close(ic);
-
- return ret;
-}
-
-gchar *
-e_utf8_to_charset_string (const gchar *charset, const gchar *string)
-{
- if (!string) return NULL;
- return e_utf8_to_charset_string_sized (charset, string, strlen (string));
-}
-
-gchar *
-e_utf8_from_locale_string_sized (const gchar *string, gint bytes)
-{
- iconv_t ic;
- char *ret;
-
- if (!string) return NULL;
-
- ic = camel_iconv_open("utf-8", camel_iconv_locale_charset());
- ret = e_utf8_from_iconv_string_sized (ic, string, bytes);
- camel_iconv_close(ic);
-
- return ret;
-}
-
-gchar *
-e_utf8_from_locale_string (const gchar *string)
-{
- if (!string) return NULL;
- return e_utf8_from_locale_string_sized (string, strlen (string));
-}
-
-gchar *
-e_utf8_to_locale_string_sized (const gchar *string, gint bytes)
-{
- iconv_t ic;
- char *ret;
-
- if (!string) return NULL;
-
- ic = camel_iconv_open(camel_iconv_locale_charset(), "utf-8");
- ret = e_utf8_to_iconv_string_sized (ic, string, bytes);
- camel_iconv_close(ic);
-
- return ret;
-}
-
-gchar *
-e_utf8_to_locale_string (const gchar *string)
-{
- if (!string) return NULL;
- return e_utf8_to_locale_string_sized (string, strlen (string));
-}
-
-gboolean
-e_utf8_is_ascii (const gchar *string)
-{
- char c;
-
- g_return_val_if_fail (string != NULL, FALSE);
-
- for (; (c = *string); string++) {
- if (c & 0x80)
- return FALSE;
- }
-
- return TRUE;
-}
-
-gchar *
-e_utf8_gtk_entry_get_text (GtkEntry *entry)
-{
- return g_strdup (gtk_entry_get_text (entry));
-}
-
-gchar *
-e_utf8_gtk_editable_get_text (GtkEditable *editable)
-{
- return gtk_editable_get_chars (editable, 0, -1);
-}
-
-gchar *
-e_utf8_gtk_editable_get_chars (GtkEditable *editable, gint start, gint end)
-{
- return gtk_editable_get_chars (editable, start, end);
-}
-
-void
-e_utf8_gtk_editable_insert_text (GtkEditable *editable, const gchar *text, gint length, gint *position)
-{
- gtk_editable_insert_text (editable, text, length, position);
-}
-
-void
-e_utf8_gtk_editable_set_text (GtkEditable *editable, const gchar *text)
-{
- int position;
-
- gtk_editable_delete_text(editable, 0, -1);
- gtk_editable_insert_text (editable, text, strlen (text), &position);
-}
-
-void
-e_utf8_gtk_entry_set_text (GtkEntry *entry, const gchar *text)
-{
- if (!text)
- gtk_entry_set_text(entry, "");
- else
- gtk_entry_set_text (entry, text);
-}
-
-/*
- * Translate \U+XXXX\ sequences to utf8 chars
- */
-
-gchar *
-e_utf8_xml1_decode (const gchar *text)
-{
- const guchar *c;
- gchar *u, *d;
- int len, s;
-
- g_return_val_if_fail (text != NULL, NULL);
-
- len = strlen (text)+1;
- /* len * 2 is absolute maximum */
- u = d = g_malloc (len * 2);
-
- c = (guchar *)text;
- s = 0;
- while (s < len) {
- if ((s <= (len - 8)) &&
- (c[s ] == '\\') &&
- (c[s + 1] == 'U' ) &&
- (c[s + 2] == '+' ) &&
- isxdigit (c[s + 3]) &&
- isxdigit (c[s + 4]) &&
- isxdigit (c[s + 5]) &&
- isxdigit (c[s + 6]) &&
- (c[s + 7] == '\\')) {
- /* Valid \U+XXXX\ sequence */
- int unival;
- unival = strtol ((char *)(c + s + 3), NULL, 16);
- d += e_unichar_to_utf8 (unival, d);
- s += 8;
- } else if (c[s] > 127) {
- /* fixme: We assume iso-8859-1 currently */
- d += e_unichar_to_utf8 (c[s], d);
- s += 1;
- } else {
- *d++ = c[s++];
- }
- }
- *d++ = '\0';
- u = g_realloc (u, (d - u));
-
- return u;
-}
-
-gchar *
-e_utf8_xml1_encode (const gchar *text)
-{
- gchar *u, *d, *c;
- unsigned int unival;
- int len;
-
- g_return_val_if_fail (text != NULL, NULL);
-
- len = 0;
- for (u = e_unicode_get_utf8 (text, &unival); u && unival; u = e_unicode_get_utf8 (u, &unival)) {
- if ((unival >= 0x80) || (unival == '\\')) {
- len += 8;
- } else {
- len += 1;
- }
- }
- d = c = (char *)g_new (guchar, len + 1);
-
- for (u = e_unicode_get_utf8 (text, &unival); u && unival; u = e_unicode_get_utf8 (u, &unival)) {
- if ((unival >= 0x80) || (unival == '\\')) {
- *c++ = '\\';
- *c++ = 'U';
- *c++ = '+';
- c += sprintf (c, "%04x", unival);
- *c++ = '\\';
- } else {
- *c++ = unival;
- }
- }
- *c = '\0';
-
- return d;
-}
-
-/**
- * e_unichar_to_utf8:
- * @c: a ISO10646 character code
- * @outbuf: output buffer, must have at least 6 bytes of space.
- * If %NULL, the length will be computed and returned
- * and nothing will be written to @out.
- *
- * Convert a single character to utf8
- *
- * Return value: number of bytes written
- **/
-
-gint
-e_unichar_to_utf8 (gint c, gchar *outbuf)
-{
- size_t len = 0;
- int first;
- int i;
-
- if (c < 0x80)
- {
- first = 0;
- len = 1;
- }
- else if (c < 0x800)
- {
- first = 0xc0;
- len = 2;
- }
- else if (c < 0x10000)
- {
- first = 0xe0;
- len = 3;
- }
- else if (c < 0x200000)
- {
- first = 0xf0;
- len = 4;
- }
- else if (c < 0x4000000)
- {
- first = 0xf8;
- len = 5;
- }
- else
- {
- first = 0xfc;
- len = 6;
- }
-
- if (outbuf)
- {
- for (i = len - 1; i > 0; --i)
- {
- outbuf[i] = (c & 0x3f) | 0x80;
- c >>= 6;
- }
- outbuf[0] = c | first;
- }
-
- return len;
-}
-
-gchar *
-e_unicode_get_utf8 (const gchar *text, gunichar *out)
-{
- *out = g_utf8_get_char (text);
- return (*out == (gunichar)-1) ? NULL : g_utf8_next_char (text);
-}
-
-/*
- * Canonical decomposition
- *
- * It is copied here from libunicode, because we do not want malloc
- *
- */
-
-typedef struct
-{
- unsigned short ch;
- char *expansion;
-} e_decomposition;
-
-static e_decomposition e_decomp_table[] =
-{
- { 0x00c0, "\x00\x41\x03\x00\0" },
- { 0x00c1, "\x00\x41\x03\x01\0" },
- { 0x00c2, "\x00\x41\x03\x02\0" },
- { 0x00c3, "\x00\x41\x03\x03\0" },
- { 0x00c4, "\x00\x41\x03\x08\0" },
- { 0x00c5, "\x00\x41\x03\x0a\0" },
- { 0x00c7, "\x00\x43\x03\x27\0" },
- { 0x00c8, "\x00\x45\x03\x00\0" },
- { 0x00c9, "\x00\x45\x03\x01\0" },
- { 0x00ca, "\x00\x45\x03\x02\0" },
- { 0x00cb, "\x00\x45\x03\x08\0" },
- { 0x00cc, "\x00\x49\x03\x00\0" },
- { 0x00cd, "\x00\x49\x03\x01\0" },
- { 0x00ce, "\x00\x49\x03\x02\0" },
- { 0x00cf, "\x00\x49\x03\x08\0" },
- { 0x00d1, "\x00\x4e\x03\x03\0" },
- { 0x00d2, "\x00\x4f\x03\x00\0" },
- { 0x00d3, "\x00\x4f\x03\x01\0" },
- { 0x00d4, "\x00\x4f\x03\x02\0" },
- { 0x00d5, "\x00\x4f\x03\x03\0" },
- { 0x00d6, "\x00\x4f\x03\x08\0" },
- { 0x00d9, "\x00\x55\x03\x00\0" },
- { 0x00da, "\x00\x55\x03\x01\0" },
- { 0x00db, "\x00\x55\x03\x02\0" },
- { 0x00dc, "\x00\x55\x03\x08\0" },
- { 0x00dd, "\x00\x59\x03\x01\0" },
- { 0x00e0, "\x00\x61\x03\x00\0" },
- { 0x00e1, "\x00\x61\x03\x01\0" },
- { 0x00e2, "\x00\x61\x03\x02\0" },
- { 0x00e3, "\x00\x61\x03\x03\0" },
- { 0x00e4, "\x00\x61\x03\x08\0" },
- { 0x00e5, "\x00\x61\x03\x0a\0" },
- { 0x00e7, "\x00\x63\x03\x27\0" },
- { 0x00e8, "\x00\x65\x03\x00\0" },
- { 0x00e9, "\x00\x65\x03\x01\0" },
- { 0x00ea, "\x00\x65\x03\x02\0" },
- { 0x00eb, "\x00\x65\x03\x08\0" },
- { 0x00ec, "\x00\x69\x03\x00\0" },
- { 0x00ed, "\x00\x69\x03\x01\0" },
- { 0x00ee, "\x00\x69\x03\x02\0" },
- { 0x00ef, "\x00\x69\x03\x08\0" },
- { 0x00f1, "\x00\x6e\x03\x03\0" },
- { 0x00f2, "\x00\x6f\x03\x00\0" },
- { 0x00f3, "\x00\x6f\x03\x01\0" },
- { 0x00f4, "\x00\x6f\x03\x02\0" },
- { 0x00f5, "\x00\x6f\x03\x03\0" },
- { 0x00f6, "\x00\x6f\x03\x08\0" },
- { 0x00f9, "\x00\x75\x03\x00\0" },
- { 0x00fa, "\x00\x75\x03\x01\0" },
- { 0x00fb, "\x00\x75\x03\x02\0" },
- { 0x00fc, "\x00\x75\x03\x08\0" },
- { 0x00fd, "\x00\x79\x03\x01\0" },
- { 0x00ff, "\x00\x79\x03\x08\0" },
- { 0x0100, "\x00\x41\x03\x04\0" },
- { 0x0101, "\x00\x61\x03\x04\0" },
- { 0x0102, "\x00\x41\x03\x06\0" },
- { 0x0103, "\x00\x61\x03\x06\0" },
- { 0x0104, "\x00\x41\x03\x28\0" },
- { 0x0105, "\x00\x61\x03\x28\0" },
- { 0x0106, "\x00\x43\x03\x01\0" },
- { 0x0107, "\x00\x63\x03\x01\0" },
- { 0x0108, "\x00\x43\x03\x02\0" },
- { 0x0109, "\x00\x63\x03\x02\0" },
- { 0x010a, "\x00\x43\x03\x07\0" },
- { 0x010b, "\x00\x63\x03\x07\0" },
- { 0x010c, "\x00\x43\x03\x0c\0" },
- { 0x010d, "\x00\x63\x03\x0c\0" },
- { 0x010e, "\x00\x44\x03\x0c\0" },
- { 0x010f, "\x00\x64\x03\x0c\0" },
- { 0x0112, "\x00\x45\x03\x04\0" },
- { 0x0113, "\x00\x65\x03\x04\0" },
- { 0x0114, "\x00\x45\x03\x06\0" },
- { 0x0115, "\x00\x65\x03\x06\0" },
- { 0x0116, "\x00\x45\x03\x07\0" },
- { 0x0117, "\x00\x65\x03\x07\0" },
- { 0x0118, "\x00\x45\x03\x28\0" },
- { 0x0119, "\x00\x65\x03\x28\0" },
- { 0x011a, "\x00\x45\x03\x0c\0" },
- { 0x011b, "\x00\x65\x03\x0c\0" },
- { 0x011c, "\x00\x47\x03\x02\0" },
- { 0x011d, "\x00\x67\x03\x02\0" },
- { 0x011e, "\x00\x47\x03\x06\0" },
- { 0x011f, "\x00\x67\x03\x06\0" },
- { 0x0120, "\x00\x47\x03\x07\0" },
- { 0x0121, "\x00\x67\x03\x07\0" },
- { 0x0122, "\x00\x47\x03\x27\0" },
- { 0x0123, "\x00\x67\x03\x27\0" },
- { 0x0124, "\x00\x48\x03\x02\0" },
- { 0x0125, "\x00\x68\x03\x02\0" },
- { 0x0128, "\x00\x49\x03\x03\0" },
- { 0x0129, "\x00\x69\x03\x03\0" },
- { 0x012a, "\x00\x49\x03\x04\0" },
- { 0x012b, "\x00\x69\x03\x04\0" },
- { 0x012c, "\x00\x49\x03\x06\0" },
- { 0x012d, "\x00\x69\x03\x06\0" },
- { 0x012e, "\x00\x49\x03\x28\0" },
- { 0x012f, "\x00\x69\x03\x28\0" },
- { 0x0130, "\x00\x49\x03\x07\0" },
- { 0x0134, "\x00\x4a\x03\x02\0" },
- { 0x0135, "\x00\x6a\x03\x02\0" },
- { 0x0136, "\x00\x4b\x03\x27\0" },
- { 0x0137, "\x00\x6b\x03\x27\0" },
- { 0x0139, "\x00\x4c\x03\x01\0" },
- { 0x013a, "\x00\x6c\x03\x01\0" },
- { 0x013b, "\x00\x4c\x03\x27\0" },
- { 0x013c, "\x00\x6c\x03\x27\0" },
- { 0x013d, "\x00\x4c\x03\x0c\0" },
- { 0x013e, "\x00\x6c\x03\x0c\0" },
- { 0x0143, "\x00\x4e\x03\x01\0" },
- { 0x0144, "\x00\x6e\x03\x01\0" },
- { 0x0145, "\x00\x4e\x03\x27\0" },
- { 0x0146, "\x00\x6e\x03\x27\0" },
- { 0x0147, "\x00\x4e\x03\x0c\0" },
- { 0x0148, "\x00\x6e\x03\x0c\0" },
- { 0x014c, "\x00\x4f\x03\x04\0" },
- { 0x014d, "\x00\x6f\x03\x04\0" },
- { 0x014e, "\x00\x4f\x03\x06\0" },
- { 0x014f, "\x00\x6f\x03\x06\0" },
- { 0x0150, "\x00\x4f\x03\x0b\0" },
- { 0x0151, "\x00\x6f\x03\x0b\0" },
- { 0x0154, "\x00\x52\x03\x01\0" },
- { 0x0155, "\x00\x72\x03\x01\0" },
- { 0x0156, "\x00\x52\x03\x27\0" },
- { 0x0157, "\x00\x72\x03\x27\0" },
- { 0x0158, "\x00\x52\x03\x0c\0" },
- { 0x0159, "\x00\x72\x03\x0c\0" },
- { 0x015a, "\x00\x53\x03\x01\0" },
- { 0x015b, "\x00\x73\x03\x01\0" },
- { 0x015c, "\x00\x53\x03\x02\0" },
- { 0x015d, "\x00\x73\x03\x02\0" },
- { 0x015e, "\x00\x53\x03\x27\0" },
- { 0x015f, "\x00\x73\x03\x27\0" },
- { 0x0160, "\x00\x53\x03\x0c\0" },
- { 0x0161, "\x00\x73\x03\x0c\0" },
- { 0x0162, "\x00\x54\x03\x27\0" },
- { 0x0163, "\x00\x74\x03\x27\0" },
- { 0x0164, "\x00\x54\x03\x0c\0" },
- { 0x0165, "\x00\x74\x03\x0c\0" },
- { 0x0168, "\x00\x55\x03\x03\0" },
- { 0x0169, "\x00\x75\x03\x03\0" },
- { 0x016a, "\x00\x55\x03\x04\0" },
- { 0x016b, "\x00\x75\x03\x04\0" },
- { 0x016c, "\x00\x55\x03\x06\0" },
- { 0x016d, "\x00\x75\x03\x06\0" },
- { 0x016e, "\x00\x55\x03\x0a\0" },
- { 0x016f, "\x00\x75\x03\x0a\0" },
- { 0x0170, "\x00\x55\x03\x0b\0" },
- { 0x0171, "\x00\x75\x03\x0b\0" },
- { 0x0172, "\x00\x55\x03\x28\0" },
- { 0x0173, "\x00\x75\x03\x28\0" },
- { 0x0174, "\x00\x57\x03\x02\0" },
- { 0x0175, "\x00\x77\x03\x02\0" },
- { 0x0176, "\x00\x59\x03\x02\0" },
- { 0x0177, "\x00\x79\x03\x02\0" },
- { 0x0178, "\x00\x59\x03\x08\0" },
- { 0x0179, "\x00\x5a\x03\x01\0" },
- { 0x017a, "\x00\x7a\x03\x01\0" },
- { 0x017b, "\x00\x5a\x03\x07\0" },
- { 0x017c, "\x00\x7a\x03\x07\0" },
- { 0x017d, "\x00\x5a\x03\x0c\0" },
- { 0x017e, "\x00\x7a\x03\x0c\0" },
- { 0x01a0, "\x00\x4f\x03\x1b\0" },
- { 0x01a1, "\x00\x6f\x03\x1b\0" },
- { 0x01af, "\x00\x55\x03\x1b\0" },
- { 0x01b0, "\x00\x75\x03\x1b\0" },
- { 0x01cd, "\x00\x41\x03\x0c\0" },
- { 0x01ce, "\x00\x61\x03\x0c\0" },
- { 0x01cf, "\x00\x49\x03\x0c\0" },
- { 0x01d0, "\x00\x69\x03\x0c\0" },
- { 0x01d1, "\x00\x4f\x03\x0c\0" },
- { 0x01d2, "\x00\x6f\x03\x0c\0" },
- { 0x01d3, "\x00\x55\x03\x0c\0" },
- { 0x01d4, "\x00\x75\x03\x0c\0" },
- { 0x01d5, "\x00\x55\x03\x08\x03\x04\0" },
- { 0x01d6, "\x00\x75\x03\x08\x03\x04\0" },
- { 0x01d7, "\x00\x55\x03\x08\x03\x01\0" },
- { 0x01d8, "\x00\x75\x03\x08\x03\x01\0" },
- { 0x01d9, "\x00\x55\x03\x08\x03\x0c\0" },
- { 0x01da, "\x00\x75\x03\x08\x03\x0c\0" },
- { 0x01db, "\x00\x55\x03\x08\x03\x00\0" },
- { 0x01dc, "\x00\x75\x03\x08\x03\x00\0" },
- { 0x01de, "\x00\x41\x03\x08\x03\x04\0" },
- { 0x01df, "\x00\x61\x03\x08\x03\x04\0" },
- { 0x01e0, "\x00\x41\x03\x07\x03\x04\0" },
- { 0x01e1, "\x00\x61\x03\x07\x03\x04\0" },
- { 0x01e2, "\x00\xc6\x03\x04\0" },
- { 0x01e3, "\x00\xe6\x03\x04\0" },
- { 0x01e6, "\x00\x47\x03\x0c\0" },
- { 0x01e7, "\x00\x67\x03\x0c\0" },
- { 0x01e8, "\x00\x4b\x03\x0c\0" },
- { 0x01e9, "\x00\x6b\x03\x0c\0" },
- { 0x01ea, "\x00\x4f\x03\x28\0" },
- { 0x01eb, "\x00\x6f\x03\x28\0" },
- { 0x01ec, "\x00\x4f\x03\x28\x03\x04\0" },
- { 0x01ed, "\x00\x6f\x03\x28\x03\x04\0" },
- { 0x01ee, "\x01\xb7\x03\x0c\0" },
- { 0x01ef, "\x02\x92\x03\x0c\0" },
- { 0x01f0, "\x00\x6a\x03\x0c\0" },
- { 0x01f4, "\x00\x47\x03\x01\0" },
- { 0x01f5, "\x00\x67\x03\x01\0" },
- { 0x01fa, "\x00\x41\x03\x0a\x03\x01\0" },
- { 0x01fb, "\x00\x61\x03\x0a\x03\x01\0" },
- { 0x01fc, "\x00\xc6\x03\x01\0" },
- { 0x01fd, "\x00\xe6\x03\x01\0" },
- { 0x01fe, "\x00\xd8\x03\x01\0" },
- { 0x01ff, "\x00\xf8\x03\x01\0" },
- { 0x0200, "\x00\x41\x03\x0f\0" },
- { 0x0201, "\x00\x61\x03\x0f\0" },
- { 0x0202, "\x00\x41\x03\x11\0" },
- { 0x0203, "\x00\x61\x03\x11\0" },
- { 0x0204, "\x00\x45\x03\x0f\0" },
- { 0x0205, "\x00\x65\x03\x0f\0" },
- { 0x0206, "\x00\x45\x03\x11\0" },
- { 0x0207, "\x00\x65\x03\x11\0" },
- { 0x0208, "\x00\x49\x03\x0f\0" },
- { 0x0209, "\x00\x69\x03\x0f\0" },
- { 0x020a, "\x00\x49\x03\x11\0" },
- { 0x020b, "\x00\x69\x03\x11\0" },
- { 0x020c, "\x00\x4f\x03\x0f\0" },
- { 0x020d, "\x00\x6f\x03\x0f\0" },
- { 0x020e, "\x00\x4f\x03\x11\0" },
- { 0x020f, "\x00\x6f\x03\x11\0" },
- { 0x0210, "\x00\x52\x03\x0f\0" },
- { 0x0211, "\x00\x72\x03\x0f\0" },
- { 0x0212, "\x00\x52\x03\x11\0" },
- { 0x0213, "\x00\x72\x03\x11\0" },
- { 0x0214, "\x00\x55\x03\x0f\0" },
- { 0x0215, "\x00\x75\x03\x0f\0" },
- { 0x0216, "\x00\x55\x03\x11\0" },
- { 0x0217, "\x00\x75\x03\x11\0" },
- { 0x0340, "\x03\x00\0" },
- { 0x0341, "\x03\x01\0" },
- { 0x0343, "\x03\x13\0" },
- { 0x0344, "\x03\x08\x03\x01\0" },
- { 0x0374, "\x02\xb9\0" },
- { 0x037e, "\x00\x3b\0" },
- { 0x0385, "\x00\xa8\x03\x01\0" },
- { 0x0386, "\x03\x91\x03\x01\0" },
- { 0x0387, "\x00\xb7\0" },
- { 0x0388, "\x03\x95\x03\x01\0" },
- { 0x0389, "\x03\x97\x03\x01\0" },
- { 0x038a, "\x03\x99\x03\x01\0" },
- { 0x038c, "\x03\x9f\x03\x01\0" },
- { 0x038e, "\x03\xa5\x03\x01\0" },
- { 0x038f, "\x03\xa9\x03\x01\0" },
- { 0x0390, "\x03\xb9\x03\x08\x03\x01\0" },
- { 0x03aa, "\x03\x99\x03\x08\0" },
- { 0x03ab, "\x03\xa5\x03\x08\0" },
- { 0x03ac, "\x03\xb1\x03\x01\0" },
- { 0x03ad, "\x03\xb5\x03\x01\0" },
- { 0x03ae, "\x03\xb7\x03\x01\0" },
- { 0x03af, "\x03\xb9\x03\x01\0" },
- { 0x03b0, "\x03\xc5\x03\x08\x03\x01\0" },
- { 0x03ca, "\x03\xb9\x03\x08\0" },
- { 0x03cb, "\x03\xc5\x03\x08\0" },
- { 0x03cc, "\x03\xbf\x03\x01\0" },
- { 0x03cd, "\x03\xc5\x03\x01\0" },
- { 0x03ce, "\x03\xc9\x03\x01\0" },
- { 0x03d3, "\x03\xd2\x03\x01\0" },
- { 0x03d4, "\x03\xd2\x03\x08\0" },
- { 0x0401, "\x04\x15\x03\x08\0" },
- { 0x0403, "\x04\x13\x03\x01\0" },
- { 0x0407, "\x04\x06\x03\x08\0" },
- { 0x040c, "\x04\x1a\x03\x01\0" },
- { 0x040e, "\x04\x23\x03\x06\0" },
- { 0x0419, "\x04\x18\x03\x06\0" },
- { 0x0439, "\x04\x38\x03\x06\0" },
- { 0x0451, "\x04\x35\x03\x08\0" },
- { 0x0453, "\x04\x33\x03\x01\0" },
- { 0x0457, "\x04\x56\x03\x08\0" },
- { 0x045c, "\x04\x3a\x03\x01\0" },
- { 0x045e, "\x04\x43\x03\x06\0" },
- { 0x0476, "\x04\x74\x03\x0f\0" },
- { 0x0477, "\x04\x75\x03\x0f\0" },
- { 0x04c1, "\x04\x16\x03\x06\0" },
- { 0x04c2, "\x04\x36\x03\x06\0" },
- { 0x04d0, "\x04\x10\x03\x06\0" },
- { 0x04d1, "\x04\x30\x03\x06\0" },
- { 0x04d2, "\x04\x10\x03\x08\0" },
- { 0x04d3, "\x04\x30\x03\x08\0" },
- { 0x04d6, "\x04\x15\x03\x06\0" },
- { 0x04d7, "\x04\x35\x03\x06\0" },
- { 0x04da, "\x04\xd8\x03\x08\0" },
- { 0x04db, "\x04\xd9\x03\x08\0" },
- { 0x04dc, "\x04\x16\x03\x08\0" },
- { 0x04dd, "\x04\x36\x03\x08\0" },
- { 0x04de, "\x04\x17\x03\x08\0" },
- { 0x04df, "\x04\x37\x03\x08\0" },
- { 0x04e2, "\x04\x18\x03\x04\0" },
- { 0x04e3, "\x04\x38\x03\x04\0" },
- { 0x04e4, "\x04\x18\x03\x08\0" },
- { 0x04e5, "\x04\x38\x03\x08\0" },
- { 0x04e6, "\x04\x1e\x03\x08\0" },
- { 0x04e7, "\x04\x3e\x03\x08\0" },
- { 0x04ea, "\x04\xe8\x03\x08\0" },
- { 0x04eb, "\x04\xe9\x03\x08\0" },
- { 0x04ee, "\x04\x23\x03\x04\0" },
- { 0x04ef, "\x04\x43\x03\x04\0" },
- { 0x04f0, "\x04\x23\x03\x08\0" },
- { 0x04f1, "\x04\x43\x03\x08\0" },
- { 0x04f2, "\x04\x23\x03\x0b\0" },
- { 0x04f3, "\x04\x43\x03\x0b\0" },
- { 0x04f4, "\x04\x27\x03\x08\0" },
- { 0x04f5, "\x04\x47\x03\x08\0" },
- { 0x04f8, "\x04\x2b\x03\x08\0" },
- { 0x04f9, "\x04\x4b\x03\x08\0" },
- { 0x0929, "\x09\x28\x09\x3c\0" },
- { 0x0931, "\x09\x30\x09\x3c\0" },
- { 0x0934, "\x09\x33\x09\x3c\0" },
- { 0x0958, "\x09\x15\x09\x3c\0" },
- { 0x0959, "\x09\x16\x09\x3c\0" },
- { 0x095a, "\x09\x17\x09\x3c\0" },
- { 0x095b, "\x09\x1c\x09\x3c\0" },
- { 0x095c, "\x09\x21\x09\x3c\0" },
- { 0x095d, "\x09\x22\x09\x3c\0" },
- { 0x095e, "\x09\x2b\x09\x3c\0" },
- { 0x095f, "\x09\x2f\x09\x3c\0" },
- { 0x09b0, "\x09\xac\x09\xbc\0" },
- { 0x09cb, "\x09\xc7\x09\xbe\0" },
- { 0x09cc, "\x09\xc7\x09\xd7\0" },
- { 0x09dc, "\x09\xa1\x09\xbc\0" },
- { 0x09dd, "\x09\xa2\x09\xbc\0" },
- { 0x09df, "\x09\xaf\x09\xbc\0" },
- { 0x0a59, "\x0a\x16\x0a\x3c\0" },
- { 0x0a5a, "\x0a\x17\x0a\x3c\0" },
- { 0x0a5b, "\x0a\x1c\x0a\x3c\0" },
- { 0x0a5c, "\x0a\x21\x0a\x3c\0" },
- { 0x0a5e, "\x0a\x2b\x0a\x3c\0" },
- { 0x0b48, "\x0b\x47\x0b\x56\0" },
- { 0x0b4b, "\x0b\x47\x0b\x3e\0" },
- { 0x0b4c, "\x0b\x47\x0b\x57\0" },
- { 0x0b5c, "\x0b\x21\x0b\x3c\0" },
- { 0x0b5d, "\x0b\x22\x0b\x3c\0" },
- { 0x0b5f, "\x0b\x2f\x0b\x3c\0" },
- { 0x0b94, "\x0b\x92\x0b\xd7\0" },
- { 0x0bca, "\x0b\xc6\x0b\xbe\0" },
- { 0x0bcb, "\x0b\xc7\x0b\xbe\0" },
- { 0x0bcc, "\x0b\xc6\x0b\xd7\0" },
- { 0x0c48, "\x0c\x46\x0c\x56\0" },
- { 0x0cc0, "\x0c\xbf\x0c\xd5\0" },
- { 0x0cc7, "\x0c\xc6\x0c\xd5\0" },
- { 0x0cc8, "\x0c\xc6\x0c\xd6\0" },
- { 0x0cca, "\x0c\xc6\x0c\xc2\0" },
- { 0x0ccb, "\x0c\xc6\x0c\xc2\x0c\xd5\0" },
- { 0x0d4a, "\x0d\x46\x0d\x3e\0" },
- { 0x0d4b, "\x0d\x47\x0d\x3e\0" },
- { 0x0d4c, "\x0d\x46\x0d\x57\0" },
- { 0x0e33, "\x0e\x4d\x0e\x32\0" },
- { 0x0eb3, "\x0e\xcd\x0e\xb2\0" },
- { 0x0f43, "\x0f\x42\x0f\xb7\0" },
- { 0x0f4d, "\x0f\x4c\x0f\xb7\0" },
- { 0x0f52, "\x0f\x51\x0f\xb7\0" },
- { 0x0f57, "\x0f\x56\x0f\xb7\0" },
- { 0x0f5c, "\x0f\x5b\x0f\xb7\0" },
- { 0x0f69, "\x0f\x40\x0f\xb5\0" },
- { 0x0f73, "\x0f\x71\x0f\x72\0" },
- { 0x0f75, "\x0f\x71\x0f\x74\0" },
- { 0x0f76, "\x0f\xb2\x0f\x80\0" },
- { 0x0f78, "\x0f\xb3\x0f\x80\0" },
- { 0x0f81, "\x0f\x71\x0f\x80\0" },
- { 0x0f93, "\x0f\x92\x0f\xb7\0" },
- { 0x0f9d, "\x0f\x9c\x0f\xb7\0" },
- { 0x0fa2, "\x0f\xa1\x0f\xb7\0" },
- { 0x0fa7, "\x0f\xa6\x0f\xb7\0" },
- { 0x0fac, "\x0f\xab\x0f\xb7\0" },
- { 0x0fb9, "\x0f\x90\x0f\xb5\0" },
- { 0x1e00, "\x00\x41\x03\x25\0" },
- { 0x1e01, "\x00\x61\x03\x25\0" },
- { 0x1e02, "\x00\x42\x03\x07\0" },
- { 0x1e03, "\x00\x62\x03\x07\0" },
- { 0x1e04, "\x00\x42\x03\x23\0" },
- { 0x1e05, "\x00\x62\x03\x23\0" },
- { 0x1e06, "\x00\x42\x03\x31\0" },
- { 0x1e07, "\x00\x62\x03\x31\0" },
- { 0x1e08, "\x00\x43\x03\x27\x03\x01\0" },
- { 0x1e09, "\x00\x63\x03\x27\x03\x01\0" },
- { 0x1e0a, "\x00\x44\x03\x07\0" },
- { 0x1e0b, "\x00\x64\x03\x07\0" },
- { 0x1e0c, "\x00\x44\x03\x23\0" },
- { 0x1e0d, "\x00\x64\x03\x23\0" },
- { 0x1e0e, "\x00\x44\x03\x31\0" },
- { 0x1e0f, "\x00\x64\x03\x31\0" },
- { 0x1e10, "\x00\x44\x03\x27\0" },
- { 0x1e11, "\x00\x64\x03\x27\0" },
- { 0x1e12, "\x00\x44\x03\x2d\0" },
- { 0x1e13, "\x00\x64\x03\x2d\0" },
- { 0x1e14, "\x00\x45\x03\x04\x03\x00\0" },
- { 0x1e15, "\x00\x65\x03\x04\x03\x00\0" },
- { 0x1e16, "\x00\x45\x03\x04\x03\x01\0" },
- { 0x1e17, "\x00\x65\x03\x04\x03\x01\0" },
- { 0x1e18, "\x00\x45\x03\x2d\0" },
- { 0x1e19, "\x00\x65\x03\x2d\0" },
- { 0x1e1a, "\x00\x45\x03\x30\0" },
- { 0x1e1b, "\x00\x65\x03\x30\0" },
- { 0x1e1c, "\x00\x45\x03\x27\x03\x06\0" },
- { 0x1e1d, "\x00\x65\x03\x27\x03\x06\0" },
- { 0x1e1e, "\x00\x46\x03\x07\0" },
- { 0x1e1f, "\x00\x66\x03\x07\0" },
- { 0x1e20, "\x00\x47\x03\x04\0" },
- { 0x1e21, "\x00\x67\x03\x04\0" },
- { 0x1e22, "\x00\x48\x03\x07\0" },
- { 0x1e23, "\x00\x68\x03\x07\0" },
- { 0x1e24, "\x00\x48\x03\x23\0" },
- { 0x1e25, "\x00\x68\x03\x23\0" },
- { 0x1e26, "\x00\x48\x03\x08\0" },
- { 0x1e27, "\x00\x68\x03\x08\0" },
- { 0x1e28, "\x00\x48\x03\x27\0" },
- { 0x1e29, "\x00\x68\x03\x27\0" },
- { 0x1e2a, "\x00\x48\x03\x2e\0" },
- { 0x1e2b, "\x00\x68\x03\x2e\0" },
- { 0x1e2c, "\x00\x49\x03\x30\0" },
- { 0x1e2d, "\x00\x69\x03\x30\0" },
- { 0x1e2e, "\x00\x49\x03\x08\x03\x01\0" },
- { 0x1e2f, "\x00\x69\x03\x08\x03\x01\0" },
- { 0x1e30, "\x00\x4b\x03\x01\0" },
- { 0x1e31, "\x00\x6b\x03\x01\0" },
- { 0x1e32, "\x00\x4b\x03\x23\0" },
- { 0x1e33, "\x00\x6b\x03\x23\0" },
- { 0x1e34, "\x00\x4b\x03\x31\0" },
- { 0x1e35, "\x00\x6b\x03\x31\0" },
- { 0x1e36, "\x00\x4c\x03\x23\0" },
- { 0x1e37, "\x00\x6c\x03\x23\0" },
- { 0x1e38, "\x00\x4c\x03\x23\x03\x04\0" },
- { 0x1e39, "\x00\x6c\x03\x23\x03\x04\0" },
- { 0x1e3a, "\x00\x4c\x03\x31\0" },
- { 0x1e3b, "\x00\x6c\x03\x31\0" },
- { 0x1e3c, "\x00\x4c\x03\x2d\0" },
- { 0x1e3d, "\x00\x6c\x03\x2d\0" },
- { 0x1e3e, "\x00\x4d\x03\x01\0" },
- { 0x1e3f, "\x00\x6d\x03\x01\0" },
- { 0x1e40, "\x00\x4d\x03\x07\0" },
- { 0x1e41, "\x00\x6d\x03\x07\0" },
- { 0x1e42, "\x00\x4d\x03\x23\0" },
- { 0x1e43, "\x00\x6d\x03\x23\0" },
- { 0x1e44, "\x00\x4e\x03\x07\0" },
- { 0x1e45, "\x00\x6e\x03\x07\0" },
- { 0x1e46, "\x00\x4e\x03\x23\0" },
- { 0x1e47, "\x00\x6e\x03\x23\0" },
- { 0x1e48, "\x00\x4e\x03\x31\0" },
- { 0x1e49, "\x00\x6e\x03\x31\0" },
- { 0x1e4a, "\x00\x4e\x03\x2d\0" },
- { 0x1e4b, "\x00\x6e\x03\x2d\0" },
- { 0x1e4c, "\x00\x4f\x03\x03\x03\x01\0" },
- { 0x1e4d, "\x00\x6f\x03\x03\x03\x01\0" },
- { 0x1e4e, "\x00\x4f\x03\x03\x03\x08\0" },
- { 0x1e4f, "\x00\x6f\x03\x03\x03\x08\0" },
- { 0x1e50, "\x00\x4f\x03\x04\x03\x00\0" },
- { 0x1e51, "\x00\x6f\x03\x04\x03\x00\0" },
- { 0x1e52, "\x00\x4f\x03\x04\x03\x01\0" },
- { 0x1e53, "\x00\x6f\x03\x04\x03\x01\0" },
- { 0x1e54, "\x00\x50\x03\x01\0" },
- { 0x1e55, "\x00\x70\x03\x01\0" },
- { 0x1e56, "\x00\x50\x03\x07\0" },
- { 0x1e57, "\x00\x70\x03\x07\0" },
- { 0x1e58, "\x00\x52\x03\x07\0" },
- { 0x1e59, "\x00\x72\x03\x07\0" },
- { 0x1e5a, "\x00\x52\x03\x23\0" },
- { 0x1e5b, "\x00\x72\x03\x23\0" },
- { 0x1e5c, "\x00\x52\x03\x23\x03\x04\0" },
- { 0x1e5d, "\x00\x72\x03\x23\x03\x04\0" },
- { 0x1e5e, "\x00\x52\x03\x31\0" },
- { 0x1e5f, "\x00\x72\x03\x31\0" },
- { 0x1e60, "\x00\x53\x03\x07\0" },
- { 0x1e61, "\x00\x73\x03\x07\0" },
- { 0x1e62, "\x00\x53\x03\x23\0" },
- { 0x1e63, "\x00\x73\x03\x23\0" },
- { 0x1e64, "\x00\x53\x03\x01\x03\x07\0" },
- { 0x1e65, "\x00\x73\x03\x01\x03\x07\0" },
- { 0x1e66, "\x00\x53\x03\x0c\x03\x07\0" },
- { 0x1e67, "\x00\x73\x03\x0c\x03\x07\0" },
- { 0x1e68, "\x00\x53\x03\x23\x03\x07\0" },
- { 0x1e69, "\x00\x73\x03\x23\x03\x07\0" },
- { 0x1e6a, "\x00\x54\x03\x07\0" },
- { 0x1e6b, "\x00\x74\x03\x07\0" },
- { 0x1e6c, "\x00\x54\x03\x23\0" },
- { 0x1e6d, "\x00\x74\x03\x23\0" },
- { 0x1e6e, "\x00\x54\x03\x31\0" },
- { 0x1e6f, "\x00\x74\x03\x31\0" },
- { 0x1e70, "\x00\x54\x03\x2d\0" },
- { 0x1e71, "\x00\x74\x03\x2d\0" },
- { 0x1e72, "\x00\x55\x03\x24\0" },
- { 0x1e73, "\x00\x75\x03\x24\0" },
- { 0x1e74, "\x00\x55\x03\x30\0" },
- { 0x1e75, "\x00\x75\x03\x30\0" },
- { 0x1e76, "\x00\x55\x03\x2d\0" },
- { 0x1e77, "\x00\x75\x03\x2d\0" },
- { 0x1e78, "\x00\x55\x03\x03\x03\x01\0" },
- { 0x1e79, "\x00\x75\x03\x03\x03\x01\0" },
- { 0x1e7a, "\x00\x55\x03\x04\x03\x08\0" },
- { 0x1e7b, "\x00\x75\x03\x04\x03\x08\0" },
- { 0x1e7c, "\x00\x56\x03\x03\0" },
- { 0x1e7d, "\x00\x76\x03\x03\0" },
- { 0x1e7e, "\x00\x56\x03\x23\0" },
- { 0x1e7f, "\x00\x76\x03\x23\0" },
- { 0x1e80, "\x00\x57\x03\x00\0" },
- { 0x1e81, "\x00\x77\x03\x00\0" },
- { 0x1e82, "\x00\x57\x03\x01\0" },
- { 0x1e83, "\x00\x77\x03\x01\0" },
- { 0x1e84, "\x00\x57\x03\x08\0" },
- { 0x1e85, "\x00\x77\x03\x08\0" },
- { 0x1e86, "\x00\x57\x03\x07\0" },
- { 0x1e87, "\x00\x77\x03\x07\0" },
- { 0x1e88, "\x00\x57\x03\x23\0" },
- { 0x1e89, "\x00\x77\x03\x23\0" },
- { 0x1e8a, "\x00\x58\x03\x07\0" },
- { 0x1e8b, "\x00\x78\x03\x07\0" },
- { 0x1e8c, "\x00\x58\x03\x08\0" },
- { 0x1e8d, "\x00\x78\x03\x08\0" },
- { 0x1e8e, "\x00\x59\x03\x07\0" },
- { 0x1e8f, "\x00\x79\x03\x07\0" },
- { 0x1e90, "\x00\x5a\x03\x02\0" },
- { 0x1e91, "\x00\x7a\x03\x02\0" },
- { 0x1e92, "\x00\x5a\x03\x23\0" },
- { 0x1e93, "\x00\x7a\x03\x23\0" },
- { 0x1e94, "\x00\x5a\x03\x31\0" },
- { 0x1e95, "\x00\x7a\x03\x31\0" },
- { 0x1e96, "\x00\x68\x03\x31\0" },
- { 0x1e97, "\x00\x74\x03\x08\0" },
- { 0x1e98, "\x00\x77\x03\x0a\0" },
- { 0x1e99, "\x00\x79\x03\x0a\0" },
- { 0x1e9b, "\x01\x7f\x03\x07\0" },
- { 0x1ea0, "\x00\x41\x03\x23\0" },
- { 0x1ea1, "\x00\x61\x03\x23\0" },
- { 0x1ea2, "\x00\x41\x03\x09\0" },
- { 0x1ea3, "\x00\x61\x03\x09\0" },
- { 0x1ea4, "\x00\x41\x03\x02\x03\x01\0" },
- { 0x1ea5, "\x00\x61\x03\x02\x03\x01\0" },
- { 0x1ea6, "\x00\x41\x03\x02\x03\x00\0" },
- { 0x1ea7, "\x00\x61\x03\x02\x03\x00\0" },
- { 0x1ea8, "\x00\x41\x03\x02\x03\x09\0" },
- { 0x1ea9, "\x00\x61\x03\x02\x03\x09\0" },
- { 0x1eaa, "\x00\x41\x03\x02\x03\x03\0" },
- { 0x1eab, "\x00\x61\x03\x02\x03\x03\0" },
- { 0x1eac, "\x00\x41\x03\x23\x03\x02\0" },
- { 0x1ead, "\x00\x61\x03\x23\x03\x02\0" },
- { 0x1eae, "\x00\x41\x03\x06\x03\x01\0" },
- { 0x1eaf, "\x00\x61\x03\x06\x03\x01\0" },
- { 0x1eb0, "\x00\x41\x03\x06\x03\x00\0" },
- { 0x1eb1, "\x00\x61\x03\x06\x03\x00\0" },
- { 0x1eb2, "\x00\x41\x03\x06\x03\x09\0" },
- { 0x1eb3, "\x00\x61\x03\x06\x03\x09\0" },
- { 0x1eb4, "\x00\x41\x03\x06\x03\x03\0" },
- { 0x1eb5, "\x00\x61\x03\x06\x03\x03\0" },
- { 0x1eb6, "\x00\x41\x03\x23\x03\x06\0" },
- { 0x1eb7, "\x00\x61\x03\x23\x03\x06\0" },
- { 0x1eb8, "\x00\x45\x03\x23\0" },
- { 0x1eb9, "\x00\x65\x03\x23\0" },
- { 0x1eba, "\x00\x45\x03\x09\0" },
- { 0x1ebb, "\x00\x65\x03\x09\0" },
- { 0x1ebc, "\x00\x45\x03\x03\0" },
- { 0x1ebd, "\x00\x65\x03\x03\0" },
- { 0x1ebe, "\x00\x45\x03\x02\x03\x01\0" },
- { 0x1ebf, "\x00\x65\x03\x02\x03\x01\0" },
- { 0x1ec0, "\x00\x45\x03\x02\x03\x00\0" },
- { 0x1ec1, "\x00\x65\x03\x02\x03\x00\0" },
- { 0x1ec2, "\x00\x45\x03\x02\x03\x09\0" },
- { 0x1ec3, "\x00\x65\x03\x02\x03\x09\0" },
- { 0x1ec4, "\x00\x45\x03\x02\x03\x03\0" },
- { 0x1ec5, "\x00\x65\x03\x02\x03\x03\0" },
- { 0x1ec6, "\x00\x45\x03\x23\x03\x02\0" },
- { 0x1ec7, "\x00\x65\x03\x23\x03\x02\0" },
- { 0x1ec8, "\x00\x49\x03\x09\0" },
- { 0x1ec9, "\x00\x69\x03\x09\0" },
- { 0x1eca, "\x00\x49\x03\x23\0" },
- { 0x1ecb, "\x00\x69\x03\x23\0" },
- { 0x1ecc, "\x00\x4f\x03\x23\0" },
- { 0x1ecd, "\x00\x6f\x03\x23\0" },
- { 0x1ece, "\x00\x4f\x03\x09\0" },
- { 0x1ecf, "\x00\x6f\x03\x09\0" },
- { 0x1ed0, "\x00\x4f\x03\x02\x03\x01\0" },
- { 0x1ed1, "\x00\x6f\x03\x02\x03\x01\0" },
- { 0x1ed2, "\x00\x4f\x03\x02\x03\x00\0" },
- { 0x1ed3, "\x00\x6f\x03\x02\x03\x00\0" },
- { 0x1ed4, "\x00\x4f\x03\x02\x03\x09\0" },
- { 0x1ed5, "\x00\x6f\x03\x02\x03\x09\0" },
- { 0x1ed6, "\x00\x4f\x03\x02\x03\x03\0" },
- { 0x1ed7, "\x00\x6f\x03\x02\x03\x03\0" },
- { 0x1ed8, "\x00\x4f\x03\x23\x03\x02\0" },
- { 0x1ed9, "\x00\x6f\x03\x23\x03\x02\0" },
- { 0x1eda, "\x00\x4f\x03\x1b\x03\x01\0" },
- { 0x1edb, "\x00\x6f\x03\x1b\x03\x01\0" },
- { 0x1edc, "\x00\x4f\x03\x1b\x03\x00\0" },
- { 0x1edd, "\x00\x6f\x03\x1b\x03\x00\0" },
- { 0x1ede, "\x00\x4f\x03\x1b\x03\x09\0" },
- { 0x1edf, "\x00\x6f\x03\x1b\x03\x09\0" },
- { 0x1ee0, "\x00\x4f\x03\x1b\x03\x03\0" },
- { 0x1ee1, "\x00\x6f\x03\x1b\x03\x03\0" },
- { 0x1ee2, "\x00\x4f\x03\x1b\x03\x23\0" },
- { 0x1ee3, "\x00\x6f\x03\x1b\x03\x23\0" },
- { 0x1ee4, "\x00\x55\x03\x23\0" },
- { 0x1ee5, "\x00\x75\x03\x23\0" },
- { 0x1ee6, "\x00\x55\x03\x09\0" },
- { 0x1ee7, "\x00\x75\x03\x09\0" },
- { 0x1ee8, "\x00\x55\x03\x1b\x03\x01\0" },
- { 0x1ee9, "\x00\x75\x03\x1b\x03\x01\0" },
- { 0x1eea, "\x00\x55\x03\x1b\x03\x00\0" },
- { 0x1eeb, "\x00\x75\x03\x1b\x03\x00\0" },
- { 0x1eec, "\x00\x55\x03\x1b\x03\x09\0" },
- { 0x1eed, "\x00\x75\x03\x1b\x03\x09\0" },
- { 0x1eee, "\x00\x55\x03\x1b\x03\x03\0" },
- { 0x1eef, "\x00\x75\x03\x1b\x03\x03\0" },
- { 0x1ef0, "\x00\x55\x03\x1b\x03\x23\0" },
- { 0x1ef1, "\x00\x75\x03\x1b\x03\x23\0" },
- { 0x1ef2, "\x00\x59\x03\x00\0" },
- { 0x1ef3, "\x00\x79\x03\x00\0" },
- { 0x1ef4, "\x00\x59\x03\x23\0" },
- { 0x1ef5, "\x00\x79\x03\x23\0" },
- { 0x1ef6, "\x00\x59\x03\x09\0" },
- { 0x1ef7, "\x00\x79\x03\x09\0" },
- { 0x1ef8, "\x00\x59\x03\x03\0" },
- { 0x1ef9, "\x00\x79\x03\x03\0" },
- { 0x1f00, "\x03\xb1\x03\x13\0" },
- { 0x1f01, "\x03\xb1\x03\x14\0" },
- { 0x1f02, "\x03\xb1\x03\x13\x03\x00\0" },
- { 0x1f03, "\x03\xb1\x03\x14\x03\x00\0" },
- { 0x1f04, "\x03\xb1\x03\x13\x03\x01\0" },
- { 0x1f05, "\x03\xb1\x03\x14\x03\x01\0" },
- { 0x1f06, "\x03\xb1\x03\x13\x03\x42\0" },
- { 0x1f07, "\x03\xb1\x03\x14\x03\x42\0" },
- { 0x1f08, "\x03\x91\x03\x13\0" },
- { 0x1f09, "\x03\x91\x03\x14\0" },
- { 0x1f0a, "\x03\x91\x03\x13\x03\x00\0" },
- { 0x1f0b, "\x03\x91\x03\x14\x03\x00\0" },
- { 0x1f0c, "\x03\x91\x03\x13\x03\x01\0" },
- { 0x1f0d, "\x03\x91\x03\x14\x03\x01\0" },
- { 0x1f0e, "\x03\x91\x03\x13\x03\x42\0" },
- { 0x1f0f, "\x03\x91\x03\x14\x03\x42\0" },
- { 0x1f10, "\x03\xb5\x03\x13\0" },
- { 0x1f11, "\x03\xb5\x03\x14\0" },
- { 0x1f12, "\x03\xb5\x03\x13\x03\x00\0" },
- { 0x1f13, "\x03\xb5\x03\x14\x03\x00\0" },
- { 0x1f14, "\x03\xb5\x03\x13\x03\x01\0" },
- { 0x1f15, "\x03\xb5\x03\x14\x03\x01\0" },
- { 0x1f18, "\x03\x95\x03\x13\0" },
- { 0x1f19, "\x03\x95\x03\x14\0" },
- { 0x1f1a, "\x03\x95\x03\x13\x03\x00\0" },
- { 0x1f1b, "\x03\x95\x03\x14\x03\x00\0" },
- { 0x1f1c, "\x03\x95\x03\x13\x03\x01\0" },
- { 0x1f1d, "\x03\x95\x03\x14\x03\x01\0" },
- { 0x1f20, "\x03\xb7\x03\x13\0" },
- { 0x1f21, "\x03\xb7\x03\x14\0" },
- { 0x1f22, "\x03\xb7\x03\x13\x03\x00\0" },
- { 0x1f23, "\x03\xb7\x03\x14\x03\x00\0" },
- { 0x1f24, "\x03\xb7\x03\x13\x03\x01\0" },
- { 0x1f25, "\x03\xb7\x03\x14\x03\x01\0" },
- { 0x1f26, "\x03\xb7\x03\x13\x03\x42\0" },
- { 0x1f27, "\x03\xb7\x03\x14\x03\x42\0" },
- { 0x1f28, "\x03\x97\x03\x13\0" },
- { 0x1f29, "\x03\x97\x03\x14\0" },
- { 0x1f2a, "\x03\x97\x03\x13\x03\x00\0" },
- { 0x1f2b, "\x03\x97\x03\x14\x03\x00\0" },
- { 0x1f2c, "\x03\x97\x03\x13\x03\x01\0" },
- { 0x1f2d, "\x03\x97\x03\x14\x03\x01\0" },
- { 0x1f2e, "\x03\x97\x03\x13\x03\x42\0" },
- { 0x1f2f, "\x03\x97\x03\x14\x03\x42\0" },
- { 0x1f30, "\x03\xb9\x03\x13\0" },
- { 0x1f31, "\x03\xb9\x03\x14\0" },
- { 0x1f32, "\x03\xb9\x03\x13\x03\x00\0" },
- { 0x1f33, "\x03\xb9\x03\x14\x03\x00\0" },
- { 0x1f34, "\x03\xb9\x03\x13\x03\x01\0" },
- { 0x1f35, "\x03\xb9\x03\x14\x03\x01\0" },
- { 0x1f36, "\x03\xb9\x03\x13\x03\x42\0" },
- { 0x1f37, "\x03\xb9\x03\x14\x03\x42\0" },
- { 0x1f38, "\x03\x99\x03\x13\0" },
- { 0x1f39, "\x03\x99\x03\x14\0" },
- { 0x1f3a, "\x03\x99\x03\x13\x03\x00\0" },
- { 0x1f3b, "\x03\x99\x03\x14\x03\x00\0" },
- { 0x1f3c, "\x03\x99\x03\x13\x03\x01\0" },
- { 0x1f3d, "\x03\x99\x03\x14\x03\x01\0" },
- { 0x1f3e, "\x03\x99\x03\x13\x03\x42\0" },
- { 0x1f3f, "\x03\x99\x03\x14\x03\x42\0" },
- { 0x1f40, "\x03\xbf\x03\x13\0" },
- { 0x1f41, "\x03\xbf\x03\x14\0" },
- { 0x1f42, "\x03\xbf\x03\x13\x03\x00\0" },
- { 0x1f43, "\x03\xbf\x03\x14\x03\x00\0" },
- { 0x1f44, "\x03\xbf\x03\x13\x03\x01\0" },
- { 0x1f45, "\x03\xbf\x03\x14\x03\x01\0" },
- { 0x1f48, "\x03\x9f\x03\x13\0" },
- { 0x1f49, "\x03\x9f\x03\x14\0" },
- { 0x1f4a, "\x03\x9f\x03\x13\x03\x00\0" },
- { 0x1f4b, "\x03\x9f\x03\x14\x03\x00\0" },
- { 0x1f4c, "\x03\x9f\x03\x13\x03\x01\0" },
- { 0x1f4d, "\x03\x9f\x03\x14\x03\x01\0" },
- { 0x1f50, "\x03\xc5\x03\x13\0" },
- { 0x1f51, "\x03\xc5\x03\x14\0" },
- { 0x1f52, "\x03\xc5\x03\x13\x03\x00\0" },
- { 0x1f53, "\x03\xc5\x03\x14\x03\x00\0" },
- { 0x1f54, "\x03\xc5\x03\x13\x03\x01\0" },
- { 0x1f55, "\x03\xc5\x03\x14\x03\x01\0" },
- { 0x1f56, "\x03\xc5\x03\x13\x03\x42\0" },
- { 0x1f57, "\x03\xc5\x03\x14\x03\x42\0" },
- { 0x1f59, "\x03\xa5\x03\x14\0" },
- { 0x1f5b, "\x03\xa5\x03\x14\x03\x00\0" },
- { 0x1f5d, "\x03\xa5\x03\x14\x03\x01\0" },
- { 0x1f5f, "\x03\xa5\x03\x14\x03\x42\0" },
- { 0x1f60, "\x03\xc9\x03\x13\0" },
- { 0x1f61, "\x03\xc9\x03\x14\0" },
- { 0x1f62, "\x03\xc9\x03\x13\x03\x00\0" },
- { 0x1f63, "\x03\xc9\x03\x14\x03\x00\0" },
- { 0x1f64, "\x03\xc9\x03\x13\x03\x01\0" },
- { 0x1f65, "\x03\xc9\x03\x14\x03\x01\0" },
- { 0x1f66, "\x03\xc9\x03\x13\x03\x42\0" },
- { 0x1f67, "\x03\xc9\x03\x14\x03\x42\0" },
- { 0x1f68, "\x03\xa9\x03\x13\0" },
- { 0x1f69, "\x03\xa9\x03\x14\0" },
- { 0x1f6a, "\x03\xa9\x03\x13\x03\x00\0" },
- { 0x1f6b, "\x03\xa9\x03\x14\x03\x00\0" },
- { 0x1f6c, "\x03\xa9\x03\x13\x03\x01\0" },
- { 0x1f6d, "\x03\xa9\x03\x14\x03\x01\0" },
- { 0x1f6e, "\x03\xa9\x03\x13\x03\x42\0" },
- { 0x1f6f, "\x03\xa9\x03\x14\x03\x42\0" },
- { 0x1f70, "\x03\xb1\x03\x00\0" },
- { 0x1f71, "\x03\xb1\x03\x01\0" },
- { 0x1f72, "\x03\xb5\x03\x00\0" },
- { 0x1f73, "\x03\xb5\x03\x01\0" },
- { 0x1f74, "\x03\xb7\x03\x00\0" },
- { 0x1f75, "\x03\xb7\x03\x01\0" },
- { 0x1f76, "\x03\xb9\x03\x00\0" },
- { 0x1f77, "\x03\xb9\x03\x01\0" },
- { 0x1f78, "\x03\xbf\x03\x00\0" },
- { 0x1f79, "\x03\xbf\x03\x01\0" },
- { 0x1f7a, "\x03\xc5\x03\x00\0" },
- { 0x1f7b, "\x03\xc5\x03\x01\0" },
- { 0x1f7c, "\x03\xc9\x03\x00\0" },
- { 0x1f7d, "\x03\xc9\x03\x01\0" },
- { 0x1f80, "\x03\xb1\x03\x13\x03\x45\0" },
- { 0x1f81, "\x03\xb1\x03\x14\x03\x45\0" },
- { 0x1f82, "\x03\xb1\x03\x13\x03\x00\x03\x45\0" },
- { 0x1f83, "\x03\xb1\x03\x14\x03\x00\x03\x45\0" },
- { 0x1f84, "\x03\xb1\x03\x13\x03\x01\x03\x45\0" },
- { 0x1f85, "\x03\xb1\x03\x14\x03\x01\x03\x45\0" },
- { 0x1f86, "\x03\xb1\x03\x13\x03\x42\x03\x45\0" },
- { 0x1f87, "\x03\xb1\x03\x14\x03\x42\x03\x45\0" },
- { 0x1f88, "\x03\x91\x03\x13\x03\x45\0" },
- { 0x1f89, "\x03\x91\x03\x14\x03\x45\0" },
- { 0x1f8a, "\x03\x91\x03\x13\x03\x00\x03\x45\0" },
- { 0x1f8b, "\x03\x91\x03\x14\x03\x00\x03\x45\0" },
- { 0x1f8c, "\x03\x91\x03\x13\x03\x01\x03\x45\0" },
- { 0x1f8d, "\x03\x91\x03\x14\x03\x01\x03\x45\0" },
- { 0x1f8e, "\x03\x91\x03\x13\x03\x42\x03\x45\0" },
- { 0x1f8f, "\x03\x91\x03\x14\x03\x42\x03\x45\0" },
- { 0x1f90, "\x03\xb7\x03\x13\x03\x45\0" },
- { 0x1f91, "\x03\xb7\x03\x14\x03\x45\0" },
- { 0x1f92, "\x03\xb7\x03\x13\x03\x00\x03\x45\0" },
- { 0x1f93, "\x03\xb7\x03\x14\x03\x00\x03\x45\0" },
- { 0x1f94, "\x03\xb7\x03\x13\x03\x01\x03\x45\0" },
- { 0x1f95, "\x03\xb7\x03\x14\x03\x01\x03\x45\0" },
- { 0x1f96, "\x03\xb7\x03\x13\x03\x42\x03\x45\0" },
- { 0x1f97, "\x03\xb7\x03\x14\x03\x42\x03\x45\0" },
- { 0x1f98, "\x03\x97\x03\x13\x03\x45\0" },
- { 0x1f99, "\x03\x97\x03\x14\x03\x45\0" },
- { 0x1f9a, "\x03\x97\x03\x13\x03\x00\x03\x45\0" },
- { 0x1f9b, "\x03\x97\x03\x14\x03\x00\x03\x45\0" },
- { 0x1f9c, "\x03\x97\x03\x13\x03\x01\x03\x45\0" },
- { 0x1f9d, "\x03\x97\x03\x14\x03\x01\x03\x45\0" },
- { 0x1f9e, "\x03\x97\x03\x13\x03\x42\x03\x45\0" },
- { 0x1f9f, "\x03\x97\x03\x14\x03\x42\x03\x45\0" },
- { 0x1fa0, "\x03\xc9\x03\x13\x03\x45\0" },
- { 0x1fa1, "\x03\xc9\x03\x14\x03\x45\0" },
- { 0x1fa2, "\x03\xc9\x03\x13\x03\x00\x03\x45\0" },
- { 0x1fa3, "\x03\xc9\x03\x14\x03\x00\x03\x45\0" },
- { 0x1fa4, "\x03\xc9\x03\x13\x03\x01\x03\x45\0" },
- { 0x1fa5, "\x03\xc9\x03\x14\x03\x01\x03\x45\0" },
- { 0x1fa6, "\x03\xc9\x03\x13\x03\x42\x03\x45\0" },
- { 0x1fa7, "\x03\xc9\x03\x14\x03\x42\x03\x45\0" },
- { 0x1fa8, "\x03\xa9\x03\x13\x03\x45\0" },
- { 0x1fa9, "\x03\xa9\x03\x14\x03\x45\0" },
- { 0x1faa, "\x03\xa9\x03\x13\x03\x00\x03\x45\0" },
- { 0x1fab, "\x03\xa9\x03\x14\x03\x00\x03\x45\0" },
- { 0x1fac, "\x03\xa9\x03\x13\x03\x01\x03\x45\0" },
- { 0x1fad, "\x03\xa9\x03\x14\x03\x01\x03\x45\0" },
- { 0x1fae, "\x03\xa9\x03\x13\x03\x42\x03\x45\0" },
- { 0x1faf, "\x03\xa9\x03\x14\x03\x42\x03\x45\0" },
- { 0x1fb0, "\x03\xb1\x03\x06\0" },
- { 0x1fb1, "\x03\xb1\x03\x04\0" },
- { 0x1fb2, "\x03\xb1\x03\x00\x03\x45\0" },
- { 0x1fb3, "\x03\xb1\x03\x45\0" },
- { 0x1fb4, "\x03\xb1\x03\x01\x03\x45\0" },
- { 0x1fb6, "\x03\xb1\x03\x42\0" },
- { 0x1fb7, "\x03\xb1\x03\x42\x03\x45\0" },
- { 0x1fb8, "\x03\x91\x03\x06\0" },
- { 0x1fb9, "\x03\x91\x03\x04\0" },
- { 0x1fba, "\x03\x91\x03\x00\0" },
- { 0x1fbb, "\x03\x91\x03\x01\0" },
- { 0x1fbc, "\x03\x91\x03\x45\0" },
- { 0x1fbe, "\x03\xb9\0" },
- { 0x1fc1, "\x00\xa8\x03\x42\0" },
- { 0x1fc2, "\x03\xb7\x03\x00\x03\x45\0" },
- { 0x1fc3, "\x03\xb7\x03\x45\0" },
- { 0x1fc4, "\x03\xb7\x03\x01\x03\x45\0" },
- { 0x1fc6, "\x03\xb7\x03\x42\0" },
- { 0x1fc7, "\x03\xb7\x03\x42\x03\x45\0" },
- { 0x1fc8, "\x03\x95\x03\x00\0" },
- { 0x1fc9, "\x03\x95\x03\x01\0" },
- { 0x1fca, "\x03\x97\x03\x00\0" },
- { 0x1fcb, "\x03\x97\x03\x01\0" },
- { 0x1fcc, "\x03\x97\x03\x45\0" },
- { 0x1fcd, "\x1f\xbf\x03\x00\0" },
- { 0x1fce, "\x1f\xbf\x03\x01\0" },
- { 0x1fcf, "\x1f\xbf\x03\x42\0" },
- { 0x1fd0, "\x03\xb9\x03\x06\0" },
- { 0x1fd1, "\x03\xb9\x03\x04\0" },
- { 0x1fd2, "\x03\xb9\x03\x08\x03\x00\0" },
- { 0x1fd3, "\x03\xb9\x03\x08\x03\x01\0" },
- { 0x1fd6, "\x03\xb9\x03\x42\0" },
- { 0x1fd7, "\x03\xb9\x03\x08\x03\x42\0" },
- { 0x1fd8, "\x03\x99\x03\x06\0" },
- { 0x1fd9, "\x03\x99\x03\x04\0" },
- { 0x1fda, "\x03\x99\x03\x00\0" },
- { 0x1fdb, "\x03\x99\x03\x01\0" },
- { 0x1fdd, "\x1f\xfe\x03\x00\0" },
- { 0x1fde, "\x1f\xfe\x03\x01\0" },
- { 0x1fdf, "\x1f\xfe\x03\x42\0" },
- { 0x1fe0, "\x03\xc5\x03\x06\0" },
- { 0x1fe1, "\x03\xc5\x03\x04\0" },
- { 0x1fe2, "\x03\xc5\x03\x08\x03\x00\0" },
- { 0x1fe3, "\x03\xc5\x03\x08\x03\x01\0" },
- { 0x1fe4, "\x03\xc1\x03\x13\0" },
- { 0x1fe5, "\x03\xc1\x03\x14\0" },
- { 0x1fe6, "\x03\xc5\x03\x42\0" },
- { 0x1fe7, "\x03\xc5\x03\x08\x03\x42\0" },
- { 0x1fe8, "\x03\xa5\x03\x06\0" },
- { 0x1fe9, "\x03\xa5\x03\x04\0" },
- { 0x1fea, "\x03\xa5\x03\x00\0" },
- { 0x1feb, "\x03\xa5\x03\x01\0" },
- { 0x1fec, "\x03\xa1\x03\x14\0" },
- { 0x1fed, "\x00\xa8\x03\x00\0" },
- { 0x1fee, "\x00\xa8\x03\x01\0" },
- { 0x1fef, "\x00\x60\0" },
- { 0x1ff2, "\x03\xc9\x03\x00\x03\x45\0" },
- { 0x1ff3, "\x03\xc9\x03\x45\0" },
- { 0x1ff4, "\x03\xc9\x03\x01\x03\x45\0" },
- { 0x1ff6, "\x03\xc9\x03\x42\0" },
- { 0x1ff7, "\x03\xc9\x03\x42\x03\x45\0" },
- { 0x1ff8, "\x03\x9f\x03\x00\0" },
- { 0x1ff9, "\x03\x9f\x03\x01\0" },
- { 0x1ffa, "\x03\xa9\x03\x00\0" },
- { 0x1ffb, "\x03\xa9\x03\x01\0" },
- { 0x1ffc, "\x03\xa9\x03\x45\0" },
- { 0x1ffd, "\x00\xb4\0" },
- { 0x2000, "\x20\x02\0" },
- { 0x2001, "\x20\x03\0" },
- { 0x2126, "\x03\xa9\0" },
- { 0x212a, "\x00\x4b\0" },
- { 0x212b, "\x00\x41\x03\x0a\0" },
- { 0x2204, "\x22\x03\x03\x38\0" },
- { 0x2209, "\x22\x08\x03\x38\0" },
- { 0x220c, "\x22\x0b\x03\x38\0" },
- { 0x2224, "\x22\x23\x03\x38\0" },
- { 0x2226, "\x22\x25\x03\x38\0" },
- { 0x2241, "\x00\x7e\x03\x38\0" },
- { 0x2244, "\x22\x43\x03\x38\0" },
- { 0x2247, "\x22\x45\x03\x38\0" },
- { 0x2249, "\x22\x48\x03\x38\0" },
- { 0x2260, "\x00\x3d\x03\x38\0" },
- { 0x2262, "\x22\x61\x03\x38\0" },
- { 0x226d, "\x22\x4d\x03\x38\0" },
- { 0x226e, "\x00\x3c\x03\x38\0" },
- { 0x226f, "\x00\x3e\x03\x38\0" },
- { 0x2270, "\x22\x64\x03\x38\0" },
- { 0x2271, "\x22\x65\x03\x38\0" },
- { 0x2274, "\x22\x72\x03\x38\0" },
- { 0x2275, "\x22\x73\x03\x38\0" },
- { 0x2278, "\x22\x76\x03\x38\0" },
- { 0x2279, "\x22\x77\x03\x38\0" },
- { 0x2280, "\x22\x7a\x03\x38\0" },
- { 0x2281, "\x22\x7b\x03\x38\0" },
- { 0x2284, "\x22\x82\x03\x38\0" },
- { 0x2285, "\x22\x83\x03\x38\0" },
- { 0x2288, "\x22\x86\x03\x38\0" },
- { 0x2289, "\x22\x87\x03\x38\0" },
- { 0x22ac, "\x22\xa2\x03\x38\0" },
- { 0x22ad, "\x22\xa8\x03\x38\0" },
- { 0x22ae, "\x22\xa9\x03\x38\0" },
- { 0x22af, "\x22\xab\x03\x38\0" },
- { 0x22e0, "\x22\x7c\x03\x38\0" },
- { 0x22e1, "\x22\x7d\x03\x38\0" },
- { 0x22e2, "\x22\x91\x03\x38\0" },
- { 0x22e3, "\x22\x92\x03\x38\0" },
- { 0x22ea, "\x22\xb2\x03\x38\0" },
- { 0x22eb, "\x22\xb3\x03\x38\0" },
- { 0x22ec, "\x22\xb4\x03\x38\0" },
- { 0x22ed, "\x22\xb5\x03\x38\0" },
- { 0x2329, "\x30\x08\0" },
- { 0x232a, "\x30\x09\0" },
- { 0x304c, "\x30\x4b\x30\x99\0" },
- { 0x304e, "\x30\x4d\x30\x99\0" },
- { 0x3050, "\x30\x4f\x30\x99\0" },
- { 0x3052, "\x30\x51\x30\x99\0" },
- { 0x3054, "\x30\x53\x30\x99\0" },
- { 0x3056, "\x30\x55\x30\x99\0" },
- { 0x3058, "\x30\x57\x30\x99\0" },
- { 0x305a, "\x30\x59\x30\x99\0" },
- { 0x305c, "\x30\x5b\x30\x99\0" },
- { 0x305e, "\x30\x5d\x30\x99\0" },
- { 0x3060, "\x30\x5f\x30\x99\0" },
- { 0x3062, "\x30\x61\x30\x99\0" },
- { 0x3065, "\x30\x64\x30\x99\0" },
- { 0x3067, "\x30\x66\x30\x99\0" },
- { 0x3069, "\x30\x68\x30\x99\0" },
- { 0x3070, "\x30\x6f\x30\x99\0" },
- { 0x3071, "\x30\x6f\x30\x9a\0" },
- { 0x3073, "\x30\x72\x30\x99\0" },
- { 0x3074, "\x30\x72\x30\x9a\0" },
- { 0x3076, "\x30\x75\x30\x99\0" },
- { 0x3077, "\x30\x75\x30\x9a\0" },
- { 0x3079, "\x30\x78\x30\x99\0" },
- { 0x307a, "\x30\x78\x30\x9a\0" },
- { 0x307c, "\x30\x7b\x30\x99\0" },
- { 0x307d, "\x30\x7b\x30\x9a\0" },
- { 0x3094, "\x30\x46\x30\x99\0" },
- { 0x309e, "\x30\x9d\x30\x99\0" },
- { 0x30ac, "\x30\xab\x30\x99\0" },
- { 0x30ae, "\x30\xad\x30\x99\0" },
- { 0x30b0, "\x30\xaf\x30\x99\0" },
- { 0x30b2, "\x30\xb1\x30\x99\0" },
- { 0x30b4, "\x30\xb3\x30\x99\0" },
- { 0x30b6, "\x30\xb5\x30\x99\0" },
- { 0x30b8, "\x30\xb7\x30\x99\0" },
- { 0x30ba, "\x30\xb9\x30\x99\0" },
- { 0x30bc, "\x30\xbb\x30\x99\0" },
- { 0x30be, "\x30\xbd\x30\x99\0" },
- { 0x30c0, "\x30\xbf\x30\x99\0" },
- { 0x30c2, "\x30\xc1\x30\x99\0" },
- { 0x30c5, "\x30\xc4\x30\x99\0" },
- { 0x30c7, "\x30\xc6\x30\x99\0" },
- { 0x30c9, "\x30\xc8\x30\x99\0" },
- { 0x30d0, "\x30\xcf\x30\x99\0" },
- { 0x30d1, "\x30\xcf\x30\x9a\0" },
- { 0x30d3, "\x30\xd2\x30\x99\0" },
- { 0x30d4, "\x30\xd2\x30\x9a\0" },
- { 0x30d6, "\x30\xd5\x30\x99\0" },
- { 0x30d7, "\x30\xd5\x30\x9a\0" },
- { 0x30d9, "\x30\xd8\x30\x99\0" },
- { 0x30da, "\x30\xd8\x30\x9a\0" },
- { 0x30dc, "\x30\xdb\x30\x99\0" },
- { 0x30dd, "\x30\xdb\x30\x9a\0" },
- { 0x30f4, "\x30\xa6\x30\x99\0" },
- { 0x30f7, "\x30\xef\x30\x99\0" },
- { 0x30f8, "\x30\xf0\x30\x99\0" },
- { 0x30f9, "\x30\xf1\x30\x99\0" },
- { 0x30fa, "\x30\xf2\x30\x99\0" },
- { 0x30fe, "\x30\xfd\x30\x99\0" },
- { 0xf900, "\x8c\x48\0" },
- { 0xf901, "\x66\xf4\0" },
- { 0xf902, "\x8e\xca\0" },
- { 0xf903, "\x8c\xc8\0" },
- { 0xf904, "\x6e\xd1\0" },
- { 0xf905, "\x4e\x32\0" },
- { 0xf906, "\x53\xe5\0" },
- { 0xf907, "\x9f\x9c\0" },
- { 0xf908, "\x9f\x9c\0" },
- { 0xf909, "\x59\x51\0" },
- { 0xf90a, "\x91\xd1\0" },
- { 0xf90b, "\x55\x87\0" },
- { 0xf90c, "\x59\x48\0" },
- { 0xf90d, "\x61\xf6\0" },
- { 0xf90e, "\x76\x69\0" },
- { 0xf90f, "\x7f\x85\0" },
- { 0xf910, "\x86\x3f\0" },
- { 0xf911, "\x87\xba\0" },
- { 0xf912, "\x88\xf8\0" },
- { 0xf913, "\x90\x8f\0" },
- { 0xf914, "\x6a\x02\0" },
- { 0xf915, "\x6d\x1b\0" },
- { 0xf916, "\x70\xd9\0" },
- { 0xf917, "\x73\xde\0" },
- { 0xf918, "\x84\x3d\0" },
- { 0xf919, "\x91\x6a\0" },
- { 0xf91a, "\x99\xf1\0" },
- { 0xf91b, "\x4e\x82\0" },
- { 0xf91c, "\x53\x75\0" },
- { 0xf91d, "\x6b\x04\0" },
- { 0xf91e, "\x72\x1b\0" },
- { 0xf91f, "\x86\x2d\0" },
- { 0xf920, "\x9e\x1e\0" },
- { 0xf921, "\x5d\x50\0" },
- { 0xf922, "\x6f\xeb\0" },
- { 0xf923, "\x85\xcd\0" },
- { 0xf924, "\x89\x64\0" },
- { 0xf925, "\x62\xc9\0" },
- { 0xf926, "\x81\xd8\0" },
- { 0xf927, "\x88\x1f\0" },
- { 0xf928, "\x5e\xca\0" },
- { 0xf929, "\x67\x17\0" },
- { 0xf92a, "\x6d\x6a\0" },
- { 0xf92b, "\x72\xfc\0" },
- { 0xf92c, "\x90\xce\0" },
- { 0xf92d, "\x4f\x86\0" },
- { 0xf92e, "\x51\xb7\0" },
- { 0xf92f, "\x52\xde\0" },
- { 0xf930, "\x64\xc4\0" },
- { 0xf931, "\x6a\xd3\0" },
- { 0xf932, "\x72\x10\0" },
- { 0xf933, "\x76\xe7\0" },
- { 0xf934, "\x80\x01\0" },
- { 0xf935, "\x86\x06\0" },
- { 0xf936, "\x86\x5c\0" },
- { 0xf937, "\x8d\xef\0" },
- { 0xf938, "\x97\x32\0" },
- { 0xf939, "\x9b\x6f\0" },
- { 0xf93a, "\x9d\xfa\0" },
- { 0xf93b, "\x78\x8c\0" },
- { 0xf93c, "\x79\x7f\0" },
- { 0xf93d, "\x7d\xa0\0" },
- { 0xf93e, "\x83\xc9\0" },
- { 0xf93f, "\x93\x04\0" },
- { 0xf940, "\x9e\x7f\0" },
- { 0xf941, "\x8a\xd6\0" },
- { 0xf942, "\x58\xdf\0" },
- { 0xf943, "\x5f\x04\0" },
- { 0xf944, "\x7c\x60\0" },
- { 0xf945, "\x80\x7e\0" },
- { 0xf946, "\x72\x62\0" },
- { 0xf947, "\x78\xca\0" },
- { 0xf948, "\x8c\xc2\0" },
- { 0xf949, "\x96\xf7\0" },
- { 0xf94a, "\x58\xd8\0" },
- { 0xf94b, "\x5c\x62\0" },
- { 0xf94c, "\x6a\x13\0" },
- { 0xf94d, "\x6d\xda\0" },
- { 0xf94e, "\x6f\x0f\0" },
- { 0xf94f, "\x7d\x2f\0" },
- { 0xf950, "\x7e\x37\0" },
- { 0xf951, "\x96\xfb\0" },
- { 0xf952, "\x52\xd2\0" },
- { 0xf953, "\x80\x8b\0" },
- { 0xf954, "\x51\xdc\0" },
- { 0xf955, "\x51\xcc\0" },
- { 0xf956, "\x7a\x1c\0" },
- { 0xf957, "\x7d\xbe\0" },
- { 0xf958, "\x83\xf1\0" },
- { 0xf959, "\x96\x75\0" },
- { 0xf95a, "\x8b\x80\0" },
- { 0xf95b, "\x62\xcf\0" },
- { 0xf95c, "\x6a\x02\0" },
- { 0xf95d, "\x8a\xfe\0" },
- { 0xf95e, "\x4e\x39\0" },
- { 0xf95f, "\x5b\xe7\0" },
- { 0xf960, "\x60\x12\0" },
- { 0xf961, "\x73\x87\0" },
- { 0xf962, "\x75\x70\0" },
- { 0xf963, "\x53\x17\0" },
- { 0xf964, "\x78\xfb\0" },
- { 0xf965, "\x4f\xbf\0" },
- { 0xf966, "\x5f\xa9\0" },
- { 0xf967, "\x4e\x0d\0" },
- { 0xf968, "\x6c\xcc\0" },
- { 0xf969, "\x65\x78\0" },
- { 0xf96a, "\x7d\x22\0" },
- { 0xf96b, "\x53\xc3\0" },
- { 0xf96c, "\x58\x5e\0" },
- { 0xf96d, "\x77\x01\0" },
- { 0xf96e, "\x84\x49\0" },
- { 0xf96f, "\x8a\xaa\0" },
- { 0xf970, "\x6b\xba\0" },
- { 0xf971, "\x8f\xb0\0" },
- { 0xf972, "\x6c\x88\0" },
- { 0xf973, "\x62\xfe\0" },
- { 0xf974, "\x82\xe5\0" },
- { 0xf975, "\x63\xa0\0" },
- { 0xf976, "\x75\x65\0" },
- { 0xf977, "\x4e\xae\0" },
- { 0xf978, "\x51\x69\0" },
- { 0xf979, "\x51\xc9\0" },
- { 0xf97a, "\x68\x81\0" },
- { 0xf97b, "\x7c\xe7\0" },
- { 0xf97c, "\x82\x6f\0" },
- { 0xf97d, "\x8a\xd2\0" },
- { 0xf97e, "\x91\xcf\0" },
- { 0xf97f, "\x52\xf5\0" },
- { 0xf980, "\x54\x42\0" },
- { 0xf981, "\x59\x73\0" },
- { 0xf982, "\x5e\xec\0" },
- { 0xf983, "\x65\xc5\0" },
- { 0xf984, "\x6f\xfe\0" },
- { 0xf985, "\x79\x2a\0" },
- { 0xf986, "\x95\xad\0" },
- { 0xf987, "\x9a\x6a\0" },
- { 0xf988, "\x9e\x97\0" },
- { 0xf989, "\x9e\xce\0" },
- { 0xf98a, "\x52\x9b\0" },
- { 0xf98b, "\x66\xc6\0" },
- { 0xf98c, "\x6b\x77\0" },
- { 0xf98d, "\x8f\x62\0" },
- { 0xf98e, "\x5e\x74\0" },
- { 0xf98f, "\x61\x90\0" },
- { 0xf990, "\x62\x00\0" },
- { 0xf991, "\x64\x9a\0" },
- { 0xf992, "\x6f\x23\0" },
- { 0xf993, "\x71\x49\0" },
- { 0xf994, "\x74\x89\0" },
- { 0xf995, "\x79\xca\0" },
- { 0xf996, "\x7d\xf4\0" },
- { 0xf997, "\x80\x6f\0" },
- { 0xf998, "\x8f\x26\0" },
- { 0xf999, "\x84\xee\0" },
- { 0xf99a, "\x90\x23\0" },
- { 0xf99b, "\x93\x4a\0" },
- { 0xf99c, "\x52\x17\0" },
- { 0xf99d, "\x52\xa3\0" },
- { 0xf99e, "\x54\xbd\0" },
- { 0xf99f, "\x70\xc8\0" },
- { 0xf9a0, "\x88\xc2\0" },
- { 0xf9a1, "\x8a\xaa\0" },
- { 0xf9a2, "\x5e\xc9\0" },
- { 0xf9a3, "\x5f\xf5\0" },
- { 0xf9a4, "\x63\x7b\0" },
- { 0xf9a5, "\x6b\xae\0" },
- { 0xf9a6, "\x7c\x3e\0" },
- { 0xf9a7, "\x73\x75\0" },
- { 0xf9a8, "\x4e\xe4\0" },
- { 0xf9a9, "\x56\xf9\0" },
- { 0xf9aa, "\x5b\xe7\0" },
- { 0xf9ab, "\x5d\xba\0" },
- { 0xf9ac, "\x60\x1c\0" },
- { 0xf9ad, "\x73\xb2\0" },
- { 0xf9ae, "\x74\x69\0" },
- { 0xf9af, "\x7f\x9a\0" },
- { 0xf9b0, "\x80\x46\0" },
- { 0xf9b1, "\x92\x34\0" },
- { 0xf9b2, "\x96\xf6\0" },
- { 0xf9b3, "\x97\x48\0" },
- { 0xf9b4, "\x98\x18\0" },
- { 0xf9b5, "\x4f\x8b\0" },
- { 0xf9b6, "\x79\xae\0" },
- { 0xf9b7, "\x91\xb4\0" },
- { 0xf9b8, "\x96\xb8\0" },
- { 0xf9b9, "\x60\xe1\0" },
- { 0xf9ba, "\x4e\x86\0" },
- { 0xf9bb, "\x50\xda\0" },
- { 0xf9bc, "\x5b\xee\0" },
- { 0xf9bd, "\x5c\x3f\0" },
- { 0xf9be, "\x65\x99\0" },
- { 0xf9bf, "\x6a\x02\0" },
- { 0xf9c0, "\x71\xce\0" },
- { 0xf9c1, "\x76\x42\0" },
- { 0xf9c2, "\x84\xfc\0" },
- { 0xf9c3, "\x90\x7c\0" },
- { 0xf9c4, "\x9f\x8d\0" },
- { 0xf9c5, "\x66\x88\0" },
- { 0xf9c6, "\x96\x2e\0" },
- { 0xf9c7, "\x52\x89\0" },
- { 0xf9c8, "\x67\x7b\0" },
- { 0xf9c9, "\x67\xf3\0" },
- { 0xf9ca, "\x6d\x41\0" },
- { 0xf9cb, "\x6e\x9c\0" },
- { 0xf9cc, "\x74\x09\0" },
- { 0xf9cd, "\x75\x59\0" },
- { 0xf9ce, "\x78\x6b\0" },
- { 0xf9cf, "\x7d\x10\0" },
- { 0xf9d0, "\x98\x5e\0" },
- { 0xf9d1, "\x51\x6d\0" },
- { 0xf9d2, "\x62\x2e\0" },
- { 0xf9d3, "\x96\x78\0" },
- { 0xf9d4, "\x50\x2b\0" },
- { 0xf9d5, "\x5d\x19\0" },
- { 0xf9d6, "\x6d\xea\0" },
- { 0xf9d7, "\x8f\x2a\0" },
- { 0xf9d8, "\x5f\x8b\0" },
- { 0xf9d9, "\x61\x44\0" },
- { 0xf9da, "\x68\x17\0" },
- { 0xf9db, "\x73\x87\0" },
- { 0xf9dc, "\x96\x86\0" },
- { 0xf9dd, "\x52\x29\0" },
- { 0xf9de, "\x54\x0f\0" },
- { 0xf9df, "\x5c\x65\0" },
- { 0xf9e0, "\x66\x13\0" },
- { 0xf9e1, "\x67\x4e\0" },
- { 0xf9e2, "\x68\xa8\0" },
- { 0xf9e3, "\x6c\xe5\0" },
- { 0xf9e4, "\x74\x06\0" },
- { 0xf9e5, "\x75\xe2\0" },
- { 0xf9e6, "\x7f\x79\0" },
- { 0xf9e7, "\x88\xcf\0" },
- { 0xf9e8, "\x88\xe1\0" },
- { 0xf9e9, "\x91\xcc\0" },
- { 0xf9ea, "\x96\xe2\0" },
- { 0xf9eb, "\x53\x3f\0" },
- { 0xf9ec, "\x6e\xba\0" },
- { 0xf9ed, "\x54\x1d\0" },
- { 0xf9ee, "\x71\xd0\0" },
- { 0xf9ef, "\x74\x98\0" },
- { 0xf9f0, "\x85\xfa\0" },
- { 0xf9f1, "\x96\xa3\0" },
- { 0xf9f2, "\x9c\x57\0" },
- { 0xf9f3, "\x9e\x9f\0" },
- { 0xf9f4, "\x67\x97\0" },
- { 0xf9f5, "\x6d\xcb\0" },
- { 0xf9f6, "\x81\xe8\0" },
- { 0xf9f7, "\x7a\xcb\0" },
- { 0xf9f8, "\x7b\x20\0" },
- { 0xf9f9, "\x7c\x92\0" },
- { 0xf9fa, "\x72\xc0\0" },
- { 0xf9fb, "\x70\x99\0" },
- { 0xf9fc, "\x8b\x58\0" },
- { 0xf9fd, "\x4e\xc0\0" },
- { 0xf9fe, "\x83\x36\0" },
- { 0xf9ff, "\x52\x3a\0" },
- { 0xfa00, "\x52\x07\0" },
- { 0xfa01, "\x5e\xa6\0" },
- { 0xfa02, "\x62\xd3\0" },
- { 0xfa03, "\x7c\xd6\0" },
- { 0xfa04, "\x5b\x85\0" },
- { 0xfa05, "\x6d\x1e\0" },
- { 0xfa06, "\x66\xb4\0" },
- { 0xfa07, "\x8f\x3b\0" },
- { 0xfa08, "\x88\x4c\0" },
- { 0xfa09, "\x96\x4d\0" },
- { 0xfa0a, "\x89\x8b\0" },
- { 0xfa0b, "\x5e\xd3\0" },
- { 0xfa0c, "\x51\x40\0" },
- { 0xfa0d, "\x55\xc0\0" },
- { 0xfa10, "\x58\x5a\0" },
- { 0xfa12, "\x66\x74\0" },
- { 0xfa15, "\x51\xde\0" },
- { 0xfa16, "\x73\x2a\0" },
- { 0xfa17, "\x76\xca\0" },
- { 0xfa18, "\x79\x3c\0" },
- { 0xfa19, "\x79\x5e\0" },
- { 0xfa1a, "\x79\x65\0" },
- { 0xfa1b, "\x79\x8f\0" },
- { 0xfa1c, "\x97\x56\0" },
- { 0xfa1d, "\x7c\xbe\0" },
- { 0xfa1e, "\x7f\xbd\0" },
- { 0xfa20, "\x86\x12\0" },
- { 0xfa22, "\x8a\xf8\0" },
- { 0xfa25, "\x90\x38\0" },
- { 0xfa26, "\x90\xfd\0" },
- { 0xfa2a, "\x98\xef\0" },
- { 0xfa2b, "\x98\xfc\0" },
- { 0xfa2c, "\x99\x28\0" },
- { 0xfa2d, "\x9d\xb4\0" },
- { 0xfb1f, "\x05\xf2\x05\xb7\0" },
- { 0xfb2a, "\x05\xe9\x05\xc1\0" },
- { 0xfb2b, "\x05\xe9\x05\xc2\0" },
- { 0xfb2c, "\x05\xe9\x05\xbc\x05\xc1\0" },
- { 0xfb2d, "\x05\xe9\x05\xbc\x05\xc2\0" },
- { 0xfb2e, "\x05\xd0\x05\xb7\0" },
- { 0xfb2f, "\x05\xd0\x05\xb8\0" },
- { 0xfb30, "\x05\xd0\x05\xbc\0" },
- { 0xfb31, "\x05\xd1\x05\xbc\0" },
- { 0xfb32, "\x05\xd2\x05\xbc\0" },
- { 0xfb33, "\x05\xd3\x05\xbc\0" },
- { 0xfb34, "\x05\xd4\x05\xbc\0" },
- { 0xfb35, "\x05\xd5\x05\xbc\0" },
- { 0xfb36, "\x05\xd6\x05\xbc\0" },
- { 0xfb38, "\x05\xd8\x05\xbc\0" },
- { 0xfb39, "\x05\xd9\x05\xbc\0" },
- { 0xfb3a, "\x05\xda\x05\xbc\0" },
- { 0xfb3b, "\x05\xdb\x05\xbc\0" },
- { 0xfb3c, "\x05\xdc\x05\xbc\0" },
- { 0xfb3e, "\x05\xde\x05\xbc\0" },
- { 0xfb40, "\x05\xe0\x05\xbc\0" },
- { 0xfb41, "\x05\xe1\x05\xbc\0" },
- { 0xfb43, "\x05\xe3\x05\xbc\0" },
- { 0xfb44, "\x05\xe4\x05\xbc\0" },
- { 0xfb46, "\x05\xe6\x05\xbc\0" },
- { 0xfb47, "\x05\xe7\x05\xbc\0" },
- { 0xfb48, "\x05\xe8\x05\xbc\0" },
- { 0xfb49, "\x05\xe9\x05\xbc\0" },
- { 0xfb4a, "\x05\xea\x05\xbc\0" },
- { 0xfb4b, "\x05\xd5\x05\xb9\0" },
- { 0xfb4c, "\x05\xd1\x05\xbf\0" },
- { 0xfb4d, "\x05\xdb\x05\xbf\0" },
- { 0xfb4e, "\x05\xe4\x05\xbf\0" }
-};
-
-/*
- * WARNING!
- *
- * NO BUFFER CHECKING AHEAD!
- *
- */
-
-static gint
-e_canonical_decomposition (gunichar ch, gunichar * buf)
-{
- gint len = 0;
-
- if (ch <= 0xffff)
- {
- int start = 0;
- int end = sizeof (e_decomp_table) / sizeof (e_decomp_table[0]);
- while (start != end)
- {
- int half = (start + end) / 2;
- if (ch == e_decomp_table[half].ch) {
- /* Found it. */
- int i;
- /* We store as a double-nul terminated string. */
- for (len = 0; (e_decomp_table[half].expansion[len] || e_decomp_table[half].expansion[len + 1]); len += 2) ;
-
- /* We've counted twice as many bytes as there are
- characters. */
- len /= 2;
-
- for (i = 0; i < len; i ++) {
- buf[i] = (e_decomp_table[half].expansion[2 * i] << 8) | e_decomp_table[half].expansion[2 * i + 1];
- }
- break;
- } else if (ch > e_decomp_table[half].ch) {
- if (start == half) break;
- start = half;
- } else {
- if (end == half) break;
- end = half;
- }
- }
- }
-
- if (len == 0)
- {
- /* Not in our table. */
- *buf = ch;
- len = 1;
- }
-
- /* Supposedly following the Unicode 2.1.9 table means that the
- decompositions come out in canonical order. I haven't tested
- this, but we rely on it here. */
- return len;
-}
-
-static gunichar
-e_stripped_char (gunichar ch)
-{
- gunichar decomp[MAX_DECOMP];
- GUnicodeType utype;
- gint dlen;
-
- utype = g_unichar_type (ch);
-
- switch (utype) {
- case G_UNICODE_CONTROL:
- case G_UNICODE_FORMAT:
- case G_UNICODE_UNASSIGNED:
- case G_UNICODE_COMBINING_MARK:
- /* Ignore those */
- return 0;
- default:
- /* Convert to lowercase, fall through */
- ch = g_unichar_tolower (ch);
- case G_UNICODE_LOWERCASE_LETTER:
- dlen = e_canonical_decomposition (ch, decomp);
- if (dlen > 0) return *decomp;
- break;
- }
-
- return 0;
-}
-
-gchar *
-e_xml_get_translated_utf8_string_prop_by_name (const xmlNode *parent, const xmlChar *prop_name)
-{
- xmlChar *prop;
- gchar *ret_val = NULL;
- gchar *combined_name;
-
- g_return_val_if_fail (parent != NULL, NULL);
- g_return_val_if_fail (prop_name != NULL, NULL);
-
- prop = xmlGetProp ((xmlNode *) parent, prop_name);
- if (prop != NULL) {
- ret_val = g_strdup ((char *)prop);
- xmlFree (prop);
- return ret_val;
- }
-
- combined_name = g_strdup_printf("_%s", prop_name);
- prop = xmlGetProp ((xmlNode *) parent, (unsigned char *)combined_name);
- if (prop != NULL) {
- ret_val = g_strdup (gettext ((char *)prop));
- xmlFree (prop);
- }
- g_free(combined_name);
-
- return ret_val;
-}
diff --git a/widgets/misc/e-unicode.h b/widgets/misc/e-unicode.h
deleted file mode 100644
index b745876b6d..0000000000
--- a/widgets/misc/e-unicode.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * e-unicode.h - utf-8 support functions for gal
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) version 3.
- *
- * 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with the program; if not, see <http://www.gnu.org/licenses/>
- *
- *
- * Authors:
- * Lauris Kaplinski <lauris@ximian.com>
- *
- * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
- *
- */
-
-#ifndef _E_UNICODE_H_
-#define _E_UNICODE_H_
-
-#include <sys/types.h>
-#include <glib.h>
-#include <gtk/gtk.h>
-#include <libxml/tree.h>
-#include <iconv.h>
-
-G_BEGIN_DECLS
-
-#define G_UTF8_IN_GAL
-
-/*
- * UTF-8 searching implementations
- *
- * e_utf8_strstrcase - case insensitive search
- * e_utf8_strstrcasedecomp - case insensitive and decompositing search (i.e. accented
- * letters are treated equal to their base letters, explicit accent marks (unicode
- * not ascii/iso ones) are ignored).
- */
-
-const gchar *e_utf8_strstrcase (const gchar *haystack,
- const gchar *needle);
-const gchar *e_utf8_strstrcasedecomp (const gchar *haystack,
- const gchar *needle);
-gchar *e_utf8_from_gtk_event_key (GtkWidget *widget,
- guint keyval,
- const gchar *string);
-gchar *e_utf8_from_iconv_string (iconv_t ic,
- const gchar *string);
-gchar *e_utf8_from_iconv_string_sized (iconv_t ic,
- const gchar *string,
- gint bytes);
-gchar *e_utf8_to_iconv_string (iconv_t ic,
- const gchar *string);
-gchar *e_utf8_to_iconv_string_sized (iconv_t ic,
- const gchar *string,
- gint bytes);
-gchar *e_utf8_from_charset_string (const gchar *charset,
- const gchar *string);
-gchar *e_utf8_from_charset_string_sized (const gchar *charset,
- const gchar *string,
- gint bytes);
-gchar *e_utf8_to_charset_string (const gchar *charset,
- const gchar *string);
-gchar *e_utf8_to_charset_string_sized (const gchar *charset,
- const gchar *string,
- gint bytes);
-gchar *e_utf8_from_locale_string (const gchar *string);
-gchar *e_utf8_from_locale_string_sized (const gchar *string,
- gint bytes);
-gchar *e_utf8_to_locale_string (const gchar *string);
-gchar *e_utf8_to_locale_string_sized (const gchar *string,
- gint bytes);
-gboolean e_utf8_is_ascii (const gchar *string);
-/*
- * These are simple wrappers that save us some typing
- */
-
-/* NB! This return newly allocated string, not const as gtk+ one */
-gchar *e_utf8_gtk_entry_get_text (GtkEntry *entry);
-void e_utf8_gtk_entry_set_text (GtkEntry *entry,
- const gchar *text);
-gchar *e_utf8_gtk_editable_get_text (GtkEditable *editable);
-void e_utf8_gtk_editable_set_text (GtkEditable *editable,
- const gchar *text);
-gchar *e_utf8_gtk_editable_get_chars (GtkEditable *editable,
- gint start,
- gint end);
-void e_utf8_gtk_editable_insert_text (GtkEditable *editable,
- const gchar *text,
- gint length,
- gint *position);
-gchar *e_utf8_xml1_decode (const gchar *text);
-gchar *e_utf8_xml1_encode (const gchar *text);
-gint e_unichar_to_utf8 (gint c,
- gchar *outbuf);
-gchar *e_unicode_get_utf8 (const gchar *text,
- gunichar *out);
-guint32 gdk_keyval_to_unicode (guint keysym);
-gchar *e_xml_get_translated_utf8_string_prop_by_name (const xmlNode *parent,
- const xmlChar *prop_name);
-
-G_END_DECLS
-
-#endif
-
-
diff --git a/widgets/table/Makefile.am b/widgets/table/Makefile.am
index be43b559e4..a53b249ce4 100644
--- a/widgets/table/Makefile.am
+++ b/widgets/table/Makefile.am
@@ -1,9 +1,3 @@
-if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = \
- $(top_builddir)/win32/libemiscwidgets.la \
- $(top_builddir)/win32/libetext.la
-endif
-
glade_DATA = \
e-table-config.glade \
e-table-field-chooser.glade
@@ -24,7 +18,9 @@ libetable_la_SOURCES = \
e-cell-checkbox.c \
e-cell-combo.c \
e-cell-date.c \
+ e-cell-date-edit.c \
e-cell-number.c \
+ e-cell-percent.c \
e-cell-pixbuf.c \
e-cell-popup.c \
e-cell-size.c \
@@ -76,7 +72,23 @@ libetable_la_SOURCES = \
e-tree-selection-model.c \
e-tree-sorted.c \
e-tree-table-adapter.c \
- e-tree.c
+ e-tree.c \
+ a11y/gal-a11y-e-cell.c \
+ a11y/gal-a11y-e-cell-popup.c \
+ a11y/gal-a11y-e-cell-registry.c \
+ a11y/gal-a11y-e-cell-text.c \
+ a11y/gal-a11y-e-cell-toggle.c \
+ a11y/gal-a11y-e-cell-tree.c \
+ a11y/gal-a11y-e-cell-vbox.c \
+ a11y/gal-a11y-e-table.c \
+ a11y/gal-a11y-e-table-click-to-add.c \
+ a11y/gal-a11y-e-table-click-to-add-factory.c \
+ a11y/gal-a11y-e-table-column-header.c \
+ a11y/gal-a11y-e-table-factory.c \
+ a11y/gal-a11y-e-table-item.c \
+ a11y/gal-a11y-e-table-item-factory.c \
+ a11y/gal-a11y-e-tree.c \
+ a11y/gal-a11y-e-tree-factory.c
libetableincludedir = $(privincludedir)/table
@@ -85,7 +97,9 @@ libetableinclude_HEADERS = \
e-cell-checkbox.h \
e-cell-combo.h \
e-cell-date.h \
+ e-cell-date-edit.h \
e-cell-number.h \
+ e-cell-percent.h \
e-cell-pixbuf.h \
e-cell-popup.h \
e-cell-size.h \
@@ -140,16 +154,34 @@ libetableinclude_HEADERS = \
e-tree-selection-model.h \
e-tree-sorted.h \
e-tree-table-adapter.h \
- e-tree.h
+ e-tree.h \
+ a11y/gal-a11y-e-cell.h \
+ a11y/gal-a11y-e-cell-popup.h \
+ a11y/gal-a11y-e-cell-registry.h \
+ a11y/gal-a11y-e-cell-text.h \
+ a11y/gal-a11y-e-cell-toggle.h \
+ a11y/gal-a11y-e-cell-tree.h \
+ a11y/gal-a11y-e-cell-vbox.h \
+ a11y/gal-a11y-e-table.h \
+ a11y/gal-a11y-e-table-click-to-add.h \
+ a11y/gal-a11y-e-table-click-to-add-factory.h \
+ a11y/gal-a11y-e-table-column-header.h \
+ a11y/gal-a11y-e-table-factory.h \
+ a11y/gal-a11y-e-table-item.h \
+ a11y/gal-a11y-e-table-item-factory.h \
+ a11y/gal-a11y-e-tree.h \
+ a11y/gal-a11y-e-tree-factory.h
libetable_la_LDFLAGS = $(NO_UNDEFINED)
libetable_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- $(top_builddir)/e-util/libeutil.la \
$(top_builddir)/a11y/libevolution-a11y.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
+ $(top_builddir)/widgets/text/libetext.la \
$(E_UTIL_LIBS) \
$(E_WIDGETS_LIBS) \
+ $(MATH_LIB) \
$(GNOME_PLATFORM_LIBS)
icons = \
diff --git a/widgets/table/a11y/gal-a11y-e-cell-popup.c b/widgets/table/a11y/gal-a11y-e-cell-popup.c
new file mode 100644
index 0000000000..1a40b23a21
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-popup.c
@@ -0,0 +1,144 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yang Wu <yang.wu@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+
+#include "a11y/gal-a11y-util.h"
+#include "table/e-cell-popup.h"
+#include <glib/gi18n.h>
+
+#include "gal-a11y-e-cell-popup.h"
+#include "gal-a11y-e-cell-registry.h"
+
+static AtkObjectClass *parent_class = NULL;
+#define PARENT_TYPE (gal_a11y_e_cell_get_type ())
+
+static void gal_a11y_e_cell_popup_class_init (GalA11yECellPopupClass *klass);
+static void popup_cell_action (GalA11yECell *cell);
+
+/**
+ * gal_a11y_e_cell_popup_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yECellPopup class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yECellPopup class.
+ **/
+GType
+gal_a11y_e_cell_popup_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yECellPopupClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gal_a11y_e_cell_popup_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yECellPopup),
+ 0,
+ (GInstanceInitFunc) NULL,
+ NULL /* value_cell_popup */
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yECellPopup", &info, 0);
+ gal_a11y_e_cell_type_add_action_interface (type);
+ }
+
+ return type;
+}
+
+static void
+gal_a11y_e_cell_popup_class_init (GalA11yECellPopupClass *klass)
+{
+ parent_class = g_type_class_ref (PARENT_TYPE);
+}
+
+AtkObject *
+gal_a11y_e_cell_popup_new (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row)
+{
+ AtkObject *a11y;
+ GalA11yECell *cell;
+ ECellPopup *popupcell;
+ ECellView* child_view = NULL;
+
+ popupcell= E_CELL_POPUP(cell_view->ecell);
+
+ if (popupcell && popupcell->popup_cell_view)
+ child_view = popupcell->popup_cell_view->child_view;
+
+ if (child_view && child_view->ecell) {
+ a11y = gal_a11y_e_cell_registry_get_object (NULL,
+ item,
+ child_view,
+ parent,
+ model_col,
+ view_col,
+ row);
+ } else {
+ a11y = g_object_new (GAL_A11Y_TYPE_E_CELL_POPUP, NULL);
+ gal_a11y_e_cell_construct (a11y,
+ item,
+ cell_view,
+ parent,
+ model_col,
+ view_col,
+ row);
+ }
+ g_return_val_if_fail (a11y != NULL, NULL);
+ cell = GAL_A11Y_E_CELL(a11y);
+ gal_a11y_e_cell_add_action (cell,
+ _("popup"), /* action name*/
+ _("popup a child"), /* action description */
+ "<Alt>Down", /* action keybinding */
+ popup_cell_action);
+
+ a11y->role = ATK_ROLE_TABLE_CELL;
+ return a11y;
+}
+
+static void
+popup_cell_action (GalA11yECell *cell)
+{
+ gint finished;
+ GdkEvent event;
+
+ event.key.type = GDK_KEY_PRESS;
+ event.key.window = GTK_LAYOUT(GNOME_CANVAS_ITEM(cell->item)->canvas)->bin_window;;
+ event.key.send_event = TRUE;
+ event.key.time = GDK_CURRENT_TIME;
+ event.key.state = GDK_MOD1_MASK;
+ event.key.keyval = GDK_Down;
+
+ g_signal_emit_by_name (cell->item, "event", &event, &finished);
+}
diff --git a/widgets/table/a11y/gal-a11y-e-cell-popup.h b/widgets/table/a11y/gal-a11y-e-cell-popup.h
new file mode 100644
index 0000000000..4f205c10bc
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-popup.h
@@ -0,0 +1,62 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yang Wu <yang.wu@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_CELL_POPUP_H__
+#define __GAL_A11Y_E_CELL_POPUP_H__
+
+#include <glib-object.h>
+#include <table/e-table-item.h>
+#include <table/a11y/gal-a11y-e-cell.h>
+#include <atk/atkgobjectaccessible.h>
+
+#define GAL_A11Y_TYPE_E_CELL_POPUP (gal_a11y_e_cell_popup_get_type ())
+#define GAL_A11Y_E_CELL_POPUP(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_POPUP, GalA11yECellPopup))
+#define GAL_A11Y_E_CELL_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL_POPUP, GalA11yECellPopupClass))
+#define GAL_A11Y_IS_E_CELL_POPUP(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_POPUP))
+#define GAL_A11Y_IS_E_CELL_POPUP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_POPUP))
+
+typedef struct _GalA11yECellPopup GalA11yECellPopup;
+typedef struct _GalA11yECellPopupClass GalA11yECellPopupClass;
+
+/* This struct should actually be larger as this isn't what we derive from.
+ * The GalA11yECellPopupPrivate comes right after the parent class structure.
+ **/
+struct _GalA11yECellPopup {
+ GalA11yECell object;
+};
+
+struct _GalA11yECellPopupClass {
+ GalA11yECellClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_cell_popup_get_type (void);
+AtkObject *gal_a11y_e_cell_popup_new (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row);
+
+#endif /* ! __GAL_A11Y_E_CELL_POPUP_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-cell-registry.c b/widgets/table/a11y/gal-a11y-e-cell-registry.c
new file mode 100644
index 0000000000..b88fb581fc
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-registry.c
@@ -0,0 +1,149 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include "gal-a11y-e-cell.h"
+#include "gal-a11y-e-cell-registry.h"
+
+static GObjectClass *parent_class;
+static GalA11yECellRegistry *default_registry;
+#define PARENT_TYPE (G_TYPE_OBJECT)
+
+struct _GalA11yECellRegistryPrivate {
+ GHashTable *table;
+};
+
+/* Static functions */
+
+static void
+gal_a11y_e_cell_registry_finalize (GObject *obj)
+{
+ GalA11yECellRegistry *registry = GAL_A11Y_E_CELL_REGISTRY (obj);
+
+ g_hash_table_destroy (registry->priv->table);
+ g_free (registry->priv);
+
+ G_OBJECT_CLASS (parent_class)->finalize (obj);
+}
+
+static void
+gal_a11y_e_cell_registry_class_init (GalA11yECellRegistryClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ object_class->finalize = gal_a11y_e_cell_registry_finalize;
+}
+
+static void
+gal_a11y_e_cell_registry_init (GalA11yECellRegistry *registry)
+{
+ registry->priv = g_new (GalA11yECellRegistryPrivate, 1);
+ registry->priv->table = g_hash_table_new (NULL, NULL);
+}
+
+/**
+ * gal_a11y_e_cell_registry_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yECellRegistry class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yECellRegistry class.
+ **/
+GType
+gal_a11y_e_cell_registry_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yECellRegistryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gal_a11y_e_cell_registry_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yECellRegistry),
+ 0,
+ (GInstanceInitFunc) gal_a11y_e_cell_registry_init,
+ NULL /* value_cell */
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yECellRegistry", &info, 0);
+ }
+
+ return type;
+}
+
+static void
+init_default_registry (void)
+{
+ if (default_registry == NULL) {
+ default_registry = g_object_new (gal_a11y_e_cell_registry_get_type(), NULL);
+ }
+}
+
+
+AtkObject *
+gal_a11y_e_cell_registry_get_object (GalA11yECellRegistry *registry,
+ ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row)
+{
+ GalA11yECellRegistryFunc func = NULL;
+ GType type;
+
+ if (registry == NULL) {
+ init_default_registry ();
+ registry = default_registry;
+ }
+
+ type = GTK_OBJECT_TYPE (cell_view->ecell);
+ while (func == NULL && type != 0) {
+ func = g_hash_table_lookup (registry->priv->table, GINT_TO_POINTER (type));
+ type = g_type_parent (type);
+ }
+
+ if (func)
+ return func (item, cell_view, parent, model_col, view_col, row);
+ else
+ return gal_a11y_e_cell_new (item, cell_view, parent, model_col, view_col, row);
+}
+
+void
+gal_a11y_e_cell_registry_add_cell_type (GalA11yECellRegistry *registry,
+ GType type,
+ GalA11yECellRegistryFunc func)
+{
+ if (registry == NULL) {
+ init_default_registry ();
+ registry = default_registry;
+ }
+
+ g_hash_table_insert (registry->priv->table, GINT_TO_POINTER (type), func);
+}
diff --git a/widgets/table/a11y/gal-a11y-e-cell-registry.h b/widgets/table/a11y/gal-a11y-e-cell-registry.h
new file mode 100644
index 0000000000..f231567222
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-registry.h
@@ -0,0 +1,72 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_CELL_REGISTRY_H__
+#define __GAL_A11Y_E_CELL_REGISTRY_H__
+
+#include <glib-object.h>
+#include <atk/atkobject.h>
+#include <table/e-table-item.h>
+#include <table/e-cell.h>
+
+#define GAL_A11Y_TYPE_E_CELL_REGISTRY (gal_a11y_e_cell_registry_get_type ())
+#define GAL_A11Y_E_CELL_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_REGISTRY, GalA11yECellRegistry))
+#define GAL_A11Y_E_CELL_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL_REGISTRY, GalA11yECellRegistryClass))
+#define GAL_A11Y_IS_E_CELL_REGISTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_REGISTRY))
+#define GAL_A11Y_IS_E_CELL_REGISTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_REGISTRY))
+
+typedef struct _GalA11yECellRegistry GalA11yECellRegistry;
+typedef struct _GalA11yECellRegistryClass GalA11yECellRegistryClass;
+typedef struct _GalA11yECellRegistryPrivate GalA11yECellRegistryPrivate;
+
+typedef AtkObject *(*GalA11yECellRegistryFunc) (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row);
+
+struct _GalA11yECellRegistry {
+ GObject object;
+
+ GalA11yECellRegistryPrivate *priv;
+};
+
+struct _GalA11yECellRegistryClass {
+ GObjectClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_cell_registry_get_type (void);
+AtkObject *gal_a11y_e_cell_registry_get_object (GalA11yECellRegistry *registry,
+ ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row);
+void gal_a11y_e_cell_registry_add_cell_type (GalA11yECellRegistry *registry,
+ GType type,
+ GalA11yECellRegistryFunc func);
+
+#endif /* ! __GAL_A11Y_E_CELL_REGISTRY_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-cell-text.c b/widgets/table/a11y/gal-a11y-e-cell-text.c
new file mode 100644
index 0000000000..e77c0739a9
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-text.c
@@ -0,0 +1,737 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <atk/atk.h>
+
+#include "a11y/gal-a11y-util.h"
+#include "table/e-cell-text.h"
+#include <glib/gi18n.h>
+
+#include "gal-a11y-e-cell-text.h"
+
+#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yECellTextClass))
+static AtkObjectClass *parent_class;
+#define PARENT_TYPE (gal_a11y_e_cell_get_type ())
+
+/* Static functions */
+static void
+ect_dispose (GObject *object)
+{
+ GObjectClass *g_class;
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (object);
+ GalA11yECellText *gaet = GAL_A11Y_E_CELL_TEXT (object);
+
+ if (gaet->inserted_id != 0) {
+ ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+
+ if (ect) {
+ g_signal_handler_disconnect (ect, gaet->inserted_id);
+ g_signal_handler_disconnect (ect, gaet->deleted_id);
+ }
+
+ gaet->inserted_id = 0;
+ gaet->deleted_id = 0;
+ }
+
+ g_class = (GObjectClass *)parent_class;
+ if (g_class->dispose)
+ g_class->dispose (object);
+
+}
+
+static gboolean
+ect_check (gpointer a11y)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y);
+ ETableItem *item = gaec->item;
+
+ g_return_val_if_fail ((gaec->item != NULL), FALSE);
+ g_return_val_if_fail ((gaec->cell_view != NULL), FALSE);
+ g_return_val_if_fail ((gaec->cell_view->ecell != NULL), FALSE);
+
+ if (atk_state_set_contains_state (gaec->state_set, ATK_STATE_DEFUNCT))
+ return FALSE;
+
+ if (gaec->row < 0 || gaec->row >= item->rows
+ || gaec->view_col <0 || gaec->view_col >= item->cols
+ || gaec->model_col <0 || gaec->model_col >= e_table_model_column_count (item->table_model))
+ return FALSE;
+
+ if (!E_IS_CELL_TEXT (gaec->cell_view->ecell))
+ return FALSE;
+
+ return TRUE;
+}
+
+static G_CONST_RETURN gchar*
+ect_get_name (AtkObject * a11y)
+{
+ GalA11yECell *gaec;
+ char *name;
+
+ if (!ect_check (a11y))
+ return NULL;
+
+ gaec = GAL_A11Y_E_CELL (a11y);
+ name = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+ if (name != NULL) {
+ ATK_OBJECT_CLASS (parent_class)->set_name (a11y, name);
+ g_free (name);
+ }
+
+ if (a11y->name != NULL && strcmp (a11y->name, "")) {
+ return a11y->name;
+ } else {
+ return parent_class->get_name (a11y);
+ }
+}
+
+static gchar *
+ect_get_text (AtkText *text,
+ gint start_offset,
+ gint end_offset)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ gchar *full_text;
+ gchar *ret_val;
+
+ if (!ect_check (text))
+ return NULL;
+
+ full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+
+ if (end_offset == -1)
+ end_offset = strlen (full_text);
+ else
+ end_offset = g_utf8_offset_to_pointer (full_text, end_offset) - full_text;
+
+ start_offset = g_utf8_offset_to_pointer (full_text, start_offset) - full_text;
+
+ ret_val = g_strndup (full_text + start_offset, end_offset - start_offset);
+
+ g_free (full_text);
+
+ return ret_val;
+}
+
+static gchar *
+ect_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+static gchar *
+ect_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+static gunichar
+ect_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ gunichar ret_val;
+ gchar *at_offset;
+ gchar *full_text;
+
+ if (!ect_check (text))
+ return -1;
+
+ full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+ at_offset = g_utf8_offset_to_pointer (full_text, offset);
+ ret_val = g_utf8_get_char_validated (at_offset, -1);
+ g_free (full_text);
+
+ return ret_val;
+}
+
+
+static gchar*
+ect_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+
+static gint
+ect_get_caret_offset (AtkText *text)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ gint start, end;
+
+ if (!ect_check (text))
+ return -1;
+
+ if (e_cell_text_get_selection (gaec->cell_view,
+ gaec->view_col, gaec->row,
+ &start, &end)) {
+ gchar *full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+ end = g_utf8_pointer_to_offset (full_text, full_text + end);
+ g_free (full_text);
+
+ return end;
+ }
+ else
+ return -1;
+}
+
+static AtkAttributeSet*
+ect_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+
+static AtkAttributeSet*
+ect_get_default_attributes (AtkText *text)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+
+static void
+ect_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ /* Unimplemented */
+}
+
+
+static gint
+ect_get_character_count (AtkText *text)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ gint ret_val;
+ gchar *full_text;
+
+ if (!ect_check (text))
+ return -1;
+
+ full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+
+ ret_val = g_utf8_strlen (full_text, -1);
+ g_free (full_text);
+ return ret_val;
+}
+
+
+static gint
+ect_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ /* Unimplemented */
+ return 0;
+}
+
+
+static gint
+ect_get_n_selections (AtkText *text)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ gint selection_start, selection_end;
+
+ if (!ect_check (text))
+ return 0;
+
+ if (e_cell_text_get_selection (gaec->cell_view,
+ gaec->view_col, gaec->row,
+ &selection_start,
+ &selection_end)
+ && selection_start != selection_end)
+ return 1;
+ return 0;
+}
+
+
+static gchar*
+ect_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_offset,
+ gint *end_offset)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ gchar *ret_val;
+ gint selection_start, selection_end;
+
+ if (selection_num == 0
+ && e_cell_text_get_selection (gaec->cell_view,
+ gaec->view_col, gaec->row,
+ &selection_start,
+ &selection_end)
+ && selection_start != selection_end) {
+ gint real_start, real_end, len;
+ gchar *full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+ len = strlen (full_text);
+ real_start = MIN (selection_start, selection_end);
+ real_end = MAX (selection_start, selection_end);
+ real_start = MIN (MAX (0, real_start), len);
+ real_end = MIN (MAX (0, real_end), len);
+
+ ret_val = g_strndup (full_text + real_start, real_end - real_start);
+
+ real_start = g_utf8_pointer_to_offset (full_text, full_text + real_start);
+ real_end = g_utf8_pointer_to_offset (full_text, full_text + real_end);
+
+ if (start_offset)
+ *start_offset = real_start;
+ if (end_offset)
+ *end_offset = real_end;
+ g_free (full_text);
+ } else {
+ if (start_offset)
+ *start_offset = 0;
+ if (end_offset)
+ *end_offset = 0;
+ ret_val = NULL;
+ }
+
+ return ret_val;
+}
+
+
+static gboolean
+ect_add_selection (AtkText *text,
+ gint start_offset,
+ gint end_offset)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+
+ if (start_offset != end_offset) {
+ gint real_start, real_end, len;
+ gchar *full_text =
+ e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+
+ len = g_utf8_strlen (full_text, -1);
+ if (end_offset == -1)
+ end_offset = len;
+
+ real_start = MIN (start_offset, end_offset);
+ real_end = MAX (start_offset, end_offset);
+
+ real_start = MIN (MAX (0, real_start), len);
+ real_end = MIN (MAX (0, real_end), len);
+
+ real_start = g_utf8_offset_to_pointer (full_text, real_start) - full_text;
+ real_end = g_utf8_offset_to_pointer (full_text, real_end) - full_text;
+ g_free (full_text);
+
+ if (e_cell_text_set_selection (gaec->cell_view,
+ gaec->view_col, gaec->row,
+ real_start, real_end)) {
+ g_signal_emit_by_name (ATK_OBJECT(text), "text_selection_changed");
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+ect_remove_selection (AtkText *text,
+ gint selection_num)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ gint selection_start, selection_end;
+
+ if (selection_num == 0
+ && e_cell_text_get_selection (gaec->cell_view,
+ gaec->view_col, gaec->row,
+ &selection_start,
+ &selection_end)
+ && selection_start != selection_end
+ && e_cell_text_set_selection (gaec->cell_view,
+ gaec->view_col, gaec->row,
+ selection_end, selection_end)) {
+ g_signal_emit_by_name (ATK_OBJECT(text), "text_selection_changed");
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+static gboolean
+ect_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_offset,
+ gint end_offset)
+{
+ if (selection_num == 0) {
+ atk_text_add_selection (text, start_offset, end_offset);
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+
+static gboolean
+ect_set_caret_offset (AtkText *text,
+ gint offset)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ gchar *full_text;
+ gint len;
+
+ full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+
+ len = g_utf8_strlen (full_text, -1);
+ if (offset == -1)
+ offset = len;
+ else
+ offset = MIN (MAX (0, offset), len);
+
+ offset = g_utf8_offset_to_pointer (full_text, offset) - full_text;
+
+ g_free (full_text);
+
+ return e_cell_text_set_selection (gaec->cell_view,
+ gaec->view_col, gaec->row,
+ offset, offset);
+}
+
+static gboolean
+ect_set_run_attributes (AtkEditableText *text,
+ AtkAttributeSet *attrib_set,
+ gint start_offset,
+ gint end_offset)
+{
+ /* Unimplemented */
+ return FALSE;
+}
+
+static void
+ect_set_text_contents (AtkEditableText *text,
+ const gchar *string)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+
+ e_cell_text_set_value (ect, gaec->item->table_model, gaec->model_col, gaec->row, string);
+ e_table_item_enter_edit (gaec->item, gaec->view_col, gaec->row);
+}
+
+static void
+ect_insert_text (AtkEditableText *text,
+ const gchar *string,
+ gint length,
+ gint *position)
+{
+ /* Utf8 unimplemented */
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+
+ gchar *full_text = e_cell_text_get_text_by_view (gaec->cell_view, gaec->model_col, gaec->row);
+ gchar *result = g_strdup_printf ("%.*s%.*s%s", *position, full_text, length, string, full_text + *position);
+
+ e_cell_text_set_value (ect, gaec->item->table_model, gaec->model_col, gaec->row, result);
+
+ *position += length;
+
+ g_free (result);
+ g_free (full_text);
+}
+
+static void
+ect_copy_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ if (start_pos != end_pos
+ && atk_text_set_selection (ATK_TEXT (text), 0, start_pos, end_pos))
+ e_cell_text_copy_clipboard (gaec->cell_view,
+ gaec->view_col, gaec->row);
+}
+
+static void
+ect_delete_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+ if (start_pos != end_pos
+ && atk_text_set_selection (ATK_TEXT (text), 0, start_pos, end_pos))
+ e_cell_text_delete_selection (gaec->cell_view,
+ gaec->view_col, gaec->row);
+}
+
+static void
+ect_cut_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ ect_copy_text (text, start_pos, end_pos);
+ ect_delete_text (text, start_pos, end_pos);
+}
+
+static void
+ect_paste_text (AtkEditableText *text,
+ gint position)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (text);
+
+ e_table_item_enter_edit (gaec->item, gaec->view_col, gaec->row);
+
+ if (atk_text_set_caret_offset (ATK_TEXT (text), position))
+ e_cell_text_paste_clipboard (gaec->cell_view,
+ gaec->view_col, gaec->row);
+}
+
+static void
+ect_do_action_edit (AtkAction *action)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (action);
+ ETableModel *e_table_model = a11y->item->table_model;
+
+ if (e_table_model_is_cell_editable(e_table_model, a11y->model_col, a11y->row)) {
+ e_table_item_enter_edit (a11y->item, a11y->view_col, a11y->row);
+ }
+}
+
+/* text signal handlers */
+static void
+ect_text_inserted_cb (ECellText *text, ECellView *cell_view, int pos, int len, int row, int model_col, gpointer data)
+{
+ GalA11yECellText *gaet;
+ GalA11yECell *gaec;
+
+ if (!ect_check (data))
+ return;
+ gaet = GAL_A11Y_E_CELL_TEXT (data);
+ gaec = GAL_A11Y_E_CELL (data);
+
+ if (cell_view == gaec->cell_view && row == gaec->row && model_col == gaec->model_col) {
+ g_signal_emit_by_name (gaet, "text_changed::insert", pos, len);
+
+ }
+}
+
+static void
+ect_text_deleted_cb (ECellText *text, ECellView *cell_view, int pos, int len, int row, int model_col, gpointer data)
+{
+ GalA11yECellText *gaet;
+ GalA11yECell *gaec;
+ if (!ect_check (data))
+ return;
+ gaet = GAL_A11Y_E_CELL_TEXT (data);
+ gaec = GAL_A11Y_E_CELL (data);
+ if (cell_view == gaec->cell_view && row == gaec->row && model_col == gaec->model_col) {
+ g_signal_emit_by_name (gaet, "text_changed::delete", pos, len);
+ }
+}
+
+static void
+ect_atk_text_iface_init (AtkTextIface *iface)
+{
+ iface->get_text = ect_get_text;
+ iface->get_text_after_offset = ect_get_text_after_offset;
+ iface->get_text_at_offset = ect_get_text_at_offset;
+ iface->get_character_at_offset = ect_get_character_at_offset;
+ iface->get_text_before_offset = ect_get_text_before_offset;
+ iface->get_caret_offset = ect_get_caret_offset;
+ iface->get_run_attributes = ect_get_run_attributes;
+ iface->get_default_attributes = ect_get_default_attributes;
+ iface->get_character_extents = ect_get_character_extents;
+ iface->get_character_count = ect_get_character_count;
+ iface->get_offset_at_point = ect_get_offset_at_point;
+ iface->get_n_selections = ect_get_n_selections;
+ iface->get_selection = ect_get_selection;
+ iface->add_selection = ect_add_selection;
+ iface->remove_selection = ect_remove_selection;
+ iface->set_selection = ect_set_selection;
+ iface->set_caret_offset = ect_set_caret_offset;
+}
+
+static void
+ect_atk_editable_text_iface_init (AtkEditableTextIface *iface)
+{
+ iface->set_run_attributes = ect_set_run_attributes;
+ iface->set_text_contents = ect_set_text_contents;
+ iface->insert_text = ect_insert_text;
+ iface->copy_text = ect_copy_text;
+ iface->cut_text = ect_cut_text;
+ iface->delete_text = ect_delete_text;
+ iface->paste_text = ect_paste_text;
+}
+
+static void
+ect_class_init (GalA11yECellTextClass *klass)
+{
+ AtkObjectClass *a11y = ATK_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+ a11y->get_name = ect_get_name;
+ object_class->dispose = ect_dispose;
+}
+
+static void
+ect_action_init (GalA11yECellText *a11y)
+{
+ GalA11yECell *gaec = GAL_A11Y_E_CELL (a11y);
+ ECellText *ect = E_CELL_TEXT (gaec->cell_view->ecell);
+ if (ect->editable && e_table_model_is_cell_editable (gaec->cell_view->e_table_model, gaec->model_col, gaec->row))
+ gal_a11y_e_cell_add_action (gaec,
+ _("edit"),
+ _("begin editing this cell"),
+ NULL,
+ (ACTION_FUNC) ect_do_action_edit);
+}
+
+/**
+ * gal_a11y_e_cell_text_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yECellText class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yECellText class.
+ **/
+GType
+gal_a11y_e_cell_text_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yECellTextClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ect_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yECellText),
+ 0,
+ (GInstanceInitFunc) NULL,
+ NULL /* value_cell_text */
+ };
+
+ static const GInterfaceInfo atk_text_info = {
+ (GInterfaceInitFunc) ect_atk_text_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ static const GInterfaceInfo atk_editable_text_info = {
+ (GInterfaceInitFunc) ect_atk_editable_text_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yECellText", &info, 0);
+ g_type_add_interface_static (type, ATK_TYPE_TEXT, &atk_text_info);
+ g_type_add_interface_static (type, ATK_TYPE_EDITABLE_TEXT, &atk_editable_text_info);
+ gal_a11y_e_cell_type_add_action_interface (type);
+ }
+
+ return type;
+}
+
+static void
+cell_text_destroyed (gpointer data)
+{
+ g_return_if_fail (GAL_A11Y_IS_E_CELL_TEXT (data));
+
+ g_object_unref (data);
+}
+
+AtkObject *
+gal_a11y_e_cell_text_new (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row)
+{
+ AtkObject *a11y;
+ GalA11yECell *gaec;
+ GalA11yECellText *gaet;
+ ECellText *ect;
+
+ a11y = g_object_new (gal_a11y_e_cell_text_get_type (), NULL);
+
+ gal_a11y_e_cell_construct (a11y,
+ item,
+ cell_view,
+ parent,
+ model_col,
+ view_col,
+ row);
+ gaet = GAL_A11Y_E_CELL_TEXT (a11y);
+
+ /* will be unrefed in cell_text_destroyed */
+ g_object_ref (a11y);
+
+ gaet->inserted_id = g_signal_connect (E_CELL_TEXT (((ECellView *)cell_view)->ecell),
+ "text_inserted", G_CALLBACK (ect_text_inserted_cb), a11y);
+ gaet->deleted_id = g_signal_connect (E_CELL_TEXT (((ECellView *)cell_view)->ecell),
+ "text_deleted", G_CALLBACK (ect_text_deleted_cb), a11y);
+
+ g_object_weak_ref (G_OBJECT (((ECellView *)cell_view)->ecell),
+ (GWeakNotify) cell_text_destroyed,
+ a11y);
+
+ ect_action_init (gaet);
+
+ ect = E_CELL_TEXT (cell_view->ecell);
+ gaec = GAL_A11Y_E_CELL (a11y);
+ if (ect->editable && e_table_model_is_cell_editable (gaec->cell_view->e_table_model, gaec->model_col, gaec->row))
+ gal_a11y_e_cell_add_state (gaec, ATK_STATE_EDITABLE, FALSE);
+ else
+ gal_a11y_e_cell_remove_state (gaec, ATK_STATE_EDITABLE, FALSE);
+
+ return a11y;
+}
diff --git a/widgets/table/a11y/gal-a11y-e-cell-text.h b/widgets/table/a11y/gal-a11y-e-cell-text.h
new file mode 100644
index 0000000000..208bc67c66
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-text.h
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_CELL_TEXT_H__
+#define __GAL_A11Y_E_CELL_TEXT_H__
+
+#include <glib-object.h>
+#include <table/e-table-item.h>
+#include <table/e-cell-text.h>
+#include <table/a11y/gal-a11y-e-cell.h>
+
+#define GAL_A11Y_TYPE_E_CELL_TEXT (gal_a11y_e_cell_text_get_type ())
+#define GAL_A11Y_E_CELL_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_TEXT, GalA11yECellText))
+#define GAL_A11Y_E_CELL_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL_TEXT, GalA11yECellTextClass))
+#define GAL_A11Y_IS_E_CELL_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_TEXT))
+#define GAL_A11Y_IS_E_CELL_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_TEXT))
+
+typedef struct _GalA11yECellText GalA11yECellText;
+typedef struct _GalA11yECellTextClass GalA11yECellTextClass;
+typedef struct _GalA11yECellTextPrivate GalA11yECellTextPrivate;
+
+/* This struct should actually be larger as this isn't what we derive from.
+ * The GalA11yECellTextPrivate comes right after the parent class structure.
+ **/
+struct _GalA11yECellText {
+ GalA11yECell object;
+ gint inserted_id;
+ gint deleted_id;
+};
+
+struct _GalA11yECellTextClass {
+ GalA11yECellClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_cell_text_get_type (void);
+AtkObject *gal_a11y_e_cell_text_new (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row);
+
+#endif /* ! __GAL_A11Y_E_CELL_TEXT_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-cell-toggle.c b/widgets/table/a11y/gal-a11y-e-cell-toggle.c
new file mode 100644
index 0000000000..23114b0373
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-toggle.c
@@ -0,0 +1,191 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <gtk/gtk.h>
+
+#include "table/e-cell-toggle.h"
+#include "table/e-table-model.h"
+#include <glib/gi18n.h>
+
+#include "gal-a11y-e-cell-toggle.h"
+
+#define PARENT_TYPE (gal_a11y_e_cell_get_type ())
+static GObjectClass *parent_class;
+
+static void gal_a11y_e_cell_toggle_class_init (GalA11yECellToggleClass *klass);
+
+static void
+gal_a11y_e_cell_toggle_dispose (GObject *object)
+{
+ GalA11yECellToggle *a11y = GAL_A11Y_E_CELL_TOGGLE (object);
+
+ ETableModel *e_table_model = GAL_A11Y_E_CELL (a11y)->item->table_model;
+
+ if (e_table_model && a11y->model_id > 0) {
+ g_signal_handler_disconnect (e_table_model, a11y->model_id);
+ a11y->model_id = 0;
+ }
+
+ if (parent_class->dispose)
+ parent_class->dispose (object);
+}
+
+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)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->dispose = gal_a11y_e_cell_toggle_dispose;
+ parent_class = g_type_class_ref (PARENT_TYPE);
+}
+
+static void
+toggle_cell_action (GalA11yECell *cell)
+{
+ 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 + width / 2 + (int)(GNOME_CANVAS_ITEM (cell->item)->x1);
+ event.y = y + height / 2 + (int)(GNOME_CANVAS_ITEM (cell->item)->y1);
+
+ 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);
+}
+
+static void
+model_change_cb (ETableModel *etm,
+ gint col,
+ gint row,
+ GalA11yECell *cell)
+{
+ gint value;
+
+ if (col == cell->model_col && row == cell->row) {
+
+ value = GPOINTER_TO_INT (
+ e_table_model_value_at (cell->cell_view->e_table_model,
+ cell->model_col, cell->row));
+ /* Cheat gnopernicus, or it will ignore the state change signal */
+ atk_focus_tracker_notify (ATK_OBJECT (cell));
+
+ if (value)
+ gal_a11y_e_cell_add_state (cell, ATK_STATE_CHECKED, TRUE);
+ else
+ gal_a11y_e_cell_remove_state (cell, ATK_STATE_CHECKED, TRUE);
+ }
+}
+
+
+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;
+ gint value;
+
+ 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);
+
+ toggle_cell->model_id = g_signal_connect (item->table_model,
+ "model_cell_changed",
+ (GCallback) model_change_cb,
+ a11y);
+
+ value = GPOINTER_TO_INT (
+ e_table_model_value_at (cell->cell_view->e_table_model,
+ cell->model_col, cell->row));
+ if (value)
+ gal_a11y_e_cell_add_state (cell, ATK_STATE_CHECKED, FALSE);
+ else
+ gal_a11y_e_cell_remove_state (cell, ATK_STATE_CHECKED, FALSE);
+
+ return a11y;
+}
diff --git a/widgets/table/a11y/gal-a11y-e-cell-toggle.h b/widgets/table/a11y/gal-a11y-e-cell-toggle.h
new file mode 100644
index 0000000000..56483aae6b
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-toggle.h
@@ -0,0 +1,68 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#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;
+ gint model_id;
+};
+
+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/widgets/table/a11y/gal-a11y-e-cell-tree.c b/widgets/table/a11y/gal-a11y-e-cell-tree.c
new file mode 100644
index 0000000000..520a818a37
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-tree.c
@@ -0,0 +1,260 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Tim Wo <tim.wo@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include <atk/atk.h>
+
+#include "a11y/gal-a11y-util.h"
+#include "table/e-cell-tree.h"
+#include "table/e-table.h"
+#include "table/e-tree-table-adapter.h"
+#include <glib/gi18n.h>
+
+#include "gal-a11y-e-cell-tree.h"
+#include "gal-a11y-e-cell-registry.h"
+
+#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yECellTreeClass))
+static AtkObjectClass *a11y_parent_class;
+#define A11Y_PARENT_TYPE (gal_a11y_e_cell_get_type ())
+
+#define d(x)
+
+static void
+ectr_model_row_changed_cb (ETableModel *etm,
+ gint row,
+ GalA11yECell *a11y)
+{
+ ETreePath node;
+ ETreeModel *tree_model;
+ ETreeTableAdapter *tree_table_adapter;
+
+ g_return_if_fail (a11y);
+ if (a11y->row != row)
+ return;
+
+ node = e_table_model_value_at (etm, -1, a11y->row);
+ tree_model = e_table_model_value_at (etm, -2, a11y->row);
+ tree_table_adapter = e_table_model_value_at (etm, -3, a11y->row);
+
+ if (e_tree_model_node_is_expandable (tree_model, node)) {
+ gboolean is_exp = e_tree_table_adapter_node_is_expanded (tree_table_adapter, node);
+ if (is_exp)
+ gal_a11y_e_cell_add_state (a11y, ATK_STATE_EXPANDED, TRUE);
+ else
+ gal_a11y_e_cell_remove_state (a11y, ATK_STATE_EXPANDED, TRUE);
+ }
+}
+
+static void
+kill_view_cb(ECellView *subcell_view,
+ gpointer psubcell_a11ies)
+{
+ GList *node;
+ GList *subcell_a11ies = (GList *) psubcell_a11ies;
+ GalA11yECell *subcell;
+
+ for (node = subcell_a11ies; node != NULL; node = g_list_next (node))
+ {
+ subcell = GAL_A11Y_E_CELL(node->data);
+ if (subcell && subcell->cell_view == subcell_view)
+ {
+ d(fprintf(stderr, "subcell_view %p deleted before the a11y object %p\n", subcell_view, subcell));
+ subcell->cell_view = NULL;
+ }
+ }
+}
+
+static void
+ectr_subcell_weak_ref (GalA11yECellTree *a11y,
+ GalA11yECell *subcell_a11y)
+{
+ ECellView *subcell_view = subcell_a11y ? subcell_a11y->cell_view : NULL;
+ if (subcell_a11y && subcell_view && subcell_view->kill_view_cb_data)
+ subcell_view->kill_view_cb_data = g_list_remove(subcell_view->kill_view_cb_data, subcell_a11y);
+
+ g_signal_handler_disconnect (GAL_A11Y_E_CELL (a11y)->item->table_model,
+ a11y->model_row_changed_id);
+ g_object_unref (a11y);
+}
+
+static void
+ectr_do_action_expand (AtkAction *action)
+{
+ GalA11yECell *a11y;
+ ETableModel *table_model;
+ ETreePath node;
+ ETreeModel *tree_model;
+ ETreeTableAdapter *tree_table_adapter;
+
+ a11y = GAL_A11Y_E_CELL (action);
+ table_model = a11y->item->table_model;
+ node = e_table_model_value_at (table_model, -1, a11y->row);
+ tree_model = e_table_model_value_at (table_model, -2, a11y->row);
+ tree_table_adapter = e_table_model_value_at (table_model, -3, a11y->row);
+
+ if (e_tree_model_node_is_expandable (tree_model, node)) {
+ e_tree_table_adapter_node_set_expanded (tree_table_adapter,
+ node,
+ TRUE);
+ gal_a11y_e_cell_add_state (a11y, ATK_STATE_EXPANDED, TRUE);
+ }
+}
+
+static void
+ectr_do_action_collapse (AtkAction *action)
+{
+ GalA11yECell *a11y;
+ ETableModel *table_model;
+ ETreePath node;
+ ETreeModel *tree_model;
+ ETreeTableAdapter *tree_table_adapter;
+
+ a11y = GAL_A11Y_E_CELL (action);
+ table_model = a11y->item->table_model;
+ node = e_table_model_value_at (table_model, -1, a11y->row);
+ tree_model = e_table_model_value_at (table_model, -2, a11y->row);
+ tree_table_adapter = e_table_model_value_at (table_model, -3, a11y->row);
+
+ if (e_tree_model_node_is_expandable (tree_model, node)) {
+ e_tree_table_adapter_node_set_expanded (tree_table_adapter,
+ node,
+ FALSE);
+ gal_a11y_e_cell_remove_state (a11y, ATK_STATE_EXPANDED, TRUE);
+ }
+}
+
+static void
+ectr_class_init (GalA11yECellTreeClass *klass)
+{
+ a11y_parent_class = g_type_class_ref (A11Y_PARENT_TYPE);
+}
+
+static void
+ectr_init (GalA11yECellTree *a11y)
+{
+}
+
+GType
+gal_a11y_e_cell_tree_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yECellTreeClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ectr_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yECellTree),
+ 0,
+ (GInstanceInitFunc) ectr_init,
+ NULL /* value_cell_text */
+ };
+
+ type = g_type_register_static (A11Y_PARENT_TYPE, "GalA11yECellTree", &info, 0);
+ gal_a11y_e_cell_type_add_action_interface (type);
+ }
+
+ return type;
+}
+
+AtkObject *
+gal_a11y_e_cell_tree_new (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row)
+{
+ AtkObject *subcell_a11y;
+ GalA11yECellTree *a11y;
+
+ ETreePath node;
+ ETreeModel *tree_model;
+ ETreeTableAdapter *tree_table_adapter;
+
+ ECellView *subcell_view;
+ subcell_view = e_cell_tree_view_get_subcell_view (cell_view);
+
+ if (subcell_view->ecell) {
+ subcell_a11y = gal_a11y_e_cell_registry_get_object (NULL,
+ item,
+ subcell_view,
+ parent,
+ model_col,
+ view_col,
+ row);
+ gal_a11y_e_cell_add_action (GAL_A11Y_E_CELL (subcell_a11y),
+ _("expand"),
+ _("expands the row in the ETree containing this cell"),
+ NULL,
+ (ACTION_FUNC)ectr_do_action_expand);
+
+ gal_a11y_e_cell_add_action (GAL_A11Y_E_CELL (subcell_a11y),
+ _("collapse"),
+ _("collapses the row in the ETree containing this cell"),
+ NULL,
+ (ACTION_FUNC)ectr_do_action_collapse);
+
+ /* init AtkStates for the cell's a11y object */
+ node = e_table_model_value_at (item->table_model, -1, row);
+ tree_model = e_table_model_value_at (item->table_model, -2, row);
+ tree_table_adapter = e_table_model_value_at (item->table_model, -3, row);
+ if (e_tree_model_node_is_expandable (tree_model, node)) {
+ gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL (subcell_a11y), ATK_STATE_EXPANDABLE, FALSE);
+ if (e_tree_table_adapter_node_is_expanded (tree_table_adapter, node))
+ gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL (subcell_a11y), ATK_STATE_EXPANDED, FALSE);
+ }
+ }
+ else
+ subcell_a11y = NULL;
+
+ /* create a companion a11y object, this object has type GalA11yECellTree
+ and it connects to some signals to determine whether a tree cell is
+ expanded or collapsed */
+ a11y = g_object_new (gal_a11y_e_cell_tree_get_type (), NULL);
+ gal_a11y_e_cell_construct (ATK_OBJECT (a11y),
+ item,
+ cell_view,
+ parent,
+ model_col,
+ view_col,
+ row);
+ a11y->model_row_changed_id =
+ g_signal_connect (item->table_model, "model_row_changed",
+ G_CALLBACK (ectr_model_row_changed_cb),
+ subcell_a11y);
+
+ if (subcell_a11y && subcell_view)
+ {
+ subcell_view->kill_view_cb = kill_view_cb;
+ if (!g_list_find(subcell_view->kill_view_cb_data, subcell_a11y))
+ subcell_view->kill_view_cb_data = g_list_append(subcell_view->kill_view_cb_data, subcell_a11y);
+ }
+
+ g_object_weak_ref (G_OBJECT (subcell_a11y), (GWeakNotify) ectr_subcell_weak_ref, a11y);
+
+ return subcell_a11y;
+}
diff --git a/widgets/table/a11y/gal-a11y-e-cell-tree.h b/widgets/table/a11y/gal-a11y-e-cell-tree.h
new file mode 100644
index 0000000000..f6f6d9dd70
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-tree.h
@@ -0,0 +1,64 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Tim Wo <tim.wo@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_CELL_TREE_H__
+#define __GAL_A11Y_E_CELL_TREE_H__
+
+#include <glib-object.h>
+#include <table/e-table-item.h>
+#include <table/e-cell-tree.h>
+#include "gal-a11y-e-cell.h"
+
+#define GAL_A11Y_TYPE_E_CELL_TREE (gal_a11y_e_cell_tree_get_type ())
+#define GAL_A11Y_E_CELL_TREE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL_TREE, GalA11yECellTree))
+#define GAL_A11Y_E_CELL_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL_TREE, GalA11yECellTreeClass))
+#define GAL_A11Y_IS_E_CELL_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL_TREE))
+#define GAL_A11Y_IS_E_CELL_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL_TREE))
+
+typedef struct _GalA11yECellTree GalA11yECellTree;
+typedef struct _GalA11yECellTreeClass GalA11yECellTreeClass;
+typedef struct _GalA11yECellTreePrivate GalA11yECellTreePrivate;
+
+/* This struct should actually be larger as this isn't what we derive from.
+ * The GalA11yECellTreePrivate comes right after the parent class structure.
+ **/
+struct _GalA11yECellTree {
+ GalA11yECell object;
+
+ int model_row_changed_id;
+};
+
+struct _GalA11yECellTreeClass {
+ GalA11yECellClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_cell_tree_get_type (void);
+AtkObject *gal_a11y_e_cell_tree_new (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row);
+
+#endif /* ! __GAL_A11Y_E_CELL_TREE_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-cell-vbox.c b/widgets/table/a11y/gal-a11y-e-cell-vbox.c
new file mode 100644
index 0000000000..08859d07ef
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-vbox.c
@@ -0,0 +1,225 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Eric Zhao <eric.zhao@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2004 Sun Microsystem, Inc.
+ *
+ */
+
+#include <config.h>
+
+#include <atk/atk.h>
+
+#include "table/e-cell-vbox.h"
+
+#include "gal-a11y-e-cell-registry.h"
+#include "gal-a11y-e-cell-vbox.h"
+
+static GObjectClass *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);
+
+ return GAL_A11Y_E_CELL_VBOX (a11y)->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) {
+ ECellView *subcell_view;
+ gint model_col, row;
+ row = gaec->row;
+ model_col = ecvv->model_cols[i];
+ subcell_view = ecvv->subcell_views[i];
+ ret = gal_a11y_e_cell_registry_get_object (NULL,
+ gaec->item,
+ subcell_view,
+ a11y,
+ model_col,
+ gaec->view_col, /* FIXME should the view column use a fake one or the same as its parent? */
+ row);
+ gaev->a11y_subcells[i] = ret;
+ g_object_ref (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);
+
+ if (parent_class->dispose)
+ parent_class->dispose (object);
+}
+
+/* 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;
+ GalA11yECell *gaec;
+ GalA11yECellVbox *gaev;
+ ECellVboxView *ecvv;
+
+ 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);
+
+ gaec = GAL_A11Y_E_CELL (a11y);
+ gaev = GAL_A11Y_E_CELL_VBOX (a11y);
+ 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;
+}
diff --git a/widgets/table/a11y/gal-a11y-e-cell-vbox.h b/widgets/table/a11y/gal-a11y-e-cell-vbox.h
new file mode 100644
index 0000000000..276a60177a
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell-vbox.h
@@ -0,0 +1,67 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Eric Zhao <eric.zhao@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ * Copyright (C) 2004 Sun Microsystem, Inc.
+ *
+ */
+
+#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__ */
diff --git a/widgets/table/a11y/gal-a11y-e-cell.c b/widgets/table/a11y/gal-a11y-e-cell.c
new file mode 100644
index 0000000000..6154fc0acd
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell.c
@@ -0,0 +1,644 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include "a11y/gal-a11y-util.h"
+#include "table/e-table.h"
+#include "table/e-tree.h"
+#include <glib/gi18n.h>
+
+#include "gal-a11y-e-cell.h"
+#include "gal-a11y-e-cell-vbox.h"
+#include "gal-a11y-e-table-item.h"
+
+#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yECellClass))
+static GObjectClass *parent_class;
+#define PARENT_TYPE (atk_object_get_type ())
+
+
+#if 0
+static void
+unref_item (gpointer user_data, GObject *obj_loc)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (user_data);
+ a11y->item = NULL;
+ g_object_unref (a11y);
+}
+
+static void
+unref_cell (gpointer user_data, GObject *obj_loc)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (user_data);
+ a11y->cell_view = NULL;
+ g_object_unref (a11y);
+}
+#endif
+
+static gboolean
+is_valid (AtkObject *cell)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (cell);
+ GalA11yETableItem *a11yItem = GAL_A11Y_E_TABLE_ITEM (a11y->parent);
+ AtkStateSet *item_ss;
+ gboolean ret = TRUE;
+
+ item_ss = atk_object_ref_state_set (ATK_OBJECT (a11yItem));
+ if (atk_state_set_contains_state (item_ss, ATK_STATE_DEFUNCT))
+ ret = FALSE;
+
+ g_object_unref (item_ss);
+
+ if (ret && atk_state_set_contains_state (a11y->state_set, ATK_STATE_DEFUNCT))
+ ret = FALSE;
+
+ return ret;
+}
+
+static void
+gal_a11y_e_cell_dispose (GObject *object)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (object);
+
+#if 0
+ if (a11y->item)
+ g_object_unref (G_OBJECT (a11y->item)); /*, unref_item, a11y); */
+ if (a11y->cell_view)
+ g_object_unref (G_OBJECT (a11y->cell_view)); /*, unref_cell, a11y); */
+ if (a11y->parent)
+ g_object_unref (a11y->parent);
+#endif
+
+ if (a11y->state_set) {
+ g_object_unref (a11y->state_set);
+ a11y->state_set = NULL;
+ }
+
+ if (parent_class->dispose)
+ parent_class->dispose (object);
+
+}
+
+/* Static functions */
+static G_CONST_RETURN gchar*
+gal_a11y_e_cell_get_name (AtkObject * a11y)
+{
+ GalA11yECell *cell = GAL_A11Y_E_CELL (a11y);
+ ETableCol *ecol;
+
+ if (a11y->name != NULL && strcmp (a11y->name, ""))
+ return a11y->name;
+
+ if (cell->item != NULL) {
+ ecol = e_table_header_get_column (cell->item->header, cell->view_col);
+ if (ecol != NULL)
+ return ecol->text;
+ }
+
+ return _("Table Cell");
+}
+
+static AtkStateSet *
+gal_a11y_e_cell_ref_state_set (AtkObject *accessible)
+{
+ GalA11yECell *cell = GAL_A11Y_E_CELL (accessible);
+
+ g_return_val_if_fail (cell->state_set, NULL);
+
+ g_object_ref(cell->state_set);
+
+ return cell->state_set;
+}
+
+static AtkObject*
+gal_a11y_e_cell_get_parent (AtkObject *accessible)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (accessible);
+ return a11y->parent;
+}
+
+static gint
+gal_a11y_e_cell_get_index_in_parent (AtkObject *accessible)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (accessible);
+
+ if (!is_valid (accessible))
+ return -1;
+
+ return (a11y->row + 1) * a11y->item->cols + a11y->view_col;
+}
+
+
+/* Component IFace */
+static void
+gal_a11y_e_cell_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (component);
+ GtkWidget *tableOrTree;
+ int row;
+ int col;
+ int xval;
+ int yval;
+
+ row = a11y->row;
+ col = a11y->view_col;
+
+ tableOrTree = gtk_widget_get_parent (GTK_WIDGET (a11y->item->parent.canvas));
+ if (E_IS_TREE (tableOrTree)) {
+ e_tree_get_cell_geometry (E_TREE (tableOrTree),
+ row, col, &xval, &yval,
+ width, height);
+ } else {
+ e_table_get_cell_geometry (E_TABLE (tableOrTree),
+ row, col, &xval, &yval,
+ width, height);
+ }
+
+ atk_component_get_position (ATK_COMPONENT (a11y->parent),
+ x, y, coord_type);
+ if (x && *x != G_MININT)
+ *x += xval;
+ if (y && *y != G_MININT)
+ *y += yval;
+}
+
+static gboolean
+gal_a11y_e_cell_grab_focus (AtkComponent *component)
+{
+ GalA11yECell *a11y;
+ gint index;
+ GtkWidget *toplevel;
+ GalA11yETableItem *a11yTableItem;
+
+ a11y = GAL_A11Y_E_CELL (component);
+
+ /* for e_cell_vbox's children, we just grab the e_cell_vbox */
+ if (GAL_A11Y_IS_E_CELL_VBOX (a11y->parent)) {
+ return atk_component_grab_focus (ATK_COMPONENT (a11y->parent));
+ }
+
+ a11yTableItem = GAL_A11Y_E_TABLE_ITEM (a11y->parent);
+ index = atk_object_get_index_in_parent (ATK_OBJECT (a11y));
+
+ atk_selection_clear_selection (ATK_SELECTION (a11yTableItem));
+ atk_selection_add_selection (ATK_SELECTION (a11yTableItem), index);
+
+ gtk_widget_grab_focus (GTK_WIDGET (GNOME_CANVAS_ITEM (a11y->item)->canvas));
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (GNOME_CANVAS_ITEM (a11y->item)->canvas));
+ if (toplevel && GTK_WIDGET_TOPLEVEL (toplevel))
+ gtk_window_present (GTK_WINDOW (toplevel));
+
+ return TRUE;
+}
+
+/* Table IFace */
+
+static void
+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 void
+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 = gal_a11y_e_cell_dispose;
+
+ 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;
+ atk_object_class->get_name = gal_a11y_e_cell_get_name;
+}
+
+static void
+gal_a11y_e_cell_init (GalA11yECell *a11y)
+{
+ a11y->item = NULL;
+ a11y->cell_view = NULL;
+ a11y->parent = NULL;
+ 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);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE);
+ atk_state_set_add_state (a11y->state_set, ATK_STATE_VISIBLE);
+}
+
+
+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_ascii_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);
+
+ if (!is_valid (ATK_OBJECT (cell)))
+ return FALSE;
+
+ cell->action_idle_handler = 0;
+ cell->action_func (cell);
+ g_object_unref (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 (!is_valid (ATK_OBJECT (action)))
+ return FALSE;
+
+ 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;
+ g_object_ref (cell);
+ 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");
+ }
+
+ return rc;
+ }
+ else
+ return FALSE;
+}
+
+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;
+
+ 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");
+ }
+
+ return rc;
+ }
+ else
+ return FALSE;
+}
+
+/**
+ * gal_a11y_e_cell_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yECell class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yECell class.
+ **/
+GType
+gal_a11y_e_cell_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yECellClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gal_a11y_e_cell_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yECell),
+ 0,
+ (GInstanceInitFunc) gal_a11y_e_cell_init,
+ NULL /* value_cell */
+ };
+
+ static const GInterfaceInfo atk_component_info = {
+ (GInterfaceInitFunc) gal_a11y_e_cell_atk_component_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yECell", &info, 0);
+ g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info);
+ }
+
+ return type;
+}
+
+AtkObject *
+gal_a11y_e_cell_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_get_type (), NULL);
+
+ gal_a11y_e_cell_construct (a11y,
+ item,
+ cell_view,
+ parent,
+ model_col,
+ view_col,
+ row);
+ return a11y;
+}
+
+void
+gal_a11y_e_cell_construct (AtkObject *object,
+ ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row)
+{
+ GalA11yECell *a11y = GAL_A11Y_E_CELL (object);
+ a11y->item = item;
+ a11y->cell_view = cell_view;
+ a11y->parent = parent;
+ a11y->model_col = model_col;
+ a11y->view_col = view_col;
+ a11y->row = row;
+ ATK_OBJECT (a11y) ->role = ATK_ROLE_TABLE_CELL;
+
+ if (item)
+ g_object_ref (G_OBJECT (item));
+
+#if 0
+ if (parent)
+ g_object_ref (parent);
+
+ if (cell_view)
+ g_object_ref (G_OBJECT (cell_view));
+
+
+#endif
+}
diff --git a/widgets/table/a11y/gal-a11y-e-cell.h b/widgets/table/a11y/gal-a11y-e-cell.h
new file mode 100644
index 0000000000..cdae721112
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-cell.h
@@ -0,0 +1,113 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_CELL_H__
+#define __GAL_A11Y_E_CELL_H__
+
+#include <glib-object.h>
+#include <table/e-table-item.h>
+#include <table/e-cell.h>
+
+#define GAL_A11Y_TYPE_E_CELL (gal_a11y_e_cell_get_type ())
+#define GAL_A11Y_E_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_CELL, GalA11yECell))
+#define GAL_A11Y_E_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_CELL, GalA11yECellClass))
+#define GAL_A11Y_IS_E_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_CELL))
+#define GAL_A11Y_IS_E_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_CELL))
+
+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.
+ **/
+struct _GalA11yECell {
+ AtkObject object;
+
+ ETableItem *item;
+ ECellView *cell_view;
+ AtkObject *parent;
+ 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);
+AtkObject *gal_a11y_e_cell_new (ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ int model_col,
+ int view_col,
+ int row);
+void gal_a11y_e_cell_construct (AtkObject *object,
+ ETableItem *item,
+ ECellView *cell_view,
+ AtkObject *parent,
+ 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);
+
+gboolean gal_a11y_e_cell_add_state (GalA11yECell *cell,
+ AtkStateType state_type,
+ gboolean emit_signal);
+
+gboolean gal_a11y_e_cell_remove_state (GalA11yECell *cell,
+ AtkStateType state_type,
+ gboolean emit_signal);
+
+
+#endif /* ! __GAL_A11Y_E_CELL_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-table-click-to-add-factory.c b/widgets/table/a11y/gal-a11y-e-table-click-to-add-factory.c
new file mode 100644
index 0000000000..9161b4d834
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-click-to-add-factory.c
@@ -0,0 +1,106 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yuedong Du <yuedong.du@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include <atk/atk.h>
+
+#include "table/e-table.h"
+#include "table/e-table-click-to-add.h"
+
+#include "gal-a11y-e-table.h"
+#include "gal-a11y-e-table-click-to-add.h"
+#include "gal-a11y-e-table-click-to-add-factory.h"
+
+#define CS_CLASS(factory) (G_TYPE_INSTANCE_GET_CLASS ((factory), C_TYPE_STREAM, GalA11yETableClickToAddFactoryClass))
+static AtkObjectFactoryClass *parent_class;
+#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY)
+
+/* Static functions */
+
+static GType
+gal_a11y_e_table_click_to_add_factory_get_accessible_type (void)
+{
+ return GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD;
+}
+
+static AtkObject*
+gal_a11y_e_table_click_to_add_factory_create_accessible (GObject *obj)
+{
+ AtkObject * atk_object;
+
+ g_return_val_if_fail (E_IS_TABLE_CLICK_TO_ADD(obj), NULL);
+
+ atk_object = gal_a11y_e_table_click_to_add_new (obj);
+
+ return atk_object;
+}
+
+static void
+gal_a11y_e_table_click_to_add_factory_class_init (GalA11yETableClickToAddFactoryClass *klass)
+{
+ AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ factory_class->create_accessible = gal_a11y_e_table_click_to_add_factory_create_accessible;
+ factory_class->get_accessible_type = gal_a11y_e_table_click_to_add_factory_get_accessible_type;
+}
+
+static void
+gal_a11y_e_table_click_to_add_factory_init (GalA11yETableClickToAddFactory *factory)
+{
+}
+
+/**
+ * gal_a11y_e_table_factory_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yETableFactory class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yETableFactory class.
+ **/
+GType
+gal_a11y_e_table_click_to_add_factory_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yETableClickToAddFactoryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gal_a11y_e_table_click_to_add_factory_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yETableClickToAddFactory),
+ 0,
+ (GInstanceInitFunc) gal_a11y_e_table_click_to_add_factory_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yETableClickToAddFactory", &info, 0);
+ }
+
+ return type;
+}
diff --git a/widgets/table/a11y/gal-a11y-e-table-click-to-add-factory.h b/widgets/table/a11y/gal-a11y-e-table-click-to-add-factory.h
new file mode 100644
index 0000000000..0e4ac11f79
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-click-to-add-factory.h
@@ -0,0 +1,50 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yuedong Du <yuedong.du@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TABLE_CLICK_TO_ADD_FACTORY_H__
+#define __GAL_A11Y_E_TABLE_CLICK_TO_ADD_FACTORY_H__
+
+#include <glib-object.h>
+#include <atk/atkobjectfactory.h>
+
+#define GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY (gal_a11y_e_table_item_factory_get_type ())
+#define GAL_A11Y_E_TABLE_CLICK_TO_ADD_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY, GalA11yETableClickToAddFactory))
+#define GAL_A11Y_E_TABLE_CLICK_TO_ADD_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY, GalA11yETableClickToAddFactoryClass))
+#define GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY))
+#define GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD_FACTORY))
+
+typedef struct _GalA11yETableClickToAddFactory GalA11yETableClickToAddFactory;
+typedef struct _GalA11yETableClickToAddFactoryClass GalA11yETableClickToAddFactoryClass;
+
+struct _GalA11yETableClickToAddFactory {
+ AtkObject object;
+};
+
+struct _GalA11yETableClickToAddFactoryClass {
+ AtkObjectClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_table_click_to_add_factory_get_type (void);
+
+#endif
diff --git a/widgets/table/a11y/gal-a11y-e-table-click-to-add.c b/widgets/table/a11y/gal-a11y-e-table-click-to-add.c
new file mode 100644
index 0000000000..85c896ccf3
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-click-to-add.c
@@ -0,0 +1,344 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yuedong Du <yuedong.du@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include <atk/atk.h>
+
+#include "a11y/gal-a11y-util.h"
+#include "table/e-table-click-to-add.h"
+#include "table/e-table-group.h"
+#include "table/e-table-group-leaf.h"
+#include <glib/gi18n.h>
+
+#include "gal-a11y-e-table-click-to-add.h"
+#include "gal-a11y-e-table-click-to-add-factory.h"
+
+static AtkObjectClass *parent_class;
+static GType parent_type;
+static gint priv_offset;
+#define GET_PRIVATE(object) ((GalA11yETableClickToAddPrivate *) (((char *) object) + priv_offset))
+#define PARENT_TYPE (parent_type)
+
+struct _GalA11yETableClickToAddPrivate {
+ gpointer rect;
+ gpointer row;
+};
+
+
+static gint
+etcta_get_n_actions (AtkAction *action)
+{
+ return 1;
+}
+
+static G_CONST_RETURN gchar*
+etcta_get_description (AtkAction *action,
+ gint i)
+{
+ if (i == 0)
+ return _("click to add");
+
+ return NULL;
+}
+
+static G_CONST_RETURN gchar*
+etcta_action_get_name (AtkAction *action, gint i)
+{
+ if (i == 0)
+ return _("click");
+
+ return NULL;
+}
+
+
+static gboolean
+idle_do_action (gpointer data)
+{
+ GdkEventButton event;
+ ETableClickToAdd * etcta;
+ gint finished;
+
+ g_return_val_if_fail ( data!= NULL, FALSE);
+
+ etcta = E_TABLE_CLICK_TO_ADD (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (data)));
+ g_return_val_if_fail (etcta, FALSE);
+
+ event.x = 0;
+ event.y = 0;
+
+ event.type = GDK_BUTTON_PRESS;
+ event.window = GTK_LAYOUT(GNOME_CANVAS_ITEM(etcta)->canvas)->bin_window;
+ event.button = 1;
+ event.send_event = TRUE;
+ event.time = GDK_CURRENT_TIME;
+ event.axes = NULL;
+
+ g_signal_emit_by_name (etcta, "event", &event, &finished);
+
+ return FALSE;
+}
+
+static gboolean
+etcta_do_action (AtkAction * action, gint i)
+{
+ g_return_val_if_fail (i == 0, FALSE);
+
+ g_idle_add (idle_do_action, action);
+
+ return TRUE;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->do_action = etcta_do_action;
+ iface->get_n_actions = etcta_get_n_actions;
+ iface->get_description = etcta_get_description;
+ iface->get_name = etcta_action_get_name;
+}
+
+
+static G_CONST_RETURN gchar *
+etcta_get_name (AtkObject *obj)
+{
+ ETableClickToAdd * etcta;
+
+ g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD (obj), NULL);
+
+ etcta = E_TABLE_CLICK_TO_ADD (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(obj)));
+ if (etcta && etcta->message != NULL)
+ return etcta->message;
+
+ return _("click to add");
+}
+
+static gint
+etcta_get_n_children (AtkObject *accessible)
+{
+ return 1;
+}
+
+static AtkObject*
+etcta_ref_child (AtkObject *accessible,
+ gint i)
+{
+ AtkObject * atk_obj = NULL;
+ ETableClickToAdd * etcta;
+
+ if ( i != 0 )
+ return NULL;
+
+ etcta = E_TABLE_CLICK_TO_ADD(atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible)));
+
+ g_return_val_if_fail (etcta, NULL);
+
+ if (etcta->rect) {
+ atk_obj = atk_gobject_accessible_for_object (G_OBJECT(etcta->rect));
+ } else if (etcta->row) {
+ atk_obj = atk_gobject_accessible_for_object (G_OBJECT(etcta->row));
+ }
+
+ g_object_ref (atk_obj);
+
+ return atk_obj;
+}
+
+static AtkStateSet *
+etcta_ref_state_set (AtkObject *accessible)
+{
+ AtkStateSet * state_set = NULL;
+
+ state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (accessible);
+ if (state_set != NULL) {
+ atk_state_set_add_state (state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (state_set, ATK_STATE_SHOWING);
+ }
+
+ return state_set;
+}
+
+static void
+etcta_class_init (GalA11yETableClickToAddClass *klass)
+{
+ AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ atk_object_class->get_name = etcta_get_name;
+ atk_object_class->get_n_children = etcta_get_n_children;
+ atk_object_class->ref_child = etcta_ref_child;
+ atk_object_class->ref_state_set = etcta_ref_state_set;
+}
+
+static void
+etcta_init (GalA11yETableClickToAdd *a11y)
+{
+}
+
+/**
+ * gal_a11y_e_table_click_to_add_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yETableClickToAdd class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yETableClickToAdd class.
+ **/
+GType
+gal_a11y_e_table_click_to_add_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ AtkObjectFactory *factory;
+
+ GTypeInfo info = {
+ sizeof (GalA11yETableClickToAddClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) etcta_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yETableClickToAdd),
+ 0,
+ (GInstanceInitFunc) etcta_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo atk_action_info = {
+ (GInterfaceInitFunc) atk_action_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ factory = atk_registry_get_factory (atk_get_default_registry (), GNOME_TYPE_CANVAS_ITEM);
+
+ parent_type = atk_object_factory_get_accessible_type (factory);
+ type = gal_a11y_type_register_static_with_private (PARENT_TYPE,
+ "GalA11yETableClickToAdd", &info, 0,
+ sizeof(GalA11yETableClickToAddPrivate), &priv_offset);
+
+ g_type_add_interface_static (type, ATK_TYPE_ACTION, &atk_action_info);
+
+ }
+
+ return type;
+}
+
+static gboolean
+etcta_event (GnomeCanvasItem *item, GdkEvent *e, gpointer data)
+{
+ ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (item);
+ GalA11yETableClickToAdd *a11y;
+ GalA11yETableClickToAddPrivate *priv;
+
+ g_return_val_if_fail (item, TRUE);
+
+ g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD(data), FALSE);
+ a11y = GAL_A11Y_E_TABLE_CLICK_TO_ADD (data);
+
+ priv = GET_PRIVATE (a11y);
+
+ /* rect replaced by row. */
+ if (etcta->rect == NULL && priv->rect != NULL) {
+ g_signal_emit_by_name (a11y, "children_changed::remove", 0, NULL, NULL);
+
+ }
+ /* row inserted, and/or replaced by a new row. */
+ if (etcta->row != NULL && priv->row == NULL) {
+ g_signal_emit_by_name (a11y, "children_changed::add", 0, NULL, NULL);
+ } else if (etcta->row != NULL && priv->row != NULL && etcta->row != priv->row) {
+ g_signal_emit_by_name (a11y, "children_changed::remove", 0, NULL, NULL);
+ g_signal_emit_by_name (a11y, "children_changed::add", 0, NULL, NULL);
+ }
+
+
+ priv->rect = etcta->rect;
+ priv->row = etcta->row;
+
+ return FALSE;
+}
+
+static void
+etcta_selection_cursor_changed (ESelectionModel *esm, gint row, gint col,
+ GalA11yETableClickToAdd *a11y)
+{
+ ETableClickToAdd *etcta;
+ AtkObject *row_a11y;
+
+ etcta = E_TABLE_CLICK_TO_ADD (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(a11y)));
+
+ if (etcta == NULL || etcta->row == NULL)
+ return;
+
+ row_a11y = atk_gobject_accessible_for_object (G_OBJECT(etcta->row));
+ if (row_a11y) {
+ AtkObject *cell_a11y = g_object_get_data (G_OBJECT(row_a11y), "gail-focus-object");
+ if (cell_a11y) {
+ atk_focus_tracker_notify (cell_a11y);
+ }
+ }
+}
+
+AtkObject *
+gal_a11y_e_table_click_to_add_new (GObject *widget)
+{
+ GalA11yETableClickToAdd *a11y;
+ ETableClickToAdd * etcta;
+ GalA11yETableClickToAddPrivate *priv;
+
+ g_return_val_if_fail (widget != NULL, NULL);
+
+ a11y = g_object_new (gal_a11y_e_table_click_to_add_get_type (), NULL);
+ priv = GET_PRIVATE (a11y);
+
+ etcta = E_TABLE_CLICK_TO_ADD(widget);
+
+
+ atk_object_initialize (ATK_OBJECT (a11y), etcta);
+
+ priv->rect = etcta->rect;
+ priv->row = etcta->row;
+
+
+ g_signal_connect_after (G_OBJECT(widget), "event",
+ G_CALLBACK (etcta_event), a11y);
+
+ g_signal_connect (etcta->selection, "cursor_changed",
+ G_CALLBACK (etcta_selection_cursor_changed), a11y);
+
+ return ATK_OBJECT (a11y);
+}
+
+void
+gal_a11y_e_table_click_to_add_init (void)
+{
+ if (atk_get_root ())
+ atk_registry_set_factory_type (atk_get_default_registry (),
+ E_TABLE_CLICK_TO_ADD_TYPE,
+ gal_a11y_e_table_click_to_add_factory_get_type ());
+
+}
+
diff --git a/widgets/table/a11y/gal-a11y-e-table-click-to-add.h b/widgets/table/a11y/gal-a11y-e-table-click-to-add.h
new file mode 100644
index 0000000000..ccefc7a9b8
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-click-to-add.h
@@ -0,0 +1,55 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TABLE_CLICK_TO_ADD_H__
+#define __GAL_A11Y_E_TABLE_CLICK_TO_ADD_H__
+
+#include <glib-object.h>
+#include <table/e-table-item.h>
+#include <atk/atkgobjectaccessible.h>
+
+#define GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD (gal_a11y_e_table_click_to_add_get_type ())
+#define GAL_A11Y_E_TABLE_CLICK_TO_ADD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD, GalA11yETableClickToAdd))
+#define GAL_A11Y_E_TABLE_CLICK_TO_ADD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD, GalA11yETableClickToAddClass))
+#define GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD))
+#define GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_CLICK_TO_ADD))
+
+typedef struct _GalA11yETableClickToAdd GalA11yETableClickToAdd;
+typedef struct _GalA11yETableClickToAddClass GalA11yETableClickToAddClass;
+typedef struct _GalA11yETableClickToAddPrivate GalA11yETableClickToAddPrivate;
+
+/* This struct should actually be larger as this isn't what we derive from.
+ * The GalA11yETableClickToAddPrivate comes right after the parent class structure.
+ **/
+struct _GalA11yETableClickToAdd {
+ AtkGObjectAccessible parent;
+};
+
+struct _GalA11yETableClickToAddClass {
+ AtkGObjectAccessibleClass parent_class;
+};
+
+/* Standard Glib function */
+GType gal_a11y_e_table_click_to_add_get_type (void);
+AtkObject *gal_a11y_e_table_click_to_add_new (GObject *widget);
+
+void gal_a11y_e_table_click_to_add_init (void);
+#endif /* ! __GAL_A11Y_E_TABLE_CLICK_TO_ADD_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-table-column-header.c b/widgets/table/a11y/gal-a11y-e-table-column-header.c
new file mode 100644
index 0000000000..a50a286940
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-column-header.c
@@ -0,0 +1,229 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Li Yuan <li.yuan@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+#include <glib/gi18n.h>
+#include <atk/atkobject.h>
+#include <atk/atkregistry.h>
+#include "table/e-table-header-item.h"
+#include "a11y/gal-a11y-util.h"
+#include "gal-a11y-e-table-column-header.h"
+
+static GObjectClass *parent_class;
+static gint priv_offset;
+
+#define GET_PRIVATE(object) ((GalA11yETableColumnHeaderPrivate *) (((char *) object) + priv_offset))
+#define PARENT_TYPE (atk_gobject_accessible_get_type ())
+
+struct _GalA11yETableColumnHeaderPrivate {
+ ETableItem *item;
+ AtkObject *parent;
+ AtkStateSet *state_set;
+};
+
+static void
+etch_init (GalA11yETableColumnHeader *a11y)
+{
+ GET_PRIVATE (a11y)->item = NULL;
+ GET_PRIVATE (a11y)->parent = NULL;
+ GET_PRIVATE (a11y)->state_set = NULL;
+}
+
+static AtkStateSet *
+gal_a11y_e_table_column_header_ref_state_set (AtkObject *accessible)
+{
+ GalA11yETableColumnHeaderPrivate *priv = GET_PRIVATE (accessible);
+
+ g_return_val_if_fail (priv->state_set, NULL);
+
+ g_object_ref(priv->state_set);
+
+ return priv->state_set;
+}
+
+static void
+gal_a11y_e_table_column_header_real_initialize (AtkObject *obj, gpointer data)
+{
+ ATK_OBJECT_CLASS (parent_class)->initialize (obj, data);
+}
+
+static void
+gal_a11y_e_table_column_header_dispose (GObject *object)
+{
+ GalA11yETableColumnHeader *a11y = GAL_A11Y_E_TABLE_COLUMN_HEADER (object);
+ GalA11yETableColumnHeaderPrivate *priv = GET_PRIVATE (a11y);
+
+ if (priv->state_set) {
+ g_object_unref (priv->state_set);
+ priv->state_set = NULL;
+ }
+
+ if (parent_class->dispose)
+ parent_class->dispose (object);
+
+}
+
+static void
+etch_class_init (GalA11yETableColumnHeaderClass *klass)
+{
+ AtkObjectClass *class = ATK_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ object_class->dispose = gal_a11y_e_table_column_header_dispose;
+
+ class->ref_state_set = gal_a11y_e_table_column_header_ref_state_set;
+ class->initialize = gal_a11y_e_table_column_header_real_initialize;
+}
+
+inline static GObject *
+etch_a11y_get_gobject (AtkGObjectAccessible *accessible)
+{
+ return atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
+}
+
+static gboolean
+gal_a11y_e_table_column_header_do_action (AtkAction *action,
+ gint i)
+{
+ gboolean return_value = TRUE;
+ GtkWidget *widget;
+ GalA11yETableColumnHeader *a11y;
+ ETableHeaderItem *ethi;
+ ETableItem *item;
+ ETableCol *col;
+
+ switch (i) {
+ case 0:
+ a11y = GAL_A11Y_E_TABLE_COLUMN_HEADER (action);
+ col = E_TABLE_COL (etch_a11y_get_gobject (ATK_GOBJECT_ACCESSIBLE (a11y)));
+ item = GET_PRIVATE (a11y)->item;
+ widget = gtk_widget_get_parent (GTK_WIDGET (item->parent.canvas));
+ if (E_IS_TREE (widget)) {
+ ethi = E_TABLE_HEADER_ITEM (e_tree_get_header_item (E_TREE (widget)));
+ }
+ else if (E_IS_TABLE (widget))
+ ethi = E_TABLE_HEADER_ITEM (E_TABLE (widget)->header_item);
+ else
+ break;
+ ethi_change_sort_state (ethi, col);
+ default:
+ return_value = FALSE;
+ break;
+ }
+ return return_value;
+}
+
+static gint
+gal_a11y_e_table_column_header_get_n_actions (AtkAction *action)
+{
+ return 1;
+}
+
+static G_CONST_RETURN gchar*
+gal_a11y_e_table_column_header_action_get_name (AtkAction *action,
+ gint i)
+{
+ G_CONST_RETURN gchar *return_value;
+
+ switch (i) {
+ case 0:
+ return_value = _("sort");
+ break;
+ default:
+ return_value = NULL;
+ break;
+ }
+ return return_value;
+}
+
+static void
+atk_action_interface_init (AtkActionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->do_action = gal_a11y_e_table_column_header_do_action;
+ iface->get_n_actions = gal_a11y_e_table_column_header_get_n_actions;
+ iface->get_name = gal_a11y_e_table_column_header_action_get_name;
+}
+
+GType
+gal_a11y_e_table_column_header_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yETableColumnHeaderClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) etch_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL,
+ sizeof (GalA11yETableColumnHeader),
+ 0,
+ (GInstanceInitFunc) etch_init,
+ NULL
+ };
+ static const GInterfaceInfo atk_action_info = {
+ (GInterfaceInitFunc) atk_action_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ type = gal_a11y_type_register_static_with_private (PARENT_TYPE, "GalA11yETableColumnHeader", &info, 0,
+ sizeof (GalA11yETableColumnHeaderPrivate), &priv_offset);
+
+ g_type_add_interface_static (type, ATK_TYPE_ACTION, &atk_action_info);
+ }
+
+ return type;
+}
+
+AtkObject *
+gal_a11y_e_table_column_header_new (ETableCol *ecol, ETableItem *item)
+{
+ GalA11yETableColumnHeader *a11y;
+ AtkObject *accessible;
+
+ g_return_val_if_fail (E_IS_TABLE_COL (ecol), NULL);
+
+ a11y = g_object_new (gal_a11y_e_table_column_header_get_type(), NULL);
+ accessible = ATK_OBJECT (a11y);
+ atk_object_initialize (accessible, ecol);
+
+ GET_PRIVATE (a11y)->item = item;
+ GET_PRIVATE (a11y)->state_set = atk_state_set_new ();
+
+ atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_VISIBLE);
+ atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_SHOWING);
+ atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_ENABLED);
+
+ if (ecol->text)
+ atk_object_set_name (accessible, ecol->text);
+ atk_object_set_role (accessible, ATK_ROLE_TABLE_COLUMN_HEADER);
+
+ return ATK_OBJECT (a11y);
+}
diff --git a/widgets/table/a11y/gal-a11y-e-table-column-header.h b/widgets/table/a11y/gal-a11y-e-table-column-header.h
new file mode 100644
index 0000000000..083f0af3de
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-column-header.h
@@ -0,0 +1,55 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Li Yuan <li.yuan@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+
+#ifndef __GAL_A11Y_E_TABLE_COLUMN_HEADER_H__
+#define __GAL_A11Y_E_TABLE_COLUMN_HEADER_H__
+
+#include <glib-object.h>
+#include <atk/atkgobjectaccessible.h>
+
+#define GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER (gal_a11y_e_table_column_header_get_type ())
+#define GAL_A11Y_E_TABLE_COLUMN_HEADER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER, GalA11yETableColumnHeader))
+#define GAL_A11Y_E_TABLE_COLUMN_HEADER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER, GalA11yETableColumnHeaderClass))
+#define GAL_A11Y_IS_E_TABLE_COLUMN_HEADER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER))
+#define GAL_A11Y_IS_E_TABLE_COLUMN_HEADER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_COLUMN_HEADER))
+
+typedef struct _GalA11yETableColumnHeader GalA11yETableColumnHeader;
+typedef struct _GalA11yETableColumnHeaderClass GalA11yETableColumnHeaderClass;
+typedef struct _GalA11yETableColumnHeaderPrivate GalA11yETableColumnHeaderPrivate;
+
+struct _GalA11yETableColumnHeader {
+ AtkGObjectAccessible parent;
+};
+
+struct _GalA11yETableColumnHeaderClass {
+ AtkGObjectAccessibleClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_table_column_header_get_type (void);
+AtkObject *gal_a11y_e_table_column_header_new (ETableCol *etc, ETableItem *item);
+void gal_a11y_e_table_column_header_init (void);
+
+#endif /* ! __GAL_A11Y_E_TABLE_COLUMN_HEADER_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-table-factory.c b/widgets/table/a11y/gal-a11y-e-table-factory.c
new file mode 100644
index 0000000000..37c396aba8
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-factory.c
@@ -0,0 +1,99 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include "gal-a11y-e-table.h"
+#include "gal-a11y-e-table-factory.h"
+
+#define CS_CLASS(factory) (G_TYPE_INSTANCE_GET_CLASS ((factory), C_TYPE_STREAM, GalA11yETableFactoryClass))
+static AtkObjectFactoryClass *parent_class;
+#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY)
+
+/* Static functions */
+
+static GType
+gal_a11y_e_table_factory_get_accessible_type (void)
+{
+ return GAL_A11Y_TYPE_E_TABLE;
+}
+
+static AtkObject*
+gal_a11y_e_table_factory_create_accessible (GObject *obj)
+{
+ AtkObject *accessible;
+
+ accessible = gal_a11y_e_table_new (obj);
+
+ return accessible;
+}
+
+static void
+gal_a11y_e_table_factory_class_init (GalA11yETableFactoryClass *klass)
+{
+ AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ factory_class->create_accessible = gal_a11y_e_table_factory_create_accessible;
+ factory_class->get_accessible_type = gal_a11y_e_table_factory_get_accessible_type;
+}
+
+static void
+gal_a11y_e_table_factory_init (GalA11yETableFactory *factory)
+{
+}
+
+/**
+ * gal_a11y_e_table_factory_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yETableFactory class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yETableFactory class.
+ **/
+GType
+gal_a11y_e_table_factory_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yETableFactoryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gal_a11y_e_table_factory_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yETableFactory),
+ 0,
+ (GInstanceInitFunc) gal_a11y_e_table_factory_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yETableFactory", &info, 0);
+ }
+
+ return type;
+}
diff --git a/widgets/table/a11y/gal-a11y-e-table-factory.h b/widgets/table/a11y/gal-a11y-e-table-factory.h
new file mode 100644
index 0000000000..e3ef52c872
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-factory.h
@@ -0,0 +1,51 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TABLE_FACTORY_H__
+#define __GAL_A11Y_E_TABLE_FACTORY_H__
+
+#include <glib-object.h>
+#include <atk/atkobjectfactory.h>
+
+#define GAL_A11Y_TYPE_E_TABLE_FACTORY (gal_a11y_e_table_factory_get_type ())
+#define GAL_A11Y_E_TABLE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_FACTORY, GalA11yETableFactory))
+#define GAL_A11Y_E_TABLE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_FACTORY, GalA11yETableFactoryClass))
+#define GAL_A11Y_IS_E_TABLE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_FACTORY))
+#define GAL_A11Y_IS_E_TABLE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_FACTORY))
+
+typedef struct _GalA11yETableFactory GalA11yETableFactory;
+typedef struct _GalA11yETableFactoryClass GalA11yETableFactoryClass;
+
+struct _GalA11yETableFactory {
+ AtkObject object;
+};
+
+struct _GalA11yETableFactoryClass {
+ AtkObjectClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_table_factory_get_type (void);
+
+#endif /* ! __GAL_A11Y_E_TABLE_FACTORY_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-table-item-factory.c b/widgets/table/a11y/gal-a11y-e-table-item-factory.c
new file mode 100644
index 0000000000..43508e4796
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-item-factory.c
@@ -0,0 +1,105 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yuedong Du <yuedong.du@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include <atk/atk.h>
+
+#include "table/e-table.h"
+#include "table/e-tree.h"
+
+#include "gal-a11y-e-table.h"
+#include "gal-a11y-e-table-item.h"
+#include "gal-a11y-e-table-item-factory.h"
+
+#define CS_CLASS(factory) (G_TYPE_INSTANCE_GET_CLASS ((factory), C_TYPE_STREAM, GalA11yETableItemFactoryClass))
+static AtkObjectFactoryClass *parent_class;
+#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY)
+
+/* Static functions */
+
+static GType
+gal_a11y_e_table_item_factory_get_accessible_type (void)
+{
+ return GAL_A11Y_TYPE_E_TABLE_ITEM;
+}
+
+static AtkObject*
+gal_a11y_e_table_item_factory_create_accessible (GObject *obj)
+{
+ AtkObject *accessible;
+
+ g_return_val_if_fail (E_IS_TABLE_ITEM(obj), NULL);
+ accessible = gal_a11y_e_table_item_new (E_TABLE_ITEM (obj));
+
+ return accessible;
+}
+
+static void
+gal_a11y_e_table_item_factory_class_init (GalA11yETableItemFactoryClass *klass)
+{
+ AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ factory_class->create_accessible = gal_a11y_e_table_item_factory_create_accessible;
+ factory_class->get_accessible_type = gal_a11y_e_table_item_factory_get_accessible_type;
+}
+
+static void
+gal_a11y_e_table_item_factory_init (GalA11yETableItemFactory *factory)
+{
+}
+
+/**
+ * gal_a11y_e_table_factory_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yETableFactory class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yETableFactory class.
+ **/
+GType
+gal_a11y_e_table_item_factory_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yETableItemFactoryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gal_a11y_e_table_item_factory_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yETableItemFactory),
+ 0,
+ (GInstanceInitFunc) gal_a11y_e_table_item_factory_init,
+ NULL /* value_table */
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yETableItemFactory", &info, 0);
+ }
+
+ return type;
+}
diff --git a/widgets/table/a11y/gal-a11y-e-table-item-factory.h b/widgets/table/a11y/gal-a11y-e-table-item-factory.h
new file mode 100644
index 0000000000..a85c9e894f
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-item-factory.h
@@ -0,0 +1,50 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yuedong Du <yuedong.du@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TABLE_ITEM_FACTORY_H__
+#define __GAL_A11Y_E_TABLE_ITEM_FACTORY_H__
+
+#include <glib-object.h>
+#include <atk/atkobjectfactory.h>
+
+#define GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY (gal_a11y_e_table_item_factory_get_type ())
+#define GAL_A11Y_E_TABLE_ITEM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY, GalA11yETableItemFactory))
+#define GAL_A11Y_E_TABLE_ITEM_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY, GalA11yETableItemFactoryClass))
+#define GAL_A11Y_IS_E_TABLE_ITEM_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY))
+#define GAL_A11Y_IS_E_TABLE_ITEM_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_ITEM_FACTORY))
+
+typedef struct _GalA11yETableItemFactory GalA11yETableItemFactory;
+typedef struct _GalA11yETableItemFactoryClass GalA11yETableItemFactoryClass;
+
+struct _GalA11yETableItemFactory {
+ AtkObject object;
+};
+
+struct _GalA11yETableItemFactoryClass {
+ AtkObjectClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_table_item_factory_get_type (void);
+
+#endif /* ! __GAL_A11Y_E_TABLE_FACTORY_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-table-item.c b/widgets/table/a11y/gal-a11y-e-table-item.c
new file mode 100644
index 0000000000..16d50df9b0
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-item.c
@@ -0,0 +1,1327 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ * Bolian Yin <bolian.yin@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <atk/atk.h>
+
+#include "a11y/gal-a11y-util.h"
+#include "table/e-table-click-to-add.h"
+#include "table/e-table-subset.h"
+#include "table/e-table.h"
+#include "table/e-tree.h"
+#include "misc/e-canvas.h"
+#include "misc/e-selection-model.h"
+
+#include "gal-a11y-e-table-item.h"
+#include "gal-a11y-e-table-item-factory.h"
+#include "gal-a11y-e-table-click-to-add.h"
+#include "gal-a11y-e-cell-registry.h"
+#include "gal-a11y-e-cell.h"
+#include "gal-a11y-e-table-column-header.h"
+
+#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yETableItemClass))
+static GObjectClass *parent_class;
+static AtkComponentIface *component_parent_iface;
+static GType parent_type;
+static gint priv_offset;
+static GQuark quark_accessible_object = 0;
+#define GET_PRIVATE(object) ((GalA11yETableItemPrivate *) (((char *) object) + priv_offset))
+#define PARENT_TYPE (parent_type)
+
+struct _GalA11yETableItemPrivate {
+ gint cols;
+ gint rows;
+ int selection_change_id;
+ int cursor_change_id;
+ ETableCol ** columns;
+ ESelectionModel *selection;
+ AtkStateSet *state_set;
+ GtkWidget *widget;
+};
+
+static gboolean gal_a11y_e_table_item_ref_selection (GalA11yETableItem *a11y,
+ ESelectionModel *selection);
+static gboolean gal_a11y_e_table_item_unref_selection (GalA11yETableItem *a11y);
+
+static AtkObject* eti_ref_at (AtkTable *table, gint row, gint column);
+
+static void
+item_destroyed (GtkObject *item, gpointer user_data)
+{
+ GalA11yETableItem *a11y = GAL_A11Y_E_TABLE_ITEM (user_data);
+ GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y);
+
+ atk_state_set_add_state (priv->state_set, ATK_STATE_DEFUNCT);
+ atk_object_notify_state_change (ATK_OBJECT (a11y), ATK_STATE_DEFUNCT, TRUE);
+
+ if (priv->selection)
+ gal_a11y_e_table_item_unref_selection (a11y);
+
+}
+
+static AtkStateSet *
+eti_ref_state_set (AtkObject *accessible)
+{
+ GalA11yETableItemPrivate *priv = GET_PRIVATE (accessible);
+
+ g_object_ref(priv->state_set);
+
+ return priv->state_set;
+}
+
+inline static gint
+view_to_model_row(ETableItem *eti, int row)
+{
+ if (eti->uses_source_model) {
+ ETableSubset *etss = E_TABLE_SUBSET(eti->table_model);
+ if (row >= 0 && row < etss->n_map) {
+ eti->row_guess = row;
+ return etss->map_table[row];
+ } else
+ return -1;
+ } else
+ return row;
+}
+
+inline static gint
+view_to_model_col(ETableItem *eti, int col)
+{
+ ETableCol *ecol = e_table_header_get_column (eti->header, col);
+ return ecol ? ecol->col_idx : -1;
+}
+
+inline static gint
+model_to_view_row(ETableItem *eti, int row)
+{
+ int i;
+ if (row == -1)
+ return -1;
+ if (eti->uses_source_model) {
+ ETableSubset *etss = E_TABLE_SUBSET(eti->table_model);
+ if (eti->row_guess >= 0 && eti->row_guess < etss->n_map) {
+ if (etss->map_table[eti->row_guess] == row) {
+ return eti->row_guess;
+ }
+ }
+ for (i = 0; i < etss->n_map; i++) {
+ if (etss->map_table[i] == row)
+ return i;
+ }
+ return -1;
+ } else
+ return row;
+}
+
+inline static gint
+model_to_view_col(ETableItem *eti, int col)
+{
+ int i;
+ if (col == -1)
+ return -1;
+ for (i = 0; i < eti->cols; i++) {
+ ETableCol *ecol = e_table_header_get_column (eti->header, i);
+ if (ecol->col_idx == col)
+ return i;
+ }
+ return -1;
+}
+
+inline static GObject *
+eti_a11y_get_gobject (AtkObject *accessible)
+{
+ return atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (accessible));
+}
+
+static void
+eti_a11y_reset_focus_object (GalA11yETableItem *a11y, ETableItem *item, gboolean notify)
+{
+ ESelectionModel * esm;
+ int cursor_row, cursor_col, view_row, view_col;
+ AtkObject *cell, *old_cell;
+
+ esm = item->selection;
+ g_return_if_fail (esm);
+
+ cursor_row = e_selection_model_cursor_row (esm);
+ cursor_col = e_selection_model_cursor_col (esm);
+
+ view_row = model_to_view_row (item, cursor_row);
+ view_col = model_to_view_col (item, cursor_col);
+
+ if (view_row == -1)
+ view_row = 0;
+ if (view_col == -1)
+ view_col = 0;
+
+ old_cell = (AtkObject *)g_object_get_data (G_OBJECT (a11y), "gail-focus-object");
+ if (old_cell && GAL_A11Y_IS_E_CELL (old_cell))
+ gal_a11y_e_cell_remove_state (GAL_A11Y_E_CELL (old_cell), ATK_STATE_FOCUSED, FALSE);
+ if (old_cell)
+ g_object_unref (old_cell);
+
+ cell = eti_ref_at (ATK_TABLE (a11y), view_row, view_col);
+
+ if (cell != NULL) {
+ g_object_set_data (G_OBJECT (a11y), "gail-focus-object", cell);
+ gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL (cell), ATK_STATE_FOCUSED, FALSE);
+ } else
+ g_object_set_data (G_OBJECT (a11y), "gail-focus-object", NULL);
+
+ if (notify && cell)
+ atk_focus_tracker_notify (cell);
+}
+
+static void
+eti_dispose (GObject *object)
+{
+ GalA11yETableItem *a11y = GAL_A11Y_E_TABLE_ITEM (object);
+ GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y);
+
+ if (priv->columns) {
+ g_free(priv->columns);
+ priv->columns = NULL;
+ }
+
+ if (parent_class->dispose)
+ parent_class->dispose (object);
+}
+
+/* Static functions */
+static gint
+eti_get_n_children (AtkObject *accessible)
+{
+ g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (accessible), 0);
+ if (!eti_a11y_get_gobject (accessible))
+ return 0;
+
+ return atk_table_get_n_columns (ATK_TABLE (accessible)) *
+ (atk_table_get_n_rows (ATK_TABLE (accessible)) + 1);
+}
+
+static AtkObject*
+eti_ref_child (AtkObject *accessible, gint index)
+{
+ ETableItem *item;
+ gint col, row;
+
+ g_return_val_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (accessible), NULL);
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (accessible));
+ if (!item)
+ return NULL;
+
+ if (index < item->cols) {
+ ETableCol *ecol;
+ AtkObject *child;
+
+ ecol = e_table_header_get_column (item->header, index);
+ child = gal_a11y_e_table_column_header_new (ecol, item);
+ return child;
+ }
+ index -= item->cols;
+
+ col = index % item->cols;
+ row = index / item->cols;
+
+ return eti_ref_at (ATK_TABLE (accessible), row, col);
+}
+
+static void
+eti_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ ETableItem *item;
+ AtkObject *parent;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (component)));
+ if (!item)
+ return;
+
+ parent = ATK_OBJECT (component)->accessible_parent;
+ if (parent && ATK_IS_COMPONENT (parent))
+ atk_component_get_extents (ATK_COMPONENT (parent), x, y,
+ width, height,
+ coord_type);
+
+ if (parent && GAL_A11Y_IS_E_TABLE_CLICK_TO_ADD (parent)) {
+ ETableClickToAdd *etcta = E_TABLE_CLICK_TO_ADD (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (parent)));
+ if (etcta) {
+ *width = etcta->width;
+ *height = etcta->height;
+ }
+ }
+}
+
+static AtkObject*
+eti_ref_accessible_at_point (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type)
+{
+ int row = -1;
+ int col = -1;
+ int x_origin, y_origin;
+ ETableItem *item;
+ GtkWidget *tableOrTree;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (component)));
+ if (!item)
+ return NULL;
+
+ atk_component_get_position (component,
+ &x_origin,
+ &y_origin,
+ coord_type);
+ x -= x_origin;
+ y -= y_origin;
+
+ tableOrTree = gtk_widget_get_parent (GTK_WIDGET (item->parent.canvas));
+
+ if (E_IS_TREE(tableOrTree))
+ e_tree_get_cell_at (E_TREE (tableOrTree), x, y, &row, &col);
+ else
+ e_table_get_cell_at (E_TABLE (tableOrTree), x, y, &row, &col);
+
+ if (row != -1 && col != -1) {
+ return eti_ref_at (ATK_TABLE (component), row, col);
+ } else {
+ return NULL;
+ }
+}
+
+
+static void
+cell_destroyed (gpointer data)
+{
+ GalA11yECell * cell;
+
+ g_return_if_fail (GAL_A11Y_IS_E_CELL (data));
+ cell = GAL_A11Y_E_CELL (data);
+
+ g_return_if_fail (cell->item && G_IS_OBJECT (cell->item));
+
+ if (cell->item) {
+ g_object_unref (cell->item);
+ cell->item = NULL;
+ }
+
+}
+
+/* atk table */
+static AtkObject*
+eti_ref_at (AtkTable *table, gint row, gint column)
+{
+ ETableItem *item;
+ AtkObject* ret;
+ GalA11yETableItemPrivate *priv = GET_PRIVATE (table);
+
+ if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT))
+ return NULL;
+
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return NULL;
+
+ if (column >= 0 &&
+ column < item->cols &&
+ row >= 0 &&
+ row < item->rows &&
+ item->cell_views_realized) {
+ ECellView *cell_view = item->cell_views[column];
+ ETableCol *ecol = e_table_header_get_column (item->header, column);
+ ret = gal_a11y_e_cell_registry_get_object (NULL,
+ item,
+ cell_view,
+ ATK_OBJECT (table),
+ ecol->col_idx,
+ column,
+ row);
+ if (ATK_IS_OBJECT (ret)) {
+ g_object_weak_ref (G_OBJECT (ret),
+ (GWeakNotify) cell_destroyed,
+ ret);
+ /* if current cell is focused, add FOCUSED state */
+ if (e_selection_model_cursor_row (item->selection) == GAL_A11Y_E_CELL (ret)->row &&
+ e_selection_model_cursor_col (item->selection) == GAL_A11Y_E_CELL (ret)->model_col)
+ gal_a11y_e_cell_add_state (GAL_A11Y_E_CELL (ret), ATK_STATE_FOCUSED, FALSE);
+ } else
+ ret = NULL;
+
+ return ret;
+ }
+
+ return NULL;
+}
+
+static gint
+eti_get_index_at (AtkTable *table, gint row, gint column)
+{
+ ETableItem *item;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return -1;
+
+ return column + (row + 1) * item->cols;
+}
+
+static gint
+eti_get_column_at_index (AtkTable *table, gint index)
+{
+ ETableItem *item;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return -1;
+
+ return index % item->cols;
+}
+
+static gint
+eti_get_row_at_index (AtkTable *table, gint index)
+{
+ ETableItem *item;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return -1;
+
+ return index / item->cols - 1;
+}
+
+static gint
+eti_get_n_columns (AtkTable *table)
+{
+ ETableItem *item;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return -1;
+
+ return item->cols;
+}
+
+static gint
+eti_get_n_rows (AtkTable *table)
+{
+ ETableItem *item;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return -1;
+
+ return item->rows;
+}
+
+static gint
+eti_get_column_extent_at (AtkTable *table,
+ gint row,
+ gint column)
+{
+ ETableItem *item;
+ int width;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return -1;
+
+ e_table_item_get_cell_geometry (item,
+ &row,
+ &column,
+ NULL,
+ NULL,
+ &width,
+ NULL);
+
+ return width;
+}
+
+static gint
+eti_get_row_extent_at (AtkTable *table,
+ gint row,
+ gint column)
+{
+ ETableItem *item;
+ int height;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return -1;
+
+ e_table_item_get_cell_geometry (item,
+ &row,
+ &column,
+ NULL,
+ NULL,
+ NULL,
+ &height);
+
+ return height;
+}
+
+static AtkObject *
+eti_get_caption (AtkTable *table)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+static G_CONST_RETURN gchar *
+eti_get_column_description (AtkTable *table,
+ gint column)
+{
+ ETableItem *item;
+ ETableCol *ecol;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return NULL;
+
+ ecol = e_table_header_get_column (item->header, column);
+
+ return ecol->text;
+}
+
+static AtkObject *
+eti_get_column_header (AtkTable *table, gint column)
+{
+ ETableItem *item;
+ ETableCol *ecol;
+ AtkObject *atk_obj = NULL;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return NULL;
+
+ ecol = e_table_header_get_column (item->header, column);
+ if (ecol) {
+ atk_obj = gal_a11y_e_table_column_header_new (ecol, item);
+ }
+
+ return atk_obj;
+}
+
+static G_CONST_RETURN gchar *
+eti_get_row_description (AtkTable *table,
+ gint row)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+static AtkObject *
+eti_get_row_header (AtkTable *table,
+ gint row)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+static AtkObject *
+eti_get_summary (AtkTable *table)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+static gboolean
+table_is_row_selected (AtkTable *table, gint row)
+{
+ ETableItem *item;
+ GalA11yETableItemPrivate *priv = GET_PRIVATE (table);
+
+ if (row < 0)
+ return FALSE;
+
+ if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT))
+ return FALSE;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return FALSE;
+
+ return e_selection_model_is_row_selected(item->selection, view_to_model_row (item, row));
+}
+
+static gboolean
+table_is_selected (AtkTable *table, gint row, gint column)
+{
+ return table_is_row_selected (table, row);
+}
+
+static gint
+table_get_selected_rows (AtkTable *table, gint **rows_selected)
+{
+ ETableItem *item;
+ gint n_selected, row, index_selected;
+ GalA11yETableItemPrivate *priv = GET_PRIVATE (table);
+
+ if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT))
+ return 0;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return 0;
+
+ n_selected = e_selection_model_selected_count (item->selection);
+ if (rows_selected) {
+ *rows_selected = (gint *) g_malloc (n_selected * sizeof (gint));
+
+ index_selected = 0;
+ for (row = 0; row < item->rows && index_selected < n_selected; ++row) {
+ if (atk_table_is_row_selected (table, row)) {
+ (*rows_selected)[index_selected] = row;
+ ++index_selected;
+ }
+ }
+ }
+ return n_selected;
+}
+
+static gboolean
+table_add_row_selection (AtkTable *table, gint row)
+{
+ ETableItem *item;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return FALSE;
+
+ if (table_is_row_selected (table, row))
+ return TRUE;
+ e_selection_model_toggle_single_row (item->selection,
+ view_to_model_row (item, row));
+
+ return TRUE;
+}
+
+static gboolean
+table_remove_row_selection (AtkTable *table, gint row)
+{
+ ETableItem *item;
+ GalA11yETableItemPrivate *priv = GET_PRIVATE (table);
+
+ if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT))
+ return FALSE;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (table)));
+ if (!item)
+ return FALSE;
+
+ if (!atk_table_is_row_selected (table, row))
+ return TRUE;
+ e_selection_model_toggle_single_row (item->selection, view_to_model_row (item, row));
+ return TRUE;
+}
+
+static void
+eti_atk_table_iface_init (AtkTableIface *iface)
+{
+ iface->ref_at = eti_ref_at;
+ iface->get_index_at = eti_get_index_at;
+ iface->get_column_at_index = eti_get_column_at_index;
+ iface->get_row_at_index = eti_get_row_at_index;
+ iface->get_n_columns = eti_get_n_columns;
+ iface->get_n_rows = eti_get_n_rows;
+ iface->get_column_extent_at = eti_get_column_extent_at;
+ iface->get_row_extent_at = eti_get_row_extent_at;
+ iface->get_caption = eti_get_caption;
+ iface->get_column_description = eti_get_column_description;
+ iface->get_column_header = eti_get_column_header;
+ iface->get_row_description = eti_get_row_description;
+ iface->get_row_header = eti_get_row_header;
+ iface->get_summary = eti_get_summary;
+
+ iface->is_row_selected = table_is_row_selected;
+ iface->is_selected = table_is_selected;
+ iface->get_selected_rows = table_get_selected_rows;
+ iface->add_row_selection = table_add_row_selection;
+ iface->remove_row_selection = table_remove_row_selection;
+}
+
+static void
+eti_atk_component_iface_init (AtkComponentIface *iface)
+{
+ component_parent_iface = g_type_interface_peek_parent (iface);
+
+ iface->ref_accessible_at_point = eti_ref_accessible_at_point;
+ iface->get_extents = eti_get_extents;
+}
+
+static void
+eti_rows_inserted (ETableModel * model, int row, int count,
+ AtkObject * table_item)
+{
+ gint n_cols,n_rows,i,j;
+ GalA11yETableItem * item_a11y;
+ gint old_nrows;
+
+ g_return_if_fail (table_item);
+ item_a11y = GAL_A11Y_E_TABLE_ITEM (table_item);
+
+ n_cols = atk_table_get_n_columns (ATK_TABLE(table_item));
+ n_rows = atk_table_get_n_rows (ATK_TABLE(table_item));
+
+ old_nrows = GET_PRIVATE(item_a11y)->rows;
+
+ g_return_if_fail (n_cols > 0 && n_rows > 0);
+ g_return_if_fail (old_nrows == n_rows - count);
+
+ GET_PRIVATE(table_item)->rows = n_rows;
+
+ g_signal_emit_by_name (table_item, "row-inserted", row,
+ count, 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 + 1)*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, old_nrows;
+ 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));
+
+ old_nrows = GET_PRIVATE(table_item)->rows;
+
+ g_return_if_fail ( row+count <= old_nrows);
+ g_return_if_fail (old_nrows == n_rows + count);
+ GET_PRIVATE(table_item)->rows = n_rows;
+
+ g_signal_emit_by_name (table_item, "row-deleted", row,
+ count, NULL);
+
+ for (i = row; i < (row + count); i ++) {
+ for (j = 0; j < n_cols; j ++) {
+ g_signal_emit_by_name (table_item,
+ "children_changed::remove",
+ ( ((i + 1)*n_cols) + j), NULL, NULL);
+ }
+ }
+ g_signal_emit_by_name (table_item, "visible-data-changed");
+ eti_a11y_reset_focus_object ((GalA11yETableItem *)table_item, item, TRUE);
+}
+
+static void
+eti_tree_model_node_changed_cb (ETreeModel *model, ETreePath node, ETableItem *eti)
+{
+ AtkObject *atk_obj;
+ GalA11yETableItem *a11y;
+
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+
+ atk_obj = atk_gobject_accessible_for_object (G_OBJECT (eti));
+ a11y = GAL_A11Y_E_TABLE_ITEM (atk_obj);
+
+ /* we can't figure out which rows are changed, so just send out a signal ... */
+ if (GET_PRIVATE (a11y)->rows > 0)
+ g_signal_emit_by_name (a11y, "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;
+
+ a11y_item = GAL_A11Y_E_TABLE_ITEM (a11y);
+ priv = GET_PRIVATE (a11y_item);
+
+ /* 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);
+
+ /* 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 ) {
+ 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;
+
+ /* 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+1)*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+1)*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)
+{
+ 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);
+ g_signal_connect (G_OBJECT (eti->header), "structure_change",
+ G_CALLBACK (eti_header_structure_changed), obj);
+
+}
+
+static void
+eti_class_init (GalA11yETableItemClass *klass)
+{
+ AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object");
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ object_class->dispose = eti_dispose;
+
+ atk_object_class->get_n_children = eti_get_n_children;
+ atk_object_class->ref_child = eti_ref_child;
+ atk_object_class->initialize = eti_real_initialize;
+ atk_object_class->ref_state_set = eti_ref_state_set;
+}
+
+static void
+eti_init (GalA11yETableItem *a11y)
+{
+ GalA11yETableItemPrivate *priv;
+
+ priv = GET_PRIVATE (a11y);
+
+ priv->selection_change_id = 0;
+ priv->cursor_change_id = 0;
+ priv->selection = NULL;
+}
+
+/* atk selection */
+
+static void atk_selection_interface_init (AtkSelectionIface *iface);
+static gboolean selection_add_selection (AtkSelection *selection,
+ gint i);
+static gboolean selection_clear_selection (AtkSelection *selection);
+static AtkObject* selection_ref_selection (AtkSelection *selection,
+ gint i);
+static gint selection_get_selection_count (AtkSelection *selection);
+static gboolean selection_is_child_selected (AtkSelection *selection,
+ gint i);
+
+/* callbacks */
+static void eti_a11y_selection_model_removed_cb (ETableItem *eti,
+ ESelectionModel *selection,
+ gpointer data);
+static void eti_a11y_selection_model_added_cb (ETableItem *eti,
+ ESelectionModel *selection,
+ gpointer data);
+static void eti_a11y_selection_changed_cb (ESelectionModel *selection,
+ GalA11yETableItem *a11y);
+static void eti_a11y_cursor_changed_cb (ESelectionModel *selection,
+ int row, int col,
+ GalA11yETableItem *a11y);
+
+/**
+ * gal_a11y_e_table_item_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yETableItem class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yETableItem class.
+ **/
+GType
+gal_a11y_e_table_item_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ AtkObjectFactory *factory;
+
+ GTypeInfo info = {
+ sizeof (GalA11yETableItemClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) eti_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yETableItem),
+ 0,
+ (GInstanceInitFunc) eti_init,
+ NULL /* value_table_item */
+ };
+
+ static const GInterfaceInfo atk_component_info = {
+ (GInterfaceInitFunc) eti_atk_component_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+ static const GInterfaceInfo atk_table_info = {
+ (GInterfaceInitFunc) eti_atk_table_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ static const GInterfaceInfo atk_selection_info = {
+ (GInterfaceInitFunc) atk_selection_interface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+
+ factory = atk_registry_get_factory (atk_get_default_registry (), GNOME_TYPE_CANVAS_ITEM);
+ parent_type = atk_object_factory_get_accessible_type (factory);
+
+ type = gal_a11y_type_register_static_with_private (PARENT_TYPE, "GalA11yETableItem", &info, 0,
+ sizeof (GalA11yETableItemPrivate), &priv_offset);
+
+ g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info);
+ g_type_add_interface_static (type, ATK_TYPE_TABLE, &atk_table_info);
+ g_type_add_interface_static (type, ATK_TYPE_SELECTION, &atk_selection_info);
+ }
+
+ return type;
+}
+
+AtkObject *
+gal_a11y_e_table_item_new (ETableItem *item)
+{
+ GalA11yETableItem *a11y;
+ AtkObject *accessible;
+ ESelectionModel * esm;
+ AtkObject *parent;
+ const char *name;
+
+ g_return_val_if_fail (item && item->cols >= 0 && item->rows >= 0, NULL);
+ a11y = g_object_new (gal_a11y_e_table_item_get_type (), NULL);
+
+ atk_object_initialize (ATK_OBJECT (a11y), item);
+
+ GET_PRIVATE (a11y)->state_set = atk_state_set_new ();
+
+ atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_TRANSIENT);
+ atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_ENABLED);
+ atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_SENSITIVE);
+ atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_SHOWING);
+ atk_state_set_add_state (GET_PRIVATE(a11y)->state_set, ATK_STATE_VISIBLE);
+
+
+ accessible = ATK_OBJECT(a11y);
+
+ /* Initialize cell data. */
+ GET_PRIVATE (a11y)->cols = item->cols;
+ GET_PRIVATE (a11y)->rows = item->rows;
+
+ 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",
+ G_CALLBACK (eti_a11y_selection_model_removed_cb), NULL);
+ g_signal_connect (G_OBJECT(item), "selection_model_added",
+ G_CALLBACK (eti_a11y_selection_model_added_cb), NULL);
+ if (item->selection)
+ gal_a11y_e_table_item_ref_selection (a11y,
+ item->selection);
+
+ /* find the TableItem's parent: table or tree */
+ GET_PRIVATE (a11y)->widget = gtk_widget_get_parent (GTK_WIDGET (item->parent.canvas));
+ parent = gtk_widget_get_accessible (GET_PRIVATE (a11y)->widget);
+ name = atk_object_get_name (parent);
+ if (name)
+ atk_object_set_name (accessible, name);
+ atk_object_set_parent (accessible, parent);
+
+ if (E_IS_TREE (GET_PRIVATE (a11y)->widget)) {
+ ETreeModel *model;
+ model = e_tree_get_model (E_TREE (GET_PRIVATE (a11y)->widget));
+ g_signal_connect (G_OBJECT(model), "node_changed",
+ G_CALLBACK (eti_tree_model_node_changed_cb), item);
+ accessible->role = ATK_ROLE_TREE_TABLE;
+ } else if (E_IS_TABLE (GET_PRIVATE (a11y)->widget)) {
+ accessible->role = ATK_ROLE_TABLE;
+ }
+ }
+
+ if (item)
+ g_signal_connect (G_OBJECT (item), "destroy",
+ G_CALLBACK (item_destroyed),
+ a11y);
+ esm = item->selection;
+
+ if (esm != NULL) {
+ eti_a11y_reset_focus_object (a11y, item, FALSE);
+ }
+
+ return ATK_OBJECT (a11y);
+}
+
+static gboolean
+gal_a11y_e_table_item_ref_selection (GalA11yETableItem *a11y,
+ ESelectionModel *selection)
+{
+ GalA11yETableItemPrivate *priv;
+
+ g_return_val_if_fail (a11y && selection, FALSE);
+
+ priv = GET_PRIVATE (a11y);
+ priv->selection_change_id = g_signal_connect (
+ G_OBJECT(selection), "selection_changed",
+ G_CALLBACK (eti_a11y_selection_changed_cb), a11y);
+ priv->cursor_change_id = g_signal_connect (
+ G_OBJECT(selection), "cursor_changed",
+ G_CALLBACK (eti_a11y_cursor_changed_cb), a11y);
+
+ priv->selection = selection;
+ g_object_ref (selection);
+
+ return TRUE;
+}
+
+static gboolean
+gal_a11y_e_table_item_unref_selection (GalA11yETableItem *a11y)
+{
+ GalA11yETableItemPrivate *priv;
+
+ g_return_val_if_fail (a11y, FALSE);
+
+ priv = GET_PRIVATE (a11y);
+
+ g_return_val_if_fail (priv->selection_change_id != 0, FALSE);
+ g_return_val_if_fail (priv->cursor_change_id != 0, FALSE);
+
+
+ g_signal_handler_disconnect (priv->selection,
+ priv->selection_change_id);
+ g_signal_handler_disconnect (priv->selection,
+ priv->cursor_change_id);
+ priv->cursor_change_id = 0;
+ priv->selection_change_id = 0;
+
+ g_object_unref (priv->selection);
+ priv->selection = NULL;
+
+ return TRUE;
+}
+
+/* callbacks */
+
+static void
+eti_a11y_selection_model_removed_cb (ETableItem *eti, ESelectionModel *selection,
+ gpointer data)
+{
+ AtkObject *atk_obj;
+ GalA11yETableItem *a11y;
+
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+ g_return_if_fail (E_IS_SELECTION_MODEL (selection));
+
+ atk_obj = atk_gobject_accessible_for_object (G_OBJECT (eti));
+ a11y = GAL_A11Y_E_TABLE_ITEM (atk_obj);
+
+ if (selection == GET_PRIVATE (a11y)->selection)
+ gal_a11y_e_table_item_unref_selection (a11y);
+}
+
+static void
+eti_a11y_selection_model_added_cb (ETableItem *eti, ESelectionModel *selection,
+ gpointer data)
+{
+ AtkObject *atk_obj;
+ GalA11yETableItem *a11y;
+
+ g_return_if_fail (E_IS_TABLE_ITEM (eti));
+ g_return_if_fail (E_IS_SELECTION_MODEL (selection));
+
+ atk_obj = atk_gobject_accessible_for_object (G_OBJECT (eti));
+ a11y = GAL_A11Y_E_TABLE_ITEM (atk_obj);
+
+ if (GET_PRIVATE (a11y)->selection)
+ gal_a11y_e_table_item_unref_selection (a11y);
+ gal_a11y_e_table_item_ref_selection (a11y, selection);
+}
+
+static void
+eti_a11y_selection_changed_cb (ESelectionModel *selection, GalA11yETableItem *a11y)
+{
+ GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y);
+
+ if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT))
+ return;
+
+ g_return_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (a11y));
+
+ g_signal_emit_by_name (a11y, "selection_changed");
+}
+
+static void
+eti_a11y_cursor_changed_cb (ESelectionModel *selection,
+ int row, int col, GalA11yETableItem *a11y)
+{
+ ETableItem *item;
+ GalA11yETableItemPrivate *priv = GET_PRIVATE (a11y);
+
+ g_return_if_fail (GAL_A11Y_IS_E_TABLE_ITEM (a11y));
+
+ if (atk_state_set_contains_state (priv->state_set, ATK_STATE_DEFUNCT))
+ return;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (a11y)));
+
+ g_return_if_fail (item);
+
+ if (row == -1 && col == -1)
+ return;
+ eti_a11y_reset_focus_object (a11y, item, TRUE);
+}
+
+/* atk selection */
+
+static void atk_selection_interface_init (AtkSelectionIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+ iface->add_selection = selection_add_selection;
+ iface->clear_selection = selection_clear_selection;
+ iface->ref_selection = selection_ref_selection;
+ iface->get_selection_count = selection_get_selection_count;
+ iface->is_child_selected = selection_is_child_selected;
+}
+
+static gboolean
+selection_add_selection (AtkSelection *selection, gint index)
+{
+ AtkTable *table;
+ gint row, col, cursor_row, cursor_col, model_row, model_col;
+ ETableItem *item;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (selection)));
+ if (!item)
+ return FALSE;
+
+ table = ATK_TABLE (selection);
+
+ row = atk_table_get_row_at_index (table, index);
+ col = atk_table_get_column_at_index (table, index);
+
+ model_row = view_to_model_row (item, row);
+ model_col = view_to_model_col (item, col);
+
+ cursor_row = e_selection_model_cursor_row (item->selection);
+ cursor_col = e_selection_model_cursor_col (item->selection);
+
+ /* check whether is selected already */
+ if (model_row == cursor_row && model_col == cursor_col)
+ return TRUE;
+
+ if (model_row != cursor_row) {
+ /* we need to make the item get focus */
+ e_canvas_item_grab_focus (GNOME_CANVAS_ITEM (item), TRUE);
+
+ /* FIXME, currently we only support single row selection */
+ atk_selection_clear_selection (selection);
+ atk_table_add_row_selection (table, row);
+ }
+
+ e_selection_model_change_cursor (item->selection,
+ model_row,
+ model_col);
+ e_selection_model_cursor_changed (item->selection,
+ model_row,
+ model_col);
+ e_selection_model_cursor_activated (item->selection,
+ model_row,
+ model_col);
+ return TRUE;
+}
+
+static gboolean
+selection_clear_selection (AtkSelection *selection)
+{
+ ETableItem *item;
+
+ item = E_TABLE_ITEM (eti_a11y_get_gobject (ATK_OBJECT (selection)));
+ if (!item)
+ return FALSE;
+
+ e_selection_model_clear (item->selection);
+ return TRUE;
+}
+
+static AtkObject *
+selection_ref_selection (AtkSelection *selection, gint index)
+{
+ AtkTable *table;
+ gint row, col;
+
+ table = ATK_TABLE (selection);
+ row = atk_table_get_row_at_index (table, index);
+ col = atk_table_get_column_at_index (table, index);
+ if (!atk_table_is_row_selected (table, row))
+ return NULL;
+
+ return eti_ref_at (table, row, col);
+}
+
+static gint
+selection_get_selection_count (AtkSelection *selection)
+{
+ AtkTable *table;
+ gint n_selected;
+
+ table = ATK_TABLE (selection);
+ n_selected = atk_table_get_selected_rows (table, NULL);
+ if (n_selected > 0)
+ n_selected *= atk_table_get_n_columns (table);
+ return n_selected;
+}
+
+static gboolean
+selection_is_child_selected (AtkSelection *selection, gint i)
+{
+ gint row;
+
+ row = atk_table_get_row_at_index (ATK_TABLE (selection), i);
+ return atk_table_is_row_selected (ATK_TABLE (selection), row);
+}
+
+void
+gal_a11y_e_table_item_init (void)
+{
+ if (atk_get_root ())
+ atk_registry_set_factory_type (atk_get_default_registry (),
+ E_TABLE_ITEM_TYPE,
+ gal_a11y_e_table_item_factory_get_type ());
+}
+
diff --git a/widgets/table/a11y/gal-a11y-e-table-item.h b/widgets/table/a11y/gal-a11y-e-table-item.h
new file mode 100644
index 0000000000..e89f0824b3
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table-item.h
@@ -0,0 +1,59 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TABLE_ITEM_H__
+#define __GAL_A11Y_E_TABLE_ITEM_H__
+
+#include <glib-object.h>
+#include <table/e-table-item.h>
+#include <atk/atkgobjectaccessible.h>
+
+#define GAL_A11Y_TYPE_E_TABLE_ITEM (gal_a11y_e_table_item_get_type ())
+#define GAL_A11Y_E_TABLE_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE_ITEM, GalA11yETableItem))
+#define GAL_A11Y_E_TABLE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE_ITEM, GalA11yETableItemClass))
+#define GAL_A11Y_IS_E_TABLE_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE_ITEM))
+#define GAL_A11Y_IS_E_TABLE_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE_ITEM))
+
+typedef struct _GalA11yETableItem GalA11yETableItem;
+typedef struct _GalA11yETableItemClass GalA11yETableItemClass;
+typedef struct _GalA11yETableItemPrivate GalA11yETableItemPrivate;
+
+/* This struct should actually be larger as this isn't what we derive from.
+ * The GalA11yETableItemPrivate comes right after the parent class structure.
+ **/
+struct _GalA11yETableItem {
+ AtkGObjectAccessible parent;
+};
+
+struct _GalA11yETableItemClass {
+ AtkGObjectAccessibleClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_table_item_get_type (void);
+AtkObject *gal_a11y_e_table_item_new (ETableItem *item);
+
+void gal_a11y_e_table_item_init (void);
+
+#endif /* ! __GAL_A11Y_E_TABLE_ITEM_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-table.c b/widgets/table/a11y/gal-a11y-e-table.c
new file mode 100644
index 0000000000..20261d4eab
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table.c
@@ -0,0 +1,308 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include "a11y/gal-a11y-util.h"
+#include "table/e-table.h"
+#include "table/e-table-click-to-add.h"
+#include "table/e-table-group.h"
+#include "table/e-table-group-container.h"
+#include "table/e-table-group-leaf.h"
+
+#include "gal-a11y-e-table.h"
+#include "gal-a11y-e-table-factory.h"
+#include "gal-a11y-e-table-item.h"
+
+#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yETableClass))
+static AtkObjectClass *parent_class;
+static GType parent_type;
+static gint priv_offset;
+#define GET_PRIVATE(object) ((GalA11yETablePrivate *) (((char *) object) + priv_offset))
+#define PARENT_TYPE (parent_type)
+
+struct _GalA11yETablePrivate {
+ AtkObject *child_item;
+};
+
+/* Static functions */
+static ETableItem *
+find_first_table_item (ETableGroup *group)
+{
+ GnomeCanvasGroup *cgroup;
+ GList *l;
+
+ cgroup = GNOME_CANVAS_GROUP (group);
+
+ for (l = cgroup->item_list; l; l = l->next) {
+ GnomeCanvasItem *i;
+
+ i = GNOME_CANVAS_ITEM (l->data);
+
+ if (E_IS_TABLE_GROUP (i))
+ return find_first_table_item (E_TABLE_GROUP (i));
+ else if (E_IS_TABLE_ITEM (i)) {
+ return E_TABLE_ITEM (i);
+ }
+ }
+
+ return NULL;
+}
+
+static AtkObject*
+eti_get_accessible (ETableItem *eti, AtkObject *parent)
+{
+ AtkObject *a11y = NULL;
+
+ g_return_val_if_fail (eti, NULL);
+
+ a11y = atk_gobject_accessible_for_object (G_OBJECT (eti));
+ g_return_val_if_fail (a11y, NULL);
+
+ return a11y;
+}
+
+static gboolean
+init_child_item (GalA11yETable *a11y)
+{
+ ETable *table;
+
+ if (!a11y || !GTK_IS_ACCESSIBLE (a11y))
+ return FALSE;
+
+ table = E_TABLE (GTK_ACCESSIBLE (a11y)->widget);
+ if (table && GTK_WIDGET_MAPPED (GTK_WIDGET (table)) && table->group && E_IS_TABLE_GROUP_CONTAINER(table->group)) {
+ ETableGroupContainer *etgc = (ETableGroupContainer *)table->group;
+ GList *list;
+
+ for (list = etgc->children; list; list = g_list_next (list)) {
+ ETableGroupContainerChildNode *child_node = list->data;
+ ETableGroup *child = child_node->child;
+ ETableItem *eti = find_first_table_item (child);
+
+ eti_get_accessible (eti, ATK_OBJECT (a11y));
+ }
+ }
+ g_object_unref (a11y);
+ g_object_unref (table);
+
+ return FALSE;
+}
+
+static AtkObject*
+et_ref_accessible_at_point (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type)
+{
+ GalA11yETable *a11y = GAL_A11Y_E_TABLE (component);
+ if (GET_PRIVATE (a11y)->child_item)
+ g_object_ref (GET_PRIVATE (a11y)->child_item);
+ return GET_PRIVATE (a11y)->child_item;
+}
+
+static gint
+et_get_n_children (AtkObject *accessible)
+{
+ GalA11yETable *a11y = GAL_A11Y_E_TABLE (accessible);
+ ETable * et;
+ int n = 0;
+
+ et = E_TABLE(GTK_ACCESSIBLE (a11y)->widget);
+
+ if (et->group) {
+ if (E_IS_TABLE_GROUP_LEAF (et->group))
+ n = 1;
+ else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
+ ETableGroupContainer *etgc = (ETableGroupContainer *)et->group;
+ n = g_list_length (etgc->children);
+ }
+ }
+
+ if (et && et->use_click_to_add && et->click_to_add) {
+ n++;
+ }
+ return n;
+}
+
+static AtkObject*
+et_ref_child (AtkObject *accessible,
+ gint i)
+{
+ GalA11yETable *a11y = GAL_A11Y_E_TABLE (accessible);
+ ETable * et;
+ gint child_no;
+
+ et = E_TABLE(GTK_ACCESSIBLE (a11y)->widget);
+
+ child_no = et_get_n_children (accessible);
+ if (i == 0 || i < child_no - 1) {
+ if (E_IS_TABLE_GROUP_LEAF (et->group)) {
+ ETableItem *eti = find_first_table_item (et->group);
+ AtkObject *aeti = eti_get_accessible (eti, accessible);
+ if (aeti)
+ g_object_ref (aeti);
+ return aeti;
+
+ } else if (E_IS_TABLE_GROUP_CONTAINER (et->group)) {
+ ETableGroupContainer *etgc = (ETableGroupContainer *) et->group;
+ ETableGroupContainerChildNode *child_node = g_list_nth_data (etgc->children, i);
+ if (child_node) {
+ ETableGroup *child = child_node->child;
+ ETableItem * eti = find_first_table_item (child);
+ AtkObject *aeti = eti_get_accessible (eti, accessible);
+ if (aeti)
+ g_object_ref (aeti);
+ return aeti;
+ }
+ }
+ } else if (i == child_no -1) {
+ ETableClickToAdd * etcta;
+
+ if (et && et->use_click_to_add && et->click_to_add) {
+ etcta = E_TABLE_CLICK_TO_ADD(et->click_to_add);
+ accessible = atk_gobject_accessible_for_object (G_OBJECT(etcta));
+ if (accessible)
+ g_object_ref (accessible);
+ return accessible;
+ }
+ }
+
+ return NULL;
+}
+
+static AtkLayer
+et_get_layer (AtkComponent *component)
+{
+ return ATK_LAYER_WIDGET;
+}
+
+static void
+et_class_init (GalA11yETableClass *klass)
+{
+ AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ atk_object_class->get_n_children = et_get_n_children;
+ atk_object_class->ref_child = et_ref_child;
+}
+
+static void
+et_atk_component_iface_init (AtkComponentIface *iface)
+{
+ iface->ref_accessible_at_point = et_ref_accessible_at_point;
+ iface->get_layer = et_get_layer;
+}
+
+static void
+et_init (GalA11yETable *a11y)
+{
+ GalA11yETablePrivate *priv;
+
+ priv = GET_PRIVATE (a11y);
+
+ priv->child_item = NULL;
+}
+
+/**
+ * gal_a11y_e_table_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yETable class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yETable class.
+ **/
+GType
+gal_a11y_e_table_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ AtkObjectFactory *factory;
+
+ GTypeInfo info = {
+ sizeof (GalA11yETableClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) et_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yETable),
+ 0,
+ (GInstanceInitFunc) et_init,
+ NULL /* value_table */
+ };
+
+ static const GInterfaceInfo atk_component_info = {
+ (GInterfaceInitFunc) et_atk_component_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ factory = atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET);
+ parent_type = atk_object_factory_get_accessible_type (factory);
+
+ type = gal_a11y_type_register_static_with_private (PARENT_TYPE, "GalA11yETable", &info, 0,
+ sizeof (GalA11yETablePrivate), &priv_offset);
+ g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info);
+ }
+
+ return type;
+}
+
+AtkObject *
+gal_a11y_e_table_new (GObject *widget)
+{
+ GalA11yETable *a11y;
+ ETable *table;
+
+ table = E_TABLE (widget);
+
+ a11y = g_object_new (gal_a11y_e_table_get_type (), NULL);
+
+ GTK_ACCESSIBLE (a11y)->widget = GTK_WIDGET (widget);
+
+ /* we need to init all the children for multiple table items */
+ if (table && GTK_WIDGET_MAPPED (GTK_WIDGET (table)) && table->group && E_IS_TABLE_GROUP_CONTAINER (table->group)) {
+ /* Ref it here so that it is still valid in the idle function */
+ /* It will be unrefed in the idle function */
+ g_object_ref (a11y);
+ g_object_ref (widget);
+
+ g_idle_add ((GSourceFunc)init_child_item, a11y);
+ }
+
+ return ATK_OBJECT (a11y);
+}
+
+void
+gal_a11y_e_table_init (void)
+{
+ if (atk_get_root ())
+ atk_registry_set_factory_type (atk_get_default_registry (),
+ E_TABLE_TYPE,
+ gal_a11y_e_table_factory_get_type ());
+
+}
+
diff --git a/widgets/table/a11y/gal-a11y-e-table.h b/widgets/table/a11y/gal-a11y-e-table.h
new file mode 100644
index 0000000000..ab133f5c71
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-table.h
@@ -0,0 +1,59 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TABLE_H__
+#define __GAL_A11Y_E_TABLE_H__
+
+#include <gtk/gtk.h>
+#include <atk/atkobject.h>
+#include <atk/atkcomponent.h>
+
+#define GAL_A11Y_TYPE_E_TABLE (gal_a11y_e_table_get_type ())
+#define GAL_A11Y_E_TABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TABLE, GalA11yETable))
+#define GAL_A11Y_E_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TABLE, GalA11yETableClass))
+#define GAL_A11Y_IS_E_TABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TABLE))
+#define GAL_A11Y_IS_E_TABLE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TABLE))
+
+typedef struct _GalA11yETable GalA11yETable;
+typedef struct _GalA11yETableClass GalA11yETableClass;
+typedef struct _GalA11yETablePrivate GalA11yETablePrivate;
+
+/* This struct should actually be larger as this isn't what we derive from.
+ * The GalA11yETablePrivate comes right after the parent class structure.
+ **/
+struct _GalA11yETable {
+ GtkAccessible object;
+};
+
+struct _GalA11yETableClass {
+ GtkAccessibleClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_table_get_type (void);
+AtkObject *gal_a11y_e_table_new (GObject *table);
+
+void gal_a11y_e_table_init (void);
+
+#endif /* ! __GAL_A11Y_E_TABLE_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-tree-factory.c b/widgets/table/a11y/gal-a11y-e-tree-factory.c
new file mode 100644
index 0000000000..cacb3fe082
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-tree-factory.c
@@ -0,0 +1,98 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yuedong Du <yuedong.du@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include "gal-a11y-e-tree.h"
+#include "gal-a11y-e-tree-factory.h"
+
+#define CS_CLASS(factory) (G_TYPE_INSTANCE_GET_CLASS ((factory), C_TYPE_STREAM, GalA11yETreeFactoryClass))
+static AtkObjectFactoryClass *parent_class;
+#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY)
+
+/* Static functions */
+
+static GType
+gal_a11y_e_tree_factory_get_accessible_type (void)
+{
+ return GAL_A11Y_TYPE_E_TREE;
+}
+
+static AtkObject*
+gal_a11y_e_tree_factory_create_accessible (GObject *obj)
+{
+ AtkObject *accessible;
+
+ accessible = gal_a11y_e_tree_new (obj);
+
+ return accessible;
+}
+
+static void
+gal_a11y_e_tree_factory_class_init (GalA11yETreeFactoryClass *klass)
+{
+ AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ factory_class->create_accessible = gal_a11y_e_tree_factory_create_accessible;
+ factory_class->get_accessible_type = gal_a11y_e_tree_factory_get_accessible_type;
+}
+
+static void
+gal_a11y_e_tree_factory_init (GalA11yETreeFactory *factory)
+{
+}
+
+/**
+ * gal_a11y_e_tree_factory_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yETreeFactory class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yETreeFactory class.
+ **/
+GType
+gal_a11y_e_tree_factory_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yETreeFactoryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gal_a11y_e_tree_factory_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yETreeFactory),
+ 0,
+ (GInstanceInitFunc) gal_a11y_e_tree_factory_init,
+ NULL /* value_tree */
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yETreeFactory", &info, 0);
+ }
+
+ return type;
+}
diff --git a/widgets/table/a11y/gal-a11y-e-tree-factory.h b/widgets/table/a11y/gal-a11y-e-tree-factory.h
new file mode 100644
index 0000000000..621d256c48
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-tree-factory.h
@@ -0,0 +1,50 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yuedong Du <yuedong.du@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TREE_FACTORY_H__
+#define __GAL_A11Y_E_TREE_FACTORY_H__
+
+#include <glib-object.h>
+#include <atk/atkobjectfactory.h>
+
+#define GAL_A11Y_TYPE_E_TREE_FACTORY (gal_a11y_e_table_factory_get_type ())
+#define GAL_A11Y_E_TREE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TREE_FACTORY, GalA11yETreeFactory))
+#define GAL_A11Y_E_TREE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TREE_FACTORY, GalA11yETreeFactoryClass))
+#define GAL_A11Y_IS_E_TREE_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TREE_FACTORY))
+#define GAL_A11Y_IS_E_TREE_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TREE_FACTORY))
+
+typedef struct _GalA11yETreeFactory GalA11yETreeFactory;
+typedef struct _GalA11yETreeFactoryClass GalA11yETreeFactoryClass;
+
+struct _GalA11yETreeFactory {
+ AtkObject object;
+};
+
+struct _GalA11yETreeFactoryClass {
+ AtkObjectClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_tree_factory_get_type (void);
+
+#endif /* ! __GAL_A11Y_E_TREE_FACTORY_H__ */
diff --git a/widgets/table/a11y/gal-a11y-e-tree.c b/widgets/table/a11y/gal-a11y-e-tree.c
new file mode 100644
index 0000000000..6fde32b8e7
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-tree.c
@@ -0,0 +1,191 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yuedong Du <yuedong.du@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include "a11y/gal-a11y-util.h"
+#include "table/e-table-item.h"
+#include "table/e-tree.h"
+
+#include "gal-a11y-e-table-item.h"
+#include "gal-a11y-e-tree.h"
+#include "gal-a11y-e-tree-factory.h"
+
+#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yETreeClass))
+static AtkObjectClass *parent_class;
+static GType parent_type;
+static gint priv_offset;
+#define GET_PRIVATE(object) ((GalA11yETreePrivate *) (((char *) object) + priv_offset))
+#define PARENT_TYPE (parent_type)
+
+struct _GalA11yETreePrivate {
+ AtkObject *child_item;
+};
+
+/* Static functions */
+
+static void
+init_child_item (GalA11yETree *a11y)
+{
+ GalA11yETreePrivate *priv = GET_PRIVATE (a11y);
+ ETree *tree = E_TREE (GTK_ACCESSIBLE (a11y)->widget);
+ ETableItem * eti;
+
+ g_return_if_fail (tree);
+ eti = e_tree_get_item (tree);
+ if (priv->child_item == NULL) {
+ priv->child_item = atk_gobject_accessible_for_object (G_OBJECT (eti));
+ }
+}
+
+static AtkObject*
+et_ref_accessible_at_point (AtkComponent *component,
+ gint x,
+ gint y,
+ AtkCoordType coord_type)
+{
+ GalA11yETree *a11y = GAL_A11Y_E_TREE (component);
+ init_child_item (a11y);
+ return GET_PRIVATE (a11y)->child_item;
+}
+
+static gint
+et_get_n_children (AtkObject *accessible)
+{
+ return 1;
+}
+
+static AtkObject*
+et_ref_child (AtkObject *accessible,
+ gint i)
+{
+ GalA11yETree *a11y = GAL_A11Y_E_TREE (accessible);
+ if (i != 0)
+ return NULL;
+ init_child_item (a11y);
+ g_object_ref (GET_PRIVATE (a11y)->child_item);
+ return GET_PRIVATE (a11y)->child_item;
+}
+
+static AtkLayer
+et_get_layer (AtkComponent *component)
+{
+ return ATK_LAYER_WIDGET;
+}
+
+static void
+et_class_init (GalA11yETreeClass *klass)
+{
+ AtkObjectClass *atk_object_class = ATK_OBJECT_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ atk_object_class->get_n_children = et_get_n_children;
+ atk_object_class->ref_child = et_ref_child;
+}
+
+static void
+et_atk_component_iface_init (AtkComponentIface *iface)
+{
+ iface->ref_accessible_at_point = et_ref_accessible_at_point;
+ iface->get_layer = et_get_layer;
+}
+
+static void
+et_init (GalA11yETree *a11y)
+{
+ GalA11yETreePrivate *priv;
+
+ priv = GET_PRIVATE (a11y);
+
+ priv->child_item = NULL;
+}
+
+/**
+ * gal_a11y_e_tree_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yETree class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yETree class.
+ **/
+GType
+gal_a11y_e_tree_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ AtkObjectFactory *factory;
+
+ GTypeInfo info = {
+ sizeof (GalA11yETreeClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) et_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yETree),
+ 0,
+ (GInstanceInitFunc) et_init,
+ NULL /* value_tree */
+ };
+
+ static const GInterfaceInfo atk_component_info = {
+ (GInterfaceInitFunc) et_atk_component_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ factory = atk_registry_get_factory (atk_get_default_registry (), GTK_TYPE_WIDGET);
+ parent_type = atk_object_factory_get_accessible_type (factory);
+
+ type = gal_a11y_type_register_static_with_private (PARENT_TYPE, "GalA11yETree", &info, 0,
+ sizeof (GalA11yETreePrivate), &priv_offset);
+ g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info);
+ }
+
+ return type;
+}
+
+AtkObject *
+gal_a11y_e_tree_new (GObject *widget)
+{
+ GalA11yETree *a11y;
+
+ a11y = g_object_new (gal_a11y_e_tree_get_type (), NULL);
+
+ GTK_ACCESSIBLE (a11y)->widget = GTK_WIDGET (widget);
+
+ return ATK_OBJECT (a11y);
+}
+
+void
+gal_a11y_e_tree_init (void)
+{
+ if (atk_get_root ())
+ atk_registry_set_factory_type (atk_get_default_registry (),
+ E_TREE_TYPE,
+ gal_a11y_e_tree_factory_get_type ());
+
+}
+
diff --git a/widgets/table/a11y/gal-a11y-e-tree.h b/widgets/table/a11y/gal-a11y-e-tree.h
new file mode 100644
index 0000000000..9fe482e1f8
--- /dev/null
+++ b/widgets/table/a11y/gal-a11y-e-tree.h
@@ -0,0 +1,58 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Yuedong Du <yuedong.du@sun.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TREE_H__
+#define __GAL_A11Y_E_TREE_H__
+
+#include <gtk/gtk.h>
+#include <atk/atkobject.h>
+#include <atk/atkcomponent.h>
+
+#define GAL_A11Y_TYPE_E_TREE (gal_a11y_e_tree_get_type ())
+#define GAL_A11Y_E_TREE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TREE, GalA11yETree))
+#define GAL_A11Y_E_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TREE, GalA11yETreeClass))
+#define GAL_A11Y_IS_E_TREE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TREE))
+#define GAL_A11Y_IS_E_TREE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TREE))
+
+typedef struct _GalA11yETree GalA11yETree;
+typedef struct _GalA11yETreeClass GalA11yETreeClass;
+typedef struct _GalA11yETreePrivate GalA11yETreePrivate;
+
+/* This struct should actually be larger as this isn't what we derive from.
+ * The GalA11yETablePrivate comes right after the parent class structure.
+ **/
+struct _GalA11yETree {
+ GtkAccessible object;
+};
+
+struct _GalA11yETreeClass {
+ GtkAccessibleClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_tree_get_type (void);
+AtkObject *gal_a11y_e_tree_new (GObject *tree);
+
+void gal_a11y_e_tree_init (void);
+
+#endif /* ! __GAL_A11Y_E_TREE_H__ */
diff --git a/widgets/table/e-cell-combo.c b/widgets/table/e-cell-combo.c
index 84d58200d2..4b75881104 100644
--- a/widgets/table/e-cell-combo.c
+++ b/widgets/table/e-cell-combo.c
@@ -62,7 +62,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-item.h"
#include "e-cell-combo.h"
diff --git a/widgets/misc/e-cell-date-edit.c b/widgets/table/e-cell-date-edit.c
index 97947980d9..1cf3838c91 100644
--- a/widgets/misc/e-cell-date-edit.c
+++ b/widgets/table/e-cell-date-edit.c
@@ -39,15 +39,15 @@
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
-#include <table/e-table-item.h>
-#include <table/e-cell-text.h>
+#include "e-table-item.h"
+#include "e-cell-text.h"
#include <glib/gi18n.h>
#include <libedataserver/e-time-utils.h>
/* This depends on ECalendar which is why I didn't put it in gal. */
-#include "e-calendar.h"
+#include <misc/e-calendar.h>
static void e_cell_date_edit_destroy (GtkObject *object);
static void e_cell_date_edit_get_property (GObject *object,
diff --git a/widgets/misc/e-cell-date-edit.h b/widgets/table/e-cell-date-edit.h
index 30dee535e8..30dee535e8 100644
--- a/widgets/misc/e-cell-date-edit.h
+++ b/widgets/table/e-cell-date-edit.h
diff --git a/widgets/table/e-cell-date.c b/widgets/table/e-cell-date.c
index ac0274f183..9199d5715b 100644
--- a/widgets/table/e-cell-date.c
+++ b/widgets/table/e-cell-date.c
@@ -29,7 +29,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-cell-date.h"
diff --git a/widgets/table/e-cell-hbox.c b/widgets/table/e-cell-hbox.c
index b9a8544f57..6c0bded852 100644
--- a/widgets/table/e-cell-hbox.c
+++ b/widgets/table/e-cell-hbox.c
@@ -32,8 +32,8 @@
#include <gtk/gtk.h>
-/* #include "a11y/e-table/gal-a11y-e-cell-registry.h" */
-/* #include "a11y/e-table/gal-a11y-e-cell-vbox.h" */
+/* #include "a11y/gal-a11y-e-cell-registry.h" */
+/* #include "a11y/gal-a11y-e-cell-vbox.h" */
#include "e-util/e-util.h"
#include "e-cell-hbox.h"
diff --git a/widgets/misc/e-cell-percent.c b/widgets/table/e-cell-percent.c
index 94e33489e5..94e33489e5 100644
--- a/widgets/misc/e-cell-percent.c
+++ b/widgets/table/e-cell-percent.c
diff --git a/widgets/misc/e-cell-percent.h b/widgets/table/e-cell-percent.h
index 46a7ddc3e3..46a7ddc3e3 100644
--- a/widgets/misc/e-cell-percent.h
+++ b/widgets/table/e-cell-percent.h
diff --git a/widgets/table/e-cell-popup.c b/widgets/table/e-cell-popup.c
index 92e03d79a1..e7203c5550 100644
--- a/widgets/table/e-cell-popup.c
+++ b/widgets/table/e-cell-popup.c
@@ -33,8 +33,8 @@
#include <gdk/gdkkeysyms.h>
-#include "a11y/e-table/gal-a11y-e-cell-popup.h"
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
+#include "a11y/gal-a11y-e-cell-popup.h"
+#include "a11y/gal-a11y-e-cell-registry.h"
#include "e-util/e-util.h"
#include "e-cell-popup.h"
diff --git a/widgets/table/e-cell-text.c b/widgets/table/e-cell-text.c
index e50d3d7ae7..55ec753c2a 100644
--- a/widgets/table/e-cell-text.c
+++ b/widgets/table/e-cell-text.c
@@ -45,15 +45,15 @@
#include <libgnomecanvas/gnome-canvas.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
-#include "a11y/e-table/gal-a11y-e-cell-text.h"
+#include "a11y/gal-a11y-e-cell-registry.h"
+#include "a11y/gal-a11y-e-cell-text.h"
#include "text/e-text.h"
#include <glib/gi18n.h>
#include "e-util/e-text-event-processor.h"
#include "e-util/e-text-event-processor-emacs-like.h"
#include "e-util/e-util.h"
#include "misc/e-canvas.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-cell-text.h"
#include "e-table-item.h"
diff --git a/widgets/table/e-cell-toggle.c b/widgets/table/e-cell-toggle.c
index 4fc6aca107..38562f58a8 100644
--- a/widgets/table/e-cell-toggle.c
+++ b/widgets/table/e-cell-toggle.c
@@ -28,8 +28,8 @@
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas.h>
-#include "a11y/e-table/gal-a11y-e-cell-toggle.h"
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
+#include "a11y/gal-a11y-e-cell-toggle.h"
+#include "a11y/gal-a11y-e-cell-registry.h"
#include "e-util/e-util.h"
#include "misc/e-hsv-utils.h"
diff --git a/widgets/table/e-cell-tree.c b/widgets/table/e-cell-tree.c
index eb7e428fb9..e9cb30bb23 100644
--- a/widgets/table/e-cell-tree.c
+++ b/widgets/table/e-cell-tree.c
@@ -38,8 +38,8 @@
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas.h>
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
-#include "a11y/e-table/gal-a11y-e-cell-tree.h"
+#include "a11y/gal-a11y-e-cell-registry.h"
+#include "a11y/gal-a11y-e-cell-tree.h"
#include "e-util/e-util.h"
#include "e-cell-tree.h"
diff --git a/widgets/table/e-cell-vbox.c b/widgets/table/e-cell-vbox.c
index af398ae872..46da90eea4 100644
--- a/widgets/table/e-cell-vbox.c
+++ b/widgets/table/e-cell-vbox.c
@@ -29,8 +29,8 @@
#include <gtk/gtk.h>
-#include "a11y/e-table/gal-a11y-e-cell-registry.h"
-#include "a11y/e-table/gal-a11y-e-cell-vbox.h"
+#include "a11y/gal-a11y-e-cell-registry.h"
+#include "a11y/gal-a11y-e-cell-vbox.h"
#include "e-util/e-util.h"
#include "e-cell-vbox.h"
diff --git a/widgets/table/e-table-click-to-add.c b/widgets/table/e-table-click-to-add.c
index 4871b055eb..dedf8e1c53 100644
--- a/widgets/table/e-table-click-to-add.c
+++ b/widgets/table/e-table-click-to-add.c
@@ -29,7 +29,7 @@
#include <libgnomecanvas/gnome-canvas-util.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
-#include "a11y/e-table/gal-a11y-e-table-click-to-add.h"
+#include "a11y/gal-a11y-e-table-click-to-add.h"
#include "text/e-text.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
diff --git a/widgets/table/e-table-config.c b/widgets/table/e-table-config.c
index 5becaa30f2..5f93c32a72 100644
--- a/widgets/table/e-table-config.c
+++ b/widgets/table/e-table-config.c
@@ -38,7 +38,7 @@
#include <glib/gi18n.h>
#include "e-util/e-util-private.h"
#include "e-util/e-util.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-config.h"
#include "e-table-memory-store.h"
diff --git a/widgets/table/e-table-group-container.c b/widgets/table/e-table-group-container.c
index c342c6ca7e..f6758025ab 100644
--- a/widgets/table/e-table-group-container.c
+++ b/widgets/table/e-table-group-container.c
@@ -31,7 +31,7 @@
#include "e-util/e-util.h"
#include "misc/e-canvas-utils.h"
#include "misc/e-canvas.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-defines.h"
#include "e-table-group-container.h"
diff --git a/widgets/table/e-table-header-utils.c b/widgets/table/e-table-header-utils.c
index afcc0720e1..80b5be42ce 100644
--- a/widgets/table/e-table-header-utils.c
+++ b/widgets/table/e-table-header-utils.c
@@ -29,7 +29,7 @@
#include <gtk/gtk.h>
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-defines.h"
#include "e-table-header-utils.h"
diff --git a/widgets/table/e-table-item.c b/widgets/table/e-table-item.c
index 58d6c65f03..394679e6ef 100644
--- a/widgets/table/e-table-item.c
+++ b/widgets/table/e-table-item.c
@@ -36,8 +36,8 @@
#include <gtk/gtk.h>
#include <gdk/gdkkeysyms.h>
-#include "a11y/e-table/gal-a11y-e-table-item-factory.h"
-#include "a11y/e-table/gal-a11y-e-table-item.h"
+#include "a11y/gal-a11y-e-table-item-factory.h"
+#include "a11y/gal-a11y-e-table-item.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "misc/e-canvas.h"
diff --git a/widgets/table/e-table-utils.c b/widgets/table/e-table-utils.c
index d01d94ae28..96b6004c41 100644
--- a/widgets/table/e-table-utils.c
+++ b/widgets/table/e-table-utils.c
@@ -27,7 +27,7 @@
#include <string.h>
#include "e-util/e-util.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table-utils.h"
#include "e-table-header-utils.h"
diff --git a/widgets/table/e-table.c b/widgets/table/e-table.c
index 69a300d950..754607c376 100644
--- a/widgets/table/e-table.c
+++ b/widgets/table/e-table.c
@@ -36,13 +36,13 @@
#include <libgnomecanvas/gnome-canvas.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include "a11y/e-table/gal-a11y-e-table.h"
+#include "a11y/gal-a11y-e-table.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "misc/e-canvas.h"
#include "misc/e-canvas-background.h"
#include "misc/e-canvas-vbox.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include "e-table.h"
#include "e-table-click-to-add.h"
diff --git a/widgets/table/e-tree.c b/widgets/table/e-tree.c
index 0963229c94..08399609a0 100644
--- a/widgets/table/e-tree.c
+++ b/widgets/table/e-tree.c
@@ -30,7 +30,7 @@
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include "a11y/e-table/gal-a11y-e-tree.h"
+#include "a11y/gal-a11y-e-tree.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
#include "misc/e-canvas.h"
diff --git a/widgets/text/Makefile.am b/widgets/text/Makefile.am
index fbe03c828f..e035d8714d 100644
--- a/widgets/text/Makefile.am
+++ b/widgets/text/Makefile.am
@@ -1,7 +1,3 @@
-if OS_WIN32
-WIN32_BOOTSTRAP_LIBS = $(top_builddir)/win32/libemiscwidgets.la
-endif
-
INCLUDES = \
-I$(top_srcdir) \
-I$(top_srcdir)/widgets \
@@ -15,22 +11,29 @@ privsolib_LTLIBRARIES = libetext.la
libetext_la_SOURCES = \
e-text-model-repos.c \
e-text-model.c \
- e-text.c
+ e-text.c \
+ e-reflow.c \
+ e-reflow-model.c \
+ a11y/gal-a11y-e-text-factory.c \
+ a11y/gal-a11y-e-text.c
libetextincludedir = $(privincludedir)/text
libetextinclude_HEADERS = \
e-text-model-repos.h \
e-text-model.h \
- e-text.h
+ e-text.h \
+ e-reflow.h \
+ e-reflow-model.h \
+ a11y/gal-a11y-e-text-factory.h \
+ a11y/gal-a11y-e-text.h
libetext_la_LDFLAGS = $(NO_UNDEFINED)
libetext_la_LIBADD = \
- $(WIN32_BOOTSTRAP_LIBS) \
- $(top_builddir)/e-util/libeutil.la \
$(top_builddir)/a11y/libevolution-a11y.la \
- $(top_builddir)/widgets/table/libetable.la \
+ $(top_builddir)/e-util/libeutil.la \
+ $(top_builddir)/widgets/misc/libemiscwidgets.la \
$(E_UTIL_LIBS) \
$(GNOME_PLATFORM_LIBS) \
$(REGEX_LIBS)
diff --git a/widgets/text/a11y/gal-a11y-e-text-factory.c b/widgets/text/a11y/gal-a11y-e-text-factory.c
new file mode 100644
index 0000000000..e1f835e912
--- /dev/null
+++ b/widgets/text/a11y/gal-a11y-e-text-factory.c
@@ -0,0 +1,101 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+#include "text/e-text.h"
+#include "gal-a11y-e-text-factory.h"
+#include "gal-a11y-e-text.h"
+
+#define CS_CLASS(factory) (G_TYPE_INSTANCE_GET_CLASS ((factory), C_TYPE_STREAM, GalA11yETextFactoryClass))
+static AtkObjectFactoryClass *parent_class;
+#define PARENT_TYPE (ATK_TYPE_OBJECT_FACTORY)
+
+/* Static functions */
+
+static GType
+gal_a11y_e_text_factory_get_accessible_type (void)
+{
+ return GAL_A11Y_TYPE_E_TEXT;
+}
+
+static AtkObject*
+gal_a11y_e_text_factory_create_accessible (GObject *obj)
+{
+ AtkObject *atk_object;
+
+ g_return_val_if_fail (E_IS_TEXT (obj), NULL);
+
+ atk_object = g_object_new (GAL_A11Y_TYPE_E_TEXT, NULL);
+ atk_object_initialize (atk_object, obj);
+
+ return atk_object;
+}
+
+static void
+gal_a11y_e_text_factory_class_init (GalA11yETextFactoryClass *klass)
+{
+ AtkObjectFactoryClass *factory_class = ATK_OBJECT_FACTORY_CLASS (klass);
+
+ parent_class = g_type_class_ref (PARENT_TYPE);
+
+ factory_class->create_accessible = gal_a11y_e_text_factory_create_accessible;
+ factory_class->get_accessible_type = gal_a11y_e_text_factory_get_accessible_type;
+}
+
+static void
+gal_a11y_e_text_factory_init (GalA11yETextFactory *factory)
+{
+}
+
+/**
+ * gal_a11y_e_text_factory_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yETextFactory class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yETextFactory class.
+ **/
+GType
+gal_a11y_e_text_factory_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ GTypeInfo info = {
+ sizeof (GalA11yETextFactoryClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) gal_a11y_e_text_factory_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yETextFactory),
+ 0,
+ (GInstanceInitFunc) gal_a11y_e_text_factory_init,
+ NULL /* value_text */
+ };
+
+ type = g_type_register_static (PARENT_TYPE, "GalA11yETextFactory", &info, 0);
+ }
+
+ return type;
+}
diff --git a/widgets/text/a11y/gal-a11y-e-text-factory.h b/widgets/text/a11y/gal-a11y-e-text-factory.h
new file mode 100644
index 0000000000..ce4d4d0a65
--- /dev/null
+++ b/widgets/text/a11y/gal-a11y-e-text-factory.h
@@ -0,0 +1,50 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TEXT_FACTORY_H__
+#define __GAL_A11Y_E_TEXT_FACTORY_H__
+
+#include <glib-object.h>
+#include <atk/atkobjectfactory.h>
+
+#define GAL_A11Y_TYPE_E_TEXT_FACTORY (gal_a11y_e_text_factory_get_type ())
+#define GAL_A11Y_E_TEXT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TEXT_FACTORY, GalA11yETextFactory))
+#define GAL_A11Y_E_TEXT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TEXT_FACTORY, GalA11yETextFactoryClass))
+#define GAL_A11Y_IS_E_TEXT_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TEXT_FACTORY))
+#define GAL_A11Y_IS_E_TEXT_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TEXT_FACTORY))
+
+typedef struct _GalA11yETextFactory GalA11yETextFactory;
+typedef struct _GalA11yETextFactoryClass GalA11yETextFactoryClass;
+
+struct _GalA11yETextFactory {
+ AtkObjectFactory object;
+};
+
+struct _GalA11yETextFactoryClass {
+ AtkObjectFactoryClass parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_text_factory_get_type (void);
+
+#endif /* ! __GAL_A11Y_E_TEXT_FACTORY_H__ */
diff --git a/widgets/text/a11y/gal-a11y-e-text.c b/widgets/text/a11y/gal-a11y-e-text.c
new file mode 100644
index 0000000000..4eeb7811fc
--- /dev/null
+++ b/widgets/text/a11y/gal-a11y-e-text.c
@@ -0,0 +1,1134 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#include <config.h>
+
+#include <string.h>
+
+#include <gtk/gtk.h>
+
+#include "a11y/gal-a11y-util.h"
+#include "text/e-text.h"
+#include "text/e-text-model-repos.h"
+
+#include "gal-a11y-e-text.h"
+#include "gal-a11y-e-text-factory.h"
+
+#define CS_CLASS(a11y) (G_TYPE_INSTANCE_GET_CLASS ((a11y), C_TYPE_STREAM, GalA11yETextClass))
+static GObjectClass *parent_class;
+static AtkComponentIface *component_parent_iface;
+static GType parent_type;
+static gint priv_offset;
+static GQuark quark_accessible_object = 0;
+#define GET_PRIVATE(object) ((GalA11yETextPrivate *) (((char *) object) + priv_offset))
+#define PARENT_TYPE (parent_type)
+
+struct _GalA11yETextPrivate {
+ int dummy;
+};
+
+static void
+et_dispose (GObject *object)
+{
+ if (parent_class->dispose)
+ parent_class->dispose (object);
+}
+
+/* Static functions */
+
+static void
+et_get_extents (AtkComponent *component,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coord_type)
+{
+ EText *item = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (component)));
+ double real_width;
+ double real_height;
+ int fake_width;
+ int fake_height;
+
+ if (component_parent_iface &&
+ component_parent_iface->get_extents)
+ component_parent_iface->get_extents (component,
+ x,
+ y,
+ &fake_width,
+ &fake_height,
+ coord_type);
+
+ g_object_get (item,
+ "text_width", &real_width,
+ "text_height", &real_height,
+ NULL);
+
+ if (width)
+ *width = real_width;
+ if (height)
+ *height = real_height;
+}
+
+static const gchar *
+et_get_full_text (AtkText *text)
+{
+ EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)));
+ ETextModel *model;
+ const char *full_text;
+
+ g_object_get (etext, "model", &model, NULL);
+
+ full_text = e_text_model_get_text (model);
+
+ return full_text;
+}
+
+static void
+et_set_full_text (AtkEditableText *text,
+ const char *full_text)
+{
+ EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)));
+ ETextModel *model;
+
+ g_object_get (etext, "model", &model, NULL);
+
+ e_text_model_set_text (model, full_text);
+}
+
+static gchar *
+et_get_text (AtkText *text,
+ gint start_offset,
+ gint end_offset)
+{
+ gint start, end, real_start, real_end, len;
+ const char *full_text = et_get_full_text (text);
+ if (full_text == NULL)
+ return NULL;
+ len = g_utf8_strlen (full_text, -1);
+
+ start = MIN (MAX (0, start_offset), len);
+ end = MIN (MAX (-1, end_offset), len);
+
+ if (end_offset == -1)
+ end = strlen (full_text);
+ else
+ end = g_utf8_offset_to_pointer (full_text, end) - full_text;
+
+ start = g_utf8_offset_to_pointer (full_text, start) - full_text;
+
+ real_start = MIN (start, end);
+ real_end = MAX (start, end);
+
+ return g_strndup (full_text + real_start, real_end - real_start);
+}
+
+static gboolean
+is_a_seperator (gunichar c)
+{
+ return g_unichar_ispunct(c) || g_unichar_isspace(c);
+}
+
+static gint
+find_word_start (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset;
+ char *at_offset;
+ gunichar current, previous;
+ gint len;
+
+ offset = begin_offset;
+ len = g_utf8_strlen (text, -1);
+
+ while (offset > 0 && offset < len) {
+ at_offset = g_utf8_offset_to_pointer (text, offset);
+ current = g_utf8_get_char_validated (at_offset, -1);
+ at_offset = g_utf8_offset_to_pointer (text, offset-1);
+ previous = g_utf8_get_char_validated (at_offset, -1);
+ if ((! is_a_seperator (current)) && is_a_seperator (previous))
+ break;
+ offset += step;
+ }
+
+ return offset;
+}
+
+static gint
+find_word_end (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset;
+ char *at_offset;
+ gunichar current, previous;
+ gint len;
+
+ offset = begin_offset;
+ len = g_utf8_strlen (text, -1);
+
+ while (offset > 0 && offset < len) {
+ at_offset = g_utf8_offset_to_pointer (text, offset);
+ current = g_utf8_get_char_validated (at_offset, -1);
+ at_offset = g_utf8_offset_to_pointer (text, offset-1);
+ previous = g_utf8_get_char_validated (at_offset, -1);
+ if (is_a_seperator (current) && (! is_a_seperator (previous)))
+ break;
+ offset += step;
+ }
+
+ return offset;
+}
+
+static gint
+find_sentence_start (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset, last_word_end, len;
+ char *at_offset;
+ gunichar ch;
+ int i;
+
+ offset = find_word_start (text, begin_offset, step);
+ len = g_utf8_strlen (text, -1);
+
+ while (offset>0 && offset <len) {
+ last_word_end = find_word_end (text, offset - 1, -1);
+ if (last_word_end == 0)
+ break;
+ for (i = last_word_end; i < offset; i++) {
+ at_offset = g_utf8_offset_to_pointer (text, i);
+ ch = g_utf8_get_char_validated (at_offset, -1);
+ if (ch == '.' || ch == '!' || ch == '?')
+ return offset;
+ }
+
+ offset = find_word_start (text, offset + step, step);
+ }
+
+ return offset;
+}
+
+static gint
+find_sentence_end (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset;
+ char *at_offset;
+ gunichar previous;
+ gint len;
+
+ offset = begin_offset;
+ len = g_utf8_strlen (text, -1);
+
+ while (offset > 0 && offset < len) {
+ at_offset = g_utf8_offset_to_pointer (text, offset - 1);
+ previous = g_utf8_get_char_validated (at_offset, -1);
+ if (previous == '.' || previous == '!' || previous == '?')
+ break;
+ offset += step;
+ }
+
+ return offset;
+}
+
+static gint
+find_line_start (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset;
+ char *at_offset;
+ gunichar previous;
+ gint len;
+
+ offset = begin_offset;
+ len = g_utf8_strlen (text, -1);
+
+ while (offset > 0 && offset < len) {
+ at_offset = g_utf8_offset_to_pointer (text, offset - 1);
+ previous = g_utf8_get_char_validated (at_offset, -1);
+ if (previous == '\n' || previous == '\r')
+ break;
+ offset += step;
+ }
+
+ return offset;
+}
+
+static gint
+find_line_end (const char *text,
+ gint begin_offset,
+ gint step)
+{
+ gint offset;
+ char *at_offset;
+ gunichar current;
+ gint len;
+
+ offset = begin_offset;
+ len = g_utf8_strlen (text, -1);
+
+ while (offset >= 0 && offset < len) {
+ at_offset = g_utf8_offset_to_pointer (text, offset);
+ current = g_utf8_get_char_validated (at_offset, -1);
+ if (current == '\n' || current == '\r')
+ break;
+ offset += step;
+ }
+
+ return offset;
+}
+
+static gchar *
+et_get_text_after_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ gint start, end, len;
+ const char *full_text = et_get_full_text (text);
+ g_return_val_if_fail (full_text, NULL);
+
+ switch (boundary_type)
+ {
+ case ATK_TEXT_BOUNDARY_CHAR:
+ start = offset + 1;
+ end = offset + 2;
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_START:
+ start = find_word_start (full_text, offset + 1, 1);
+ end = find_word_start (full_text, start + 1, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_END:
+ start = find_word_end (full_text, offset + 1, 1);
+ end = find_word_end (full_text, start + 1, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_START:
+ start = find_sentence_start (full_text, offset + 1, 1);
+ end = find_sentence_start (full_text, start + 1, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_END:
+ start = find_sentence_end (full_text, offset + 1, 1);
+ end = find_sentence_end (full_text, start + 1, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ start = find_line_start (full_text, offset + 1, 1);
+ end = find_line_start (full_text, start + 1, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_END:
+ start = find_line_end (full_text, offset + 1, 1);
+ end = find_line_end (full_text, start + 1, 1);
+ break;
+ default:
+ return NULL;
+ }
+
+ len = g_utf8_strlen (full_text, -1);
+ if (start_offset)
+ *start_offset = MIN (MAX (0, start), len);
+ if (end_offset)
+ *end_offset = MIN (MAX (0, end), len);
+ return et_get_text (text, start, end);
+}
+
+static gchar *
+et_get_text_at_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ gint start, end, len;
+ const char *full_text = et_get_full_text (text);
+ g_return_val_if_fail (full_text, NULL);
+
+ switch (boundary_type)
+ {
+ case ATK_TEXT_BOUNDARY_CHAR:
+ start = offset;
+ end = offset + 1;
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_START:
+ start = find_word_start (full_text, offset - 1, -1);
+ end = find_word_start (full_text, offset, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_END:
+ start = find_word_end (full_text, offset, -1);
+ end = find_word_end (full_text, offset + 1, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_START:
+ start = find_sentence_start (full_text, offset - 1, -1);
+ end = find_sentence_start (full_text, offset, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_END:
+ start = find_sentence_end (full_text, offset, -1);
+ end = find_sentence_end (full_text, offset + 1, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ start = find_line_start (full_text, offset - 1, -1);
+ end = find_line_start (full_text, offset, 1);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_END:
+ start = find_line_end (full_text, offset, -1);
+ end = find_line_end (full_text, offset + 1, 1);
+ break;
+ default:
+ return NULL;
+ }
+
+ len = g_utf8_strlen (full_text, -1);
+ if (start_offset)
+ *start_offset = MIN (MAX (0, start), len);
+ if (end_offset)
+ *end_offset = MIN (MAX (0, end), len);
+ return et_get_text (text, start, end);
+}
+
+static gunichar
+et_get_character_at_offset (AtkText *text,
+ gint offset)
+{
+ const char *full_text = et_get_full_text (text);
+ char *at_offset;
+
+ at_offset = g_utf8_offset_to_pointer (full_text, offset);
+ return g_utf8_get_char_validated (at_offset, -1);
+}
+
+
+static gchar*
+et_get_text_before_offset (AtkText *text,
+ gint offset,
+ AtkTextBoundary boundary_type,
+ gint *start_offset,
+ gint *end_offset)
+{
+ gint start, end, len;
+ const char *full_text = et_get_full_text (text);
+ g_return_val_if_fail (full_text, NULL);
+
+ switch (boundary_type)
+ {
+ case ATK_TEXT_BOUNDARY_CHAR:
+ start = offset - 1;
+ end = offset;
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_START:
+ end = find_word_start (full_text, offset - 1, -1);
+ start = find_word_start (full_text, end - 1, -1) ;
+ break;
+ case ATK_TEXT_BOUNDARY_WORD_END:
+ end = find_word_end (full_text, offset, -1);
+ start = find_word_end (full_text, end - 1, -1);
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_START:
+ end = find_sentence_start (full_text, offset, -1);
+ start = find_sentence_start (full_text, end - 1, -1);
+ break;
+ case ATK_TEXT_BOUNDARY_SENTENCE_END:
+ end = find_sentence_end (full_text, offset, -1);
+ start = find_sentence_end (full_text, end - 1, -1);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_START:
+ end = find_line_start (full_text, offset, -1);
+ start = find_line_start (full_text, end - 1, -1);
+ break;
+ case ATK_TEXT_BOUNDARY_LINE_END:
+ end = find_line_end (full_text, offset, -1);
+ start = find_line_end (full_text, end - 1, -1);
+ break;
+ default:
+ return NULL;
+ }
+
+ len = g_utf8_strlen (full_text, -1);
+ if (start_offset)
+ *start_offset = MIN (MAX (0, start), len);
+ if (end_offset)
+ *end_offset = MIN (MAX (0, end), len);
+ return et_get_text (text, start, end);
+}
+
+static gint
+et_get_caret_offset (AtkText *text)
+{
+ GObject *obj;
+ EText *etext;
+ int offset;
+
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE(text), -1);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return -1;
+
+ g_return_val_if_fail (E_IS_TEXT (obj), -1);
+ etext = E_TEXT (obj);
+
+ g_object_get (etext, "cursor_pos", &offset, NULL);
+ return offset;
+}
+
+
+static AtkAttributeSet*
+et_get_run_attributes (AtkText *text,
+ gint offset,
+ gint *start_offset,
+ gint *end_offset)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+
+static AtkAttributeSet*
+et_get_default_attributes (AtkText *text)
+{
+ /* Unimplemented */
+ return NULL;
+}
+
+
+static void
+et_get_character_extents (AtkText *text,
+ gint offset,
+ gint *x,
+ gint *y,
+ gint *width,
+ gint *height,
+ AtkCoordType coords)
+{
+ GObject *obj;
+ EText *etext;
+ GnomeCanvas *canvas;
+ gint x_widget, y_widget, x_window, y_window;
+ GdkWindow *window;
+ GtkWidget *widget;
+ PangoRectangle pango_pos;
+
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE(text));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return;
+ g_return_if_fail (E_IS_TEXT (obj));
+ etext = E_TEXT(obj);
+ canvas = GNOME_CANVAS_ITEM(etext)->canvas;
+ widget = GTK_WIDGET(canvas);
+ window = widget->window;
+ gdk_window_get_origin (window, &x_widget, &y_widget);
+
+ pango_layout_index_to_pos (etext->layout, offset, &pango_pos);
+ pango_pos.x = PANGO_PIXELS (pango_pos.x);
+ pango_pos.y = PANGO_PIXELS (pango_pos.y);
+ pango_pos.width = (pango_pos.width + PANGO_SCALE / 2) / PANGO_SCALE;
+ pango_pos.height = (pango_pos.height + PANGO_SCALE / 2) / PANGO_SCALE;
+
+ *x = pango_pos.x + x_widget;
+ *y = pango_pos.y + y_widget;
+
+ *width = pango_pos.width;
+ *height = pango_pos.height;
+
+ if (etext->draw_borders) {
+ *x += 3; /*BORDER_INDENT;*/
+ *y += 3; /*BORDER_INDENT;*/
+ }
+
+ *x += etext->xofs;
+ *y += etext->yofs;
+
+ if (etext->editing) {
+ *x -= etext->xofs_edit;
+ *y -= etext->yofs_edit;
+ }
+
+ *x += etext->cx;
+ *y += etext->cy;
+
+ if (coords == ATK_XY_WINDOW) {
+ window = gdk_window_get_toplevel (window);
+ gdk_window_get_origin (window, &x_window, &y_window);
+ *x -= x_window;
+ *y -= y_window;
+ }
+ else if (coords == ATK_XY_SCREEN) {
+ }
+ else {
+ *x = 0;
+ *y = 0;
+ *height = 0;
+ *width = 0;
+ }
+}
+
+
+static gint
+et_get_character_count (AtkText *text)
+{
+ const char *full_text = et_get_full_text (text);
+
+ return g_utf8_strlen (full_text, -1);
+}
+
+
+static gint
+et_get_offset_at_point (AtkText *text,
+ gint x,
+ gint y,
+ AtkCoordType coords)
+{
+ GObject *obj;
+ EText *etext;
+ GnomeCanvas *canvas;
+ gint x_widget, y_widget, x_window, y_window;
+ GdkWindow *window;
+ GtkWidget *widget;
+ int index;
+ int trailing;
+
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE(text), -1);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return -1;
+ g_return_val_if_fail (E_IS_TEXT (obj), -1);
+ etext = E_TEXT(obj);
+ canvas = GNOME_CANVAS_ITEM(etext)->canvas;
+ widget = GTK_WIDGET(canvas);
+ window = widget->window;
+ gdk_window_get_origin (window, &x_widget, &y_widget);
+
+ if (coords == ATK_XY_SCREEN) {
+ x = x - x_widget;
+ y = y - y_widget;
+ }
+ else if (coords == ATK_XY_WINDOW) {
+ window = gdk_window_get_toplevel (window);
+ gdk_window_get_origin (window, &x_window, &y_window);
+ x = x - x_widget + x_window;
+ y = y - y_widget + y_window;
+ }
+ else
+ return -1;
+
+ if (etext->draw_borders) {
+ x -= 3; /*BORDER_INDENT;*/
+ y -= 3; /*BORDER_INDENT;*/
+ }
+
+ x -= etext->xofs;
+ y -= etext->yofs;
+
+ if (etext->editing) {
+ x += etext->xofs_edit;
+ y += etext->yofs_edit;
+ }
+
+ x -= etext->cx;
+ y -= etext->cy;
+
+ pango_layout_xy_to_index (etext->layout,
+ x * PANGO_SCALE - PANGO_SCALE / 2,
+ y * PANGO_SCALE - PANGO_SCALE / 2,
+ &index,
+ &trailing);
+
+ return g_utf8_pointer_to_offset (etext->text, etext->text + index + trailing);
+}
+
+
+static gint
+et_get_n_selections (AtkText *text)
+{
+ EText *etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)));
+ if (etext->selection_start !=
+ etext->selection_end)
+ return 1;
+ return 0;
+}
+
+
+static gchar*
+et_get_selection (AtkText *text,
+ gint selection_num,
+ gint *start_offset,
+ gint *end_offset)
+{
+ gint start, end, real_start, real_end, len;
+ EText *etext;
+ if (selection_num == 0) {
+ const char *full_text = et_get_full_text (text);
+ if (full_text == NULL)
+ return NULL;
+ len = g_utf8_strlen (full_text, -1);
+ etext = E_TEXT (atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text)));
+ start = MIN (etext->selection_start, etext->selection_end);
+ end = MAX (etext->selection_start, etext->selection_end);
+ start = MIN (MAX (0, start), len);
+ end = MIN (MAX (0, end), len);
+ if (start != end) {
+ if (start_offset)
+ *start_offset = start;
+ if (end_offset)
+ *end_offset = end;
+ real_start = g_utf8_offset_to_pointer (full_text, start) - full_text;
+ real_end = g_utf8_offset_to_pointer (full_text, end) - full_text;
+ return g_strndup (full_text + real_start, real_end - real_start);
+ }
+ }
+
+ return NULL;
+}
+
+
+static gboolean
+et_add_selection (AtkText *text,
+ gint start_offset,
+ gint end_offset)
+{
+ GObject *obj;
+ EText *etext;
+
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return FALSE;
+ g_return_val_if_fail (E_IS_TEXT (obj), FALSE);
+ etext = E_TEXT (obj);
+
+ g_return_val_if_fail (start_offset >= 0, FALSE);
+ g_return_val_if_fail (start_offset >= -1, FALSE);
+ if (end_offset == -1)
+ end_offset = et_get_character_count (text);
+
+ if (start_offset != end_offset) {
+ gint real_start, real_end;
+ real_start = MIN (start_offset, end_offset);
+ real_end = MAX (start_offset, end_offset);
+ etext->selection_start = real_start;
+ etext->selection_end = real_end;
+
+ gnome_canvas_item_grab_focus (GNOME_CANVAS_ITEM (etext));
+ gnome_canvas_item_request_update (GNOME_CANVAS_ITEM (etext));
+
+ g_signal_emit_by_name (ATK_OBJECT (text), "text_selection_changed");
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+et_remove_selection (AtkText *text,
+ gint selection_num)
+{
+ GObject *obj;
+ EText *etext;
+
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return FALSE;
+ g_return_val_if_fail (E_IS_TEXT (obj), FALSE);
+ etext = E_TEXT (obj);
+
+ if (selection_num == 0
+ && etext->selection_start != etext->selection_end) {
+ etext->selection_end = etext->selection_start;
+ g_signal_emit_by_name (ATK_OBJECT(text), "text_selection_changed");
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
+et_set_selection (AtkText *text,
+ gint selection_num,
+ gint start_offset,
+ gint end_offset)
+{
+ GObject *obj;
+
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return FALSE;
+ g_return_val_if_fail (E_IS_TEXT (obj), FALSE);
+ if (selection_num == 0)
+ return et_add_selection (text, start_offset, end_offset);
+ return FALSE;
+}
+
+
+static gboolean
+et_set_caret_offset (AtkText *text,
+ gint offset)
+{
+ GObject *obj;
+ EText *etext;
+
+ g_return_val_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text), FALSE);
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return FALSE;
+
+ g_return_val_if_fail (E_IS_TEXT (obj), FALSE);
+ etext = E_TEXT (obj);
+
+ if (offset < -1)
+ return FALSE;
+ else {
+ ETextEventProcessorCommand command;
+
+ if (offset == -1)
+ offset = et_get_character_count (text);
+
+ command.action = E_TEP_MOVE;
+ command.position = E_TEP_VALUE;
+ command.value = offset;
+ command.time = GDK_CURRENT_TIME;
+ g_signal_emit_by_name (etext->tep, "command", &command);
+ return TRUE;
+ }
+}
+
+static gboolean
+et_set_run_attributes (AtkEditableText *text,
+ AtkAttributeSet *attrib_set,
+ gint start_offset,
+ gint end_offset)
+{
+ /* Unimplemented */
+ return FALSE;
+}
+
+static void
+et_set_text_contents (AtkEditableText *text,
+ const gchar *string)
+{
+ et_set_full_text (text, string);
+}
+
+static void
+et_insert_text (AtkEditableText *text,
+ const gchar *string,
+ gint length,
+ gint *position)
+{
+ /* Utf8 unimplemented */
+ char *result;
+
+ const char *full_text = et_get_full_text (ATK_TEXT (text));
+ if (full_text == NULL)
+ return;
+
+ result = g_strdup_printf ("%.*s%.*s%s", *position, full_text, length, string, full_text + *position);
+
+ et_set_full_text (text, result);
+
+ *position += length;
+
+ g_free (result);
+}
+
+static void
+et_copy_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GObject *obj;
+ EText *etext;
+
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return;
+
+ g_return_if_fail (E_IS_TEXT (obj));
+ etext = E_TEXT (obj);
+
+ if (start_pos != end_pos) {
+ etext->selection_start = start_pos;
+ etext->selection_end = end_pos;
+ e_text_copy_clipboard (etext);
+ }
+}
+
+static void
+et_delete_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ GObject *obj;
+ EText *etext;
+
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE(text));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return;
+
+ g_return_if_fail (E_IS_TEXT (obj));
+ etext = E_TEXT (obj);
+
+ etext->selection_start = start_pos;
+ etext->selection_end = end_pos;
+
+ e_text_delete_selection (etext);
+}
+
+static void
+et_cut_text (AtkEditableText *text,
+ gint start_pos,
+ gint end_pos)
+{
+ et_copy_text (text, start_pos, end_pos);
+ et_delete_text (text, start_pos, end_pos);
+}
+
+static void
+et_paste_text (AtkEditableText *text,
+ gint position)
+{
+ GObject *obj;
+ EText *etext;
+
+ g_return_if_fail (ATK_IS_GOBJECT_ACCESSIBLE (text));
+ obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (text));
+ if (obj == NULL)
+ return;
+
+ g_return_if_fail (E_IS_TEXT (obj));
+ etext = E_TEXT (obj);
+
+ g_object_set (etext, "cursor_pos", position, NULL);
+ e_text_paste_clipboard (etext);
+}
+
+static void
+et_atk_component_iface_init (AtkComponentIface *iface)
+{
+ iface->get_extents = et_get_extents;
+}
+
+static void
+et_atk_text_iface_init (AtkTextIface *iface)
+{
+ iface->get_text = et_get_text;
+ iface->get_text_after_offset = et_get_text_after_offset;
+ iface->get_text_at_offset = et_get_text_at_offset;
+ iface->get_character_at_offset = et_get_character_at_offset;
+ iface->get_text_before_offset = et_get_text_before_offset;
+ iface->get_caret_offset = et_get_caret_offset;
+ iface->get_run_attributes = et_get_run_attributes;
+ iface->get_default_attributes = et_get_default_attributes;
+ iface->get_character_extents = et_get_character_extents;
+ iface->get_character_count = et_get_character_count;
+ iface->get_offset_at_point = et_get_offset_at_point;
+ iface->get_n_selections = et_get_n_selections;
+ iface->get_selection = et_get_selection;
+ iface->add_selection = et_add_selection;
+ iface->remove_selection = et_remove_selection;
+ iface->set_selection = et_set_selection;
+ iface->set_caret_offset = et_set_caret_offset;
+}
+
+static void
+et_atk_editable_text_iface_init (AtkEditableTextIface *iface)
+{
+ iface->set_run_attributes = et_set_run_attributes;
+ iface->set_text_contents = et_set_text_contents;
+ iface->insert_text = et_insert_text;
+ iface->copy_text = et_copy_text;
+ iface->cut_text = et_cut_text;
+ iface->delete_text = et_delete_text;
+ iface->paste_text = et_paste_text;
+}
+
+static void
+_et_reposition_cb (ETextModel *model,
+ ETextModelReposFn fn,
+ gpointer repos_data,
+ gpointer user_data)
+{
+ AtkObject *accessible;
+ AtkText *text;
+
+ accessible = ATK_OBJECT (user_data);
+ text = ATK_TEXT (accessible);
+
+ if (fn == e_repos_delete_shift) {
+ EReposDeleteShift *info = (EReposDeleteShift *) repos_data;
+ g_signal_emit_by_name (text, "text-changed::delete", info->pos, info->len);
+ }
+ else if (fn == e_repos_insert_shift) {
+ EReposInsertShift *info = (EReposInsertShift *) repos_data;
+ g_signal_emit_by_name (text, "text-changed::insert", info->pos, info->len);
+ }
+}
+
+static void
+_et_command_cb (ETextEventProcessor *tep,
+ ETextEventProcessorCommand *command,
+ gpointer user_data)
+{
+ AtkObject *accessible;
+ AtkText *text;
+
+ accessible = ATK_OBJECT (user_data);
+ text = ATK_TEXT (accessible);
+
+ switch (command->action) {
+ case E_TEP_MOVE:
+ g_signal_emit_by_name (text, "text-caret-moved", et_get_caret_offset (text));
+ break;
+ case E_TEP_SELECT:
+ g_signal_emit_by_name (text, "text-selection-changed");
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+et_real_initialize (AtkObject *obj,
+ gpointer data)
+{
+ EText *etext;
+
+ ATK_OBJECT_CLASS (parent_class)->initialize (obj, data);
+
+ g_return_if_fail (GAL_A11Y_IS_E_TEXT (obj));
+ g_return_if_fail (E_IS_TEXT (data));
+
+ etext = E_TEXT (data);
+
+ /* Set up signal callbacks */
+ g_signal_connect (etext->model, "reposition",
+ G_CALLBACK (_et_reposition_cb), obj);
+
+ if (etext->tep)
+ g_signal_connect_after (etext->tep, "command",
+ (GCallback) _et_command_cb, obj);
+
+ obj->role = ATK_ROLE_TEXT;
+}
+
+static void
+et_class_init (GalA11yETextClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ AtkObjectClass *atk_class = ATK_OBJECT_CLASS (klass);
+
+ quark_accessible_object = g_quark_from_static_string ("gtk-accessible-object");
+ parent_class = g_type_class_ref (PARENT_TYPE);
+ component_parent_iface = g_type_interface_peek(parent_class, ATK_TYPE_COMPONENT);
+ object_class->dispose = et_dispose;
+ atk_class->initialize = et_real_initialize;
+}
+
+static void
+et_init (GalA11yEText *a11y)
+{
+#if 0
+ GalA11yETextPrivate *priv;
+
+ priv = GET_PRIVATE (a11y);
+#endif
+}
+
+/**
+ * gal_a11y_e_text_get_type:
+ * @void:
+ *
+ * Registers the &GalA11yEText class if necessary, and returns the type ID
+ * associated to it.
+ *
+ * Return value: The type ID of the &GalA11yEText class.
+ **/
+GType
+gal_a11y_e_text_get_type (void)
+{
+ static GType type = 0;
+
+ if (!type) {
+ AtkObjectFactory *factory;
+
+ GTypeInfo info = {
+ sizeof (GalA11yETextClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) et_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (GalA11yEText),
+ 0,
+ (GInstanceInitFunc) et_init,
+ NULL /* value_text */
+ };
+
+ static const GInterfaceInfo atk_component_info = {
+ (GInterfaceInitFunc) et_atk_component_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+ static const GInterfaceInfo atk_text_info = {
+ (GInterfaceInitFunc) et_atk_text_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+ static const GInterfaceInfo atk_editable_text_info = {
+ (GInterfaceInitFunc) et_atk_editable_text_iface_init,
+ (GInterfaceFinalizeFunc) NULL,
+ NULL
+ };
+
+ factory = atk_registry_get_factory (atk_get_default_registry (), GNOME_TYPE_CANVAS_ITEM);
+ parent_type = atk_object_factory_get_accessible_type (factory);
+
+ type = gal_a11y_type_register_static_with_private (PARENT_TYPE, "GalA11yEText", &info, 0,
+ sizeof (GalA11yETextPrivate), &priv_offset);
+
+ g_type_add_interface_static (type, ATK_TYPE_COMPONENT, &atk_component_info);
+ g_type_add_interface_static (type, ATK_TYPE_TEXT, &atk_text_info);
+ g_type_add_interface_static (type, ATK_TYPE_EDITABLE_TEXT, &atk_editable_text_info);
+ }
+
+ return type;
+}
+
+void
+gal_a11y_e_text_init (void)
+{
+ if (atk_get_root ())
+ atk_registry_set_factory_type (atk_get_default_registry (),
+ E_TYPE_TEXT,
+ gal_a11y_e_text_factory_get_type ());
+
+}
+
diff --git a/widgets/text/a11y/gal-a11y-e-text.h b/widgets/text/a11y/gal-a11y-e-text.h
new file mode 100644
index 0000000000..5cebd0ff83
--- /dev/null
+++ b/widgets/text/a11y/gal-a11y-e-text.h
@@ -0,0 +1,57 @@
+/*
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) version 3.
+ *
+ * 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with the program; if not, see <http://www.gnu.org/licenses/>
+ *
+ *
+ * Authors:
+ * Christopher James Lahey <clahey@ximian.com>
+ *
+ * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
+ *
+ */
+
+#ifndef __GAL_A11Y_E_TEXT_H__
+#define __GAL_A11Y_E_TEXT_H__
+
+#include <glib-object.h>
+#include <table/e-table-item.h>
+
+#define GAL_A11Y_TYPE_E_TEXT (gal_a11y_e_text_get_type ())
+#define GAL_A11Y_E_TEXT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GAL_A11Y_TYPE_E_TEXT, GalA11yEText))
+#define GAL_A11Y_E_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GAL_A11Y_TYPE_E_TEXT, GalA11yETextClass))
+#define GAL_A11Y_IS_E_TEXT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GAL_A11Y_TYPE_E_TEXT))
+#define GAL_A11Y_IS_E_TEXT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GAL_A11Y_TYPE_E_TEXT))
+
+typedef struct _GalA11yEText GalA11yEText;
+typedef struct _GalA11yETextClass GalA11yETextClass;
+typedef struct _GalA11yETextPrivate GalA11yETextPrivate;
+
+/* This struct should actually be larger as this isn't what we derive from.
+ * The GalA11yETextPrivate comes right after the parent class structure.
+ **/
+struct _GalA11yEText {
+ AtkObject object;
+};
+
+struct _GalA11yETextClass {
+ AtkObject parent_class;
+};
+
+
+/* Standard Glib function */
+GType gal_a11y_e_text_get_type (void);
+
+void gal_a11y_e_text_init (void);
+
+#endif /* ! __GAL_A11Y_E_TEXT_H__ */
diff --git a/widgets/misc/e-reflow-model.c b/widgets/text/e-reflow-model.c
index eae3d43324..eae3d43324 100644
--- a/widgets/misc/e-reflow-model.c
+++ b/widgets/text/e-reflow-model.c
diff --git a/widgets/misc/e-reflow-model.h b/widgets/text/e-reflow-model.h
index 7482e5079f..7482e5079f 100644
--- a/widgets/misc/e-reflow-model.h
+++ b/widgets/text/e-reflow-model.h
diff --git a/widgets/misc/e-reflow.c b/widgets/text/e-reflow.c
index f51a502a83..c17b970a23 100644
--- a/widgets/misc/e-reflow.c
+++ b/widgets/text/e-reflow.c
@@ -30,12 +30,12 @@
#include "text/e-text.h"
#include <glib/gi18n.h>
#include "e-util/e-util.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
-#include "e-canvas.h"
-#include "e-canvas-utils.h"
+#include "misc/e-canvas.h"
+#include "misc/e-canvas-utils.h"
#include "e-reflow.h"
-#include "e-selection-model-simple.h"
+#include "misc/e-selection-model-simple.h"
static gboolean e_reflow_event (GnomeCanvasItem *item, GdkEvent *event);
static void e_reflow_realize (GnomeCanvasItem *item);
diff --git a/widgets/misc/e-reflow.h b/widgets/text/e-reflow.h
index 6d67369209..afdc9edb67 100644
--- a/widgets/misc/e-reflow.h
+++ b/widgets/text/e-reflow.h
@@ -24,7 +24,7 @@
#define __E_REFLOW_H__
#include <libgnomecanvas/gnome-canvas.h>
-#include <misc/e-reflow-model.h>
+#include <text/e-reflow-model.h>
#include <misc/e-selection-model.h>
#include <e-util/e-sorter-array.h>
diff --git a/widgets/text/e-text.c b/widgets/text/e-text.c
index 0890b46243..3ce0065210 100644
--- a/widgets/text/e-text.c
+++ b/widgets/text/e-text.c
@@ -46,10 +46,10 @@
#include <gtk/gtk.h>
#include <libgnomecanvas/gnome-canvas-rect-ellipse.h>
-#include "a11y/e-text/gal-a11y-e-text.h"
+#include "a11y/gal-a11y-e-text.h"
#include "misc/e-canvas.h"
#include "misc/e-canvas-utils.h"
-#include "misc/e-unicode.h"
+#include "e-util/e-unicode.h"
#include <glib/gi18n.h>
#include "e-util/e-text-event-processor-emacs-like.h"
#include "e-util/e-util.h"