From fd52cd5eeb0f48087306d3473ef20925e27b664d Mon Sep 17 00:00:00 2001 From: Bolian Yin Date: Tue, 4 Nov 2003 08:15:56 +0000 Subject: Fixes # 48509 2003-11-04 Bolian Yin Fixes # 48509 * new files: ea-cell-table.h ea-cell-table.c * calendar/Makefile.am: add entries for new files * calendar/New files added: ea-day-view-main-item.c ea-day-view-main-item.h ea-day-view-cell.c ea-day-view-cell.h * Add debug info and remove some non-C99 compilers warnings. * calendar/ea-cal-view: add action interface. svn path=/trunk/; revision=23180 --- a11y/ChangeLog | 13 + a11y/Makefile.am | 15 +- a11y/calendar/Makefile.am | 21 +- a11y/calendar/ea-cal-view-event.c | 122 ++-- a11y/calendar/ea-cal-view.c | 213 +++++- a11y/calendar/ea-calendar.c | 145 ++-- a11y/calendar/ea-calendar.h | 1 + a11y/calendar/ea-day-view-cell.c | 336 +++++++++ a11y/calendar/ea-day-view-cell.h | 91 +++ a11y/calendar/ea-day-view-main-item.c | 1259 +++++++++++++++++++++++++++++++++ a11y/calendar/ea-day-view-main-item.h | 64 ++ a11y/calendar/ea-day-view.c | 92 ++- a11y/calendar/ea-gnome-calendar.c | 4 +- a11y/calendar/ea-week-view.c | 131 +++- a11y/ea-cell-table.c | 207 ++++++ a11y/ea-cell-table.h | 63 ++ 16 files changed, 2554 insertions(+), 223 deletions(-) create mode 100644 a11y/calendar/ea-day-view-cell.c create mode 100644 a11y/calendar/ea-day-view-cell.h create mode 100644 a11y/calendar/ea-day-view-main-item.c create mode 100644 a11y/calendar/ea-day-view-main-item.h create mode 100644 a11y/ea-cell-table.c create mode 100644 a11y/ea-cell-table.h diff --git a/a11y/ChangeLog b/a11y/ChangeLog index ff406f373e..8d3d11e3af 100644 --- a/a11y/ChangeLog +++ b/a11y/ChangeLog @@ -1,3 +1,16 @@ +2003-11-04 Bolian Yin + + Fixes # 48509 + + * new files: + ea-cell-table.h ea-cell-table.c + * calendar/Makefile.am: add entries for new files + * calendar/New files added: + ea-day-view-main-item.c ea-day-view-main-item.h + ea-day-view-cell.c ea-day-view-cell.h + * Add debug info and remove some non-C99 compilers warnings. + * calendar/ea-cal-view: add action interface. + 2003-10-09 Jeffrey Stedfast * calendar/Makefile.am: INCLUDE path fixes for changes made to diff --git a/a11y/Makefile.am b/a11y/Makefile.am index 796eeba234..c3e7a89fed 100644 --- a/a11y/Makefile.am +++ b/a11y/Makefile.am @@ -1,5 +1,16 @@ +SUBDIRS = . calendar widgets -SUBDIRS = calendar widgets +# for debug +#A11Y_CFLAGS += -pedantic -ansi -DACC_DEBUG -Werror +privlib_LTLIBRARIES = libevolution-a11y.la + +INCLUDES = \ + -I$(top_srcdir)/a11y \ + $(A11Y_CFLAGS) + +libevolution_a11y_la_SOURCES = \ + ea-factory.h \ + ea-cell-table.h \ + ea-cell-table.c -EXTRA_DIST = ea-factory.h diff --git a/a11y/calendar/Makefile.am b/a11y/calendar/Makefile.am index dc08c333b8..80f7274396 100644 --- a/a11y/calendar/Makefile.am +++ b/a11y/calendar/Makefile.am @@ -1,5 +1,8 @@ # Calendar IDL files +# for debug +#A11Y_CFLAGS += -pedantic -ansi -DACC_DEBUG -Werror + CALENDAR_IDLS = $(top_srcdir)/calendar/idl/evolution-calendar.idl SHELL_IDLS = \ $(top_srcdir)/shell/Evolution-Activity.idl \ @@ -16,7 +19,7 @@ SHELL_IDLS = \ $(top_srcdir)/shell/Evolution-Wizard.idl \ $(top_srcdir)/shell/Evolution-common.idl \ $(top_srcdir)/shell/Evolution.idl - + CALENDAR_IDL_GENERATED_H = evolution-calendar.h CALENDAR_IDL_GENERATED_C = \ evolution-calendar-common.c \ @@ -28,11 +31,11 @@ SHELL_IDL_GENERATED_C = \ Evolution-common.c \ Evolution-skels.c \ Evolution-stubs.c - + $(CALENDAR_IDL_GENERATED_H): $(CALENDAR_IDLS) $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) \ $(top_srcdir)/calendar/idl/evolution-calendar.idl - + $(SHELL_IDL_GENERATED_H): $(SHELL_IDLS) $(ORBIT_IDL) -I $(srcdir) $(IDL_INCLUDES) \ $(top_srcdir)/shell/Evolution.idl @@ -40,8 +43,8 @@ $(SHELL_IDL_GENERATED_H): $(SHELL_IDLS) IDL_GENERATED = $(SHELL_IDL_GENERATED_H) $(CALENDAR_IDL_GENERATED_H) BUILT_SOURCES = $(IDL_GENERATED) CLEANFILES = $(BUILT_SOURCES) $(CALENDAR_IDL_GENERATED_C) $(SHELL_IDL_GENERATED_C) - -noinst_LTLIBRARIES = libevolution-calendar-a11y.la + +privlib_LTLIBRARIES = libevolution-calendar-a11y.la INCLUDES = \ -DG_LOG_DOMAIN=\"evolution-a11y\" \ @@ -76,7 +79,15 @@ libevolution_calendar_a11y_la_SOURCES = \ ea-cal-view-event.h \ ea-day-view.c \ ea-day-view.h \ + ea-day-view-main-item.c \ + ea-day-view-main-item.h \ + ea-day-view-cell.c \ + ea-day-view-cell.h \ ea-week-view.c \ ea-week-view.h \ ea-gnome-calendar.c \ ea-gnome-calendar.h + +libevolution_calendar_a11y_la_LIBADD = \ + $(top_builddir)/a11y/libevolution-a11y.la + diff --git a/a11y/calendar/ea-cal-view-event.c b/a11y/calendar/ea-cal-view-event.c index deffa32ce8..80122375c3 100644 --- a/a11y/calendar/ea-cal-view-event.c +++ b/a11y/calendar/ea-cal-view-event.c @@ -42,6 +42,11 @@ static void ea_cal_view_get_extents (AtkComponent *component, gint *x, gint *y, gint *width, gint *height, AtkCoordType coord_type); +#ifdef ACC_DEBUG +static gint n_ea_cal_view_event_created = 0, n_ea_cal_view_event_destroyed = 0; +static void ea_cal_view_finalize (GObject *object); +#endif + static gpointer parent_class = NULL; GType @@ -100,6 +105,10 @@ static void ea_cal_view_event_class_init (EaCalViewEventClass *klass) { AtkObjectClass *class = ATK_OBJECT_CLASS (klass); +#ifdef ACC_DEBUG + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = ea_cal_view_finalize; +#endif parent_class = g_type_class_peek_parent (klass); @@ -111,6 +120,15 @@ ea_cal_view_event_class_init (EaCalViewEventClass *klass) } +#ifdef ACC_DEBUG +static void ea_cal_view_finalize (GObject *object) +{ + ++n_ea_cal_view_event_destroyed; + printf ("ACC_DEBUG: n_ea_cal_view_event_destroyed = %d\n", + n_ea_cal_view_event_destroyed); +} +#endif + AtkObject* ea_cal_view_event_new (GObject *obj) { @@ -157,8 +175,9 @@ ea_cal_view_event_new (GObject *obj) event_role = atk_role_register ("Calendar Event"); atk_obj->role = event_role; #ifdef ACC_DEBUG - printf ("EvoAcc: ea_cal_view_event created %p for item=%p\n", - atk_obj, target_obj); + ++n_ea_cal_view_event_created; + printf ("ACC_DEBUG: n_ea_cal_view_event_created = %d\n", + n_ea_cal_view_event_created); #endif } @@ -173,73 +192,70 @@ ea_cal_view_event_new (GObject *obj) static G_CONST_RETURN gchar* ea_cal_view_event_get_name (AtkObject *accessible) { - g_return_val_if_fail (EA_IS_CAL_VIEW_EVENT (accessible), NULL); + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalViewEvent *event; + gchar *tmp_name; + gchar *new_name = g_strdup (""); + const char *summary; - if (accessible->name) - return accessible->name; - else { - AtkGObjectAccessible *atk_gobj; - GObject *g_obj; - ECalViewEvent *event; - gchar *tmp_name; - gchar *new_name = g_strdup (""); - const char *summary; - - atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); - g_obj = atk_gobject_accessible_get_object (atk_gobj); - if (!g_obj || !E_IS_TEXT (g_obj)) - return NULL; - event = ea_calendar_helpers_get_cal_view_event_from (GNOME_CANVAS_ITEM(g_obj)); - if (event && event->comp_data) { - if (cal_util_component_has_alarms (event->comp_data->icalcomp)) { - tmp_name = new_name; - new_name = g_strconcat (new_name, "alarm ", NULL); - g_free (tmp_name); - } + g_return_val_if_fail (EA_IS_CAL_VIEW_EVENT (accessible), NULL); - if (cal_util_component_has_recurrences (event->comp_data->icalcomp)) { - tmp_name = new_name; - new_name = g_strconcat (new_name, "recurrence ", NULL); - g_free (tmp_name); - } + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj || !E_IS_TEXT (g_obj)) + return NULL; + event = ea_calendar_helpers_get_cal_view_event_from (GNOME_CANVAS_ITEM(g_obj)); - if (event->different_timezone) { - tmp_name = new_name; - new_name = g_strconcat (new_name, "time-zone ", NULL); - g_free (tmp_name); - } + if (event && event->comp_data) { + if (cal_util_component_has_alarms (event->comp_data->icalcomp)) { + tmp_name = new_name; + new_name = g_strconcat (new_name, "alarm ", NULL); + g_free (tmp_name); + } - if (cal_util_component_has_organizer (event->comp_data->icalcomp)) { - tmp_name = new_name; - new_name = g_strconcat (new_name, "meeting ", NULL); - g_free (tmp_name); - } + if (cal_util_component_has_recurrences (event->comp_data->icalcomp)) { + tmp_name = new_name; + new_name = g_strconcat (new_name, "recurrence ", NULL); + g_free (tmp_name); } - tmp_name = new_name; - new_name = g_strconcat (new_name, "event. Summary is ", NULL); - g_free (tmp_name); - summary = icalcomponent_get_summary (event->comp_data->icalcomp); - if (summary) { + if (event->different_timezone) { tmp_name = new_name; - new_name = g_strconcat (new_name, summary, NULL); + new_name = g_strconcat (new_name, "time-zone ", NULL); g_free (tmp_name); } - else { + + if (cal_util_component_has_organizer (event->comp_data->icalcomp)) { tmp_name = new_name; - new_name = g_strconcat (new_name, "empty", NULL); + new_name = g_strconcat (new_name, "meeting ", NULL); g_free (tmp_name); } + } + tmp_name = new_name; + new_name = g_strconcat (new_name, "event. Summary is ", NULL); + g_free (tmp_name); + + summary = icalcomponent_get_summary (event->comp_data->icalcomp); + if (summary) { + tmp_name = new_name; + new_name = g_strconcat (new_name, summary, NULL); + g_free (tmp_name); + } + else { + tmp_name = new_name; + new_name = g_strconcat (new_name, "empty", NULL); + g_free (tmp_name); + } - ATK_OBJECT_CLASS (parent_class)->set_name (accessible, new_name); + ATK_OBJECT_CLASS (parent_class)->set_name (accessible, new_name); #ifdef ACC_DEBUG - printf("EvoAcc: name for event accobj=%p, is %s\n", - accessible, new_name); + printf("EvoAcc: name for event accobj=%p, is %s\n", + (void *)accessible, new_name); #endif - g_free (new_name); - return accessible->name; - } + g_free (new_name); + return accessible->name; } static G_CONST_RETURN gchar* diff --git a/a11y/calendar/ea-cal-view.c b/a11y/calendar/ea-cal-view.c index f31d24cc55..fe3c3de1cf 100644 --- a/a11y/calendar/ea-cal-view.c +++ b/a11y/calendar/ea-cal-view.c @@ -28,12 +28,12 @@ #include "e-day-view.h" #include "e-week-view.h" #include "calendar-commands.h" +#include "goto.h" #include static void ea_cal_view_class_init (EaCalViewClass *klass); static AtkObject* ea_cal_view_get_parent (AtkObject *accessible); -static gint ea_cal_view_get_index_in_parent (AtkObject *accessible); static void ea_cal_view_real_initialize (AtkObject *accessible, gpointer data); static void ea_cal_view_event_changed_cb (ECalView *cal_view, @@ -41,8 +41,19 @@ static void ea_cal_view_event_changed_cb (ECalView *cal_view, static void ea_cal_view_event_added_cb (ECalView *cal_view, ECalViewEvent *event, gpointer data); +static gboolean idle_dates_changed (gpointer data); static void ea_cal_view_dates_change_cb (GnomeCalendar *gcal, gpointer data); +static void atk_action_interface_init (AtkActionIface *iface); +static gboolean action_interface_do_action (AtkAction *action, gint i); +static gint action_interface_get_n_actions (AtkAction *action); +static G_CONST_RETURN gchar* +action_interface_get_description(AtkAction *action, gint i); +static G_CONST_RETURN gchar* +action_interface_get_keybinding (AtkAction *action, gint i); +static G_CONST_RETURN gchar* +action_interface_action_get_name(AtkAction *action, gint i); + static gpointer parent_class = NULL; GType @@ -67,6 +78,12 @@ ea_cal_view_get_type (void) NULL /* value table */ }; + static const GInterfaceInfo atk_action_info = { + (GInterfaceInitFunc) atk_action_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + /* * Figure out the size of the class and instance * we are run-time deriving from (GailWidget, in this case) @@ -82,6 +99,8 @@ ea_cal_view_get_type (void) type = g_type_register_static (derived_atk_type, "EaCalView", &tinfo, 0); + g_type_add_interface_static (type, ATK_TYPE_ACTION, + &atk_action_info); } return type; @@ -95,7 +114,6 @@ ea_cal_view_class_init (EaCalViewClass *klass) parent_class = g_type_class_peek_parent (klass); class->get_parent = ea_cal_view_get_parent; - class->get_index_in_parent = ea_cal_view_get_index_in_parent; class->initialize = ea_cal_view_real_initialize; } @@ -120,12 +138,15 @@ ea_cal_view_real_initialize (AtkObject *accessible, gpointer data) { ECalView *cal_view; GnomeCalendar *gcal; + static AtkRole role = ATK_ROLE_INVALID; g_return_if_fail (EA_IS_CAL_VIEW (accessible)); g_return_if_fail (E_IS_CAL_VIEW (data)); ATK_OBJECT_CLASS (parent_class)->initialize (accessible, data); - accessible->role = ATK_ROLE_CANVAS; + if (role == ATK_ROLE_INVALID) + role = atk_role_register ("Calendar View"); + accessible->role = role; cal_view = E_CAL_VIEW (data); /* add listener for event_changed, event_added @@ -164,12 +185,6 @@ ea_cal_view_get_parent (AtkObject *accessible) return gtk_widget_get_accessible (GTK_WIDGET(gnomeCalendar)); } -static gint -ea_cal_view_get_index_in_parent (AtkObject *accessible) -{ - return 1; -} - static void ea_cal_view_event_changed_cb (ECalView *cal_view, ECalViewEvent *event, gpointer data) @@ -201,7 +216,7 @@ ea_cal_view_event_changed_cb (ECalView *cal_view, ECalViewEvent *event, } if (event_atk_obj) { #ifdef ACC_DEBUG - printf ("AccDebug: event=%p changed\n", event); + printf ("AccDebug: event=%p changed\n", (void *)event); #endif g_object_notify (G_OBJECT(event_atk_obj), "accessible-name"); g_signal_emit_by_name (event_atk_obj, "visible_data_changed"); @@ -245,27 +260,181 @@ ea_cal_view_event_added_cb (ECalView *cal_view, ECalViewEvent *event, if (index < 0) return; #ifdef ACC_DEBUG - printf ("AccDebug: event=%p added\n", event); + printf ("AccDebug: event=%p added\n", (void *)event); #endif g_signal_emit_by_name (atk_obj, "children_changed::add", index, event_atk_obj, NULL); } } +static gboolean +idle_dates_changed (gpointer data) +{ + AtkObject *ea_cal_view; + + g_return_val_if_fail (data, FALSE); + g_return_val_if_fail (EA_IS_CAL_VIEW (data), FALSE); + + ea_cal_view = ATK_OBJECT(data); + + if (ea_cal_view->name) { + g_free (ea_cal_view->name); + ea_cal_view->name = NULL; + } + g_object_notify (G_OBJECT (ea_cal_view), "accessible-name"); + g_signal_emit_by_name (ea_cal_view, "visible_data_changed"); + g_signal_emit_by_name (ea_cal_view, "children_changed", NULL); +#ifdef ACC_DEBUG + printf ("AccDebug: cal view date changed\n"); +#endif + + return FALSE; +} + static void ea_cal_view_dates_change_cb (GnomeCalendar *gcal, gpointer data) { - AtkObject *atk_obj; + g_idle_add (idle_dates_changed, data); +} - g_return_if_fail (GNOME_IS_CALENDAR (gcal)); - g_return_if_fail (data); - g_return_if_fail (EA_IS_CAL_VIEW (data)); +/* atk action interface */ - atk_obj = ATK_OBJECT(data); - if (atk_obj->name) { - g_free (atk_obj->name); - atk_obj->name = NULL; - } - g_object_notify (G_OBJECT (data), "accessible-name"); - g_signal_emit_by_name (data, "visible_data_changed"); +#define CAL_VIEW_ACTION_NUM 5 + +static const char * action_name [CAL_VIEW_ACTION_NUM] = { + "New Appointment", + "New Event", + "New Meeting", + "Go to Today", + "Go to Date" +}; + +static void +atk_action_interface_init (AtkActionIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->do_action = action_interface_do_action; + iface->get_n_actions = action_interface_get_n_actions; + iface->get_description = action_interface_get_description; + iface->get_keybinding = action_interface_get_keybinding; + iface->get_name = action_interface_action_get_name; +} + +static gboolean +action_interface_do_action (AtkAction *action, gint index) +{ + GtkWidget *widget; + gboolean return_value = TRUE; + time_t dtstart, dtend; + ECalView *cal_view; + + widget = GTK_ACCESSIBLE (action)->widget; + if (widget == NULL) + /* + * State is defunct + */ + return FALSE; + + if (!GTK_WIDGET_IS_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget)) + return FALSE; + + cal_view = E_CAL_VIEW (widget); + switch (index) { + case 0: + /* New Appointment */ + e_cal_view_new_appointment (cal_view); + break; + case 1: + /* New Event */ + e_cal_view_get_selected_time_range (cal_view, + &dtstart, &dtend); + e_cal_view_new_appointment_for (cal_view, + dtstart, dtend, TRUE, FALSE); + break; + case 2: + /* New Meeting */ + e_cal_view_get_selected_time_range (cal_view, + &dtstart, &dtend); + e_cal_view_new_appointment_for (cal_view, + dtstart, dtend, FALSE, TRUE); + break; + case 3: + /* Go to today */ + break; + calendar_goto_today (e_cal_view_get_calendar (cal_view)); + case 4: + /* Go to date */ + goto_dialog (e_cal_view_get_calendar (cal_view)); + break; + default: + return_value = FALSE; + break; + } + return return_value; +} + +static gint +action_interface_get_n_actions (AtkAction *action) +{ + return CAL_VIEW_ACTION_NUM; +} + +static G_CONST_RETURN gchar* +action_interface_get_description(AtkAction *action, gint index) +{ + return action_interface_action_get_name (action, index); +} + +static G_CONST_RETURN gchar* +action_interface_get_keybinding (AtkAction *action, gint index) +{ + GtkWidget *widget; + EaCalView *ea_cal_view; + + widget = GTK_ACCESSIBLE (action)->widget; + if (widget == NULL) + /* + * State is defunct + */ + return NULL; + + if (!GTK_WIDGET_IS_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget)) + return FALSE; + + ea_cal_view = EA_CAL_VIEW (action); + + switch (index) { + case 0: + /* New Appointment */ + return "fna;n"; + break; + case 1: + /* New Event */ + return "fnd;d"; + break; + case 2: + /* New Meeting */ + return "fne;e"; + break; + case 3: + /* Go to today */ + return "vt;t"; + break; + case 4: + /* Go to date */ + return "vd;g"; + break; + default: + break; + } + return NULL; +} + +static G_CONST_RETURN gchar* +action_interface_action_get_name(AtkAction *action, gint i) +{ + if (i >= 0 && i < CAL_VIEW_ACTION_NUM) + return action_name [i]; + return NULL; } diff --git a/a11y/calendar/ea-calendar.c b/a11y/calendar/ea-calendar.c index b5296c2618..0882f9c653 100644 --- a/a11y/calendar/ea-calendar.c +++ b/a11y/calendar/ea-calendar.c @@ -31,57 +31,65 @@ #include "calendar/ea-cal-view.h" #include "calendar/ea-cal-view-event.h" #include "calendar/ea-day-view.h" +#include "calendar/ea-day-view-main-item.h" #include "calendar/ea-week-view.h" #include "calendar/ea-gnome-calendar.h" -EA_FACTORY (EA_TYPE_CAL_VIEW, ea_cal_view, ea_cal_view_new); -EA_FACTORY (EA_TYPE_DAY_VIEW, ea_day_view, ea_day_view_new); -EA_FACTORY (EA_TYPE_WEEK_VIEW, ea_week_view, ea_week_view_new); -EA_FACTORY (EA_TYPE_GNOME_CALENDAR, ea_gnome_calendar, ea_gnome_calendar_new); +EA_FACTORY (EA_TYPE_CAL_VIEW, ea_cal_view, ea_cal_view_new) +EA_FACTORY (EA_TYPE_DAY_VIEW, ea_day_view, ea_day_view_new) +EA_FACTORY_GOBJECT (EA_TYPE_DAY_VIEW_MAIN_ITEM, ea_day_view_main_item, ea_day_view_main_item_new) +EA_FACTORY (EA_TYPE_WEEK_VIEW, ea_week_view, ea_week_view_new) +EA_FACTORY (EA_TYPE_GNOME_CALENDAR, ea_gnome_calendar, ea_gnome_calendar_new) static gboolean ea_calendar_focus_watcher (GSignalInvocationHint *ihint, - guint n_param_values, - const GValue *param_values, - gpointer data); + guint n_param_values, + const GValue *param_values, + gpointer data); void gnome_calendar_a11y_init (void) { - EA_SET_FACTORY (gnome_calendar_get_type(), ea_gnome_calendar); - /* we only add focus watcher when accessibility is enabled - */ - if (atk_get_root ()) - g_signal_add_emission_hook (g_signal_lookup ("event", E_TYPE_TEXT), - 0, ea_calendar_focus_watcher, - NULL, (GDestroyNotify) NULL); + EA_SET_FACTORY (gnome_calendar_get_type(), ea_gnome_calendar); + /* we only add focus watcher when accessibility is enabled + */ + if (atk_get_root ()) { + g_signal_add_emission_hook (g_signal_lookup ("event", E_TYPE_TEXT), + 0, ea_calendar_focus_watcher, + NULL, (GDestroyNotify) NULL); + g_signal_add_emission_hook (g_signal_lookup ("event-after", + e_day_view_get_type()), + 0, ea_calendar_focus_watcher, + NULL, (GDestroyNotify) NULL); + g_signal_add_emission_hook (g_signal_lookup ("event", + e_day_view_main_item_get_type()), + 0, ea_calendar_focus_watcher, + NULL, (GDestroyNotify) NULL); + + } } void e_cal_view_a11y_init (void) { - EA_SET_FACTORY (e_cal_view_get_type(), ea_cal_view); - /* we only add focus watcher when accessibility is enabled - */ -#if 0 - if (atk_get_root ()) - g_signal_add_emission_hook (g_signal_lookup ("selection_time_changed", - e_cal_view_get_type ()), - 0, ea_calendar_focus_watcher, - NULL, (GDestroyNotify) NULL); -#endif + EA_SET_FACTORY (e_cal_view_get_type(), ea_cal_view); } void e_day_view_a11y_init (void) { - EA_SET_FACTORY (e_day_view_get_type(), ea_day_view); + EA_SET_FACTORY (e_day_view_get_type(), ea_day_view); +} + +void e_day_view_main_item_a11y_init (void) +{ + EA_SET_FACTORY (e_day_view_main_item_get_type (), ea_day_view_main_item); } void e_week_view_a11y_init (void) { - EA_SET_FACTORY (e_week_view_get_type(), ea_week_view); + EA_SET_FACTORY (e_week_view_get_type(), ea_week_view); } gboolean @@ -90,46 +98,53 @@ ea_calendar_focus_watcher (GSignalInvocationHint *ihint, const GValue *param_values, gpointer data) { - GObject *object; - GdkEvent *event; - - object = g_value_get_object (param_values + 0); - event = g_value_get_boxed (param_values + 1); - - if (E_IS_TEXT (object)) { - /* "event" signal on canvas item - */ - GnomeCanvasItem *canvas_item; - AtkObject *ea_event; - - canvas_item = GNOME_CANVAS_ITEM (object); - if (event->type == GDK_FOCUS_CHANGE) { - if (event->focus_change.in) - ea_event = - ea_calendar_helpers_get_accessible_for (canvas_item); - else - /* focus out */ - ea_event = NULL; - atk_focus_tracker_notify (ea_event); - - } - } -#if 0 - else if (E_IS_DAY_VIEW (object)) { - /* "selection_time_changed" signal on day_view - */ - if (ATK_IS_SELECTION (object)) { - AtkSelection *atk_selection; - AtkObject *atk_obj; - atk_selection = ATK_SELECTION (object); - atk_obj = atk_selection_ref_selection (atk_selection, 0); + GObject *object; + GdkEvent *event; + AtkObject *ea_event = NULL; + object = g_value_get_object (param_values + 0); + event = g_value_get_boxed (param_values + 1); + + if (E_IS_TEXT (object)) { + /* "event" signal on canvas item + */ + GnomeCanvasItem *canvas_item; + + canvas_item = GNOME_CANVAS_ITEM (object); + if (event->type == GDK_FOCUS_CHANGE) { + if (event->focus_change.in) + ea_event = + ea_calendar_helpers_get_accessible_for (canvas_item); + else + /* focus out */ + ea_event = NULL; + atk_focus_tracker_notify (ea_event); + + } + } + else if (E_IS_DAY_VIEW (object)) { + EDayView *day_view = E_DAY_VIEW (object); + if (event->type == GDK_FOCUS_CHANGE) { + if (event->focus_change.in) { + /* give main item chance to emit focus */ + gnome_canvas_item_grab_focus (day_view->main_canvas_item); + } + } + } + else if (E_IS_DAY_VIEW_MAIN_ITEM (object)) { + if (event->type == GDK_FOCUS_CHANGE) { + if (event->focus_change.in) { + /* we should emit focus on main item */ + ea_event = atk_gobject_accessible_for_object (object); + } + else + /* focus out */ + ea_event = NULL; #ifdef ACC_DEBUG - printf ("EvoAcc: ref a selection %p\n", atk_selection); -#endif - atk_focus_tracker_notify (atk_obj); - } - } + printf ("EvoAcc: focus notify on day main item %p\n", (void *)object); #endif - return TRUE; + atk_focus_tracker_notify (ea_event); + } + } + return TRUE; } diff --git a/a11y/calendar/ea-calendar.h b/a11y/calendar/ea-calendar.h index 61cdab1a89..4b1779c0b5 100644 --- a/a11y/calendar/ea-calendar.h +++ b/a11y/calendar/ea-calendar.h @@ -32,6 +32,7 @@ void gnome_calendar_a11y_init (void); void e_cal_view_a11y_init (void); void e_day_view_a11y_init (void); +void e_day_view_main_item_a11y_init (void); void e_week_view_a11y_init (void); #endif /* _EA_CALENDAR_H__ */ diff --git a/a11y/calendar/ea-day-view-cell.c b/a11y/calendar/ea-day-view-cell.c new file mode 100644 index 0000000000..52fb860fd6 --- /dev/null +++ b/a11y/calendar/ea-day-view-cell.c @@ -0,0 +1,336 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* vim:expandtab:shiftwidth=8:tabstop=8: + */ +/* Evolution Accessibility: ea-day-view-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 Sun Microsystem Inc., 2003 + * + */ + +#include "ea-day-view-cell.h" +#include "ea-day-view-main-item.h" +#include "ea-day-view.h" +#include "ea-factory.h" + +/* EDayViewCell */ + +static void e_day_view_cell_class_init (EDayViewCellClass *class); + +EA_FACTORY_GOBJECT (EA_TYPE_DAY_VIEW_CELL, ea_day_view_cell, ea_day_view_cell_new) + +GType +e_day_view_cell_get_type (void) +{ + static GType type = 0; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EDayViewCellClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) e_day_view_cell_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EDayViewCell), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, + "EDayViewCell", &tinfo, 0); + } + + return type; +} + +static void +e_day_view_cell_class_init (EDayViewCellClass *class) +{ + EA_SET_FACTORY (e_day_view_cell_get_type (), ea_day_view_cell); +} + +EDayViewCell * +e_day_view_cell_new (EDayView *day_view, gint row, gint column) +{ + GObject *object; + EDayViewCell *cell; + + g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL); + + object = g_object_new (E_TYPE_DAY_VIEW_CELL, NULL); + cell = E_DAY_VIEW_CELL (object); + cell->day_view = day_view; + cell->row = row; + cell->column = column; + +#ifdef ACC_DEBUG + printf ("EvoAcc: e_day_view_cell created %p\n", (void *)cell); +#endif + + return cell; +} + +/* EaDayViewCell */ + +static void ea_day_view_cell_class_init (EaDayViewCellClass *klass); + +static G_CONST_RETURN gchar* ea_day_view_cell_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_day_view_cell_get_description (AtkObject *accessible); +static AtkStateSet* ea_day_view_cell_ref_state_set (AtkObject *obj); +static AtkObject * ea_day_view_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_day_view_cell_created = 0, n_ea_day_view_cell_destroyed = 0; +static void ea_day_view_cell_finalize (GObject *object); +#endif + +GType +ea_day_view_cell_get_type (void) +{ + static GType type = 0; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaDayViewCellClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_day_view_cell_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaDayViewCell), /* 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, + "EaDayViewCell", &tinfo, 0); + g_type_add_interface_static (type, ATK_TYPE_COMPONENT, + &atk_component_info); + } + + return type; +} + +static void +ea_day_view_cell_class_init (EaDayViewCellClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + +#ifdef ACC_DEBUG + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = ea_day_view_cell_finalize; +#endif + + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_day_view_cell_get_name; + class->get_description = ea_day_view_cell_get_description; + class->ref_state_set = ea_day_view_cell_ref_state_set; + + class->get_parent = ea_day_view_cell_get_parent; +} + +AtkObject* +ea_day_view_cell_new (GObject *obj) +{ + gpointer object; + AtkObject *atk_object; + + g_return_val_if_fail (E_IS_DAY_VIEW_CELL (obj), NULL); + + object = g_object_new (EA_TYPE_DAY_VIEW_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_day_view_cell_created; + printf ("ACC_DEBUG: n_ea_day_view_cell_created = %d\n", + n_ea_day_view_cell_created); +#endif + return atk_object; +} + +#ifdef ACC_DEBUG +static void ea_day_view_cell_finalize (GObject *object) +{ + ++n_ea_day_view_cell_destroyed; + printf ("ACC_DEBUG: n_ea_day_view_cell_destroyed = %d\n", + n_ea_day_view_cell_destroyed); +} +#endif + +static G_CONST_RETURN gchar* +ea_day_view_cell_get_name (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewCell *cell; + + g_return_val_if_fail (EA_IS_DAY_VIEW_CELL (accessible), NULL); + + if (!accessible->name) { + AtkObject *ea_main_item; + GnomeCanvasItem *main_item; + gchar *new_name = g_strdup (""); + const gchar *row_label, *column_label; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + cell = E_DAY_VIEW_CELL (g_obj); + main_item = cell->day_view->main_canvas_item; + ea_main_item = atk_gobject_accessible_for_object (G_OBJECT (main_item)); + column_label = atk_table_get_column_description (ATK_TABLE (ea_main_item), + cell->column); + row_label = atk_table_get_row_description (ATK_TABLE (ea_main_item), + cell->row); + new_name = g_strconcat (column_label, " ", row_label, NULL); + ATK_OBJECT_CLASS (parent_class)->set_name (accessible, new_name); + g_free (new_name); + } + return accessible->name; +} + +static G_CONST_RETURN gchar* +ea_day_view_cell_get_description (AtkObject *accessible) +{ + return ea_day_view_cell_get_name (accessible); +} + +static AtkStateSet* +ea_day_view_cell_ref_state_set (AtkObject *obj) +{ + AtkStateSet *state_set; + GObject *g_obj; + AtkObject *parent; + gint x, y, width, height; + gint parent_x, parent_y, parent_width, parent_height; + + state_set = ATK_OBJECT_CLASS (parent_class)->ref_state_set (obj); + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(obj)); + if (!g_obj) + return state_set; + + atk_state_set_add_state (state_set, ATK_STATE_SELECTABLE); + + parent = atk_object_get_parent (obj); + atk_component_get_extents (ATK_COMPONENT (obj), &x, &y, + &width, &height, ATK_XY_WINDOW); + atk_component_get_extents (ATK_COMPONENT (parent), &parent_x, &parent_y, + &parent_width, &parent_height, ATK_XY_WINDOW); + + + if (x + width < parent_x || x > parent_x + parent_width || + y + height < parent_y || y > parent_y + parent_height) + /* the cell is out of the main canvas */ + ; + else + atk_state_set_add_state (state_set, ATK_STATE_VISIBLE); + + return state_set; +} + +static AtkObject * +ea_day_view_cell_get_parent (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewCell *cell; + + g_return_val_if_fail (EA_IS_DAY_VIEW_CELL (accessible), NULL); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + cell = E_DAY_VIEW_CELL (g_obj); + return gtk_widget_get_accessible (GTK_WIDGET (cell->day_view->main_canvas)); +} + +/* 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; + EDayViewCell *cell; + EDayView *day_view; + GtkWidget *main_canvas; + gint day_view_width, day_view_height; + gint scroll_x, scroll_y; + + *x = *y = *width = *height = 0; + + g_return_if_fail (EA_IS_DAY_VIEW_CELL (component)); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component)); + if (!g_obj) + /* defunct object*/ + return; + + cell = E_DAY_VIEW_CELL (g_obj); + day_view = cell->day_view; + main_canvas = cell->day_view->main_canvas; + + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (main_canvas)); + atk_component_get_extents (ATK_COMPONENT (atk_obj), + x, y, + &day_view_width, &day_view_height, + coord_type); + gnome_canvas_get_scroll_offsets (GNOME_CANVAS (day_view->main_canvas), + &scroll_x, &scroll_y); + *x += day_view->day_offsets[cell->column] - scroll_x; + *y += day_view->row_height * cell->row + - scroll_y; + printf ("ybl: cellrow=%d, cellcol=%d, scroll_x=%d, scroll_y=%d\n", + cell->row, cell->column, scroll_x, scroll_y); + *width = day_view->day_widths[cell->column]; + *height = day_view->row_height; +} diff --git a/a11y/calendar/ea-day-view-cell.h b/a11y/calendar/ea-day-view-cell.h new file mode 100644 index 0000000000..cba2fec15b --- /dev/null +++ b/a11y/calendar/ea-day-view-cell.h @@ -0,0 +1,91 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* vim:expandtab:shiftwidth=8:tabstop=8: + */ +/* Evolution Accessibility: ea-day-view-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 Sun Microsystem Inc., 2003 + * + */ + +#ifndef __EA_DAY_VIEW_CELL_H__ +#define __EA_DAY_VIEW_CELL_H__ + +#include +#include "e-day-view.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define E_TYPE_DAY_VIEW_CELL (e_day_view_cell_get_type ()) +#define E_DAY_VIEW_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_DAY_VIEW_CELL, EDayViewCell)) +#define E_DAY_VIEW_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_DAY_VIEW_CELL, EDayViewCellClass)) +#define E_IS_DAY_VIEW_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_DAY_VIEW_CELL)) +#define E_IS_DAY_VIEW_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_DAY_VIEW_CELL)) +#define E_DAY_VIEW_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_DAY_VIEW_CELL, EDayViewCellClass)) + +typedef struct _EDayViewCell EDayViewCell; +typedef struct _EDayViewCellClass EDayViewCellClass; + +struct _EDayViewCell +{ + GObject parent; + EDayView *day_view; + gint row; + gint column; +}; + +GType e_day_view_cell_get_type (void); + +struct _EDayViewCellClass +{ + GObjectClass parent_class; +}; + +EDayViewCell * e_day_view_cell_new (EDayView *day_view, gint row, gint column); + +#define EA_TYPE_DAY_VIEW_CELL (ea_day_view_cell_get_type ()) +#define EA_DAY_VIEW_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_DAY_VIEW_CELL, EaDayViewCell)) +#define EA_DAY_VIEW_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_DAY_VIEW_CELL, EaDayViewCellClass)) +#define EA_IS_DAY_VIEW_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_DAY_VIEW_CELL)) +#define EA_IS_DAY_VIEW_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_DAY_VIEW_CELL)) +#define EA_DAY_VIEW_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_DAY_VIEW_CELL, EaDayViewCellClass)) + +typedef struct _EaDayViewCell EaDayViewCell; +typedef struct _EaDayViewCellClass EaDayViewCellClass; + +struct _EaDayViewCell +{ + AtkGObjectAccessible parent; +}; + +GType ea_day_view_cell_get_type (void); + +struct _EaDayViewCellClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject* ea_day_view_cell_new (GObject *gobj); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EA_DAY_VIEW_CELL_H__ */ diff --git a/a11y/calendar/ea-day-view-main-item.c b/a11y/calendar/ea-day-view-main-item.c new file mode 100644 index 0000000000..970550a139 --- /dev/null +++ b/a11y/calendar/ea-day-view-main-item.c @@ -0,0 +1,1259 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* vim:expandtab:shiftwidth=8:tabstop=8: + */ +/* Evolution Accessibility: ea-day-view-main-item.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 Sun Microsystem Inc., 2003 + * + */ + +#include "ea-day-view-main-item.h" +#include "e-day-view-top-item.h" +#include "ea-day-view.h" +#include "ea-day-view-cell.h" +#include "ea-cell-table.h" + +/* EaDayViewMainItem */ +static void ea_day_view_main_item_class_init (EaDayViewMainItemClass *klass); + +static void ea_day_view_main_item_finalize (GObject *object); +static G_CONST_RETURN gchar* ea_day_view_main_item_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_day_view_main_item_get_description (AtkObject *accessible); + +static gint ea_day_view_main_item_get_n_children (AtkObject *obj); +static AtkObject* ea_day_view_main_item_ref_child (AtkObject *obj, + gint i); +static AtkObject * ea_day_view_main_item_get_parent (AtkObject *accessible); +static gint ea_day_view_main_item_get_index_in_parent (AtkObject *accessible); + +/* callbacks */ +static void ea_day_view_main_item_dates_change_cb (GnomeCalendar *gcal, gpointer data); +static void ea_day_view_main_item_time_change_cb (EDayView *day_view, gpointer data); + +/* 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); +/* 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); + +/* helpers */ +static EaCellTable * +ea_day_view_main_item_get_cell_data (EaDayViewMainItem *ea_main_item); + +static void +ea_day_view_main_item_destory_cell_data (EaDayViewMainItem *ea_main_item); + +static gint +ea_day_view_main_item_get_child_index_at (EaDayViewMainItem *ea_main_item, + gint row, gint column); +static gint +ea_day_view_main_item_get_row_at_index (EaDayViewMainItem *ea_main_item, + gint index); +static gint +ea_day_view_main_item_get_column_at_index (EaDayViewMainItem *ea_main_item, + gint index); +static gint +ea_day_view_main_item_get_row_label (EaDayViewMainItem *ea_main_item, + gint row, gchar *buffer, + gint buffer_size); + +#ifdef ACC_DEBUG +static gint n_ea_day_view_main_item_created = 0; +static gint n_ea_day_view_main_item_destroyed = 0; +#endif + +static gpointer parent_class = NULL; + +GType +ea_day_view_main_item_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaDayViewMainItemClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_day_view_main_item_class_init, + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaDayViewMainItem), /* 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 + }; + + 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 (), + e_day_view_main_item_get_type()); + 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, + "EaDayViewMainItem", &tinfo, 0); + 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; +} + +static void +ea_day_view_main_item_class_init (EaDayViewMainItemClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + gobject_class->finalize = ea_day_view_main_item_finalize; + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_day_view_main_item_get_name; + class->get_description = ea_day_view_main_item_get_description; + + class->get_n_children = ea_day_view_main_item_get_n_children; + class->ref_child = ea_day_view_main_item_ref_child; + class->get_parent = ea_day_view_main_item_get_parent; + class->get_index_in_parent = ea_day_view_main_item_get_index_in_parent; +} + +AtkObject* +ea_day_view_main_item_new (GObject *obj) +{ + AtkObject *accessible; + GnomeCalendar *gcal; + EDayViewMainItem *main_item; + + g_return_val_if_fail (E_IS_DAY_VIEW_MAIN_ITEM (obj), NULL); + + accessible = ATK_OBJECT (g_object_new (EA_TYPE_DAY_VIEW_MAIN_ITEM, + NULL)); + + atk_object_initialize (accessible, obj); + accessible->role = ATK_ROLE_TABLE; + +#ifdef ACC_DEBUG + ++n_ea_day_view_main_item_created; + printf ("ACC_DEBUG: n_ea_day_view_main_item_created = %d\n", + n_ea_day_view_main_item_created); +#endif + main_item = E_DAY_VIEW_MAIN_ITEM (obj); + g_signal_connect (main_item->day_view, "selected_time_changed", + G_CALLBACK (ea_day_view_main_item_time_change_cb), + accessible); + + /* listen for date changes of calendar */ + gcal = e_cal_view_get_calendar (E_CAL_VIEW (main_item->day_view)); + if (gcal) + g_signal_connect (gcal, "dates_shown_changed", + G_CALLBACK (ea_day_view_main_item_dates_change_cb), + accessible); + + return accessible; +} + +static void +ea_day_view_main_item_finalize (GObject *object) +{ + EaDayViewMainItem *ea_main_item; + + g_return_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (object)); + + ea_main_item = EA_DAY_VIEW_MAIN_ITEM (object); + + /* Free the allocated cell data */ + ea_day_view_main_item_destory_cell_data (ea_main_item); + + G_OBJECT_CLASS (parent_class)->finalize (object); +#ifdef ACC_DEBUG + ++n_ea_day_view_main_item_destroyed; + printf ("ACC_DEBUG: n_ea_day_view_main_item_destroyed = %d\n", + n_ea_day_view_main_item_destroyed); +#endif +} + +static G_CONST_RETURN gchar* +ea_day_view_main_item_get_name (AtkObject *accessible) +{ + AtkObject *parent; + g_return_val_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (accessible), NULL); + parent = atk_object_get_parent (accessible); + return atk_object_get_name (parent); +} + +static G_CONST_RETURN gchar* +ea_day_view_main_item_get_description (AtkObject *accessible) +{ + return "a table to view and select the current time range"; +} + +static gint +ea_day_view_main_item_get_n_children (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + + g_return_val_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (accessible), -1); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + return day_view->rows * day_view->days_shown; +} + +static AtkObject * +ea_day_view_main_item_ref_child (AtkObject *accessible, gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + gint n_children; + EDayViewCell *cell; + EaCellTable *cell_data; + EaDayViewMainItem *ea_main_item; + + g_return_val_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (accessible), NULL); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + n_children = ea_day_view_main_item_get_n_children (accessible); + if (index < 0 || index >= n_children) + return NULL; + + ea_main_item = EA_DAY_VIEW_MAIN_ITEM (accessible); + cell_data = ea_day_view_main_item_get_cell_data (ea_main_item); + if (!cell_data) + return NULL; + + cell = ea_cell_table_get_cell_at_index (cell_data, index); + if (!cell) { + gint row, column; + + row = ea_day_view_main_item_get_row_at_index (ea_main_item, index); + column = ea_day_view_main_item_get_column_at_index (ea_main_item, index); + cell = e_day_view_cell_new (day_view, row, column); + ea_cell_table_set_cell_at_index (cell_data, index, cell); + g_object_unref (cell); + } + return g_object_ref (atk_gobject_accessible_for_object (G_OBJECT(cell))); +} + +static AtkObject * +ea_day_view_main_item_get_parent (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + + g_return_val_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (accessible), NULL); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + return gtk_widget_get_accessible (GTK_WIDGET (main_item->day_view)); +} + +static gint +ea_day_view_main_item_get_index_in_parent (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + + g_return_val_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (accessible), -1); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + /* always the first child of ea-day-view */ + return 0; +} + +/* callbacks */ + +static void +ea_day_view_main_item_dates_change_cb (GnomeCalendar *gcal, gpointer data) +{ + EaDayViewMainItem *ea_main_item; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + g_return_if_fail (data); + g_return_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (data)); + + ea_main_item = EA_DAY_VIEW_MAIN_ITEM (data); + +#ifdef ACC_DEBUG + printf ("EvoAcc: ea_day_view_main_item update cb\n"); +#endif + + ea_day_view_main_item_destory_cell_data (ea_main_item); +} + +static void +ea_day_view_main_item_time_change_cb (EDayView *day_view, gpointer data) +{ + EaDayViewMainItem *ea_main_item; + + g_return_if_fail (E_IS_DAY_VIEW (day_view)); + g_return_if_fail (data); + g_return_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (data)); + + ea_main_item = EA_DAY_VIEW_MAIN_ITEM (data); + +#ifdef ACC_DEBUG + printf ("EvoAcc: ea_day_view_main_item time changed cb\n"); +#endif + g_signal_emit_by_name (data, "selection_changed"); +} + +/* helpers */ + +static gint +ea_day_view_main_item_get_child_index_at (EaDayViewMainItem *ea_main_item, + gint row, gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + + g_return_val_if_fail (ea_main_item, -1); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + if (row >= 0 && row < day_view->rows && + column >= 0 && column < day_view->days_shown) + return column * day_view->rows + row; + return -1; +} + +static gint +ea_day_view_main_item_get_row_at_index (EaDayViewMainItem *ea_main_item, + gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + gint n_children; + + g_return_val_if_fail (ea_main_item, -1); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + n_children = ea_day_view_main_item_get_n_children (ATK_OBJECT (ea_main_item)); + if (index >= 0 && index < n_children) + return index % day_view->rows; + return -1; +} + +static gint +ea_day_view_main_item_get_column_at_index (EaDayViewMainItem *ea_main_item, + gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + gint n_children; + + g_return_val_if_fail (ea_main_item, -1); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + n_children = ea_day_view_main_item_get_n_children (ATK_OBJECT (ea_main_item)); + if (index >= 0 && index < n_children) + return index / day_view->rows; + return -1; +} + +static gint +ea_day_view_main_item_get_row_label (EaDayViewMainItem *ea_main_item, + gint row, gchar *buffer, gint buffer_size) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + gchar *suffix; + gint hour, minute, suffix_width; + + g_return_val_if_fail (ea_main_item, 0); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return 0 ; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + hour = day_view->first_hour_shown; + minute = day_view->first_minute_shown; + minute += row * day_view->mins_per_row; + hour = (hour + minute / 60) % 24; + minute %= 60; + + e_day_view_convert_time_to_display (day_view, hour, &hour, + &suffix, &suffix_width); + return g_snprintf (buffer, buffer_size, "%i:%02i %s", + hour, minute, suffix); +} + +static EaCellTable * +ea_day_view_main_item_get_cell_data (EaDayViewMainItem *ea_main_item) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaCellTable *cell_data; + + g_return_val_if_fail (ea_main_item, NULL); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + cell_data = g_object_get_data (G_OBJECT(ea_main_item), + "ea-day-view-cell-table"); + if (!cell_data) { + cell_data = ea_cell_table_create (day_view->rows, + day_view->days_shown, TRUE); + g_object_set_data (G_OBJECT(ea_main_item), + "ea-day-view-cell-table", cell_data); + } + return cell_data; +} + +static void +ea_day_view_main_item_destory_cell_data (EaDayViewMainItem *ea_main_item) +{ + EaCellTable *cell_data; + + g_return_if_fail (ea_main_item); + + cell_data = g_object_get_data (G_OBJECT(ea_main_item), + "ea-day-view-cell-table"); + if (cell_data) { + ea_cell_table_destroy (cell_data); + g_object_set_data (G_OBJECT(ea_main_item), + "ea-day-view-cell-table", NULL); + } +} + +/* 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 *ea_canvas; + EDayViewMainItem *main_item; + EDayView *day_view; + + *x = *y = *width = *height = 0; + + g_return_if_fail (EA_IS_DAY_VIEW_MAIN_ITEM (component)); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component)); + if (!g_obj) + /* defunct object*/ + return; + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + ea_canvas = gtk_widget_get_accessible (day_view->main_canvas); + atk_component_get_extents (ATK_COMPONENT (ea_canvas), x, y, + width, height, coord_type); +} + +/* 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; + + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + index = ea_day_view_main_item_get_child_index_at (ea_main_item, + row, column); + return ea_day_view_main_item_ref_child (ATK_OBJECT (ea_main_item), index); +} + +static gint +table_interface_get_n_rows (AtkTable *table) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + return day_view->rows; +} + +static gint +table_interface_get_n_columns (AtkTable *table) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + return day_view->days_shown; +} + +static gint +table_interface_get_index_at (AtkTable *table, + gint row, + gint column) +{ + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + return ea_day_view_main_item_get_child_index_at (ea_main_item, + row, column); +} + +static gint +table_interface_get_column_at_index (AtkTable *table, + gint index) +{ + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + return ea_day_view_main_item_get_column_at_index (ea_main_item, index); +} + +static gint +table_interface_get_row_at_index (AtkTable *table, + gint index) +{ + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + return ea_day_view_main_item_get_row_at_index (ea_main_item, index); +} + +static gint +table_interface_get_column_extent_at (AtkTable *table, + gint row, + gint column) +{ + gint index; + gint width = 0, height = 0; + AtkObject *child; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + + index = ea_day_view_main_item_get_child_index_at (ea_main_item, + row, column); + child = atk_object_ref_accessible_child (ATK_OBJECT (ea_main_item), + index); + if (child) + atk_component_get_size (ATK_COMPONENT (child), + &width, &height); + + return width; +} + +static gint +table_interface_get_row_extent_at (AtkTable *table, + gint row, + gint column) +{ + gint index; + gint width = 0, height = 0; + AtkObject *child; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + + index = ea_day_view_main_item_get_child_index_at (ea_main_item, + row, column); + child = atk_object_ref_accessible_child (ATK_OBJECT (ea_main_item), + index); + if (child) + atk_component_get_size (ATK_COMPONENT (child), + &width, &height); + + return height; +} + +static gboolean +table_interface_is_row_selected (AtkTable *table, + gint row) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + if (day_view->selection_start_day == -1) + /* no selection */ + return FALSE; + if (day_view->selection_start_day != day_view->selection_end_day) + /* all row is selected */ + return TRUE; + if (row >= day_view->selection_start_row && + row <= day_view->selection_end_row) + return TRUE; + return FALSE; +} + +static gboolean +table_interface_is_selected (AtkTable *table, + gint row, + gint column) +{ + return table_interface_is_row_selected (table, row) && + table_interface_is_column_selected (table, column); +} + +static gboolean +table_interface_is_column_selected (AtkTable *table, + gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + if (column >= day_view->selection_start_day && + column <= day_view->selection_end_day) + return TRUE; + return FALSE; +} + +static gint +table_interface_get_selected_rows (AtkTable *table, + gint **rows_selected) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + gint start_row = -1, n_rows = 0; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + if (day_view->selection_start_day == -1) + return 0; + + if (day_view->selection_start_day != day_view->selection_end_day) { + /* all the rows should be selected */ + n_rows = day_view->rows; + start_row = 0; + } + else if (day_view->selection_start_row != -1) { + start_row = day_view->selection_start_row; + n_rows = day_view->selection_end_row - start_row + 1; + } + if (n_rows > 0 && start_row != -1 && rows_selected) { + gint index; + + *rows_selected = (gint *) g_malloc (n_rows * sizeof (gint)); + for (index = 0; index < n_rows; ++index) + (*rows_selected)[index] = start_row + index; + } + return n_rows; +} + +static gint +table_interface_get_selected_columns (AtkTable *table, + gint **columns_selected) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + gint start_column = -1, n_columns = 0; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + if (day_view->selection_start_day == -1) + return 0; + + start_column = day_view->selection_start_day; + n_columns = day_view->selection_end_day - start_column + 1; + if (n_columns > 0 && start_column != -1 && columns_selected) { + gint index; + + *columns_selected = (gint *) g_malloc (n_columns * sizeof (gint)); + for (index = 0; index < n_columns; ++index) + (*columns_selected)[index] = start_column + index; + } + return n_columns; +} + +static gboolean +table_interface_add_row_selection (AtkTable *table, + gint row) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + /* FIXME: we need multi-selection */ + + day_view->selection_start_day = 0; + day_view->selection_end_day = 0; + day_view->selection_start_row = row; + day_view->selection_end_row = row; + + e_day_view_ensure_rows_visible (day_view, + day_view->selection_start_row, + day_view->selection_end_row); + e_day_view_update_calendar_selection_time (day_view); + gtk_widget_queue_draw (day_view->main_canvas); + return TRUE; +} + +static gboolean +table_interface_remove_row_selection (AtkTable *table, + gint row) +{ + return FALSE; +} + +static gboolean +table_interface_add_column_selection (AtkTable *table, + gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + /* FIXME: we need multi-selection */ + + day_view->selection_start_day = column; + day_view->selection_end_day = column; + day_view->selection_start_row = 0; + day_view->selection_end_row = day_view->rows; + + e_day_view_update_calendar_selection_time (day_view); + gtk_widget_queue_draw (day_view->main_canvas); + return TRUE; +} + +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; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + const gchar *description; + EaCellTable *cell_data; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + if (in_col < 0 || in_col >= day_view->days_shown) + return NULL; + cell_data = ea_day_view_main_item_get_cell_data (ea_main_item); + if (!cell_data) + return NULL; + + description = ea_cell_table_get_column_label (cell_data, in_col); + if (!description) { + gchar buffer[128]; + e_day_view_top_item_get_day_label (day_view, in_col, buffer, 128); + 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; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (table); + const gchar *description; + EaCellTable *cell_data; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + if (row < 0 || row >= 12 * 24) + return NULL; + cell_data = ea_day_view_main_item_get_cell_data (ea_main_item); + if (!cell_data) + return NULL; + + description = ea_cell_table_get_row_label (cell_data, row); + if (!description) { + gchar buffer[128]; + ea_day_view_main_item_get_row_label (ea_main_item, 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 i) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (selection); + gint column, row; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + row = ea_day_view_main_item_get_row_at_index (ea_main_item, i); + column = ea_day_view_main_item_get_column_at_index (ea_main_item, i); + + if (row == -1 || column == -1) + return FALSE; + + /*FIXME: multi-selection is needed */ + day_view->selection_start_day = column; + day_view->selection_end_day = column; + day_view->selection_start_row = row; + day_view->selection_end_row = row; + + e_day_view_ensure_rows_visible (day_view, + day_view->selection_start_row, + day_view->selection_end_row); + e_day_view_update_calendar_selection_time (day_view); + gtk_widget_queue_draw (day_view->main_canvas); + return TRUE; +} + +static gboolean +selection_interface_clear_selection (AtkSelection *selection) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (selection); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + day_view->selection_start_row = -1; + day_view->selection_start_day = -1; + day_view->selection_end_row = -1; + day_view->selection_end_day = -1; + + e_day_view_update_calendar_selection_time (day_view); + gtk_widget_queue_draw (day_view->main_canvas); + + return TRUE; +} + +static AtkObject* +selection_interface_ref_selection (AtkSelection *selection, gint i) +{ + if (selection_interface_is_child_selected (selection, i)) + return ea_day_view_main_item_ref_child (ATK_OBJECT (selection), i); + return NULL; +} + +static gint +selection_interface_get_selection_count (AtkSelection *selection) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (selection); + gint start_index, end_index; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return 0; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + if (day_view->selection_start_day == -1 || + day_view->selection_start_row == -1) + return 0; + start_index = ea_day_view_main_item_get_child_index_at (ea_main_item, + day_view->selection_start_row, + day_view->selection_start_day); + end_index = ea_day_view_main_item_get_child_index_at (ea_main_item, + day_view->selection_end_row, + day_view->selection_end_day); + + return end_index - start_index + 1; +} + +static gboolean +selection_interface_is_child_selected (AtkSelection *selection, gint i) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewMainItem *main_item; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (selection); + gint column, row; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (ea_main_item); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + main_item = E_DAY_VIEW_MAIN_ITEM (g_obj); + day_view = main_item->day_view; + + row = ea_day_view_main_item_get_row_at_index (ea_main_item, i); + column = ea_day_view_main_item_get_column_at_index (ea_main_item, i); + + if (column < day_view->selection_start_day || + column > day_view->selection_end_day) + return FALSE; + + if ((column == day_view->selection_start_day || + column == day_view->selection_end_day) && + (row < day_view->selection_start_row || + row > day_view->selection_end_row)) + return FALSE; + + /* if comes here, the cell is selected */ + return TRUE; +} diff --git a/a11y/calendar/ea-day-view-main-item.h b/a11y/calendar/ea-day-view-main-item.h new file mode 100644 index 0000000000..d22372d064 --- /dev/null +++ b/a11y/calendar/ea-day-view-main-item.h @@ -0,0 +1,64 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* vim:expandtab:shiftwidth=8:tabstop=8: + */ +/* Evolution Accessibility: ea-day-view-main-item.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 Sun Microsystem Inc., 2003 + * + */ + +#ifndef __EA_DAY_VIEW_MAIN_ITEM_H__ +#define __EA_DAY_VIEW_MAIN_ITEM_H__ + +#include +#include "e-day-view-main-item.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EA_TYPE_DAY_VIEW_MAIN_ITEM (ea_day_view_main_item_get_type ()) +#define EA_DAY_VIEW_MAIN_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_DAY_VIEW_MAIN_ITEM, EaDayViewMainItem)) +#define EA_DAY_VIEW_MAIN_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_DAY_VIEW_MAIN_ITEM, EaDayViewMainItemClass)) +#define EA_IS_DAY_VIEW_MAIN_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_DAY_VIEW_MAIN_ITEM)) +#define EA_IS_DAY_VIEW_MAIN_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_DAY_VIEW_MAIN_ITEM)) +#define EA_DAY_VIEW_MAIN_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_DAY_VIEW_MAIN_ITEM, EaDayViewMainItemClass)) + +typedef struct _EaDayViewMainItem EaDayViewMainItem; +typedef struct _EaDayViewMainItemClass EaDayViewMainItemClass; + +struct _EaDayViewMainItem +{ + AtkGObjectAccessible parent; +}; + +GType ea_day_view_main_item_get_type (void); + +struct _EaDayViewMainItemClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject* ea_day_view_main_item_new (GObject *obj); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EA_DAY_VIEW_MAIN_ITEM_H__ */ diff --git a/a11y/calendar/ea-day-view.c b/a11y/calendar/ea-day-view.c index 65cfb31752..c4b1520916 100644 --- a/a11y/calendar/ea-day-view.c +++ b/a11y/calendar/ea-day-view.c @@ -112,7 +112,7 @@ ea_day_view_new (GtkWidget *widget) atk_object_initialize (accessible, widget); #ifdef ACC_DEBUG - printf ("EvoAcc: ea_day_view created %p\n", accessible); + printf ("EvoAcc: ea_day_view created %p\n", (void *)accessible); #endif return accessible; @@ -122,6 +122,12 @@ static G_CONST_RETURN gchar* ea_day_view_get_name (AtkObject *accessible) { EDayView *day_view; + GnomeCalendar *gcal; + const gchar *label_text; + GnomeCalendarViewType view_type; + gchar buffer[128] = ""; + gint n_events; + g_return_val_if_fail (EA_IS_DAY_VIEW (accessible), NULL); @@ -129,23 +135,24 @@ ea_day_view_get_name (AtkObject *accessible) return NULL; day_view = E_DAY_VIEW (GTK_ACCESSIBLE (accessible)->widget); - if (!accessible->name) { - GnomeCalendar *gcal; - const gchar *label_text; - GnomeCalendarViewType view_type; - - gcal = e_cal_view_get_calendar (E_CAL_VIEW (day_view)); - label_text = calendar_get_text_for_folder_bar_label (gcal); - - view_type = gnome_calendar_get_view (gcal); - if (view_type == GNOME_CAL_WORK_WEEK_VIEW) - accessible->name = g_strconcat ("work week view :", - label_text, - NULL); - else - accessible->name = g_strconcat ("day view :", - label_text, NULL); - } + gcal = e_cal_view_get_calendar (E_CAL_VIEW (day_view)); + label_text = calendar_get_text_for_folder_bar_label (gcal); + + n_events = atk_object_get_n_accessible_children (accessible); + /* the child main item is always there */ + --n_events; + if (n_events > 0) + g_snprintf (buffer, sizeof (buffer), + ", %d events", n_events); + view_type = gnome_calendar_get_view (gcal); + if (view_type == GNOME_CAL_WORK_WEEK_VIEW) + accessible->name = g_strconcat ("work week view :", + label_text, buffer, + NULL); + else + accessible->name = g_strconcat ("day view :", + label_text, buffer, + NULL); return accessible->name; } @@ -196,7 +203,8 @@ ea_day_view_get_n_children (AtkObject *accessible) child_num += day_view->events[day]->len; } - return child_num; + /* "+1" for the main item */ + return child_num + 1; } static AtkObject * @@ -218,28 +226,36 @@ ea_day_view_ref_child (AtkObject *accessible, gint index) return NULL; day_view = E_DAY_VIEW (GTK_ACCESSIBLE (accessible)->widget); - /* a long event */ - if (index < day_view->long_events->len) { - event = &g_array_index (day_view->long_events, - EDayViewEvent, index); + if (index == 0) { + /* index == 0 is the main item */ + atk_object = atk_gobject_accessible_for_object (G_OBJECT (day_view->main_canvas_item)); + g_object_ref (atk_object); } else { - index -= day_view->long_events->len; - day = 0; - while (index >= day_view->events[day]->len) { - index -= day_view->events[day]->len; - ++day; + --index; + /* a long event */ + if (index < day_view->long_events->len) { + event = &g_array_index (day_view->long_events, + EDayViewEvent, index); + } + else { + index -= day_view->long_events->len; + day = 0; + while (index >= day_view->events[day]->len) { + index -= day_view->events[day]->len; + ++day; + } + + event = &g_array_index (day_view->events[day], + EDayViewEvent, index); + } + if (event && event->canvas_item) { + /* Not use atk_gobject_accessible_for_object here, + * we need to do special thing here + */ + atk_object = ea_calendar_helpers_get_accessible_for (event->canvas_item); + g_object_ref (atk_object); } - - event = &g_array_index (day_view->events[day], - EDayViewEvent, index); - } - if (event && event->canvas_item) { - /* Not use atk_gobject_accessible_for_object here, - * we need to do special thing here - */ - atk_object = ea_calendar_helpers_get_accessible_for (event->canvas_item); - g_object_ref (atk_object); } return atk_object; } diff --git a/a11y/calendar/ea-gnome-calendar.c b/a11y/calendar/ea-gnome-calendar.c index 407b8ed95f..9d057ee31a 100644 --- a/a11y/calendar/ea-gnome-calendar.c +++ b/a11y/calendar/ea-gnome-calendar.c @@ -128,7 +128,7 @@ ea_gnome_calendar_new (GtkWidget *widget) } #ifdef ACC_DEBUG - printf ("EvoAcc: ea-gnome-calendar created: %p\n", accessible); + printf ("EvoAcc: ea-gnome-calendar created: %p\n", (void *)accessible); #endif return accessible; @@ -225,7 +225,7 @@ ea_gcal_switch_view_cb (GtkNotebook *widget, GtkNotebookPage *page, #ifdef ACC_DEBUG printf ("AccDebug: view switch to widget %p (index=%d) \n", - new_widget, index); + (void *)new_widget, index); #endif } diff --git a/a11y/calendar/ea-week-view.c b/a11y/calendar/ea-week-view.c index 9917d147d2..f3ca38027e 100644 --- a/a11y/calendar/ea-week-view.c +++ b/a11y/calendar/ea-week-view.c @@ -28,6 +28,7 @@ #include "ea-cal-view-event.h" #include "ea-calendar-helpers.h" #include "calendar-commands.h" +#include static void ea_week_view_class_init (EaWeekViewClass *klass); @@ -37,6 +38,8 @@ static gint ea_week_view_get_n_children (AtkObject *obj); static AtkObject* ea_week_view_ref_child (AtkObject *obj, gint i); +static void get_visible_text_item_count (GnomeCanvasItem *item, gpointer data); + static gpointer parent_class = NULL; GType @@ -113,7 +116,7 @@ ea_week_view_new (GtkWidget *widget) atk_object_initialize (accessible, widget); #ifdef ACC_DEBUG - printf ("EvoAcc: ea_week_view created %p\n", accessible); + printf ("EvoAcc: ea_week_view created %p\n", (void *)accessible); #endif return accessible; @@ -123,6 +126,11 @@ static G_CONST_RETURN gchar* ea_week_view_get_name (AtkObject *accessible) { EWeekView *week_view; + GnomeCalendar *gcal; + const gchar *label_text; + GnomeCalendarViewType view_type; + gchar buffer[128] = ""; + gint n_events; g_return_val_if_fail (EA_IS_WEEK_VIEW (accessible), NULL); @@ -130,27 +138,27 @@ ea_week_view_get_name (AtkObject *accessible) return NULL; week_view = E_WEEK_VIEW (GTK_ACCESSIBLE (accessible)->widget); - if (!accessible->name) { - GnomeCalendar *gcal; - const gchar *label_text; - GnomeCalendarViewType view_type; + gcal = e_cal_view_get_calendar (E_CAL_VIEW (week_view)); + label_text = calendar_get_text_for_folder_bar_label (gcal); - gcal = e_cal_view_get_calendar (E_CAL_VIEW (week_view)); - label_text = calendar_get_text_for_folder_bar_label (gcal); - view_type = gnome_calendar_get_view (gcal); + n_events = atk_object_get_n_accessible_children (accessible); + /* the child main item is always there */ + --n_events; + if (n_events > 0) + g_snprintf (buffer, sizeof (buffer), + ", %d events", n_events); - view_type = gnome_calendar_get_view (gcal); - - if (view_type == GNOME_CAL_MONTH_VIEW) - accessible->name = g_strconcat ("month view :", - label_text, - NULL); + view_type = gnome_calendar_get_view (gcal); + if (view_type == GNOME_CAL_MONTH_VIEW) + accessible->name = g_strconcat ("month view :", + label_text, buffer, + NULL); - else - accessible->name = g_strconcat ("week view :", - label_text, NULL); - } + else + accessible->name = g_strconcat ("week view :", + label_text, buffer, + NULL); return accessible->name; } @@ -185,51 +193,102 @@ static gint ea_week_view_get_n_children (AtkObject *accessible) { EWeekView *week_view; + GnomeCanvasGroup *canvas_group; + gint i, count = 0; g_return_val_if_fail (EA_IS_WEEK_VIEW (accessible), -1); if (!GTK_ACCESSIBLE (accessible)->widget) return -1; week_view = E_WEEK_VIEW (GTK_ACCESSIBLE (accessible)->widget); + canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (week_view->main_canvas)->root); + g_list_foreach (canvas_group->item_list, (GFunc)get_visible_text_item_count, + &count); + + /* add the number of visible jump buttons */ + for (i = 0; i < E_WEEK_VIEW_MAX_WEEKS * 7; i++) { + if (week_view->jump_buttons[i]->object.flags & GNOME_CANVAS_ITEM_VISIBLE) + ++count; + } - return week_view->events->len; +#ifdef ACC_DEBUG + printf("AccDebug: week view %p has %d children\n", (void *)week_view, count); +#endif + return count; } static AtkObject * ea_week_view_ref_child (AtkObject *accessible, gint index) { EWeekView *week_view; - gint child_num; + gint child_num, max_count; AtkObject *atk_object = NULL; - EWeekViewEvent *event; - EWeekViewEventSpan *span; + gint event_index; + gint jump_button = -1; gint span_num = 0; + gint count = 0; g_return_val_if_fail (EA_IS_WEEK_VIEW (accessible), NULL); child_num = atk_object_get_n_accessible_children (accessible); - if (child_num <= 0 || index < 0 || index >= child_num) + if (child_num <= 0 || index < 0 || index >= child_num) return NULL; if (!GTK_ACCESSIBLE (accessible)->widget) return NULL; week_view = E_WEEK_VIEW (GTK_ACCESSIBLE (accessible)->widget); - - event = &g_array_index (week_view->events, - EWeekViewEvent, index); - span = &g_array_index (week_view->spans, EWeekViewEventSpan, - event->spans_index + span_num); - - if (event) { - /* Not use atk_gobject_accessible_for_object here, - * we need to do special thing here - */ - atk_object = ea_calendar_helpers_get_accessible_for (span->text_item); - g_object_ref (atk_object); + max_count = week_view->events->len; + + for (event_index = 0; event_index < max_count; ++event_index) { + EWeekViewEvent *event; + EWeekViewEventSpan *span; + gint current_day; + + event = &g_array_index (week_view->events, + EWeekViewEvent, event_index); + span = &g_array_index (week_view->spans, EWeekViewEventSpan, + event->spans_index + span_num); + + if (!event || !span) + continue; + + current_day = span->start_day; + if (span->text_item) + ++count; + else if (current_day != jump_button) { + /* we should go to the jump button */ + jump_button = current_day; + ++count; + } + else + continue; + + if (count == (index + 1)) { + if (span->text_item) { + /* Not use atk_gobject_accessible_for_object for event + * text_item we need to do special thing here + */ + atk_object = ea_calendar_helpers_get_accessible_for (span->text_item); + } + else { + atk_object = atk_gobject_accessible_for_object (G_OBJECT(week_view->jump_buttons[current_day == -1 ? 0 : current_day])); + } + g_object_ref (atk_object); + break; + } } + #ifdef ACC_DEBUG printf ("EvoAcc: ea_week_view_ref_child [%d]=%p\n", - index, atk_object); + index, (void *)atk_object); #endif return atk_object; } + +static void get_visible_text_item_count (GnomeCanvasItem *item, gpointer data) +{ + gint *count = (gint *)data; + + if (item && E_IS_TEXT (item)) + ++(*count); +} diff --git a/a11y/ea-cell-table.c b/a11y/ea-cell-table.c new file mode 100644 index 0000000000..80f5ecbaaa --- /dev/null +++ b/a11y/ea-cell-table.c @@ -0,0 +1,207 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* vim:expandtab:shiftwidth=8:tabstop=8: + */ +/* Evolution Accessibility: ea-cell-table.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 Sun Microsystem Inc., 2003 + * + */ + +#include "ea-cell-table.h" + +EaCellTable * +ea_cell_table_create (gint rows, gint columns, gboolean column_first) +{ + EaCellTable * cell_data; + gint index; + + g_return_val_if_fail (((columns > 0) && (rows > 0)), NULL); + + cell_data = g_new0 (EaCellTable, 1); + + cell_data->column_first = column_first; + cell_data->columns = columns; + cell_data->rows = rows; + + cell_data->column_labels = g_new0 (gchar*, columns); + for (index = columns -1; index >= 0; --index) + cell_data->column_labels [index] = NULL; + + cell_data->row_labels = g_new0 (gchar*, rows); + for (index = rows -1; index >= 0; --index) + cell_data->row_labels [index] = NULL; + + cell_data->cells = g_new0(gpointer, (columns * rows)); + for (index = (columns * rows) -1; index >= 0; --index) + cell_data->cells [index] = NULL; + return cell_data; +} + +void +ea_cell_table_destroy (EaCellTable * cell_data) +{ + gint index; + g_return_if_fail (cell_data); + + g_print ("destroy cell table (%d, %d)\n", cell_data->rows, + cell_data->columns); + for (index = 0; index < cell_data->columns; ++index) + if (cell_data->column_labels [index]) + g_free (cell_data->column_labels [index]); + g_free (cell_data->column_labels); + + for (index = 0; index < cell_data->rows; ++index) + if (cell_data->row_labels [index]) + g_free (cell_data->row_labels [index]); + g_free (cell_data->row_labels); + + for (index = (cell_data->columns * cell_data->rows) -1; + index >= 0; --index) + if (cell_data->cells[index] && + G_IS_OBJECT (cell_data->cells[index])) + g_object_unref (cell_data->cells[index]); + + g_free (cell_data->cells); +} + +gpointer +ea_cell_table_get_cell (EaCellTable * cell_data, + gint row, gint column) +{ + gint index; + + g_return_val_if_fail (cell_data, NULL); + + index = ea_cell_table_get_index (cell_data, column, row); + if (index == -1) + return NULL; + + return cell_data->cells[index]; +} + +gboolean +ea_cell_table_set_cell (EaCellTable * cell_data, + gint row, gint column, gpointer cell) +{ + gint index; + + g_return_val_if_fail (cell_data, FALSE); + + index = ea_cell_table_get_index (cell_data, column, row); + if (index == -1) + return FALSE; + + if (cell && G_IS_OBJECT(cell)) + g_object_ref (cell); + if (cell_data->cells[index] && + G_IS_OBJECT (cell_data->cells[index])) + g_object_unref (cell_data->cells[index]); + cell_data->cells[index] = cell; + + return TRUE; +} + +gpointer +ea_cell_table_get_cell_at_index (EaCellTable * cell_data, + gint index) +{ + g_return_val_if_fail (cell_data, NULL); + + if (index >=0 && index < (cell_data->columns * cell_data->rows)) + return cell_data->cells [index]; + return NULL; +} + +gboolean +ea_cell_table_set_cell_at_index (EaCellTable * cell_data, + gint index, gpointer cell) +{ + g_return_val_if_fail (cell_data, FALSE); + + if (index < 0 || index >=cell_data->columns * cell_data->rows) + return FALSE; + + if (cell && G_IS_OBJECT(cell)) + g_object_ref (cell); + if (cell_data->cells[index] && + G_IS_OBJECT (cell_data->cells[index])) + g_object_unref (cell_data->cells[index]); + cell_data->cells[index] = cell; + + return TRUE; +} + +G_CONST_RETURN gchar* +ea_cell_table_get_column_label (EaCellTable * cell_data, + gint column) +{ + g_return_val_if_fail (cell_data, NULL); + g_return_val_if_fail ((column >= 0 && column < cell_data->columns), NULL); + + return cell_data->column_labels[column]; +} + +void +ea_cell_table_set_column_label (EaCellTable * cell_data, + gint column, const gchar *label) +{ + g_return_if_fail (cell_data); + g_return_if_fail ((column >= 0 && column < cell_data->columns)); + + if (cell_data->column_labels[column]) + g_free (cell_data->column_labels[column]); + cell_data->column_labels[column] = g_strdup(label); +} + +G_CONST_RETURN gchar* +ea_cell_table_get_row_label (EaCellTable * cell_data, + gint row) +{ + g_return_val_if_fail (cell_data, NULL); + g_return_val_if_fail ((row >= 0 && row < cell_data->rows), NULL); + + return cell_data->row_labels[row]; +} + +void +ea_cell_table_set_row_label (EaCellTable * cell_data, + gint row, const gchar *label) +{ + g_return_if_fail (cell_data); + g_return_if_fail ((row >= 0 && row < cell_data->rows)); + + if (cell_data->row_labels[row]) + g_free (cell_data->row_labels[row]); + cell_data->row_labels[row] = g_strdup(label); +} + +gint +ea_cell_table_get_index (EaCellTable *cell_data, + gint row, gint column) +{ + g_return_val_if_fail (cell_data, -1); + if (row < 0 || row >= cell_data->rows || + column < 0 || column >= cell_data->columns) + return -1; + + if (cell_data->column_first) + return column * cell_data->rows + row; + else + return row * cell_data->columns + column; +} diff --git a/a11y/ea-cell-table.h b/a11y/ea-cell-table.h new file mode 100644 index 0000000000..932fe8b4fd --- /dev/null +++ b/a11y/ea-cell-table.h @@ -0,0 +1,63 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* vim:expandtab:shiftwidth=8:tabstop=8: + */ +/* Evolution Accessibility: ea-table-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 Sun Microsystem Inc., 2003 + * + */ + +/* EaCellTable */ + +#include +#include + +struct _EaCellTable { + gint columns; + gint rows; + gboolean column_first; /* index order */ + gchar **column_labels; + gchar **row_labels; + gpointer *cells; +}; + +typedef struct _EaCellTable EaCellTable; + +EaCellTable * ea_cell_table_create (gint rows, gint columns, + gboolean column_first); +void ea_cell_table_destroy (EaCellTable * cell_data); +gpointer ea_cell_table_get_cell (EaCellTable * cell_data, + gint row, gint column); +gboolean ea_cell_table_set_cell (EaCellTable * cell_data, + gint row, gint column, gpointer cell); +gpointer ea_cell_table_get_cell_at_index (EaCellTable * cell_data, + gint index); +gboolean ea_cell_table_set_cell_at_index (EaCellTable * cell_data, + gint index, gpointer cell); + +G_CONST_RETURN gchar* +ea_cell_table_get_column_label (EaCellTable * cell_data, gint column); +void ea_cell_table_set_column_label (EaCellTable * cell_data, + gint column, const gchar *label); +G_CONST_RETURN gchar* +ea_cell_table_get_row_label (EaCellTable * cell_data, gint row); +void ea_cell_table_set_row_label (EaCellTable * cell_data, + gint row, const gchar *label); +gint ea_cell_table_get_index (EaCellTable *cell_data, + gint row, gint column); -- cgit v1.2.3