aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--a11y/ChangeLog9
-rw-r--r--a11y/widgets/Makefile.am11
-rw-r--r--a11y/widgets/ea-calendar-cell.c305
-rw-r--r--a11y/widgets/ea-calendar-cell.h92
-rw-r--r--a11y/widgets/ea-calendar-item.c1096
-rw-r--r--a11y/widgets/ea-calendar-item.h12
-rw-r--r--a11y/widgets/ea-widgets.c2
7 files changed, 1518 insertions, 9 deletions
diff --git a/a11y/ChangeLog b/a11y/ChangeLog
index 0f22cd70bb..abfb372bd2 100644
--- a/a11y/ChangeLog
+++ b/a11y/ChangeLog
@@ -1,3 +1,12 @@
+2003-11-11 Bolian Yin <bolian.yin@sun.com>
+
+ Fixes #50538
+
+ * new files:
+ widgets/ea-calendar-cell.[hc]
+
+ * widgets/ea-calendar-item: impl. atk selection and atk table interface. * widgets/Makefile.am : use shared object library (.so)
+
2003-11-07 JP Rosevear <jpr@ximian.com>
* calendar/Makefile.am (INCLUDES): don't include toplevel libical
diff --git a/a11y/widgets/Makefile.am b/a11y/widgets/Makefile.am
index c6b0ea2221..0fb3e11b43 100644
--- a/a11y/widgets/Makefile.am
+++ b/a11y/widgets/Makefile.am
@@ -1,5 +1,8 @@
-noinst_LTLIBRARIES = libevolution-widgets-a11y.la
+# for debug
+#A11Y_CFLAGS += -pedantic -ansi -DACC_DEBUG -Werror
+
+privlib_LTLIBRARIES = libevolution-widgets-a11y.la
INCLUDES = \
-DG_LOG_DOMAIN=\"evolution-a11y\" \
@@ -19,5 +22,11 @@ INCLUDES = \
libevolution_widgets_a11y_la_SOURCES = \
ea-calendar-item.c \
ea-calendar-item.h \
+ ea-calendar-cell.c \
+ ea-calendar-cell.h \
ea-widgets.c \
ea-widgets.h
+
+libevolution_widgets_a11y_la_LIBADD = \
+ $(top_builddir)/a11y/libevolution-a11y.la
+
diff --git a/a11y/widgets/ea-calendar-cell.c b/a11y/widgets/ea-calendar-cell.c
new file mode 100644
index 0000000000..4b0fe75156
--- /dev/null
+++ b/a11y/widgets/ea-calendar-cell.c
@@ -0,0 +1,305 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+/* Evolution Accessibility: ea-calendar-cell.c
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Bolian Yin <bolian.yin@sun.com> Sun Microsystem Inc., 2003
+ *
+ */
+
+#include "ea-calendar-cell.h"
+#include "ea-calendar-item.h"
+#include "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 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);
+
+/* 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 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) NULL, /* 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;
+}
+
+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)
+{
+ ++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));
+}
+
+/* Atk Component Interface */
+
+static void
+atk_component_interface_init (AtkComponentIface *iface)
+{
+ g_return_if_fail (iface != NULL);
+
+ iface->get_extents = component_interface_get_extents;
+}
+
+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;
+}
diff --git a/a11y/widgets/ea-calendar-cell.h b/a11y/widgets/ea-calendar-cell.h
new file mode 100644
index 0000000000..f87ede90a7
--- /dev/null
+++ b/a11y/widgets/ea-calendar-cell.h
@@ -0,0 +1,92 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/* vim:expandtab:shiftwidth=8:tabstop=8:
+ */
+/* Evolution Accessibility: ea-calendar-cell.h
+ *
+ * Copyright (C) 2003 Ximian, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of version 2 of the GNU General Public
+ * License as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Bolian Yin <bolian.yin@sun.com> Sun Microsystem Inc., 2003
+ *
+ */
+
+#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;
+};
+
+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/a11y/widgets/ea-calendar-item.c b/a11y/widgets/ea-calendar-item.c
index fee92e27d7..b0d366e089 100644
--- a/a11y/widgets/ea-calendar-item.c
+++ b/a11y/widgets/ea-calendar-item.c
@@ -24,15 +24,109 @@
*/
#include <stdio.h>
+#include <time.h>
#include <string.h>
#include <libgnomecanvas/gnome-canvas.h>
#include <glib/gdate.h>
#include "ea-calendar-item.h"
+#include "ea-calendar-cell.h"
+#include "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);
+
+/* 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);
+static void selection_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);
+
+#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;
@@ -44,7 +138,6 @@ ea_calendar_item_get_type (void)
GTypeQuery query;
GType derived_atk_type;
-
if (!type) {
static GTypeInfo tinfo = {
sizeof (EaCalendarItemClass),
@@ -59,6 +152,17 @@ ea_calendar_item_get_type (void)
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)
@@ -74,6 +178,10 @@ ea_calendar_item_get_type (void)
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;
@@ -82,12 +190,17 @@ ea_calendar_item_get_type (void)
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->get_n_children = ea_calendar_item_get_n_children;
+ class->ref_child = ea_calendar_item_ref_child;
}
AtkObject*
@@ -100,13 +213,46 @@ ea_calendar_item_new (GObject *obj)
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;
+ atk_object->role = ATK_ROLE_TABLE;
#ifdef ACC_DEBUG
- g_print ("ea_calendar_item created %p\n", atk_object);
+ ++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);
+ g_signal_connect (obj, "selection_preview_changed",
+ G_CALLBACK (selection_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)
{
@@ -114,7 +260,6 @@ ea_calendar_item_get_name (AtkObject *accessible)
ECalendarItem *calitem;
gint start_year, start_month, start_day;
gint end_year, end_month, end_day;
- GDate select_start, select_end;
static gchar new_name[256] = "";
g_return_val_if_fail (EA_IS_CALENDAR_ITEM (accessible), NULL);
@@ -131,11 +276,14 @@ ea_calendar_item_get_name (AtkObject *accessible)
&end_year, &end_month, &end_day)) {
++start_month;
++end_month;
- sprintf (new_name, "calendar date range: from %d-%d-%d to %d-%d-%d.",
+ sprintf (new_name, "calendar (from %d-%d-%d to %d-%d-%d)",
start_year, start_month, start_day,
end_year, end_month, end_day);
}
+
+#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);
@@ -147,10 +295,11 @@ ea_calendar_item_get_name (AtkObject *accessible)
day2 = g_date_get_day (&select_end);
sprintf (new_name + strlen (new_name),
- "current selection: from %d-%d-%d to %d-%d-%d.",
+ " : current selection: from %d-%d-%d to %d-%d-%d.",
year1, month1, day1,
year2, month2, day2);
}
+#endif
return new_name;
}
@@ -161,5 +310,938 @@ ea_calendar_item_get_description (AtkObject *accessible)
if (accessible->description)
return accessible->description;
- return "evolution calendar widget";
+ return "evolution calendar item";
+}
+
+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);
+ e_calendar_item_get_selection (calitem, &start_date, &end_date);
+
+ sel_index_start =
+ 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_end =
+ 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));
+
+ 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);
+ e_calendar_item_get_selection (calitem, &start_date, &end_date);
+
+ sel_index_start =
+ 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_end =
+ 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));
+
+ 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;
+ ECalendarItem *calitem;
+ 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;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ 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;
+ ECalendarItem *calitem;
+ 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;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ 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);
+ e_calendar_item_get_selection (calitem, &start_date, &end_date);
+ sel_offset = 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));
+
+ 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);
+ e_calendar_item_get_selection (calitem, &start_date, &end_date);
+
+ return g_date_days_between (&start_date, &end_date) + 1;
+}
+
+static gboolean
+selection_interface_is_child_selected (AtkSelection *selection, gint index)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ 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;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+ 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;
+
+ g_return_if_fail (E_IS_CALENDAR_ITEM (calitem));
+ atk_obj = atk_gobject_accessible_for_object (G_OBJECT (calitem));
+
+ g_signal_emit_by_name (atk_obj, "selection_changed");
+}
+
+static void
+date_range_changed_cb (ECalendarItem *calitem)
+{
+ AtkObject *atk_obj;
+
+ 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));
+
+ g_signal_emit_by_name (atk_obj, "model_changed");
+}
+
+static void
+selection_changed_cb (ECalendarItem *calitem)
+{
+ selection_preview_change_cb (calitem);
+}
+
+/* helpers */
+
+static EaCellTable *
+ea_calendar_item_get_cell_data (EaCalendarItem *ea_calitem)
+{
+ AtkGObjectAccessible *atk_gobj;
+ GObject *g_obj;
+ ECalendarItem *calitem;
+ 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;
+
+ calitem = E_CALENDAR_ITEM (g_obj);
+
+ 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) {
+ ea_cell_table_destroy (cell_data);
+ g_object_set_data (G_OBJECT(ea_calitem),
+ "ea-calendar-cell-table", NULL);
+ }
+}
+
+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;
+ gchar *week_char;
+ gint char_size;
+
+ 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);
+ week_char = g_utf8_offset_to_pointer (calitem->days, column);
+ char_size = strlen (calitem->days) -
+ strlen (g_utf8_find_next_char (calitem->days, NULL));
+
+ if (week_char && char_size < buffer_size) {
+ memcpy (buffer, week_char, char_size);
+ buffer[char_size] = '\0';
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* 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;
+}
+
+/* month is from 0 to 11 */
+gint
+e_calendar_item_get_offset_for_date (ECalendarItem *calitem,
+ gint year, gint month, gint day)
+{
+ gint start_year, start_month, start_day;
+ gint end_year, end_month, end_day;
+ GDate *start_date, *end_date;
+ gint n_days;
+
+ g_return_val_if_fail (E_IS_CALENDAR_ITEM (calitem), -1);
+
+ 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);
+
+ n_days = g_date_days_between (start_date, end_date);
+ g_free (start_date);
+ g_free (end_date);
+ return n_days;
+}
+
+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;
}
diff --git a/a11y/widgets/ea-calendar-item.h b/a11y/widgets/ea-calendar-item.h
index 675cb4c6e7..04df5f94ac 100644
--- a/a11y/widgets/ea-calendar-item.h
+++ b/a11y/widgets/ea-calendar-item.h
@@ -56,6 +56,18 @@ struct _EaCalendarItemClass
};
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_offset_for_date (ECalendarItem *calitem,
+ gint year, gint month, gint day);
+gint e_calendar_item_get_n_days_from_week_start (ECalendarItem *calitem,
+ gint year, gint month);
#ifdef __cplusplus
}
diff --git a/a11y/widgets/ea-widgets.c b/a11y/widgets/ea-widgets.c
index 3b288dc669..edead1b785 100644
--- a/a11y/widgets/ea-widgets.c
+++ b/a11y/widgets/ea-widgets.c
@@ -27,7 +27,7 @@
#include "widgets/ea-calendar-item.h"
#include "ea-widgets.h"
-EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_ITEM, ea_calendar_item, ea_calendar_item_new);
+EA_FACTORY_GOBJECT (EA_TYPE_CALENDAR_ITEM, ea_calendar_item, ea_calendar_item_new)
void e_calendar_item_a11y_init (void)
{