diff options
Diffstat (limited to 'calendar')
38 files changed, 6749 insertions, 24 deletions
diff --git a/calendar/gui/Makefile.am b/calendar/gui/Makefile.am index a2b4be2b8f..1b9a5d23c2 100644 --- a/calendar/gui/Makefile.am +++ b/calendar/gui/Makefile.am @@ -172,11 +172,33 @@ libcal_gui_la_SOURCES = \ weekday-picker.c \ weekday-picker.h -# Removed -# $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la +# no gnome-cal no a11y. FIXME: KILL-BONOBO +# a11y/ea-calendar.c \ +# a11y/ea-calendar.h \ +# a11y/ea-calendar-helpers.c \ +# a11y/ea-calendar-helpers.h \ +# a11y/ea-cal-view.c \ +# a11y/ea-cal-view.h \ +# a11y/ea-cal-view-event.c \ +# a11y/ea-cal-view-event.h \ +# a11y/ea-day-view.c \ +# a11y/ea-day-view.h \ +# a11y/ea-day-view-main-item.c \ +# a11y/ea-day-view-main-item.h \ +# a11y/ea-day-view-cell.c \ +# a11y/ea-day-view-cell.h \ +# a11y/ea-week-view.c \ +# a11y/ea-week-view.h \ +# a11y/ea-week-view-main-item.c \ +# a11y/ea-week-view-main-item.h \ +# a11y/ea-week-view-cell.c \ +# a11y/ea-week-view-cell.h \ +# a11y/ea-jump-button.c \ +# a11y/ea-jump-button.h \ +# a11y/ea-gnome-calendar.c \ +# a11y/ea-gnome-calendar.h libcal_gui_la_LIBADD = \ - $(WIN32_BOOTSTRAP_LIBS) \ $(top_builddir)/composer/libcomposer.la \ $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \ $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \ @@ -187,6 +209,7 @@ libcal_gui_la_LIBADD = \ $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \ $(top_builddir)/widgets/e-timezone-dialog/libetimezonedialog.la \ $(top_builddir)/widgets/misc/libemiscwidgets.la \ + $(top_builddir)/widgets/table/libetable.la \ $(top_builddir)/filter/libfilter.la \ $(top_builddir)/e-util/libeutil.la \ $(LIBSOUP_LIBS) \ diff --git a/calendar/gui/a11y/ea-cal-view-event.c b/calendar/gui/a11y/ea-cal-view-event.c new file mode 100644 index 0000000000..49cf525511 --- /dev/null +++ b/calendar/gui/a11y/ea-cal-view-event.c @@ -0,0 +1,570 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-cal-view-event.h" +#include "ea-calendar-helpers.h" +#include "ea-day-view.h" +#include "ea-week-view.h" +#include <text/e-text.h> +#include <glib/gi18n.h> + +static void ea_cal_view_event_class_init (EaCalViewEventClass *klass); +static void ea_cal_view_event_init (EaCalViewEvent *a11y); + +static void ea_cal_view_event_dispose (GObject *object); +static G_CONST_RETURN gchar* ea_cal_view_event_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_cal_view_event_get_description (AtkObject *accessible); +static AtkObject* ea_cal_view_event_get_parent (AtkObject *accessible); +static gint ea_cal_view_event_get_index_in_parent (AtkObject *accessible); +static AtkStateSet *ea_cal_view_event_ref_state_set (AtkObject *accessible); + +/* component interface */ +static void atk_component_interface_init (AtkComponentIface *iface); +static void ea_cal_view_get_extents (AtkComponent *component, + gint *x, gint *y, gint *width, gint *height, + AtkCoordType coord_type); +/* action interface */ +static void atk_action_interface_init (AtkActionIface *iface); +static gboolean ea_cal_view_event_do_action (AtkAction *action, gint i); +static gint ea_cal_view_event_get_n_actions (AtkAction *action); +static G_CONST_RETURN gchar* ea_cal_view_event_action_get_name (AtkAction *action, gint i); + + +#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 +ea_cal_view_event_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaCalViewEventClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_cal_view_event_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaCalViewEvent), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) ea_cal_view_event_init, /* instance init */ + NULL /* value table */ + }; + + static const GInterfaceInfo atk_component_info = { + (GInterfaceInitFunc) atk_component_interface_init, + (GInterfaceFinalizeFunc) NULL, + NULL + }; + + 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 (atk object for E_TEXT, in this case) + */ + + factory = atk_registry_get_factory (atk_get_default_registry (), + E_TYPE_TEXT); + 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; + + /* we inherit the component, text and other interfaces from E_TEXT */ + type = g_type_register_static (derived_atk_type, + "EaCalViewEvent", &tinfo, 0); + g_type_add_interface_static (type, ATK_TYPE_COMPONENT, + &atk_component_info); + g_type_add_interface_static (type, ATK_TYPE_ACTION, + &atk_action_info); + + + } + + return type; +} + +static void +ea_cal_view_event_class_init (EaCalViewEventClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); +#ifdef ACC_DEBUG + gobject_class->finalize = ea_cal_view_finalize; +#endif + + parent_class = g_type_class_peek_parent (klass); + + gobject_class->dispose = ea_cal_view_event_dispose; + + class->get_name = ea_cal_view_event_get_name; + class->get_description = ea_cal_view_event_get_description; + class->get_parent = ea_cal_view_event_get_parent; + class->get_index_in_parent = ea_cal_view_event_get_index_in_parent; + class->ref_state_set = ea_cal_view_event_ref_state_set; + +} + +static void +ea_cal_view_event_init (EaCalViewEvent *a11y) +{ + a11y->state_set = atk_state_set_new (); + atk_state_set_add_state (a11y->state_set, ATK_STATE_TRANSIENT); + atk_state_set_add_state (a11y->state_set, ATK_STATE_ENABLED); + atk_state_set_add_state (a11y->state_set, ATK_STATE_SENSITIVE); + atk_state_set_add_state (a11y->state_set, ATK_STATE_SELECTABLE); + atk_state_set_add_state (a11y->state_set, ATK_STATE_SHOWING); + atk_state_set_add_state (a11y->state_set, ATK_STATE_FOCUSABLE); +} + +#ifdef ACC_DEBUG +static void ea_cal_view_finalize (GObject *object) +{ + G_OBJECT_CLASS (parent_class)->finalize (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) +{ + AtkObject *atk_obj = NULL; + GObject *target_obj; + ECalendarView *cal_view; + + g_return_val_if_fail (E_IS_TEXT (obj), NULL); + cal_view = ea_calendar_helpers_get_cal_view_from (GNOME_CANVAS_ITEM (obj)); + if (!cal_view) + return NULL; + + if (E_IS_WEEK_VIEW (cal_view)) { + gint event_num, span_num; + EWeekViewEvent *week_view_event; + EWeekViewEventSpan *event_span; + EWeekView *week_view = E_WEEK_VIEW (cal_view); + + /* for week view, we need to check if a atkobject exists for + * the first span of the same event + */ + if (!e_week_view_find_event_from_item (week_view, + GNOME_CANVAS_ITEM (obj), + &event_num, + &span_num)) + return NULL; + week_view_event = &g_array_index (week_view->events, + EWeekViewEvent, + event_num); + /* get the first span */ + event_span = &g_array_index (week_view->spans, + EWeekViewEventSpan, + week_view_event->spans_index); + target_obj = G_OBJECT (event_span->text_item); + atk_obj = g_object_get_data (target_obj, "accessible-object"); + + } + else + target_obj = obj; + + if (!atk_obj) { + static AtkRole event_role = ATK_ROLE_INVALID; + atk_obj = ATK_OBJECT (g_object_new (EA_TYPE_CAL_VIEW_EVENT, + NULL)); + atk_object_initialize (atk_obj, target_obj); + if (event_role == ATK_ROLE_INVALID) + event_role = atk_role_register ("Calendar Event"); + atk_obj->role = event_role; +#ifdef ACC_DEBUG + ++n_ea_cal_view_event_created; + printf ("ACC_DEBUG: n_ea_cal_view_event_created = %d\n", + n_ea_cal_view_event_created); +#endif + } + + /* the registered factory for E_TEXT is cannot create a EaCalViewEvent, + * we should save the EaCalViewEvent object in it. + */ + g_object_set_data (obj, "accessible-object", atk_obj); + + return atk_obj; +} + +static void +ea_cal_view_event_dispose (GObject *object) +{ + EaCalViewEvent *a11y = EA_CAL_VIEW_EVENT (object); + + if (a11y->state_set) { + g_object_unref (a11y->state_set); + a11y->state_set = NULL; + } + + if (G_OBJECT_CLASS(parent_class)->dispose) + G_OBJECT_CLASS(parent_class)->dispose (object); +} + +static G_CONST_RETURN gchar* +ea_cal_view_event_get_name (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + ECalendarViewEvent *event; + gchar *name_string; + gchar *alarm_string, *recur_string, *meeting_string, *summary_string; + const char *summary; + + + g_return_val_if_fail (EA_IS_CAL_VIEW_EVENT (accessible), NULL); + + 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)); + + alarm_string = recur_string = meeting_string = ""; + if (event && event->comp_data) { + if (e_cal_util_component_has_alarms (event->comp_data->icalcomp)) + alarm_string = _("It has alarms."); + + if (e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) + recur_string = _("It has recurrences."); + + if (e_cal_util_component_has_organizer (event->comp_data->icalcomp)) + meeting_string = _("It is a meeting."); + + } + + summary = icalcomponent_get_summary (event->comp_data->icalcomp); + if (summary) + summary_string = g_strdup_printf (_("Calendar Event: Summary is %s."), summary); + else + summary_string = g_strdup (_("Calendar Event: It has no summary.")); + + name_string = g_strdup_printf ("%s %s %s %s", summary_string, alarm_string, recur_string, meeting_string); + g_free (summary_string); + + ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_string); +#ifdef ACC_DEBUG + printf("EvoAcc: name for event accobj=%p, is %s\n", + (void *)accessible, new_name); +#endif + g_free (name_string); + return accessible->name; +} + +static G_CONST_RETURN gchar* +ea_cal_view_event_get_description (AtkObject *accessible) +{ + if (accessible->description) + return accessible->description; + + return _("calendar view event"); +} + +static AtkObject * +ea_cal_view_event_get_parent (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + GnomeCanvasItem *canvas_item; + ECalendarView *cal_view; + + g_return_val_if_fail (EA_IS_CAL_VIEW_EVENT (accessible), NULL); + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (g_obj == NULL) + /* Object is defunct */ + return NULL; + canvas_item = GNOME_CANVAS_ITEM (g_obj); + + cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item); + + if (!cal_view) + return NULL; + + return gtk_widget_get_accessible (GTK_WIDGET (cal_view)); +} + +static gint +ea_cal_view_event_get_index_in_parent (AtkObject *accessible) +{ + GObject *g_obj; + GnomeCanvasItem *canvas_item; + ECalendarView *cal_view; + ECalendarViewEvent *cal_view_event; + + g_return_val_if_fail (EA_IS_CAL_VIEW_EVENT (accessible), -1); + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(accessible)); + if (!g_obj) + /* defunct object*/ + return -1; + + canvas_item = GNOME_CANVAS_ITEM (g_obj); + cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item); + if (!cal_view) + return -1; + + cal_view_event = ea_calendar_helpers_get_cal_view_event_from (canvas_item); + if (!cal_view_event) + return -1; + + if (E_IS_DAY_VIEW (cal_view)) { + gint day, event_num, num_before; + EDayViewEvent *day_view_event; + EDayView *day_view = E_DAY_VIEW (cal_view); + + /* the long event comes first in the order */ + for (event_num = day_view->long_events->len - 1; event_num >= 0; + --event_num) { + day_view_event = &g_array_index (day_view->long_events, + EDayViewEvent, event_num); + if (cal_view_event == (ECalendarViewEvent*)day_view_event) + return event_num; + + } + num_before = day_view->long_events->len; + + for (day = 0; day < day_view->days_shown; ++day) { + for (event_num = day_view->events[day]->len - 1; event_num >= 0; + --event_num) { + day_view_event = &g_array_index (day_view->events[day], + EDayViewEvent, event_num); + if (cal_view_event == (ECalendarViewEvent*)day_view_event) + return num_before + event_num; + } + num_before += day_view->events[day]->len; + } + } + else if (E_IS_WEEK_VIEW (cal_view)) { + AtkObject *atk_parent, *atk_child; + gint index = 0; + + atk_parent = atk_object_get_parent (accessible); + while ((atk_child = atk_object_ref_accessible_child (atk_parent, + index)) != NULL) { + if (atk_child == accessible) { + g_object_unref (atk_child); + return index; + } + g_object_unref (atk_child); + ++index; + } + } + else { + g_return_val_if_reached (-1); + } + return -1; +} + +static AtkStateSet * +ea_cal_view_event_ref_state_set (AtkObject *accessible) +{ + EaCalViewEvent *atk_event = EA_CAL_VIEW_EVENT (accessible); + + g_return_val_if_fail (atk_event->state_set, NULL); + + g_object_ref (atk_event->state_set); + + return atk_event->state_set; +} + +/* Atk Component Interface */ + +static void +atk_component_interface_init (AtkComponentIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->get_extents = ea_cal_view_get_extents; +} + +static void +ea_cal_view_get_extents (AtkComponent *component, + gint *x, + gint *y, + gint *width, + gint *height, + AtkCoordType coord_type) +{ + GObject *g_obj; + GnomeCanvasItem *canvas_item; + gint x_window, y_window; + gint scroll_x, scroll_y; + ECalendarView *cal_view; + gint item_x, item_y, item_w, item_h; + GtkWidget *canvas = NULL; + + g_return_if_fail (EA_IS_CAL_VIEW_EVENT (component)); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component)); + if (!g_obj) + /* defunct object*/ + return; + g_return_if_fail (E_IS_TEXT (g_obj)); + + canvas_item = GNOME_CANVAS_ITEM (g_obj); + cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item); + if (!cal_view) + return; + + if (E_IS_DAY_VIEW (cal_view)) { + gint day, event_num; + + if (!e_day_view_find_event_from_item (E_DAY_VIEW (cal_view), + canvas_item, + &day, &event_num)) + return; + if (day == E_DAY_VIEW_LONG_EVENT) { + gint start_day, end_day; + if (!e_day_view_get_long_event_position (E_DAY_VIEW (cal_view), + event_num, + &start_day, + &end_day, + &item_x, + &item_y, + &item_w, + &item_h)) + return; + canvas = E_DAY_VIEW (cal_view)->top_canvas; + } + else { + if (!e_day_view_get_event_position (E_DAY_VIEW (cal_view), day, + event_num, + &item_x, &item_y, + &item_w, &item_h)) + + return; + canvas = E_DAY_VIEW (cal_view)->main_canvas; + } + } + else if (E_IS_WEEK_VIEW (cal_view)) { + gint event_num, span_num; + if (!e_week_view_find_event_from_item (E_WEEK_VIEW (cal_view), + canvas_item, &event_num, + &span_num)) + return; + + if (!e_week_view_get_span_position (E_WEEK_VIEW (cal_view), + event_num, span_num, + &item_x, &item_y, &item_w)) + return; + item_h = E_WEEK_VIEW_ICON_HEIGHT; + canvas = E_WEEK_VIEW (cal_view)->main_canvas; + } + else + return; + + if (!canvas) + return; + + gdk_window_get_origin (canvas->window, + &x_window, &y_window); + gnome_canvas_get_scroll_offsets (GNOME_CANVAS (canvas), &scroll_x, &scroll_y); + + *x = item_x + x_window - scroll_x; + *y = item_y + y_window - scroll_y; + *width = item_w; + *height = item_h; + + if (coord_type == ATK_XY_WINDOW) { + GdkWindow *window; + gint x_toplevel, y_toplevel; + + window = gdk_window_get_toplevel (GTK_WIDGET (cal_view)->window); + gdk_window_get_origin (window, &x_toplevel, &y_toplevel); + + *x -= x_toplevel; + *y -= y_toplevel; + } + +#ifdef ACC_DEBUG + printf ("Event Bounds (%d, %d, %d, %d)\n", *x, *y, *width, *height); +#endif +} + +#define CAL_VIEW_EVENT_ACTION_NUM 1 + +static const char * action_name [CAL_VIEW_EVENT_ACTION_NUM] = { + N_("Grab Focus") +}; + +static void +atk_action_interface_init (AtkActionIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->do_action = ea_cal_view_event_do_action; + iface->get_n_actions = ea_cal_view_event_get_n_actions; + iface->get_name = ea_cal_view_event_action_get_name; +} + +static gboolean +ea_cal_view_event_do_action (AtkAction *action, gint i) +{ + AtkGObjectAccessible *atk_gobj; + AtkComponent *atk_comp; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (action); + + if (i == 0) { + atk_comp = (AtkComponent *)atk_gobj; + return atk_component_grab_focus (atk_comp); + } + + return FALSE; + +} + +static gint +ea_cal_view_event_get_n_actions (AtkAction *action) +{ + return CAL_VIEW_EVENT_ACTION_NUM; +} + +static G_CONST_RETURN gchar* +ea_cal_view_event_action_get_name (AtkAction *action, gint i) +{ + if (i >= 0 && i < CAL_VIEW_EVENT_ACTION_NUM) + return action_name [i]; + return NULL; +} + diff --git a/calendar/gui/a11y/ea-cal-view-event.h b/calendar/gui/a11y/ea-cal-view-event.h new file mode 100644 index 0000000000..c5000095f6 --- /dev/null +++ b/calendar/gui/a11y/ea-cal-view-event.h @@ -0,0 +1,62 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_CAL_VIEW_EVENT_H__ +#define __EA_CAL_VIEW_EVENT_H__ + +#include <atk/atkgobjectaccessible.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EA_TYPE_CAL_VIEW_EVENT (ea_cal_view_event_get_type ()) +#define EA_CAL_VIEW_EVENT(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CAL_VIEW_EVENT, EaCalViewEvent)) +#define EA_CAL_VIEW_EVENT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CAL_VIEW_EVENT, EaCalViewEventClass)) +#define EA_IS_CAL_VIEW_EVENT(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CAL_VIEW_EVENT)) +#define EA_IS_CAL_VIEW_EVENT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CAL_VIEW_EVENT)) +#define EA_CAL_VIEW_EVENT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CAL_VIEW_EVENT, EaCalViewEventClass)) + +typedef struct _EaCalViewEvent EaCalViewEvent; +typedef struct _EaCalViewEventClass EaCalViewEventClass; + +struct _EaCalViewEvent +{ + AtkGObjectAccessible parent; + AtkStateSet *state_set; +}; + +GType ea_cal_view_event_get_type (void); + +struct _EaCalViewEventClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject *ea_cal_view_event_new (GObject *obj); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __EA_CAL_VIEW_EVENT_H__ */ diff --git a/calendar/gui/a11y/ea-cal-view.c b/calendar/gui/a11y/ea-cal-view.c new file mode 100644 index 0000000000..e184b919b9 --- /dev/null +++ b/calendar/gui/a11y/ea-cal-view.c @@ -0,0 +1,426 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-cal-view.h" +#include "ea-calendar-helpers.h" +#include "e-day-view.h" +#include "e-week-view.h" +#include "calendar-commands.h" +#include "goto.h" +#include <glib.h> +#include <glib/gi18n.h> + +static void ea_cal_view_class_init (EaCalViewClass *klass); + +static AtkObject* ea_cal_view_get_parent (AtkObject *accessible); +static void ea_cal_view_real_initialize (AtkObject *accessible, gpointer data); + +static void ea_cal_view_event_changed_cb (ECalendarView *cal_view, + ECalendarViewEvent *event, gpointer data); +static void ea_cal_view_event_added_cb (ECalendarView *cal_view, + ECalendarViewEvent *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 +ea_cal_view_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaCalViewClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_cal_view_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaCalView), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + 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) + */ + + factory = atk_registry_get_factory (atk_get_default_registry (), + GTK_TYPE_WIDGET); + 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, + "EaCalView", &tinfo, 0); + g_type_add_interface_static (type, ATK_TYPE_ACTION, + &atk_action_info); + } + + return type; +} + +static void +ea_cal_view_class_init (EaCalViewClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + class->get_parent = ea_cal_view_get_parent; + class->initialize = ea_cal_view_real_initialize; +} + +AtkObject* +ea_cal_view_new (GtkWidget *widget) +{ + GObject *object; + AtkObject *accessible; + + g_return_val_if_fail (E_IS_CALENDAR_VIEW (widget), NULL); + + object = g_object_new (EA_TYPE_CAL_VIEW, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, widget); + + return accessible; +} + +static void +ea_cal_view_real_initialize (AtkObject *accessible, gpointer data) +{ + ECalendarView *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_CALENDAR_VIEW (data)); + + ATK_OBJECT_CLASS (parent_class)->initialize (accessible, data); + if (role == ATK_ROLE_INVALID) + role = atk_role_register ("Calendar View"); + accessible->role = role; + cal_view = E_CALENDAR_VIEW (data); + + /* add listener for event_changed, event_added + * we don't need to listen on event_removed. When the e_text + * of the event is removed, the cal_view_event will go to the state + * of "defunct" (changed by weak ref callback of atkgobjectaccessible + */ + g_signal_connect (G_OBJECT(cal_view), "event_changed", + G_CALLBACK (ea_cal_view_event_changed_cb), NULL); + g_signal_connect (G_OBJECT(cal_view), "event_added", + G_CALLBACK (ea_cal_view_event_added_cb), NULL); + + /* listen for date changes of calendar */ + gcal = e_calendar_view_get_calendar (cal_view); + + if (gcal) + g_signal_connect (gcal, "dates_shown_changed", + G_CALLBACK (ea_cal_view_dates_change_cb), + accessible); +} + +static AtkObject* +ea_cal_view_get_parent (AtkObject *accessible) +{ + ECalendarView *cal_view; + GnomeCalendar *gnomeCalendar; + + g_return_val_if_fail (EA_IS_CAL_VIEW (accessible), NULL); + + if (!GTK_ACCESSIBLE (accessible)->widget) + return NULL; + cal_view = E_CALENDAR_VIEW (GTK_ACCESSIBLE (accessible)->widget); + + gnomeCalendar = e_calendar_view_get_calendar (cal_view); + + return gtk_widget_get_accessible (GTK_WIDGET(gnomeCalendar)); +} + +static void +ea_cal_view_event_changed_cb (ECalendarView *cal_view, ECalendarViewEvent *event, + gpointer data) +{ + AtkObject *atk_obj; + AtkObject *event_atk_obj = NULL; + + g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); + + atk_obj = gtk_widget_get_accessible (GTK_WIDGET(cal_view)); + if (!EA_IS_CAL_VIEW (atk_obj)) + return; + + if ((E_IS_DAY_VIEW (cal_view)) && event && event->canvas_item) { + event_atk_obj = + ea_calendar_helpers_get_accessible_for (event->canvas_item); + } + else if ((E_IS_WEEK_VIEW (cal_view)) && event) { + EWeekViewEventSpan *span; + EWeekViewEvent *week_view_event = (EWeekViewEvent *)event; + EWeekView *week_view = E_WEEK_VIEW (cal_view); + /* get the first span of the event */ + span = &g_array_index (week_view->spans, EWeekViewEventSpan, + week_view_event->spans_index); + if (span && span->text_item) + event_atk_obj = ea_calendar_helpers_get_accessible_for (span->text_item); + } + if (event_atk_obj) { +#ifdef ACC_DEBUG + 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"); + } + +} + +static void +ea_cal_view_event_added_cb (ECalendarView *cal_view, ECalendarViewEvent *event, + gpointer data) +{ + AtkObject *atk_obj; + AtkObject *event_atk_obj = NULL; + gint index; + + g_return_if_fail (E_IS_CALENDAR_VIEW (cal_view)); + + atk_obj = gtk_widget_get_accessible (GTK_WIDGET(cal_view)); + if (!EA_IS_CAL_VIEW (atk_obj)) + return; + + if ((E_IS_DAY_VIEW (cal_view)) && event && event->canvas_item) { + event_atk_obj = + ea_calendar_helpers_get_accessible_for (event->canvas_item); + } + else if ((E_IS_WEEK_VIEW (cal_view)) && event) { + EWeekViewEventSpan *span; + EWeekViewEvent *week_view_event = (EWeekViewEvent *)event; + EWeekView *week_view = E_WEEK_VIEW (cal_view); + /* get the first span of the event */ + span = &g_array_index (week_view->spans, EWeekViewEventSpan, + week_view_event->spans_index); + if (span && span->text_item) + event_atk_obj = ea_calendar_helpers_get_accessible_for (span->text_item); + + } + if (event_atk_obj) { + index = atk_object_get_index_in_parent (event_atk_obj); + if (index < 0) + return; +#ifdef ACC_DEBUG + 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, NULL, 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) +{ + g_idle_add (idle_dates_changed, data); +} + +/* atk action interface */ + +#define CAL_VIEW_ACTION_NUM 5 + +static const char * action_name [CAL_VIEW_ACTION_NUM] = { + N_("New Appointment"), + N_("New All Day Event"), + N_("New Meeting"), + N_("Go to Today"), + N_("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; + ECalendarView *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_CALENDAR_VIEW (widget); + switch (index) { + case 0: + /* New Appointment */ + e_calendar_view_new_appointment (cal_view); + break; + case 1: + /* New All Day Event */ + e_calendar_view_get_selected_time_range (cal_view, + &dtstart, &dtend); + e_calendar_view_new_appointment_for (cal_view, + dtstart, dtend, TRUE, FALSE); + break; + case 2: + /* New Meeting */ + e_calendar_view_get_selected_time_range (cal_view, + &dtstart, &dtend); + e_calendar_view_new_appointment_for (cal_view, + dtstart, dtend, FALSE, TRUE); + break; + case 3: + /* Go to today */ + break; + calendar_goto_today (e_calendar_view_get_calendar (cal_view)); + case 4: + /* Go to date */ + goto_dialog (e_calendar_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; + + widget = GTK_ACCESSIBLE (action)->widget; + if (widget == NULL) + /* + * State is defunct + */ + return NULL; + + if (!GTK_WIDGET_IS_SENSITIVE (widget) || !GTK_WIDGET_VISIBLE (widget)) + return NULL; + + switch (index) { + case 0: + /* New Appointment */ + return "<Alt>fna;<Control>n"; + case 1: + /* New Event */ + return "<Alt>fnd;<Shift><Control>d"; + case 2: + /* New Meeting */ + return "<Alt>fne;<Shift><Control>e"; + case 3: + /* Go to today */ + return "<Alt>vt;<Alt><Control>t"; + case 4: + /* Go to date */ + return "<Alt>vd;<Alt><Control>g"; + 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/calendar/gui/a11y/ea-cal-view.h b/calendar/gui/a11y/ea-cal-view.h new file mode 100644 index 0000000000..e8ebb9eb37 --- /dev/null +++ b/calendar/gui/a11y/ea-cal-view.h @@ -0,0 +1,62 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_CAL_VIEW_H__ +#define __EA_CAL_VIEW_H__ + +#include <gtk/gtk.h> +#include "e-calendar-view.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EA_TYPE_CAL_VIEW (ea_cal_view_get_type ()) +#define EA_CAL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_CAL_VIEW, EaCalView)) +#define EA_CAL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_CAL_VIEW, EaCalViewClass)) +#define EA_IS_CAL_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_CAL_VIEW)) +#define EA_IS_CAL_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_CAL_VIEW)) +#define EA_CAL_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_CAL_VIEW, EaCalViewClass)) + +typedef struct _EaCalView EaCalView; +typedef struct _EaCalViewClass EaCalViewClass; + +struct _EaCalView +{ + GtkAccessible parent; +}; + +GType ea_cal_view_get_type (void); + +struct _EaCalViewClass +{ + GtkAccessibleClass parent_class; +}; + +AtkObject* ea_cal_view_new (GtkWidget *widget); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EA_CAL_VIEW_H__ */ diff --git a/calendar/gui/a11y/ea-calendar-helpers.c b/calendar/gui/a11y/ea-calendar-helpers.c new file mode 100644 index 0000000000..cc9474c0bc --- /dev/null +++ b/calendar/gui/a11y/ea-calendar-helpers.c @@ -0,0 +1,156 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-calendar-helpers.h" +#include "ea-cal-view-event.h" +#include "ea-jump-button.h" +#include "e-day-view.h" +#include "e-week-view.h" + +#include <text/e-text.h> +#include <libgnomecanvas/gnome-canvas-pixbuf.h> + +/** + * ea_calendar_helpers_get_accessible_for + * @canvas_item: the canvas item for a event or a jump button + * @returns: the atk object for the canvas_item + * + **/ +AtkObject * +ea_calendar_helpers_get_accessible_for (GnomeCanvasItem *canvas_item) +{ + AtkObject *atk_obj = NULL; + GObject *g_obj; + + g_return_val_if_fail ((E_IS_TEXT (canvas_item)) || (GNOME_IS_CANVAS_ITEM (canvas_item)), NULL);; + + g_obj = G_OBJECT (canvas_item); + /* we cannot use atk_gobject_accessible_for_object here, + * EaDayViewEvent/EaWeekViewEvent cannot be created by the + * registered facotry of E_TEXT + */ + atk_obj = g_object_get_data (g_obj, "accessible-object"); + if (!atk_obj) { + if (E_IS_TEXT (canvas_item)) { + atk_obj = ea_cal_view_event_new (g_obj); + } + else if (GNOME_IS_CANVAS_PIXBUF(canvas_item)) { + atk_obj = ea_jump_button_new (g_obj); + } + else + return NULL; + } + return atk_obj; +} + +/** + * ea_calendar_helpers_get_view_widget_from: + * @canvas_item: the canvas item for a event or a jump button + * @returns: the cal view widget if exists + * + * Get the cal view widget contains the canvas_item. + * + **/ +ECalendarView * +ea_calendar_helpers_get_cal_view_from (GnomeCanvasItem *canvas_item) +{ + GnomeCanvas *canvas; + GtkWidget *view_widget = NULL; + + g_return_val_if_fail (canvas_item, NULL); + g_return_val_if_fail ((E_IS_TEXT (canvas_item)) || (GNOME_IS_CANVAS_ITEM (canvas_item)), NULL); + + /* canvas_item is the e_text for the event */ + /* canvas_item->canvas is the ECanvas for day view */ + /* parent of canvas_item->canvas is the EDayView or EWeekView widget */ + canvas = canvas_item->canvas; + view_widget = gtk_widget_get_parent (GTK_WIDGET(canvas)); + if (!view_widget || !E_IS_CALENDAR_VIEW (view_widget)) + return NULL; + + return E_CALENDAR_VIEW (view_widget); +} + +/** + * ea_calendar_helpers_get_cal_view_event_from + * @canvas_item: the cavas_item (e_text) for the event + * @returns: the ECalendarViewEvent + * + * Get the ECalendarViewEvent for the canvas_item. + * + **/ +ECalendarViewEvent * +ea_calendar_helpers_get_cal_view_event_from (GnomeCanvasItem *canvas_item) +{ + ECalendarView *cal_view; + gboolean event_found; + ECalendarViewEvent *cal_view_event; + + g_return_val_if_fail (E_IS_TEXT (canvas_item), NULL); + + cal_view = ea_calendar_helpers_get_cal_view_from (canvas_item); + + if (!cal_view) + return NULL; + + if (E_IS_DAY_VIEW (cal_view)) { + gint event_day, event_num; + EDayViewEvent *day_view_event; + EDayView *day_view = E_DAY_VIEW (cal_view); + event_found = e_day_view_find_event_from_item (day_view, canvas_item, + &event_day, &event_num); + if (!event_found) + return NULL; + if (event_day == E_DAY_VIEW_LONG_EVENT) { + /* a long event */ + day_view_event = &g_array_index (day_view->long_events, + EDayViewEvent, event_num); + } + else { + /* a main canvas event */ + day_view_event = &g_array_index (day_view->events[event_day], + EDayViewEvent, event_num); + } + cal_view_event = (ECalendarViewEvent *) day_view_event; + } + else if (E_IS_WEEK_VIEW (cal_view)) { + gint event_num, span_num; + EWeekViewEvent *week_view_event; + EWeekView *week_view = E_WEEK_VIEW (cal_view); + event_found = e_week_view_find_event_from_item (week_view, + canvas_item, + &event_num, + &span_num); + if (!event_found) + return NULL; + + week_view_event = &g_array_index (week_view->events, EWeekViewEvent, + event_num); + + cal_view_event = (ECalendarViewEvent *)week_view_event; + } + else { + g_return_val_if_reached (NULL); + } + return cal_view_event; +} diff --git a/calendar/gui/a11y/ea-calendar-helpers.h b/calendar/gui/a11y/ea-calendar-helpers.h new file mode 100644 index 0000000000..3c980f2911 --- /dev/null +++ b/calendar/gui/a11y/ea-calendar-helpers.h @@ -0,0 +1,41 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* Evolution Accessibility + */ + +#ifndef _EA_CALENDAR_HELPERS_H__ +#define _EA_CALENDAR_HELPERS_H__ + +#include "ea-cal-view.h" + +AtkObject * +ea_calendar_helpers_get_accessible_for (GnomeCanvasItem *canvas_item); + +ECalendarView * +ea_calendar_helpers_get_cal_view_from (GnomeCanvasItem *canvas_item); + +ECalendarViewEvent * +ea_calendar_helpers_get_cal_view_event_from (GnomeCanvasItem *canvas_item); + +#endif /* _EA_CALENDAR_HELPERS_H__ */ diff --git a/calendar/gui/a11y/ea-calendar.c b/calendar/gui/a11y/ea-calendar.c new file mode 100644 index 0000000000..3cf41f3512 --- /dev/null +++ b/calendar/gui/a11y/ea-calendar.c @@ -0,0 +1,204 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include <text/e-text.h> +#include <libgnomecanvas/gnome-canvas-pixbuf.h> +#include "ea-calendar-helpers.h" +#include "a11y/ea-factory.h" +#include "ea-calendar.h" + +#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-week-view-main-item.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_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_GOBJECT (EA_TYPE_WEEK_VIEW_MAIN_ITEM, ea_week_view_main_item, ea_week_view_main_item_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); + +static gpointer e_text_type, pixbuf_type, e_day_view_type, e_week_view_type; +static gpointer e_day_view_main_item_type, e_week_view_main_item_type; + +void +gnome_calendar_a11y_init (void) +{ + /* we only add focus watcher when accessibility is enabled + */ + if (atk_get_root ()) { + EA_SET_FACTORY (gnome_calendar_get_type(), ea_gnome_calendar); + + /* force loading some types */ + e_text_type = g_type_class_ref (E_TYPE_TEXT); + pixbuf_type = g_type_class_ref (GNOME_TYPE_CANVAS_PIXBUF); + e_day_view_type = g_type_class_ref (e_day_view_get_type ()); + e_week_view_type = g_type_class_ref (e_week_view_get_type ()); + e_day_view_main_item_type = g_type_class_ref (e_day_view_main_item_get_type ()); + e_week_view_main_item_type = g_type_class_ref (e_week_view_main_item_get_type ()); + + 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", GNOME_TYPE_CANVAS_PIXBUF), + 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); + g_signal_add_emission_hook (g_signal_lookup ("event-after", + e_week_view_get_type()), + 0, ea_calendar_focus_watcher, + NULL, (GDestroyNotify) NULL); + g_signal_add_emission_hook (g_signal_lookup ("event", + e_week_view_main_item_get_type()), + 0, ea_calendar_focus_watcher, + NULL, (GDestroyNotify) NULL); + + } +} + +void +e_cal_view_a11y_init (void) +{ + EA_SET_FACTORY (e_calendar_view_get_type(), ea_cal_view); +} + +void +e_day_view_a11y_init (void) +{ + 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); +} + +void +e_week_view_main_item_a11y_init (void) +{ + EA_SET_FACTORY (e_week_view_main_item_get_type (), ea_week_view_main_item); +} + +static gboolean +ea_calendar_focus_watcher (GSignalInvocationHint *ihint, + guint n_param_values, + const GValue *param_values, + gpointer data) +{ + 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)) || (GNOME_IS_CANVAS_PIXBUF (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); + if (!ea_event) + /* not canvas item we want */ + return TRUE; + + } + 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: focus notify on day main item %p\n", (void *)object); +#endif + atk_focus_tracker_notify (ea_event); + } + } else if (E_IS_WEEK_VIEW (object)) { + EWeekView *week_view = E_WEEK_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 (week_view->main_canvas_item); + } + } + } + else if (E_IS_WEEK_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: focus notify on week main item %p\n", (void *)object); +#endif + atk_focus_tracker_notify (ea_event); + } + } + return TRUE; +} diff --git a/calendar/gui/a11y/ea-calendar.h b/calendar/gui/a11y/ea-calendar.h new file mode 100644 index 0000000000..36ef7d5ea0 --- /dev/null +++ b/calendar/gui/a11y/ea-calendar.h @@ -0,0 +1,37 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +/* Evolution Accessibility +*/ + +#ifndef _EA_CALENDAR_H__ +#define _EA_CALENDAR_H__ + +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); +void e_week_view_main_item_a11y_init (void); + +#endif /* _EA_CALENDAR_H__ */ diff --git a/calendar/gui/a11y/ea-day-view-cell.c b/calendar/gui/a11y/ea-day-view-cell.c new file mode 100644 index 0000000000..4698a3ddf4 --- /dev/null +++ b/calendar/gui/a11y/ea-day-view-cell.c @@ -0,0 +1,396 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-day-view-cell.h" +#include "ea-day-view-main-item.h" +#include "ea-day-view.h" +#include "a11y/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); +static gint ea_day_view_cell_get_index_in_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 gboolean component_interface_grab_focus (AtkComponent *component); + +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; + class->get_index_in_parent = ea_day_view_cell_get_index_in_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_UNKNOWN; + +#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) +{ + G_OBJECT_CLASS (parent_class)->finalize (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 atk_gobject_accessible_for_object (G_OBJECT (cell->day_view->main_canvas_item)); +} + +static gint +ea_day_view_cell_get_index_in_parent (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EDayViewCell *cell; + AtkObject *parent; + + g_return_val_if_fail (EA_IS_DAY_VIEW_CELL (accessible), -1); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + cell = E_DAY_VIEW_CELL (g_obj); + parent = atk_object_get_parent (accessible); + return atk_table_get_index_at (ATK_TABLE (parent), + cell->row, cell->column); +} + +/* Atk Component Interface */ + +static void +atk_component_interface_init (AtkComponentIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->get_extents = component_interface_get_extents; + iface->grab_focus = component_interface_grab_focus; +} + +static void +component_interface_get_extents (AtkComponent *component, + gint *x, gint *y, gint *width, gint *height, + AtkCoordType coord_type) +{ + GObject *g_obj; + AtkObject *atk_obj; + 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; + *width = day_view->day_widths[cell->column]; + *height = day_view->row_height; +} + +static gboolean +component_interface_grab_focus (AtkComponent *comp) +{ + GObject *g_obj; + EDayViewCell *cell; + EDayView *day_view; + GtkWidget *toplevel; + + g_return_val_if_fail (EA_IS_DAY_VIEW_CELL (comp), FALSE); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (comp)); + if (!g_obj) + return FALSE; + + cell = E_DAY_VIEW_CELL (g_obj); + day_view = cell->day_view; + + day_view->selection_start_day = cell->column; + day_view->selection_end_day = cell->column; + day_view->selection_start_row = cell->row; + day_view->selection_end_row = cell->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); + + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (day_view)); + if (GTK_WIDGET_TOPLEVEL (toplevel)) + gtk_window_present (GTK_WINDOW (toplevel)); + + return TRUE; +} + diff --git a/calendar/gui/a11y/ea-day-view-cell.h b/calendar/gui/a11y/ea-day-view-cell.h new file mode 100644 index 0000000000..ca674e2451 --- /dev/null +++ b/calendar/gui/a11y/ea-day-view-cell.h @@ -0,0 +1,89 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_DAY_VIEW_CELL_H__ +#define __EA_DAY_VIEW_CELL_H__ + +#include <atk/atkgobjectaccessible.h> +#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/calendar/gui/a11y/ea-day-view-main-item.c b/calendar/gui/a11y/ea-day-view-main-item.c new file mode 100644 index 0000000000..55602e5d92 --- /dev/null +++ b/calendar/gui/a11y/ea-day-view-main-item.c @@ -0,0 +1,1289 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "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" +#include <glib/gi18n.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_calendar_view_get_calendar (E_CALENDAR_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); + + if (!parent) + return NULL; + + 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; + AtkObject *item_cell = NULL; + + 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 + /* only deal with the first selected child, for now */ + item_cell = atk_selection_ref_selection (ATK_SELECTION (ea_main_item), + 0); + if (item_cell) { + AtkStateSet *state_set; + state_set = atk_object_ref_state_set (item_cell); + atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); + g_object_unref (state_set); + + g_signal_emit_by_name (ea_main_item, + "active-descendant-changed", + item_cell); + g_signal_emit_by_name (data, "selection_changed"); + + atk_focus_tracker_notify (item_cell); + g_object_unref (item_cell); + } + +} + +/* 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) { + g_object_set_data (G_OBJECT(ea_main_item), + "ea-day-view-cell-table", NULL); + ea_cell_table_destroy (cell_data); + } +} + +/* 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; + 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; + + 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) +{ + gint count; + GObject *g_obj; + EDayView *day_view; + EaDayViewMainItem* ea_main_item = EA_DAY_VIEW_MAIN_ITEM (selection); + gint start_index; + + count = selection_interface_get_selection_count (selection); + if (i < 0 || i >=count) + return NULL; + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_main_item)); + day_view = E_DAY_VIEW_MAIN_ITEM (g_obj)->day_view; + start_index = ea_day_view_main_item_get_child_index_at (ea_main_item, + day_view->selection_start_row, + day_view->selection_start_day); + + return ea_day_view_main_item_ref_child (ATK_OBJECT (selection), start_index + i); +} + +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/calendar/gui/a11y/ea-day-view-main-item.h b/calendar/gui/a11y/ea-day-view-main-item.h new file mode 100644 index 0000000000..79b166f39a --- /dev/null +++ b/calendar/gui/a11y/ea-day-view-main-item.h @@ -0,0 +1,62 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_DAY_VIEW_MAIN_ITEM_H__ +#define __EA_DAY_VIEW_MAIN_ITEM_H__ + +#include <atk/atkgobjectaccessible.h> +#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/calendar/gui/a11y/ea-day-view.c b/calendar/gui/a11y/ea-day-view.c new file mode 100644 index 0000000000..b43ddbe56f --- /dev/null +++ b/calendar/gui/a11y/ea-day-view.c @@ -0,0 +1,277 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-day-view.h" +#include "ea-cal-view-event.h" + +#include "ea-calendar-helpers.h" +#include "ea-gnome-calendar.h" +#include "calendar-commands.h" +#include <glib.h> +#include <glib/gi18n.h> + +static void ea_day_view_class_init (EaDayViewClass *klass); + +static G_CONST_RETURN gchar* ea_day_view_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_day_view_get_description (AtkObject *accessible); +static gint ea_day_view_get_n_children (AtkObject *obj); +static AtkObject* ea_day_view_ref_child (AtkObject *obj, + gint i); +static gpointer parent_class = NULL; + +GType +ea_day_view_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaDayViewClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_day_view_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaDayView), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + /* + * Figure out the size of the class and instance + * we are run-time deriving from (EaCalView, in this case) + * + * Note: we must still use run-time deriving here, because + * our parent class EaCalView is run-time deriving. + */ + + factory = atk_registry_get_factory (atk_get_default_registry (), + e_calendar_view_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, + "EaDayView", &tinfo, 0); + } + + return type; +} + +static void +ea_day_view_class_init (EaDayViewClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_day_view_get_name; + class->get_description = ea_day_view_get_description; + + class->get_n_children = ea_day_view_get_n_children; + class->ref_child = ea_day_view_ref_child; +} + +AtkObject* +ea_day_view_new (GtkWidget *widget) +{ + GObject *object; + AtkObject *accessible; + + g_return_val_if_fail (E_IS_DAY_VIEW (widget), NULL); + + object = g_object_new (EA_TYPE_DAY_VIEW, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, widget); + +#ifdef ACC_DEBUG + printf ("EvoAcc: ea_day_view created %p\n", (void *)accessible); +#endif + + return accessible; +} + +static G_CONST_RETURN gchar* +ea_day_view_get_name (AtkObject *accessible) +{ + EDayView *day_view; + GnomeCalendar *gcal; + const gchar *label_text; + GnomeCalendarViewType view_type; + gint n_events; + gchar *event_str, *name_str; + + g_return_val_if_fail (EA_IS_DAY_VIEW (accessible), NULL); + + if (!GTK_ACCESSIBLE (accessible)->widget) + return NULL; + + day_view = E_DAY_VIEW (GTK_ACCESSIBLE (accessible)->widget); + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view)); + if (!GTK_WIDGET_VISIBLE (GTK_WIDGET (gcal))) + return NULL; + + label_text = ea_gnome_calendar_get_label_description (gcal); + + n_events = atk_object_get_n_accessible_children (accessible); + /* the child main item is always there */ + --n_events; + if (n_events >= 1) + /* To translators: Here, "It" is either like "Work Week View: July + 10th - July 14th, 2006." or "Day View: Thursday July 13th, 2006." */ + event_str = g_strdup_printf (ngettext ("It has %d event.", "It has %d events.", n_events), n_events); + else + /* To translators: Here, "It" is either like "Work Week View: July + 10th - July 14th, 2006." or "Day View: Thursday July 13th, 2006." */ + event_str = g_strdup (_("It has no events.")); + + view_type = gnome_calendar_get_view (gcal); + if (view_type == GNOME_CAL_WORK_WEEK_VIEW) + /* To translators: First %s is the week, for example "July 10th - + July 14th, 2006". Second %s is the number of events in this work + week, for example "It has %d event/events." or "It has no events." */ + name_str = g_strdup_printf (_("Work Week View: %s. %s"), + label_text, event_str); + else + /* To translators: First %s is the day, for example "Thursday July + 13th, 2006". Second %s is the number of events on this day, for + example "It has %d event/events." or "It has no events." */ + name_str = g_strdup_printf (_("Day View: %s. %s"), + label_text, event_str); + + ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str); + g_free (name_str); + g_free (event_str); + + return accessible->name; +} + +static G_CONST_RETURN gchar* +ea_day_view_get_description (AtkObject *accessible) +{ + EDayView *day_view; + + g_return_val_if_fail (EA_IS_DAY_VIEW (accessible), NULL); + + if (!GTK_ACCESSIBLE (accessible)->widget) + return NULL; + day_view = E_DAY_VIEW (GTK_ACCESSIBLE (accessible)->widget); + + if (accessible->description) + return accessible->description; + else { + GnomeCalendar *gcal; + GnomeCalendarViewType view_type; + + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (day_view)); + view_type = gnome_calendar_get_view (gcal); + + if (view_type == GNOME_CAL_WORK_WEEK_VIEW) + return _("calendar view for a work week"); + else + return _("calendar view for one or more days"); + } +} + +static gint +ea_day_view_get_n_children (AtkObject *accessible) +{ + EDayView *day_view; + gint day; + gint child_num = 0; + + g_return_val_if_fail (EA_IS_DAY_VIEW (accessible), -1); + + if (!GTK_ACCESSIBLE (accessible)->widget) + return -1; + + day_view = E_DAY_VIEW (GTK_ACCESSIBLE (accessible)->widget); + + child_num += day_view->long_events->len; + + for (day = 0; day < day_view->days_shown; day++) { + child_num += day_view->events[day]->len; + } + + /* "+1" for the main item */ + return child_num + 1; +} + +static AtkObject * +ea_day_view_ref_child (AtkObject *accessible, gint index) +{ + EDayView *day_view; + gint child_num; + gint day; + AtkObject *atk_object = NULL; + EDayViewEvent *event = NULL; + + g_return_val_if_fail (EA_IS_DAY_VIEW (accessible), NULL); + + child_num = atk_object_get_n_accessible_children (accessible); + if (child_num <= 0 || index < 0 || index >= child_num) + return NULL; + + if (!GTK_ACCESSIBLE (accessible)->widget) + return NULL; + day_view = E_DAY_VIEW (GTK_ACCESSIBLE (accessible)->widget); + + 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; + /* 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); + } + } + return atk_object; +} diff --git a/calendar/gui/a11y/ea-day-view.h b/calendar/gui/a11y/ea-day-view.h new file mode 100644 index 0000000000..5c4773d048 --- /dev/null +++ b/calendar/gui/a11y/ea-day-view.h @@ -0,0 +1,61 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_DAY_VIEW_H__ +#define __EA_DAY_VIEW_H__ + +#include "ea-cal-view.h" +#include "e-day-view.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EA_TYPE_DAY_VIEW (ea_day_view_get_type ()) +#define EA_DAY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_DAY_VIEW, EaDayView)) +#define EA_DAY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_DAY_VIEW, EaDayViewClass)) +#define EA_IS_DAY_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_DAY_VIEW)) +#define EA_IS_DAY_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_DAY_VIEW)) +#define EA_DAY_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_DAY_VIEW, EaDayViewClass)) + +typedef struct _EaDayView EaDayView; +typedef struct _EaDayViewClass EaDayViewClass; + +struct _EaDayView +{ + EaCalView parent; +}; + +GType ea_day_view_get_type (void); + +struct _EaDayViewClass +{ + EaCalViewClass parent_class; +}; + +AtkObject* ea_day_view_new (GtkWidget *widget); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EA_DAY_VIEW_H__ */ diff --git a/calendar/gui/a11y/ea-gnome-calendar.c b/calendar/gui/a11y/ea-gnome-calendar.c new file mode 100644 index 0000000000..b6eee2699c --- /dev/null +++ b/calendar/gui/a11y/ea-gnome-calendar.c @@ -0,0 +1,351 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-gnome-calendar.h" +#include "calendar-commands.h" +#include <string.h> +#include <gtk/gtk.h> +#include <libecal/e-cal-time-util.h> +#include <libedataserver/e-data-server-util.h> +#include <glib/gi18n.h> + +static void ea_gnome_calendar_class_init (EaGnomeCalendarClass *klass); + +static G_CONST_RETURN gchar* ea_gnome_calendar_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_gnome_calendar_get_description (AtkObject *accessible); +static gint ea_gnome_calendar_get_n_children (AtkObject* obj); +static AtkObject * ea_gnome_calendar_ref_child (AtkObject *obj, gint i); + +static void ea_gcal_switch_view_cb (GtkNotebook *widget, GtkNotebookPage *page, + guint index, gpointer data); +static void ea_gcal_dates_change_cb (GnomeCalendar *gcal, gpointer data); + +static gpointer parent_class = NULL; + +GType +ea_gnome_calendar_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaGnomeCalendarClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_gnome_calendar_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaGnomeCalendar), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + /* + * Figure out the size of the class and instance + * we are run-time deriving from (GailWidget, in this case) + */ + + factory = atk_registry_get_factory (atk_get_default_registry (), + GTK_TYPE_WIDGET); + 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, + "EaGnomeCalendar", &tinfo, 0); + + } + + return type; +} + +static void +ea_gnome_calendar_class_init (EaGnomeCalendarClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_gnome_calendar_get_name; + class->get_description = ea_gnome_calendar_get_description; + + class->get_n_children = ea_gnome_calendar_get_n_children; + class->ref_child = ea_gnome_calendar_ref_child; +} + +AtkObject* +ea_gnome_calendar_new (GtkWidget *widget) +{ + GObject *object; + AtkObject *accessible; + GnomeCalendar *gcal; + GtkWidget *notebook; + + g_return_val_if_fail (GNOME_IS_CALENDAR (widget), NULL); + + object = g_object_new (EA_TYPE_GNOME_CALENDAR, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, widget); + + accessible->role = ATK_ROLE_FILLER; + + gcal = GNOME_CALENDAR (widget); + + /* listen on view type change + */ + g_signal_connect (widget, "dates_shown_changed", + G_CALLBACK (ea_gcal_dates_change_cb), + accessible); + notebook = gnome_calendar_get_view_notebook_widget (gcal); + if (notebook) { + g_signal_connect (notebook, "switch_page", + G_CALLBACK (ea_gcal_switch_view_cb), + accessible); + } + +#ifdef ACC_DEBUG + printf ("EvoAcc: ea-gnome-calendar created: %p\n", (void *)accessible); +#endif + + return accessible; +} + +const gchar * +ea_gnome_calendar_get_label_description (GnomeCalendar *gcal) +{ + icaltimezone *zone; + struct icaltimetype start_tt, end_tt; + time_t start_time, end_time; + struct tm start_tm, end_tm; + static char buffer[512]; + char end_buffer[256]; + GnomeCalendarViewType view; + + gnome_calendar_get_visible_time_range (gcal, &start_time, &end_time); + zone = gnome_calendar_get_timezone (gcal); + + start_tt = icaltime_from_timet_with_zone (start_time, FALSE, zone); + start_tm.tm_year = start_tt.year - 1900; + start_tm.tm_mon = start_tt.month - 1; + start_tm.tm_mday = start_tt.day; + start_tm.tm_hour = start_tt.hour; + start_tm.tm_min = start_tt.minute; + start_tm.tm_sec = start_tt.second; + start_tm.tm_isdst = -1; + start_tm.tm_wday = time_day_of_week (start_tt.day, start_tt.month - 1, + start_tt.year); + + /* Take one off end_time so we don't get an extra day. */ + end_tt = icaltime_from_timet_with_zone (end_time - 1, FALSE, zone); + end_tm.tm_year = end_tt.year - 1900; + end_tm.tm_mon = end_tt.month - 1; + end_tm.tm_mday = end_tt.day; + end_tm.tm_hour = end_tt.hour; + end_tm.tm_min = end_tt.minute; + end_tm.tm_sec = end_tt.second; + end_tm.tm_isdst = -1; + end_tm.tm_wday = time_day_of_week (end_tt.day, end_tt.month - 1, + end_tt.year); + + view = gnome_calendar_get_view (gcal); + + switch (view) { + case GNOME_CAL_DAY_VIEW: + case GNOME_CAL_WORK_WEEK_VIEW: + case GNOME_CAL_WEEK_VIEW: + if (start_tm.tm_year == end_tm.tm_year + && start_tm.tm_mon == end_tm.tm_mon + && start_tm.tm_mday == end_tm.tm_mday) { + e_utf8_strftime (buffer, sizeof (buffer), + _("%A %d %b %Y"), &start_tm); + } else if (start_tm.tm_year == end_tm.tm_year) { + e_utf8_strftime (buffer, sizeof (buffer), + _("%a %d %b"), &start_tm); + e_utf8_strftime (end_buffer, sizeof (end_buffer), + _("%a %d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } else { + e_utf8_strftime (buffer, sizeof (buffer), + _("%a %d %b %Y"), &start_tm); + e_utf8_strftime (end_buffer, sizeof (end_buffer), + _("%a %d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } + break; + case GNOME_CAL_MONTH_VIEW: + case GNOME_CAL_LIST_VIEW: + if (start_tm.tm_year == end_tm.tm_year) { + if (start_tm.tm_mon == end_tm.tm_mon) { + if (start_tm.tm_mday == end_tm.tm_mday) { + buffer [0] = '\0'; + } else { + e_utf8_strftime (buffer, sizeof (buffer), + "%d", &start_tm); + strcat (buffer, " - "); + } + e_utf8_strftime (end_buffer, sizeof (end_buffer), + _("%d %b %Y"), &end_tm); + strcat (buffer, end_buffer); + } else { + e_utf8_strftime (buffer, sizeof (buffer), + _("%d %b"), &start_tm); + e_utf8_strftime (end_buffer, sizeof (end_buffer), + _("%d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } + } else { + e_utf8_strftime (buffer, sizeof (buffer), + _("%d %b %Y"), &start_tm); + e_utf8_strftime (end_buffer, sizeof (end_buffer), + _("%d %b %Y"), &end_tm); + strcat (buffer, " - "); + strcat (buffer, end_buffer); + } + break; + default: + g_return_val_if_reached (NULL); + } + return buffer; +} + +static G_CONST_RETURN gchar* +ea_gnome_calendar_get_name (AtkObject *accessible) +{ + if (accessible->name) + return accessible->name; + return _("Gnome Calendar"); +} + +static G_CONST_RETURN gchar* +ea_gnome_calendar_get_description (AtkObject *accessible) +{ + if (accessible->description) + return accessible->description; + return _("Gnome Calendar"); +} + +static gint +ea_gnome_calendar_get_n_children (AtkObject* obj) +{ + g_return_val_if_fail (EA_IS_GNOME_CALENDAR (obj), 0); + + if (!GTK_ACCESSIBLE (obj)->widget) + return -1; + return 4; +} + +static AtkObject * +ea_gnome_calendar_ref_child (AtkObject *obj, gint i) +{ + AtkObject * child = NULL; + GnomeCalendar * calendarWidget; + GtkWidget *childWidget; + + g_return_val_if_fail (EA_IS_GNOME_CALENDAR (obj), NULL); + /* valid child index range is [0-3] */ + if (i < 0 || i >3 ) + return NULL; + + if (!GTK_ACCESSIBLE (obj)->widget) + return NULL; + calendarWidget = GNOME_CALENDAR (GTK_ACCESSIBLE (obj)->widget); + + switch (i) { + case 0: + /* for the search bar */ + childWidget = gnome_calendar_get_search_bar_widget (calendarWidget); + child = gtk_widget_get_accessible (childWidget); + atk_object_set_parent (child, obj); + atk_object_set_name (child, _("search bar")); + atk_object_set_description (child, _("evolution calendar search bar")); + break; + case 1: + /* for the day/week view */ + childWidget = gnome_calendar_get_current_view_widget (calendarWidget); + child = gtk_widget_get_accessible (childWidget); + atk_object_set_parent (child, obj); + break; + case 2: + /* for calendar */ + childWidget = gnome_calendar_get_e_calendar_widget (calendarWidget); + child = gtk_widget_get_accessible (childWidget); + break; + case 3: + /* for todo list */ + childWidget = GTK_WIDGET (gnome_calendar_get_task_pad (calendarWidget)); + child = gtk_widget_get_accessible (childWidget); + break; + default: + break; + } + if (child) + g_object_ref(child); + return child; +} + +static void +ea_gcal_switch_view_cb (GtkNotebook *widget, GtkNotebookPage *page, + guint index, gpointer data) +{ + GtkWidget *new_widget; + + new_widget = gtk_notebook_get_nth_page (widget, index); + + /* views are always the second child in gnome calendar + */ + if (new_widget) + g_signal_emit_by_name (G_OBJECT(data), "children_changed::add", + 1, gtk_widget_get_accessible (new_widget), NULL); + +#ifdef ACC_DEBUG + printf ("AccDebug: view switch to widget %p (index=%d) \n", + (void *)new_widget, index); +#endif +} + +static void +ea_gcal_dates_change_cb (GnomeCalendar *gcal, gpointer data) +{ + const gchar *new_name; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + g_return_if_fail (data); + g_return_if_fail (EA_IS_GNOME_CALENDAR (data)); + + new_name = ea_gnome_calendar_get_label_description (gcal); + atk_object_set_name (ATK_OBJECT(data), new_name); + g_signal_emit_by_name (data, "visible_data_changed"); + +#ifdef ACC_DEBUG + printf ("AccDebug: calendar dates changed, label=%s\n", new_name); +#endif +} diff --git a/calendar/gui/a11y/ea-gnome-calendar.h b/calendar/gui/a11y/ea-gnome-calendar.h new file mode 100644 index 0000000000..50c43072af --- /dev/null +++ b/calendar/gui/a11y/ea-gnome-calendar.h @@ -0,0 +1,64 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_GNOME_CALENDAR_H__ +#define __EA_GNOME_CALENDAR_H__ + +#include <gtk/gtk.h> +#include "gnome-cal.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EA_TYPE_GNOME_CALENDAR (ea_gnome_calendar_get_type ()) +#define EA_GNOME_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_GNOME_CALENDAR, EaGnomeCalendar)) +#define EA_GNOME_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_GNOME_CALENDAR, EaGnomeCalendarClass)) +#define EA_IS_GNOME_CALENDAR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_GNOME_CALENDAR)) +#define EA_IS_GNOME_CALENDAR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_GNOME_CALENDAR)) +#define EA_GNOME_CALENDAR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_GNOME_CALENDAR, EaGnomeCalendarClass)) + +typedef struct _EaGnomeCalendar EaGnomeCalendar; +typedef struct _EaGnomeCalendarClass EaGnomeCalendarClass; + +struct _EaGnomeCalendar +{ + GtkAccessible parent; +}; + +GType ea_gnome_calendar_get_type (void); + +struct _EaGnomeCalendarClass +{ + GtkAccessibleClass parent_class; +}; + +AtkObject* ea_gnome_calendar_new (GtkWidget *widget); + +const gchar * ea_gnome_calendar_get_label_description (GnomeCalendar *gcal); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __EA_GNOME_CALENDAR_H__ */ diff --git a/calendar/gui/a11y/ea-jump-button.c b/calendar/gui/a11y/ea-jump-button.c new file mode 100644 index 0000000000..cfe8e32cbb --- /dev/null +++ b/calendar/gui/a11y/ea-jump-button.c @@ -0,0 +1,224 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Yang Wu <yang.wu@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-jump-button.h" +#include "ea-calendar-helpers.h" +#include "ea-week-view.h" +#include "e-week-view.h" +#include <libgnomecanvas/gnome-canvas.h> +#include <glib/gi18n.h> + +static void ea_jump_button_class_init (EaJumpButtonClass *klass); + +static G_CONST_RETURN gchar* ea_jump_button_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_jump_button_get_description (AtkObject *accessible); + +/* action interface */ +static void atk_action_interface_init (AtkActionIface *iface); +static gboolean jump_button_do_action (AtkAction *action, + gint i); +static gint jump_button_get_n_actions (AtkAction *action); +static G_CONST_RETURN gchar* jump_button_get_keybinding (AtkAction *action, + gint i); + +static gpointer parent_class = NULL; + +GType +ea_jump_button_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaJumpButtonClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_jump_button_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaJumpButton), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + 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 (atk object for GNOME_TYPE_CANVAS_ITEM, in this case) + */ + + factory = atk_registry_get_factory (atk_get_default_registry (), + GNOME_TYPE_CANVAS_ITEM); + derived_atk_type = atk_object_factory_get_accessible_type (factory); + g_type_query (derived_atk_type, &query); + + tinfo.class_size = query.class_size; + tinfo.instance_size = query.instance_size; + + /* we inherit the component and other interfaces from GNOME_TYPE_CANVAS_ITEM */ + type = g_type_register_static (derived_atk_type, + "EaJumpButton", &tinfo, 0); + + g_type_add_interface_static (type, ATK_TYPE_ACTION, + &atk_action_info); + } + + return type; +} + +static void +ea_jump_button_class_init (EaJumpButtonClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_jump_button_get_name; + class->get_description = ea_jump_button_get_description; +} + +AtkObject* +ea_jump_button_new (GObject *obj) +{ + AtkObject *atk_obj = NULL; + GObject *target_obj; + + g_return_val_if_fail (GNOME_IS_CANVAS_ITEM (obj), NULL); + + target_obj = obj; + atk_obj = g_object_get_data (target_obj, "accessible-object"); + + if (!atk_obj) { + static AtkRole event_role = ATK_ROLE_INVALID; + atk_obj = ATK_OBJECT (g_object_new (EA_TYPE_JUMP_BUTTON, + NULL)); + atk_object_initialize (atk_obj, target_obj); + if (event_role == ATK_ROLE_INVALID) + event_role = atk_role_register ("Jump Button"); + atk_obj->role = event_role; + } + + /* the registered factory for GNOME_TYPE_CANVAS_ITEM is cannot create a EaJumpbutton, + * we should save the EaJumpbutton object in it. + */ + g_object_set_data (obj, "accessible-object", atk_obj); + + return atk_obj; +} + +static G_CONST_RETURN gchar* +ea_jump_button_get_name (AtkObject *accessible) +{ + g_return_val_if_fail (EA_IS_JUMP_BUTTON (accessible), NULL); + + if (accessible->name) + return accessible->name; + return _("Jump button"); +} + +static G_CONST_RETURN gchar* +ea_jump_button_get_description (AtkObject *accessible) +{ + if (accessible->description) + return accessible->description; + + return _("Click here, you can find more events."); +} + +static void +atk_action_interface_init (AtkActionIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->do_action = jump_button_do_action; + iface->get_n_actions = jump_button_get_n_actions; + iface->get_keybinding = jump_button_get_keybinding; +} + +static gboolean +jump_button_do_action (AtkAction *action, + gint i) +{ + gboolean return_value = TRUE; + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + GnomeCanvasItem *item; + ECalendarView *cal_view; + EWeekView *week_view; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (action); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return FALSE; + + item = GNOME_CANVAS_ITEM (g_obj); + cal_view = ea_calendar_helpers_get_cal_view_from (GNOME_CANVAS_ITEM (item)); + week_view = E_WEEK_VIEW (cal_view); + + switch (i) + { + case 0: + e_week_view_jump_to_button_item (week_view, GNOME_CANVAS_ITEM (item)); + break; + default: + return_value = FALSE; + break; + } + return return_value; +} + +static gint +jump_button_get_n_actions (AtkAction *action) +{ + return 1; +} + +static G_CONST_RETURN gchar* +jump_button_get_keybinding (AtkAction *action, + gint i) +{ + gchar *return_value = NULL; + + switch (i) + { + case 0: + { + return_value = "space or enter"; + break; + } + default: + break; + } + return return_value; +} diff --git a/calendar/gui/a11y/ea-jump-button.h b/calendar/gui/a11y/ea-jump-button.h new file mode 100644 index 0000000000..4fbd92022f --- /dev/null +++ b/calendar/gui/a11y/ea-jump-button.h @@ -0,0 +1,62 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Yang Wu <yang.wu@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_JUMP_BUTTON_H__ +#define __EA_JUMP_BUTTON_H__ + +#include <atk/atkgobjectaccessible.h> + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EA_TYPE_JUMP_BUTTON (ea_jump_button_get_type ()) +#define EA_JUMP_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_JUMP_BUTTON, EaJumpButton)) +#define EA_JUMP_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_JUMP_BUTTON, EaJumpButtonClass)) +#define EA_IS_JUMP_BUTTON(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_JUMP_BUTTON)) +#define EA_IS_JUMP_BUTTON_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_JUMP_BUTTON)) +#define EA_JUMP_BUTTON_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_JUMP_BUTTON, EaJumpButtonClass)) + +typedef struct _EaJumpButton EaJumpButton; +typedef struct _EaJumpButtonClass EaJumpButtonClass; + +struct _EaJumpButton +{ + AtkGObjectAccessible parent; +}; + +GType ea_jump_button_get_type (void); + +struct _EaJumpButtonClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject *ea_jump_button_new (GObject *obj); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __EA_JUMP_BUTTON_H__ */ diff --git a/calendar/gui/a11y/ea-week-view-cell.c b/calendar/gui/a11y/ea-week-view-cell.c new file mode 100644 index 0000000000..3ec553b5ba --- /dev/null +++ b/calendar/gui/a11y/ea-week-view-cell.c @@ -0,0 +1,478 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * Yang Wu <Yang.Wu@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-week-view-cell.h" +#include "ea-week-view-main-item.h" +#include "a11y/ea-factory.h" + +/* EWeekViewCell */ + +static void e_week_view_cell_class_init (EWeekViewCellClass *class); + +EA_FACTORY_GOBJECT (EA_TYPE_WEEK_VIEW_CELL, ea_week_view_cell, ea_week_view_cell_new) + +GType +e_week_view_cell_get_type (void) +{ + static GType type = 0; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EWeekViewCellClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) e_week_view_cell_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EWeekViewCell), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + type = g_type_register_static (G_TYPE_OBJECT, + "EWeekViewCell", &tinfo, 0); + } + + return type; +} + +static void +e_week_view_cell_class_init (EWeekViewCellClass *class) +{ + EA_SET_FACTORY (e_week_view_cell_get_type (), ea_week_view_cell); +} + +EWeekViewCell * +e_week_view_cell_new (EWeekView *week_view, gint row, gint column) +{ + GObject *object; + EWeekViewCell *cell; + + g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), NULL); + + object = g_object_new (E_TYPE_WEEK_VIEW_CELL, NULL); + cell = E_WEEK_VIEW_CELL (object); + cell->week_view = week_view; + cell->row = row; + cell->column = column; + +#ifdef ACC_DEBUG + printf ("EvoAcc: e_week_view_cell created %p\n", (void *)cell); +#endif + + return cell; +} + +/* EaWeekViewCell */ + +static void ea_week_view_cell_class_init (EaWeekViewCellClass *klass); + +static G_CONST_RETURN gchar* ea_week_view_cell_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_week_view_cell_get_description (AtkObject *accessible); +static AtkStateSet* ea_week_view_cell_ref_state_set (AtkObject *obj); +static AtkObject * ea_week_view_cell_get_parent (AtkObject *accessible); +static gint ea_week_view_cell_get_index_in_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 gboolean component_interface_grab_focus (AtkComponent *component); + +static gpointer parent_class = NULL; + +#ifdef ACC_DEBUG +static gint n_ea_week_view_cell_created = 0, n_ea_week_view_cell_destroyed = 0; +static void ea_week_view_cell_finalize (GObject *object); +#endif + +GType +ea_week_view_cell_get_type (void) +{ + static GType type = 0; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaWeekViewCellClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_week_view_cell_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaWeekViewCell), /* 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, + "EaWeekViewCell", &tinfo, 0); + g_type_add_interface_static (type, ATK_TYPE_COMPONENT, + &atk_component_info); + + } + + return type; +} + +static void +ea_week_view_cell_class_init (EaWeekViewCellClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + +#ifdef ACC_DEBUG + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + gobject_class->finalize = ea_week_view_cell_finalize; +#endif + + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_week_view_cell_get_name; + class->get_description = ea_week_view_cell_get_description; + class->ref_state_set = ea_week_view_cell_ref_state_set; + + class->get_parent = ea_week_view_cell_get_parent; + class->get_index_in_parent = ea_week_view_cell_get_index_in_parent; + +} + +AtkObject* +ea_week_view_cell_new (GObject *obj) +{ + gpointer object; + AtkObject *atk_object; + + g_return_val_if_fail (E_IS_WEEK_VIEW_CELL (obj), NULL); + object = g_object_new (EA_TYPE_WEEK_VIEW_CELL, NULL); + atk_object = ATK_OBJECT (object); + atk_object_initialize (atk_object, obj); + atk_object->role = ATK_ROLE_UNKNOWN; + +#ifdef ACC_DEBUG + ++n_ea_week_view_cell_created; + printf ("ACC_DEBUG: n_ea_week_view_cell_created = %d\n", + n_ea_week_view_cell_created); +#endif + return atk_object; +} + +#ifdef ACC_DEBUG +static void ea_week_view_cell_finalize (GObject *object) +{ + G_OBJECT_CLASS (parent_class)->finalize (object); + + ++n_ea_week_view_cell_destroyed; + printf ("ACC_DEBUG: n_ea_week_view_cell_destroyed = %d\n", + n_ea_week_view_cell_destroyed); +} +#endif + +static G_CONST_RETURN gchar* +ea_week_view_cell_get_name (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewCell *cell; + + g_return_val_if_fail (EA_IS_WEEK_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; + gint new_column, new_row; + gint start_day; + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return NULL; + + cell = E_WEEK_VIEW_CELL (g_obj); + main_item = cell->week_view->main_canvas_item; + ea_main_item = atk_gobject_accessible_for_object (G_OBJECT (main_item)); + + start_day = cell->week_view->display_start_day; + if (cell->column + start_day >= 7) { + new_column = cell->column + start_day - 7; + new_row = cell->row + 1; + } else { + new_column = cell->column + start_day; + new_row = cell->row; + } + + column_label = atk_table_get_column_description (ATK_TABLE (ea_main_item), + new_column); + row_label = atk_table_get_row_description (ATK_TABLE (ea_main_item), + new_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_week_view_cell_get_description (AtkObject *accessible) +{ + return ea_week_view_cell_get_name (accessible); +} + +static AtkStateSet* +ea_week_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_week_view_cell_get_parent (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewCell *cell; + + g_return_val_if_fail (EA_IS_WEEK_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_WEEK_VIEW_CELL (g_obj); + return atk_gobject_accessible_for_object (G_OBJECT (cell->week_view->main_canvas_item)); +} + +static gint +ea_week_view_cell_get_index_in_parent (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewCell *cell; + AtkObject *parent; + + g_return_val_if_fail (EA_IS_WEEK_VIEW_CELL (accessible), -1); + + atk_gobj = ATK_GOBJECT_ACCESSIBLE (accessible); + g_obj = atk_gobject_accessible_get_object (atk_gobj); + if (!g_obj) + return -1; + + cell = E_WEEK_VIEW_CELL (g_obj); + parent = atk_object_get_parent (accessible); + return atk_table_get_index_at (ATK_TABLE (parent), + cell->row, cell->column); +} + +/* Atk Component Interface */ + +static void +atk_component_interface_init (AtkComponentIface *iface) +{ + g_return_if_fail (iface != NULL); + + iface->get_extents = component_interface_get_extents; + iface->grab_focus = component_interface_grab_focus; +} + +static void +component_interface_get_extents (AtkComponent *component, + gint *x, gint *y, gint *width, gint *height, + AtkCoordType coord_type) +{ + GObject *g_obj; + AtkObject *atk_obj; + EWeekViewCell *cell; + EWeekView *week_view; + GtkWidget *main_canvas; + gint week_view_width, week_view_height; + gint scroll_x, scroll_y; + gint start_day; + + *x = *y = *width = *height = 0; + + g_return_if_fail (EA_IS_WEEK_VIEW_CELL (component)); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component)); + if (!g_obj) + /* defunct object*/ + return; + + cell = E_WEEK_VIEW_CELL (g_obj); + week_view = cell->week_view; + main_canvas = cell->week_view->main_canvas; + + atk_obj = atk_gobject_accessible_for_object (G_OBJECT (main_canvas)); + atk_component_get_extents (ATK_COMPONENT (atk_obj), + x, y, + &week_view_width, &week_view_height, + coord_type); + gnome_canvas_get_scroll_offsets (GNOME_CANVAS (week_view->main_canvas), + &scroll_x, &scroll_y); + start_day = week_view->display_start_day; + if (week_view->multi_week_view) { + if (week_view->compress_weekend && (cell->column == (5 - start_day))) { + *height = week_view->row_heights[cell->row*2]; + *width = week_view->col_widths[cell->column]; + *x += week_view->col_offsets[cell->column] - scroll_x; + *y += week_view->row_offsets[cell->row*2]- scroll_y; + } else if (week_view->compress_weekend && (cell->column == (6 - start_day))) { + *height = week_view->row_heights[cell->row*2]; + *width = week_view->col_widths[cell->column - 1]; + *x += week_view->col_offsets[cell->column - 1]- scroll_x; + *y += week_view->row_offsets[cell->row*2 + 1]- scroll_y; + } else if (week_view->compress_weekend && (cell->column > (6 - start_day))){ + *height = week_view->row_heights[cell->row*2]*2; + *width = week_view->col_widths[cell->column - 1]; + *x += week_view->col_offsets[cell->column - 1] - scroll_x; + *y += week_view->row_offsets[cell->row*2]- scroll_y; + } else { + *height = week_view->row_heights[cell->row*2]*2; + *width = week_view->col_widths[cell->column]; + *x += week_view->col_offsets[cell->column] - scroll_x; + *y += week_view->row_offsets[cell->row*2]- scroll_y; + } + } else { + if (start_day < 3) { + if (cell->column < 3) { + *height = week_view->row_heights[cell->column*2]*2; + *width = week_view->col_widths[0]; + *x += week_view->col_offsets[0] - scroll_x; + *y += week_view->row_offsets[cell->column*2]- scroll_y; + } else { + if (cell->column == 5 - start_day) { + *height = week_view->row_heights[(cell->column - 3)*2]; + *width = week_view->col_widths[1]; + *x += week_view->col_offsets[1] - scroll_x; + *y += week_view->row_offsets[(cell->column - 3)*2]- scroll_y; + } else if (cell->column == 6 - start_day) { + *height = week_view->row_heights[(cell->column - 4)*2]; + *width = week_view->col_widths[1]; + *x += week_view->col_offsets[1] - scroll_x; + *y += week_view->row_offsets[(cell->column - 3)*2 - 1]- scroll_y; + } else if (cell->column > 6 - start_day) { + *height = week_view->row_heights[(cell->column - 4)*2]*2; + *width = week_view->col_widths[1]; + *x += week_view->col_offsets[1] - scroll_x; + *y += week_view->row_offsets[(cell->column - 4)*2]- scroll_y; + } else { + *height = week_view->row_heights[(cell->column - 3)*2]*2; + *width = week_view->col_widths[1]; + *x += week_view->col_offsets[1] - scroll_x; + *y += week_view->row_offsets[(cell->column - 3)*2]- scroll_y; + } + } + } else if (cell->column < 4) { + if (cell->column == 5 - start_day) { + *height = week_view->row_heights[cell->column*2]; + *width = week_view->col_widths[0]; + *x += week_view->col_offsets[0] - scroll_x; + *y += week_view->row_offsets[cell->column*2]- scroll_y; + } else if (cell->column == 6 - start_day) { + *height = week_view->row_heights[(cell->column - 1)*2]; + *width = week_view->col_widths[0]; + *x += week_view->col_offsets[0] - scroll_x; + *y += week_view->row_offsets[cell->column*2 - 1]- scroll_y; + } else if (cell->column > 6 - start_day) { + *height = week_view->row_heights[(cell->column - 1)*2]*2; + *width = week_view->col_widths[0]; + *x += week_view->col_offsets[0] - scroll_x; + *y += week_view->row_offsets[(cell->column - 1)*2]- scroll_y; + } else { + *height = week_view->row_heights[(cell->column)*2]*2; + *width = week_view->col_widths[0]; + *x += week_view->col_offsets[0] - scroll_x; + *y += week_view->row_offsets[cell->column*2]- scroll_y; + } + } else { + *height = week_view->row_heights[(cell->column - 4)*2]*2; + *width = week_view->col_widths[1]; + *x += week_view->col_offsets[1] - scroll_x; + *y += week_view->row_offsets[(cell->column - 4)*2]- scroll_y; + } + } +} + +static gboolean +component_interface_grab_focus (AtkComponent *comp) +{ + GObject *g_obj; + EWeekViewCell *cell; + EWeekView *week_view; + GtkWidget *toplevel; + + g_return_val_if_fail (EA_IS_WEEK_VIEW_CELL (comp), FALSE); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (comp)); + if (!g_obj) + return FALSE; + + cell = E_WEEK_VIEW_CELL (g_obj); + week_view = cell->week_view; + + week_view->selection_start_day = cell->row * 7 + cell->column; + week_view->selection_end_day = cell->row * 7 + cell->column; + gtk_widget_queue_draw (week_view->main_canvas); + + toplevel = gtk_widget_get_toplevel (GTK_WIDGET (week_view)); + if (GTK_WIDGET_TOPLEVEL (toplevel)) + gtk_window_present (GTK_WINDOW (toplevel)); + + return TRUE; +} diff --git a/calendar/gui/a11y/ea-week-view-cell.h b/calendar/gui/a11y/ea-week-view-cell.h new file mode 100644 index 0000000000..b09d7d1789 --- /dev/null +++ b/calendar/gui/a11y/ea-week-view-cell.h @@ -0,0 +1,89 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * Yang Wu <yang.wu@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_WEEK_VIEW_CELL_H__ +#define __EA_WEEK_VIEW_CELL_H__ + +#include <atk/atkgobjectaccessible.h> +#include "e-week-view.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define E_TYPE_WEEK_VIEW_CELL (e_week_view_cell_get_type ()) +#define E_WEEK_VIEW_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), E_TYPE_WEEK_VIEW_CELL, EWeekViewCell)) +#define E_WEEK_VIEW_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), E_TYPE_WEEK_VIEW_CELL, EWeekViewCellClass)) +#define E_IS_WEEK_VIEW_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), E_TYPE_WEEK_VIEW_CELL)) +#define E_IS_WEEK_VIEW_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), E_TYPE_WEEK_VIEW_CELL)) +#define E_WEEK_VIEW_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), E_TYPE_WEEK_VIEW_CELL, EWeekViewCellClass)) + +typedef struct _EWeekViewCell EWeekViewCell; +typedef struct _EWeekViewCellClass EWeekViewCellClass; + +struct _EWeekViewCell +{ + GObject parent; + EWeekView *week_view; + gint row; + gint column; +}; + +GType e_week_view_cell_get_type (void); + +struct _EWeekViewCellClass +{ + GObjectClass parent_class; +}; + +EWeekViewCell * e_week_view_cell_new (EWeekView *week_view, gint row, gint column); + +#define EA_TYPE_WEEK_VIEW_CELL (ea_week_view_cell_get_type ()) +#define EA_WEEK_VIEW_CELL(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_WEEK_VIEW_CELL, EaWeekViewCell)) +#define EA_WEEK_VIEW_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_WEEK_VIEW_CELL, EaWeekViewCellClass)) +#define EA_IS_WEEK_VIEW_CELL(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_WEEK_VIEW_CELL)) +#define EA_IS_WEEK_VIEW_CELL_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_WEEK_VIEW_CELL)) +#define EA_WEEK_VIEW_CELL_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_WEEK_VIEW_CELL, EaWeekViewCellClass)) + +typedef struct _EaWeekViewCell EaWeekViewCell; +typedef struct _EaWeekViewCellClass EaWeekViewCellClass; + +struct _EaWeekViewCell +{ + AtkGObjectAccessible parent; +}; + +GType ea_week_view_cell_get_type (void); + +struct _EaWeekViewCellClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject* ea_week_view_cell_new (GObject *gobj); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EA_WEEK_VIEW_CELL_H__ */ diff --git a/calendar/gui/a11y/ea-week-view-main-item.c b/calendar/gui/a11y/ea-week-view-main-item.c new file mode 100644 index 0000000000..5bfb73306b --- /dev/null +++ b/calendar/gui/a11y/ea-week-view-main-item.c @@ -0,0 +1,1247 @@ +/* + * Evolution Accessibility: ea-week-view-main-item.c + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-week-view-main-item.h" +#include "ea-week-view.h" +#include "ea-week-view-cell.h" +#include "ea-cell-table.h" +#include <glib/gi18n.h> + +/* EaWeekViewMainItem */ +static void ea_week_view_main_item_class_init (EaWeekViewMainItemClass *klass); + +static void ea_week_view_main_item_finalize (GObject *object); +static G_CONST_RETURN gchar* ea_week_view_main_item_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_week_view_main_item_get_description (AtkObject *accessible); + +static gint ea_week_view_main_item_get_n_children (AtkObject *obj); +static AtkObject* ea_week_view_main_item_ref_child (AtkObject *obj, + gint i); +static AtkObject * ea_week_view_main_item_get_parent (AtkObject *accessible); +static gint ea_week_view_main_item_get_index_in_parent (AtkObject *accessible); + +/* callbacks */ +static void ea_week_view_main_item_dates_change_cb (GnomeCalendar *gcal, gpointer data); +static void ea_week_view_main_item_time_change_cb (EWeekView *week_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_week_view_main_item_get_cell_data (EaWeekViewMainItem *ea_main_item); + +static void +ea_week_view_main_item_destory_cell_data (EaWeekViewMainItem *ea_main_item); + +static gint +ea_week_view_main_item_get_child_index_at (EaWeekViewMainItem *ea_main_item, + gint row, gint column); +static gint +ea_week_view_main_item_get_row_at_index (EaWeekViewMainItem *ea_main_item, + gint index); +static gint +ea_week_view_main_item_get_column_at_index (EaWeekViewMainItem *ea_main_item, + gint index); +static gint +ea_week_view_main_item_get_row_label (EaWeekViewMainItem *ea_main_item, + gint row, gchar *buffer, + gint buffer_size); + +#ifdef ACC_DEBUG +static gint n_ea_week_view_main_item_created = 0; +static gint n_ea_week_view_main_item_destroyed = 0; +#endif + +static gpointer parent_class = NULL; + +GType +ea_week_view_main_item_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaWeekViewMainItemClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_week_view_main_item_class_init, + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaWeekViewMainItem), /* 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_week_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, + "EaWeekViewMainItem", &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_week_view_main_item_class_init (EaWeekViewMainItemClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + gobject_class->finalize = ea_week_view_main_item_finalize; + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_week_view_main_item_get_name; + class->get_description = ea_week_view_main_item_get_description; + + class->get_n_children = ea_week_view_main_item_get_n_children; + class->ref_child = ea_week_view_main_item_ref_child; + class->get_parent = ea_week_view_main_item_get_parent; + class->get_index_in_parent = ea_week_view_main_item_get_index_in_parent; +} + +AtkObject* +ea_week_view_main_item_new (GObject *obj) +{ + AtkObject *accessible; + GnomeCalendar *gcal; + EWeekViewMainItem *main_item; + + g_return_val_if_fail (E_IS_WEEK_VIEW_MAIN_ITEM (obj), NULL); + + accessible = ATK_OBJECT (g_object_new (EA_TYPE_WEEK_VIEW_MAIN_ITEM, + NULL)); + + atk_object_initialize (accessible, obj); + accessible->role = ATK_ROLE_TABLE; + +#ifdef ACC_DEBUG + ++n_ea_week_view_main_item_created; + printf ("ACC_DEBUG: n_ea_week_view_main_item_created = %d\n", + n_ea_week_view_main_item_created); +#endif + main_item = E_WEEK_VIEW_MAIN_ITEM (obj); + g_signal_connect (main_item->week_view, "selected_time_changed", + G_CALLBACK (ea_week_view_main_item_time_change_cb), + accessible); + + /* listen for date changes of calendar */ + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (main_item->week_view)); + if (gcal) + g_signal_connect (gcal, "dates_shown_changed", + G_CALLBACK (ea_week_view_main_item_dates_change_cb), + accessible); + + return accessible; +} + +static void +ea_week_view_main_item_finalize (GObject *object) +{ + EaWeekViewMainItem *ea_main_item; + + g_return_if_fail (EA_IS_WEEK_VIEW_MAIN_ITEM (object)); + + ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (object); + + /* Free the allocated cell data */ + ea_week_view_main_item_destory_cell_data (ea_main_item); + + G_OBJECT_CLASS (parent_class)->finalize (object); +#ifdef ACC_DEBUG + ++n_ea_week_view_main_item_destroyed; + printf ("ACC_DEBUG: n_ea_week_view_main_item_destroyed = %d\n", + n_ea_week_view_main_item_destroyed); +#endif +} + +static G_CONST_RETURN gchar* +ea_week_view_main_item_get_name (AtkObject *accessible) +{ + AtkObject *parent; + g_return_val_if_fail (EA_IS_WEEK_VIEW_MAIN_ITEM (accessible), NULL); + parent = atk_object_get_parent (accessible); + return atk_object_get_name (parent); + +} + +static G_CONST_RETURN gchar* +ea_week_view_main_item_get_description (AtkObject *accessible) +{ + return _("a table to view and select the current time range"); +} + +static gint +ea_week_view_main_item_get_n_children (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewMainItem *main_item; + EWeekView *week_view; + + g_return_val_if_fail (EA_IS_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if (week_view->multi_week_view) + return 7 * week_view->weeks_shown; + else + return 7; +} + +static AtkObject * +ea_week_view_main_item_ref_child (AtkObject *accessible, gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewMainItem *main_item; + EWeekView *week_view; + gint n_children; + EWeekViewCell *cell; + EaCellTable *cell_data; + EaWeekViewMainItem *ea_main_item; + + g_return_val_if_fail (EA_IS_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + n_children = ea_week_view_main_item_get_n_children (accessible); + if (index < 0 || index >= n_children) + return NULL; + + ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (accessible); + cell_data = ea_week_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_week_view_main_item_get_row_at_index (ea_main_item, index); + column = ea_week_view_main_item_get_column_at_index (ea_main_item, index); + cell = e_week_view_cell_new (week_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_week_view_main_item_get_parent (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewMainItem *main_item; + + g_return_val_if_fail (EA_IS_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + return gtk_widget_get_accessible (GTK_WIDGET (main_item->week_view)); +} + +static gint +ea_week_view_main_item_get_index_in_parent (AtkObject *accessible) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + + g_return_val_if_fail (EA_IS_WEEK_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-week-view */ + return 0; +} + +/* callbacks */ + +static void +ea_week_view_main_item_dates_change_cb (GnomeCalendar *gcal, gpointer data) +{ + EaWeekViewMainItem *ea_main_item; + + g_return_if_fail (GNOME_IS_CALENDAR (gcal)); + g_return_if_fail (data); + g_return_if_fail (EA_IS_WEEK_VIEW_MAIN_ITEM (data)); + + ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (data); + +#ifdef ACC_DEBUG + printf ("EvoAcc: ea_week_view_main_item update cb\n"); +#endif + + ea_week_view_main_item_destory_cell_data (ea_main_item); +} + +static void +ea_week_view_main_item_time_change_cb (EWeekView *week_view, gpointer data) +{ + EaWeekViewMainItem *ea_main_item; + AtkObject *item_cell = NULL; + + g_return_if_fail (E_IS_WEEK_VIEW (week_view)); + g_return_if_fail (data); + g_return_if_fail (EA_IS_WEEK_VIEW_MAIN_ITEM (data)); + + ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (data); + +#ifdef ACC_DEBUG + printf ("EvoAcc: ea_week_view_main_item time changed cb\n"); +#endif + /* only deal with the first selected child, for now */ + item_cell = atk_selection_ref_selection (ATK_SELECTION (ea_main_item), + 0); + if (item_cell) { + AtkStateSet *state_set; + state_set = atk_object_ref_state_set (item_cell); + atk_state_set_add_state (state_set, ATK_STATE_FOCUSED); + g_object_unref (state_set); + + g_signal_emit_by_name (ea_main_item, + "active-descendant-changed", + item_cell); + g_signal_emit_by_name (data, "selection_changed"); + atk_focus_tracker_notify (item_cell); + g_object_unref (item_cell); + } +} + +/* helpers */ + +static gint +ea_week_view_main_item_get_child_index_at (EaWeekViewMainItem *ea_main_item, + gint row, gint column) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewMainItem *main_item; + EWeekView *week_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if (row >= 0 && row < week_view->weeks_shown && + column >= 0 && column < 7) + return row * 7 + column; + + return -1; +} + +static gint +ea_week_view_main_item_get_row_at_index (EaWeekViewMainItem *ea_main_item, + gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + 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; + + n_children = ea_week_view_main_item_get_n_children (ATK_OBJECT (ea_main_item)); + if (index >= 0 && index < n_children) + return index / 7; + return -1; +} + +static gint +ea_week_view_main_item_get_column_at_index (EaWeekViewMainItem *ea_main_item, + gint index) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + 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; + + n_children = ea_week_view_main_item_get_n_children (ATK_OBJECT (ea_main_item)); + if (index >= 0 && index < n_children) + return index % 7; + return -1; +} + +static gint +ea_week_view_main_item_get_row_label (EaWeekViewMainItem *ea_main_item, + gint row, gchar *buffer, gint buffer_size) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + + 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 ; + + return g_snprintf (buffer, buffer_size, "the %i week", + row + 1); + +} + +static EaCellTable * +ea_week_view_main_item_get_cell_data (EaWeekViewMainItem *ea_main_item) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewMainItem *main_item; + EWeekView *week_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + cell_data = g_object_get_data (G_OBJECT(ea_main_item), + "ea-week-view-cell-table"); + if (!cell_data) { + cell_data = ea_cell_table_create (week_view->weeks_shown, 7, TRUE); + g_object_set_data (G_OBJECT(ea_main_item), + "ea-week-view-cell-table", cell_data); + } + return cell_data; +} + +static void +ea_week_view_main_item_destory_cell_data (EaWeekViewMainItem *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-week-view-cell-table"); + if (cell_data) { + g_object_set_data (G_OBJECT(ea_main_item), + "ea-week-view-cell-table", NULL); + ea_cell_table_destroy (cell_data); + } +} + +/* 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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + + *x = *y = *width = *height = 0; + + g_return_if_fail (EA_IS_WEEK_VIEW_MAIN_ITEM (component)); + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE(component)); + if (!g_obj) + /* defunct object*/ + return; + main_item = E_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + ea_canvas = gtk_widget_get_accessible (week_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; + + EaWeekViewMainItem* ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (table); + index = ea_week_view_main_item_get_child_index_at (ea_main_item, + row, column); + return ea_week_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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + return week_view->weeks_shown; +} + +static gint +table_interface_get_n_columns (AtkTable *table) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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; + + return 7; +} + +static gint +table_interface_get_index_at (AtkTable *table, + gint row, + gint column) +{ + EaWeekViewMainItem* ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (table); + return ea_week_view_main_item_get_child_index_at (ea_main_item, + row, column); +} + +static gint +table_interface_get_column_at_index (AtkTable *table, + gint index) +{ + EaWeekViewMainItem* ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (table); + return ea_week_view_main_item_get_column_at_index (ea_main_item, index); +} + +static gint +table_interface_get_row_at_index (AtkTable *table, + gint index) +{ + EaWeekViewMainItem* ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (table); + return ea_week_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; + EaWeekViewMainItem* ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (table); + + index = ea_week_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; + EaWeekViewMainItem* ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (table); + + index = ea_week_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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if (week_view->selection_start_day == -1) + /* no selection */ + return FALSE; + if ((row < 0)&&(row + 1 > week_view->weeks_shown )) + return FALSE; + if (((week_view->selection_start_day < row*7)&&(week_view->selection_end_day<row*7)) + ||((week_view->selection_start_day > row*7+6)&&(week_view->selection_end_day > row*7+6))) + return FALSE; + else + return TRUE; +} + +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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if ((column <0)||(column >6)) + return FALSE; + else { + gint i; + for (i=0;i<week_view->weeks_shown;i++) + if ((column + i*7>= week_view->selection_start_day ) && + (column + i*7<= week_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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if (week_view->selection_start_day == -1) + return 0; + + start_row = week_view->selection_start_day; + n_rows = week_view->selection_end_day - 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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if (week_view->selection_start_day == -1) + return 0; + if (week_view->selection_end_day - week_view->selection_start_day >= 6 ) { + start_column = 0; + n_columns =7; + } else { + start_column = week_view->selection_start_day % 7; + n_columns = (week_view->selection_end_day % 7) - 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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + /* FIXME: we need multi-selection */ + + week_view->selection_start_day = row * 7; + week_view->selection_end_day = row *7 + 6; + + gtk_widget_queue_draw (week_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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + /* FIXME: we need multi-selection */ + + week_view->selection_start_day = column; + week_view->selection_end_day = (week_view->weeks_shown - 1)*7+column; + + gtk_widget_queue_draw (week_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; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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; + + if (in_col < 0 || in_col > 6) + return NULL; + cell_data = ea_week_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]; + + switch (in_col) { + case 0: + g_snprintf(buffer,128,"Monday"); + break; + case 1: + g_snprintf(buffer,128,"Tuesday"); + break; + case 2: + g_snprintf(buffer,128,"Wednesday"); + break; + case 3: + g_snprintf(buffer,128,"Thursday"); + break; + case 4: + g_snprintf(buffer,128,"Friday"); + break; + case 5: + g_snprintf(buffer,128,"Saturday"); + break; + case 6: + g_snprintf(buffer,128,"Sunday"); + break; + default: + break; + } + + 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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if (row < 0 || row >= week_view->weeks_shown) + return NULL; + cell_data = ea_week_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_week_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; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if (i < 0 || i > week_view->weeks_shown * 7 -1) + return FALSE; + + /*FIXME: multi-selection is needed */ + week_view->selection_start_day = i; + week_view->selection_end_day = i; + + gtk_widget_queue_draw (week_view->main_canvas); + return TRUE; +} + +static gboolean +selection_interface_clear_selection (AtkSelection *selection) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + week_view->selection_start_day = -1; + week_view->selection_end_day = -1; + + gtk_widget_queue_draw (week_view->main_canvas); + + return TRUE; +} + +static AtkObject* +selection_interface_ref_selection (AtkSelection *selection, gint i) +{ + gint count; + GObject *g_obj; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_VIEW_MAIN_ITEM (selection); + gint start_index; + + count = selection_interface_get_selection_count (selection); + if (i < 0 || i >=count) + return NULL; + + g_obj = atk_gobject_accessible_get_object (ATK_GOBJECT_ACCESSIBLE (ea_main_item)); + week_view = E_WEEK_VIEW_MAIN_ITEM (g_obj)->week_view; + start_index = ea_week_view_main_item_get_child_index_at (ea_main_item, + week_view->selection_start_day / 7, + week_view->selection_start_day % 7); + + return ea_week_view_main_item_ref_child (ATK_OBJECT (selection), start_index + i); +} + +static gint +selection_interface_get_selection_count (AtkSelection *selection) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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 0; + + main_item = E_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if (week_view->selection_start_day == -1 || + week_view->selection_end_day == -1) + return 0; + + return week_view->selection_end_day - week_view->selection_start_day + 1; +} + +static gboolean +selection_interface_is_child_selected (AtkSelection *selection, gint i) +{ + AtkGObjectAccessible *atk_gobj; + GObject *g_obj; + EWeekViewMainItem *main_item; + EWeekView *week_view; + EaWeekViewMainItem* ea_main_item = EA_WEEK_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_WEEK_VIEW_MAIN_ITEM (g_obj); + week_view = main_item->week_view; + + if ((week_view->selection_start_day <= i)&&(week_view->selection_end_day >= i)) + return TRUE; + else + return FALSE; +} + diff --git a/calendar/gui/a11y/ea-week-view-main-item.h b/calendar/gui/a11y/ea-week-view-main-item.h new file mode 100644 index 0000000000..12687d26c0 --- /dev/null +++ b/calendar/gui/a11y/ea-week-view-main-item.h @@ -0,0 +1,63 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * Yang Wu <Yang.Wu@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_WEEK_VIEW_MAIN_ITEM_H__ +#define __EA_WEEK_VIEW_MAIN_ITEM_H__ + +#include <atk/atkgobjectaccessible.h> +#include "e-week-view-main-item.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EA_TYPE_WEEK_VIEW_MAIN_ITEM (ea_week_view_main_item_get_type ()) +#define EA_WEEK_VIEW_MAIN_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_WEEK_VIEW_MAIN_ITEM, EaWeekViewMainItem)) +#define EA_WEEK_VIEW_MAIN_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_WEEK_VIEW_MAIN_ITEM, EaWeekViewMainItemClass)) +#define EA_IS_WEEK_VIEW_MAIN_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_WEEK_VIEW_MAIN_ITEM)) +#define EA_IS_WEEK_VIEW_MAIN_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_WEEK_VIEW_MAIN_ITEM)) +#define EA_WEEK_VIEW_MAIN_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_WEEK_VIEW_MAIN_ITEM, EaWeekViewMainItemClass)) + +typedef struct _EaWeekViewMainItem EaWeekViewMainItem; +typedef struct _EaWeekViewMainItemClass EaWeekViewMainItemClass; + +struct _EaWeekViewMainItem +{ + AtkGObjectAccessible parent; +}; + +GType ea_week_view_main_item_get_type (void); + +struct _EaWeekViewMainItemClass +{ + AtkGObjectAccessibleClass parent_class; +}; + +AtkObject* ea_week_view_main_item_new (GObject *obj); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* __EA_WEEK_VIEW_MAIN_ITEM_H__ */ diff --git a/calendar/gui/a11y/ea-week-view.c b/calendar/gui/a11y/ea-week-view.c new file mode 100644 index 0000000000..6cf234c864 --- /dev/null +++ b/calendar/gui/a11y/ea-week-view.c @@ -0,0 +1,321 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#include "ea-week-view.h" +#include "ea-cal-view-event.h" +#include "ea-calendar-helpers.h" +#include "ea-gnome-calendar.h" +#include "calendar-commands.h" +#include <text/e-text.h> +#include <glib/gi18n.h> + +static void ea_week_view_class_init (EaWeekViewClass *klass); + +static G_CONST_RETURN gchar* ea_week_view_get_name (AtkObject *accessible); +static G_CONST_RETURN gchar* ea_week_view_get_description (AtkObject *accessible); +static gint ea_week_view_get_n_children (AtkObject *obj); +static AtkObject* ea_week_view_ref_child (AtkObject *obj, + gint i); + +static gpointer parent_class = NULL; + +GType +ea_week_view_get_type (void) +{ + static GType type = 0; + AtkObjectFactory *factory; + GTypeQuery query; + GType derived_atk_type; + + if (!type) { + static GTypeInfo tinfo = { + sizeof (EaWeekViewClass), + (GBaseInitFunc) NULL, /* base init */ + (GBaseFinalizeFunc) NULL, /* base finalize */ + (GClassInitFunc) ea_week_view_class_init, /* class init */ + (GClassFinalizeFunc) NULL, /* class finalize */ + NULL, /* class data */ + sizeof (EaWeekView), /* instance size */ + 0, /* nb preallocs */ + (GInstanceInitFunc) NULL, /* instance init */ + NULL /* value table */ + }; + + /* + * Figure out the size of the class and instance + * we are run-time deriving from (EaCalView, in this case) + * + * Note: we must still use run-time deriving here, because + * our parent class EaCalView is run-time deriving. + */ + + factory = atk_registry_get_factory (atk_get_default_registry (), + e_calendar_view_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, + "EaWeekView", &tinfo, 0); + + } + + return type; +} + +static void +ea_week_view_class_init (EaWeekViewClass *klass) +{ + AtkObjectClass *class = ATK_OBJECT_CLASS (klass); + + parent_class = g_type_class_peek_parent (klass); + + class->get_name = ea_week_view_get_name; + class->get_description = ea_week_view_get_description; + + class->get_n_children = ea_week_view_get_n_children; + class->ref_child = ea_week_view_ref_child; +} + +AtkObject* +ea_week_view_new (GtkWidget *widget) +{ + GObject *object; + AtkObject *accessible; + + g_return_val_if_fail (GTK_IS_WIDGET (widget), NULL); + + object = g_object_new (EA_TYPE_WEEK_VIEW, NULL); + + accessible = ATK_OBJECT (object); + atk_object_initialize (accessible, widget); + +#ifdef ACC_DEBUG + printf ("EvoAcc: ea_week_view created %p\n", (void *)accessible); +#endif + + return accessible; +} + +static G_CONST_RETURN gchar* +ea_week_view_get_name (AtkObject *accessible) +{ + EWeekView *week_view; + GnomeCalendar *gcal; + const gchar *label_text; + GnomeCalendarViewType view_type; + gint n_events; + gchar *event_str, *name_str; + + g_return_val_if_fail (EA_IS_WEEK_VIEW (accessible), NULL); + + if (!GTK_ACCESSIBLE (accessible)->widget) + return NULL; + + week_view = E_WEEK_VIEW (GTK_ACCESSIBLE (accessible)->widget); + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)); + if (!GTK_WIDGET_VISIBLE (GTK_WIDGET (gcal))) + return NULL; + + label_text = ea_gnome_calendar_get_label_description (gcal); + + n_events = atk_object_get_n_accessible_children (accessible); + /* the child main item is always there */ + --n_events; + if (n_events >= 1) + event_str = g_strdup_printf (ngettext ("It has %d event.", "It has %d events.", n_events), n_events); + else + event_str = g_strdup (_("It has no events.")); + + view_type = gnome_calendar_get_view (gcal); + + if (view_type == GNOME_CAL_MONTH_VIEW) + name_str = g_strdup_printf (_("Month View: %s. %s"), + label_text, event_str); + + else + name_str = g_strdup_printf (_("Week View: %s. %s"), + label_text, event_str); + + ATK_OBJECT_CLASS (parent_class)->set_name (accessible, name_str); + g_free (name_str); + g_free (event_str); + + return accessible->name; +} + +static G_CONST_RETURN gchar* +ea_week_view_get_description (AtkObject *accessible) +{ + EWeekView *week_view; + + g_return_val_if_fail (EA_IS_WEEK_VIEW (accessible), NULL); + + if (!GTK_ACCESSIBLE (accessible)->widget) + return NULL; + week_view = E_WEEK_VIEW (GTK_ACCESSIBLE (accessible)->widget); + + if (accessible->description) + return accessible->description; + else { + GnomeCalendar *gcal; + GnomeCalendarViewType view_type; + + gcal = e_calendar_view_get_calendar (E_CALENDAR_VIEW (week_view)); + view_type = gnome_calendar_get_view (gcal); + + if (view_type == GNOME_CAL_MONTH_VIEW) + return _("calendar view for a month"); + else + return _("calendar view for one or more weeks"); + } +} + +static gint +ea_week_view_get_n_children (AtkObject *accessible) +{ + EWeekView *week_view; + gint i, count = 0; + gint event_index; + + 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); + + for (event_index = 0; event_index < week_view->events->len; + ++event_index) { + EWeekViewEvent *event; + EWeekViewEventSpan *span; + + /* If week_view->spans == NULL, there is no visible events. */ + if (!week_view->spans) + break; + + event = &g_array_index (week_view->events, + EWeekViewEvent, event_index); + if (!event) + continue; + span = &g_array_index (week_view->spans, EWeekViewEventSpan, + event->spans_index + 0); + + if (!span) + continue; + + /* at least one of the event spans is visible, count it */ + if (span->text_item) + ++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; + } + + /* "+1" for the main item */ + count++; + +#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, max_count; + AtkObject *atk_object = NULL; + 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) + return NULL; + + if (!GTK_ACCESSIBLE (accessible)->widget) + return NULL; + week_view = E_WEEK_VIEW (GTK_ACCESSIBLE (accessible)->widget); + max_count = week_view->events->len; + + if (index == 0) { + /* index == 0 is the main item */ + atk_object = atk_gobject_accessible_for_object (G_OBJECT (week_view->main_canvas_item)); + g_object_ref (atk_object); + } else + 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); + if (!event) + continue; + + span = &g_array_index (week_view->spans, EWeekViewEventSpan, + event->spans_index + span_num); + + if (!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) { + 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 = ea_calendar_helpers_get_accessible_for (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, (void *)atk_object); +#endif + return atk_object; +} diff --git a/calendar/gui/a11y/ea-week-view.h b/calendar/gui/a11y/ea-week-view.h new file mode 100644 index 0000000000..b24fe72103 --- /dev/null +++ b/calendar/gui/a11y/ea-week-view.h @@ -0,0 +1,63 @@ +/* + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) version 3. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with the program; if not, see <http://www.gnu.org/licenses/> + * + * + * Authors: + * Bolian Yin <bolian.yin@sun.com> + * + * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com) + * + */ + +#ifndef __EA_WEEK_VIEW_H__ +#define __EA_WEEK_VIEW_H__ + +#include "ea-cal-view.h" +#include "e-week-view.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +#define EA_TYPE_WEEK_VIEW (ea_week_view_get_type ()) +#define EA_WEEK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EA_TYPE_WEEK_VIEW, EaWeekView)) +#define EA_WEEK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EA_TYPE_WEEK_VIEW, EaWeekViewClass)) +#define EA_IS_WEEK_VIEW(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EA_TYPE_WEEK_VIEW)) +#define EA_IS_WEEK_VIEW_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EA_TYPE_WEEK_VIEW)) +#define EA_WEEK_VIEW_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EA_TYPE_WEEK_VIEW, EaWeekViewClass)) + +typedef struct _EaWeekView EaWeekView; +typedef struct _EaWeekViewClass EaWeekViewClass; + +struct _EaWeekView +{ + EaCalView parent; +}; + +GType ea_week_view_get_type (void); + +struct _EaWeekViewClass +{ + EaCalViewClass parent_class; +}; + +AtkObject* ea_week_view_new (GtkWidget *widget); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + + +#endif /* __EA_WEEK_VIEW_H__ */ diff --git a/calendar/gui/e-cal-list-view.c b/calendar/gui/e-cal-list-view.c index 6c71d1c8c7..2da55bb8d9 100644 --- a/calendar/gui/e-cal-list-view.c +++ b/calendar/gui/e-cal-list-view.c @@ -25,7 +25,7 @@ #endif #include "e-cal-list-view.h" -#include "ea-calendar.h" +#include "a11y/ea-calendar.h" #include <math.h> #include <time.h> @@ -41,7 +41,7 @@ #include <table/e-cell-text.h> #include <table/e-cell-combo.h> #include <misc/e-popup-menu.h> -#include <misc/e-cell-date-edit.h> +#include <table/e-cell-date-edit.h> #include <e-util/e-categories-config.h> #include <e-util/e-dialog-utils.h> #include <e-util/e-util-private.h> diff --git a/calendar/gui/e-calendar-table.c b/calendar/gui/e-calendar-table.c index a4320273ac..e914e5095b 100644 --- a/calendar/gui/e-calendar-table.c +++ b/calendar/gui/e-calendar-table.c @@ -43,8 +43,8 @@ #include <table/e-cell-combo.h> #include <e-util/e-dialog-utils.h> #include <e-util/e-util-private.h> -#include <widgets/misc/e-cell-date-edit.h> -#include <widgets/misc/e-cell-percent.h> +#include <table/e-cell-date-edit.h> +#include <table/e-cell-percent.h> #include <libecal/e-cal-time-util.h> #include <libedataserver/e-time-utils.h> diff --git a/calendar/gui/e-calendar-table.h b/calendar/gui/e-calendar-table.h index a3dba94841..5f83606827 100644 --- a/calendar/gui/e-calendar-table.h +++ b/calendar/gui/e-calendar-table.h @@ -24,8 +24,8 @@ #define _E_CALENDAR_TABLE_H_ #include <shell/e-shell-view.h> -#include <widgets/table/e-table-scrolled.h> -#include <widgets/misc/e-cell-date-edit.h> +#include <table/e-table-scrolled.h> +#include <table/e-cell-date-edit.h> #include "e-cal-model.h" /* diff --git a/calendar/gui/e-calendar-view.c b/calendar/gui/e-calendar-view.c index 2294c0b0ed..a888e04c02 100644 --- a/calendar/gui/e-calendar-view.c +++ b/calendar/gui/e-calendar-view.c @@ -55,7 +55,7 @@ #include "dialogs/select-source-dialog.h" #include "print.h" #include "goto.h" -#include "ea-calendar.h" +#include "a11y/ea-calendar.h" #include "e-cal-popup.h" #include "misc.h" diff --git a/calendar/gui/e-cell-date-edit-config.h b/calendar/gui/e-cell-date-edit-config.h index 6203aec1a4..36259354ed 100644 --- a/calendar/gui/e-cell-date-edit-config.h +++ b/calendar/gui/e-cell-date-edit-config.h @@ -24,7 +24,7 @@ #ifndef _E_CELL_DATE_EDIT_CONFIG_H_ #define _E_CELL_DATE_EDIT_CONFIG_H_ -#include <misc/e-cell-date-edit.h> +#include <table/e-cell-date-edit.h> #include "e-cell-date-edit-text.h" G_BEGIN_DECLS diff --git a/calendar/gui/e-day-view-main-item.c b/calendar/gui/e-day-view-main-item.c index f96e6cc5ed..3718725c08 100644 --- a/calendar/gui/e-day-view-main-item.c +++ b/calendar/gui/e-day-view-main-item.c @@ -32,7 +32,7 @@ #include "e-util/e-categories-config.h" #include "e-day-view-layout.h" #include "e-day-view-main-item.h" -#include "ea-calendar.h" +#include "a11y/ea-calendar.h" #include "e-calendar-view.h" #include "comp-util.h" #include <libecal/e-cal-time-util.h> diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 9f48cdecb1..7c082e5c6b 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -26,7 +26,7 @@ #endif #include "e-day-view.h" -#include "ea-calendar.h" +#include "a11y/ea-calendar.h" #include <math.h> #include <time.h> @@ -35,7 +35,7 @@ #include <misc/e-canvas-utils.h> #include <misc/e-popup-menu.h> #include <misc/e-gui-utils.h> -#include <misc/e-unicode.h> +#include <e-util/e-unicode.h> #include <libgnomecanvas/gnome-canvas-rect-ellipse.h> #include <glib/gi18n.h> #include <e-util/e-categories-config.h> diff --git a/calendar/gui/e-memo-table.c b/calendar/gui/e-memo-table.c index 891bec6d32..208e3ad9fc 100644 --- a/calendar/gui/e-memo-table.c +++ b/calendar/gui/e-memo-table.c @@ -42,8 +42,8 @@ #include <table/e-cell-combo.h> #include <e-util/e-dialog-utils.h> #include <e-util/e-util-private.h> -#include <widgets/misc/e-cell-date-edit.h> -#include <widgets/misc/e-cell-percent.h> +#include <table/e-cell-date-edit.h> +#include <table/e-cell-percent.h> #include <libecal/e-cal-time-util.h> #include <libedataserver/e-time-utils.h> diff --git a/calendar/gui/e-memo-table.h b/calendar/gui/e-memo-table.h index 0a13006262..421a15352f 100644 --- a/calendar/gui/e-memo-table.h +++ b/calendar/gui/e-memo-table.h @@ -26,8 +26,8 @@ #define _E_MEMO_TABLE_H_ #include <shell/e-shell-view.h> -#include <widgets/table/e-table-scrolled.h> -#include <widgets/misc/e-cell-date-edit.h> +#include <table/e-table-scrolled.h> +#include <table/e-cell-date-edit.h> #include "e-cal-model.h" /* diff --git a/calendar/gui/e-week-view-main-item.c b/calendar/gui/e-week-view-main-item.c index 322acc6676..82dc43e944 100644 --- a/calendar/gui/e-week-view-main-item.c +++ b/calendar/gui/e-week-view-main-item.c @@ -29,7 +29,7 @@ #include <glib.h> #include <glib/gi18n.h> #include "e-week-view-main-item.h" -#include "ea-calendar.h" +#include "a11y/ea-calendar.h" static void e_week_view_main_item_set_property (GObject *object, guint property_id, diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c index 80248ec771..22dfb3d725 100644 --- a/calendar/gui/e-week-view.c +++ b/calendar/gui/e-week-view.c @@ -30,7 +30,7 @@ #endif #include "e-week-view.h" -#include "ea-calendar.h" +#include "a11y/ea-calendar.h" #include <math.h> #include <gdk/gdkkeysyms.h> @@ -39,7 +39,7 @@ #include <text/e-text.h> #include <misc/e-canvas-utils.h> #include <misc/e-gui-utils.h> -#include <misc/e-unicode.h> +#include <e-util/e-unicode.h> #include <e-util/e-categories-config.h> #include <e-util/e-dialog-utils.h> #include <e-util/e-util.h> diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index 2217cd5b0e..75a3764183 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -74,7 +74,7 @@ #include "calendar-view-factory.h" #include "tag-calendar.h" #include "misc.h" -#include "ea-calendar.h" +#include "a11y/ea-calendar.h" #include "common/authentication.h" #include "e-cal-popup.h" #include "e-cal-menu.h" diff --git a/calendar/module/Makefile.am b/calendar/module/Makefile.am index ca2a4b4ec5..49442cb955 100644 --- a/calendar/module/Makefile.am +++ b/calendar/module/Makefile.am @@ -61,11 +61,19 @@ libevolution_module_calendar_la_SOURCES = \ # $(top_builddir)/a11y/calendar/libevolution-calendar-a11y.la libevolution_module_calendar_la_LIBADD = \ - $(WIN32_BOOTSTRAP_LIBS) \ $(top_builddir)/shell/libeshell.la \ $(top_builddir)/calendar/gui/libcal-gui.la \ + $(top_builddir)/calendar/importers/libevolution-calendar-importers.la \ $(top_builddir)/mail/libevolution-module-mail.la \ - $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la + $(top_builddir)/addressbook/gui/contact-editor/libecontacteditor.la \ + $(top_builddir)/addressbook/gui/contact-list-editor/libecontactlisteditor.la \ + $(top_builddir)/e-util/libeutil.la \ + $(top_builddir)/filter/libfilter.la \ + $(top_builddir)/widgets/menus/libmenus.la \ + $(top_builddir)/widgets/misc/libemiscwidgets.la \ + $(top_builddir)/widgets/table/libetable.la \ + $(CAMEL_LIBS) \ + $(EVOLUTION_CALENDAR_LIBS) libevolution_module_calendar_la_LDFLAGS = \ -module -avoid-version $(NO_UNDEFINED) |