aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/e-day-view.c
diff options
context:
space:
mode:
authorMatthew Barnes <mbarnes@redhat.com>2013-03-07 04:24:08 +0800
committerMatthew Barnes <mbarnes@redhat.com>2013-03-09 04:58:33 +0800
commitacdcd71d3074ebe3b3a758769eaa300dd50c3207 (patch)
tree8423cb0b8180f4fb7f0cfff574be00752b9962f3 /calendar/gui/e-day-view.c
parent529c50f134e9b0fdaa7e02eb8dd9d5efd6e4179e (diff)
downloadgsoc2013-evolution-acdcd71d3074ebe3b3a758769eaa300dd50c3207.tar.gz
gsoc2013-evolution-acdcd71d3074ebe3b3a758769eaa300dd50c3207.tar.zst
gsoc2013-evolution-acdcd71d3074ebe3b3a758769eaa300dd50c3207.zip
EDayView cleanups.
Diffstat (limited to 'calendar/gui/e-day-view.c')
-rw-r--r--calendar/gui/e-day-view.c2227
1 files changed, 1111 insertions, 1116 deletions
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index 6f2b53507c..980c8ed990 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -55,6 +55,10 @@
#include "misc.h"
#include "print.h"
+#define E_DAY_VIEW_GET_PRIVATE(obj) \
+ (G_TYPE_INSTANCE_GET_PRIVATE \
+ ((obj), E_TYPE_DAY_VIEW, EDayViewPrivate))
+
/* The minimum amount of space wanted on each side of the date string. */
#define E_DAY_VIEW_DATE_X_PAD 4
@@ -90,6 +94,10 @@
* caption item and DnD space */
#define E_DAY_VIEW_MAX_ROWS_AT_TOP 6
+struct _EDayViewPrivate {
+ gint placeholder;
+};
+
typedef struct {
EDayView *day_view;
ECalModelComponent *comp_data;
@@ -100,23 +108,8 @@ static GtkTargetEntry target_table[] = {
{ (gchar *) "application/x-e-calendar-event", 0, 0 }
};
-static void e_day_view_dispose (GObject *object);
-static void e_day_view_realize (GtkWidget *widget);
static void e_day_view_set_colors (EDayView *day_view, GtkWidget *widget);
-static void e_day_view_unrealize (GtkWidget *widget);
-static void e_day_view_style_set (GtkWidget *widget,
- GtkStyle *previous_style);
-static void e_day_view_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
static gboolean e_day_view_update_scroll_regions (EDayView *day_view);
-static gint e_day_view_focus_in (GtkWidget *widget,
- GdkEventFocus *event);
-static gint e_day_view_focus_out (GtkWidget *widget,
- GdkEventFocus *event);
-static gboolean e_day_view_key_press (GtkWidget *widget,
- GdkEventKey *event);
-static gboolean e_day_view_focus (GtkWidget *widget,
- GtkDirectionType direction);
static gboolean e_day_view_get_next_tab_event (EDayView *day_view,
GtkDirectionType direction,
gint *day, gint *event_num);
@@ -132,12 +125,6 @@ static gboolean e_day_view_get_extreme_event (EDayView *day_view,
gint *event_num_out);
static gboolean e_day_view_do_key_press (GtkWidget *widget,
GdkEventKey *event);
-static gboolean e_day_view_popup_menu (GtkWidget *widget);
-static GList *e_day_view_get_selected_events (ECalendarView *cal_view);
-static gboolean e_day_view_get_selected_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time);
-static void e_day_view_set_selected_time_range (ECalendarView *cal_view, time_t start_time, time_t end_time);
-static gboolean e_day_view_get_visible_time_range (ECalendarView *cal_view, time_t *start_time, time_t *end_time);
-static void e_day_view_paste_text (ECalendarView *day_view);
static void e_day_view_update_query (EDayView *day_view);
static void e_day_view_goto_start_of_work_day (EDayView *day_view);
static void e_day_view_goto_end_of_work_day (EDayView *day_view);
@@ -469,6 +456,206 @@ day_view_notify_week_start_day_cb (EDayView *day_view)
}
static void
+e_day_view_recalc_main_canvas_size (EDayView *day_view)
+{
+ ECalModel *model;
+ gint work_day_start_hour;
+ gint work_day_start_minute;
+ gint day, scroll_y;
+ gboolean need_reshape;
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+ work_day_start_hour = e_cal_model_get_work_day_start_hour (model);
+ work_day_start_minute = e_cal_model_get_work_day_start_minute (model);
+
+ /* Set the scroll region of the top canvas */
+ e_day_view_update_top_scroll (day_view, TRUE);
+
+ need_reshape = e_day_view_update_scroll_regions (day_view);
+
+ e_day_view_recalc_cell_sizes (day_view);
+
+ /* Scroll to the start of the working day, if this is the initial
+ * allocation. */
+ if (day_view->scroll_to_work_day) {
+ scroll_y = e_day_view_convert_time_to_position (
+ day_view, work_day_start_hour, work_day_start_minute);
+ gnome_canvas_scroll_to (
+ GNOME_CANVAS (day_view->main_canvas), 0, scroll_y);
+ day_view->scroll_to_work_day = FALSE;
+ }
+
+ /* Flag that we need to reshape the events. Note that changes in height
+ * don't matter, since the rows are always the same height. */
+ if (need_reshape) {
+ day_view->long_events_need_reshape = TRUE;
+ for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++)
+ day_view->need_reshape[day] = TRUE;
+
+ e_day_view_check_layout (day_view);
+ }
+}
+
+static GdkColor
+e_day_view_get_text_color (EDayView *day_view,
+ EDayViewEvent *event,
+ GtkWidget *widget)
+{
+ GtkStyle *style;
+ GdkColor bg_color;
+ guint16 red, green, blue;
+ gdouble cc = 65535.0;
+
+ red = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].red;
+ green = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].green;
+ blue = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].blue;
+
+ if (is_comp_data_valid (event) && gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data),
+ &bg_color)) {
+ red = bg_color.red;
+ green = bg_color.green;
+ blue = bg_color.blue;
+ }
+
+ style = gtk_widget_get_style (widget);
+
+ if ((red / cc > 0.7) || (green / cc > 0.7) || (blue / cc > 0.7))
+ return style->black;
+ else
+ return style->white;
+}
+
+/* Returns the selected time range. */
+static gboolean
+day_view_get_selected_time_range (ECalendarView *cal_view,
+ time_t *start_time,
+ time_t *end_time)
+{
+ gint start_col, start_row, end_col, end_row;
+ time_t start, end;
+ EDayView *day_view = E_DAY_VIEW (cal_view);
+
+ start_col = day_view->selection_start_day;
+ start_row = day_view->selection_start_row;
+ end_col = day_view->selection_end_day;
+ end_row = day_view->selection_end_row;
+
+ if (start_col == -1) {
+ start_col = 0;
+ start_row = 0;
+ end_col = 0;
+ end_row = 0;
+ }
+
+ /* Check if the selection is only in the top canvas, in which case
+ * we can simply use the day_starts array. */
+ if (day_view->selection_in_top_canvas) {
+ start = day_view->day_starts[start_col];
+ end = day_view->day_starts[end_col + 1];
+ } else {
+ /* Convert the start col + row into a time. */
+ start = e_day_view_convert_grid_position_to_time (day_view, start_col, start_row);
+ end = e_day_view_convert_grid_position_to_time (day_view, end_col, end_row + 1);
+ }
+
+ if (start_time)
+ *start_time = start;
+
+ if (end_time)
+ *end_time = end;
+
+ return TRUE;
+}
+
+static gboolean
+e_day_view_add_new_event_in_selected_range (EDayView *day_view,
+ GdkEventKey *key_event)
+{
+ icalcomponent *icalcomp;
+ ECalClient *client;
+ ECalModel *model;
+ ECalComponent *comp;
+ gint day, event_num;
+ time_t dtstart, dtend;
+ ECalComponentDateTime start_dt, end_dt;
+ struct icaltimetype start_tt, end_tt;
+ const gchar *uid;
+ AddEventData add_event_data;
+ ESourceRegistry *registry;
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+
+ registry = e_cal_model_get_registry (model);
+ client = e_cal_model_get_default_client (model);
+
+ /* Check if the client is read only */
+ if (e_client_is_readonly (E_CLIENT (client)))
+ return FALSE;
+
+ icalcomp = e_cal_model_create_component_with_defaults (model, day_view->selection_in_top_canvas);
+ if (!icalcomp)
+ return FALSE;
+
+ uid = icalcomponent_get_uid (icalcomp);
+
+ comp = e_cal_component_new ();
+ e_cal_component_set_icalcomponent (comp, icalcomp);
+
+ day_view_get_selected_time_range ((ECalendarView *) day_view, &dtstart, &dtend);
+
+ start_tt = icaltime_from_timet_with_zone (
+ dtstart, FALSE,
+ e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
+
+ end_tt = icaltime_from_timet_with_zone (
+ dtend, FALSE,
+ e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
+
+ if (day_view->selection_in_top_canvas) {
+ start_dt.tzid = NULL;
+ start_tt.is_date = 1;
+ end_tt.is_date = 1;
+
+ /* Editor default in day/work-week view - top canvas */
+ e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT);
+ } else {
+ start_dt.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
+
+ /* Editor default in day/work-week view - main canvas */
+ e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_OPAQUE);
+ }
+
+ start_dt.value = &start_tt;
+ end_dt.value = &end_tt;
+ end_dt.tzid = start_dt.tzid;
+ e_cal_component_set_dtstart (comp, &start_dt);
+ e_cal_component_set_dtend (comp, &end_dt);
+
+ e_cal_component_set_categories (
+ comp, e_calendar_view_get_default_category (E_CALENDAR_VIEW (day_view)));
+
+ /* We add the event locally and start editing it. We don't send it
+ * to the server until the user finishes editing it. */
+ add_event_data.day_view = day_view;
+ add_event_data.comp_data = NULL;
+ e_day_view_add_event (registry, comp, dtstart, dtend, &add_event_data);
+ e_day_view_check_layout (day_view);
+ gtk_widget_queue_draw (day_view->top_canvas);
+ gtk_widget_queue_draw (day_view->main_canvas);
+
+ if (!e_day_view_find_event_from_uid (day_view, client, uid, NULL, &day, &event_num)) {
+ g_warning ("Couldn't find event to start editing.\n");
+ g_object_unref (comp);
+ return FALSE;
+ }
+
+ e_day_view_start_editing_event (day_view, day, event_num, key_event);
+
+ g_object_unref (comp);
+ return TRUE;
+}
+
+static void
day_view_set_property (GObject *object,
guint property_id,
const GValue *value,
@@ -543,6 +730,70 @@ day_view_get_property (GObject *object,
}
static void
+day_view_dispose (GObject *object)
+{
+ EDayView *day_view;
+ gint day;
+
+ day_view = E_DAY_VIEW (object);
+
+ e_day_view_cancel_layout (day_view);
+
+ e_day_view_stop_auto_scroll (day_view);
+
+ if (day_view->large_font_desc) {
+ pango_font_description_free (day_view->large_font_desc);
+ day_view->large_font_desc = NULL;
+ }
+
+ if (day_view->small_font_desc) {
+ pango_font_description_free (day_view->small_font_desc);
+ day_view->small_font_desc = NULL;
+ }
+
+ if (day_view->normal_cursor) {
+ g_object_unref (day_view->normal_cursor);
+ day_view->normal_cursor = NULL;
+ }
+ if (day_view->move_cursor) {
+ g_object_unref (day_view->move_cursor);
+ day_view->move_cursor = NULL;
+ }
+ if (day_view->resize_width_cursor) {
+ g_object_unref (day_view->resize_width_cursor);
+ day_view->resize_width_cursor = NULL;
+ }
+ if (day_view->resize_height_cursor) {
+ g_object_unref (day_view->resize_height_cursor);
+ day_view->resize_height_cursor = NULL;
+ }
+
+ if (day_view->long_events) {
+ e_day_view_free_events (day_view);
+ g_array_free (day_view->long_events, TRUE);
+ day_view->long_events = NULL;
+ }
+
+ for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) {
+ if (day_view->events[day]) {
+ g_array_free (day_view->events[day], TRUE);
+ day_view->events[day] = NULL;
+ }
+ }
+
+ if (day_view->grabbed_pointer != NULL) {
+ gdk_device_ungrab (
+ day_view->grabbed_pointer,
+ GDK_CURRENT_TIME);
+ g_object_unref (day_view->grabbed_pointer);
+ day_view->grabbed_pointer = NULL;
+ }
+
+ /* Chain up to parent's dispose() method. */
+ G_OBJECT_CLASS (e_day_view_parent_class)->dispose (object);
+}
+
+static void
day_view_constructed (GObject *object)
{
EDayView *day_view;
@@ -581,355 +832,657 @@ day_view_constructed (GObject *object)
}
static void
-e_day_view_class_init (EDayViewClass *class)
+day_view_realize (GtkWidget *widget)
{
- GObjectClass *object_class;
- GtkWidgetClass *widget_class;
- ECalendarViewClass *view_class;
+ EDayView *day_view;
- object_class = G_OBJECT_CLASS (class);
- object_class->set_property = day_view_set_property;
- object_class->get_property = day_view_get_property;
- object_class->constructed = day_view_constructed;
- object_class->dispose = e_day_view_dispose;
+ if (GTK_WIDGET_CLASS (e_day_view_parent_class)->realize)
+ (*GTK_WIDGET_CLASS (e_day_view_parent_class)->realize)(widget);
- widget_class = GTK_WIDGET_CLASS (class);
- widget_class->realize = e_day_view_realize;
- widget_class->unrealize = e_day_view_unrealize;
- widget_class->style_set = e_day_view_style_set;
- widget_class->size_allocate = e_day_view_size_allocate;
- widget_class->focus_in_event = e_day_view_focus_in;
- widget_class->focus_out_event = e_day_view_focus_out;
- widget_class->key_press_event = e_day_view_key_press;
- widget_class->focus = e_day_view_focus;
- widget_class->popup_menu = e_day_view_popup_menu;
+ day_view = E_DAY_VIEW (widget);
- view_class = E_CALENDAR_VIEW_CLASS (class);
- view_class->get_selected_events = e_day_view_get_selected_events;
- view_class->get_selected_time_range = e_day_view_get_selected_time_range;
- view_class->set_selected_time_range = e_day_view_set_selected_time_range;
- view_class->get_visible_time_range = e_day_view_get_visible_time_range;
- view_class->paste_text = e_day_view_paste_text;
+ /* Allocate the colors. */
- /* XXX Should these be constructor properties? */
+ e_day_view_set_colors (day_view, widget);
- g_object_class_install_property (
- object_class,
- PROP_MARCUS_BAINS_SHOW_LINE,
- g_param_spec_boolean (
- "marcus-bains-show-line",
- "Marcus Bains Show Line",
- NULL,
- TRUE,
- G_PARAM_READWRITE));
+ /* Create the pixmaps. */
+ day_view->reminder_icon = e_icon_factory_get_icon ("stock_bell", GTK_ICON_SIZE_MENU);
+ day_view->recurrence_icon = e_icon_factory_get_icon ("view-refresh", GTK_ICON_SIZE_MENU);
+ day_view->timezone_icon = e_icon_factory_get_icon ("stock_timezone", GTK_ICON_SIZE_MENU);
+ day_view->meeting_icon = e_icon_factory_get_icon ("stock_people", GTK_ICON_SIZE_MENU);
+ day_view->attach_icon = e_icon_factory_get_icon ("mail-attachment", GTK_ICON_SIZE_MENU);
- g_object_class_install_property (
- object_class,
- PROP_MARCUS_BAINS_DAY_VIEW_COLOR,
- g_param_spec_string (
- "marcus-bains-day-view-color",
- "Marcus Bains Day View Color",
- NULL,
- NULL,
- G_PARAM_READWRITE));
+ /* Set the canvas item colors. */
+ gnome_canvas_item_set (
+ day_view->drag_long_event_rect_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
- g_object_class_install_property (
- object_class,
- PROP_MARCUS_BAINS_TIME_BAR_COLOR,
- g_param_spec_string (
- "marcus-bains-time-bar-color",
- "Marcus Bains Time Bar Color",
- NULL,
- NULL,
- G_PARAM_READWRITE));
+ gnome_canvas_item_set (
+ day_view->drag_rect_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
- /* FIXME Make this a real GFlags type. */
- g_object_class_install_property (
- object_class,
- PROP_WORKING_DAYS,
- g_param_spec_int (
- "working-days",
- "Working Days",
- NULL,
- 0x00,
- 0x7f,
- 0,
- G_PARAM_READWRITE));
+ gnome_canvas_item_set (
+ day_view->drag_bar_item,
+ "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
+ "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
+ NULL);
+}
- /* init the accessibility support for e_day_view */
- e_day_view_a11y_init ();
+static void
+day_view_unrealize (GtkWidget *widget)
+{
+ EDayView *day_view;
+
+ day_view = E_DAY_VIEW (widget);
+
+ g_object_unref (day_view->reminder_icon);
+ day_view->reminder_icon = NULL;
+ g_object_unref (day_view->recurrence_icon);
+ day_view->recurrence_icon = NULL;
+ g_object_unref (day_view->timezone_icon);
+ day_view->timezone_icon = NULL;
+ g_object_unref (day_view->meeting_icon);
+ day_view->meeting_icon = NULL;
+ g_object_unref (day_view->attach_icon);
+ day_view->attach_icon = NULL;
+
+ if (GTK_WIDGET_CLASS (e_day_view_parent_class)->unrealize)
+ (*GTK_WIDGET_CLASS (e_day_view_parent_class)->unrealize)(widget);
}
static void
-time_range_changed_cb (ECalModel *model,
- time_t start_time,
- time_t end_time,
- gpointer user_data)
+day_view_size_allocate (GtkWidget *widget,
+ GtkAllocation *allocation)
{
- EDayView *day_view = E_DAY_VIEW (user_data);
- EDayViewTimeItem *eti;
- time_t lower;
+ (*GTK_WIDGET_CLASS (e_day_view_parent_class)->size_allocate) (widget, allocation);
- g_return_if_fail (E_IS_DAY_VIEW (day_view));
+ e_day_view_recalc_main_canvas_size (E_DAY_VIEW (widget));
+}
- /* Calculate the first day that should be shown, based on start_time
- * and the days_shown setting. If we are showing 1 day it is just the
- * start of the day given by start_time, otherwise it is the previous
- * work-week start day. */
- if (!day_view->work_week_view) {
- lower = time_day_begin_with_zone (start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
- } else {
- lower = e_day_view_find_work_week_start (day_view, start_time);
+static void
+day_view_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ EDayView *day_view;
+ gint hour;
+ gint minute, max_minute_width, i;
+ gint month, day, width;
+ gint longest_month_width, longest_abbreviated_month_width;
+ gint longest_weekday_width, longest_abbreviated_weekday_width;
+ gchar buffer[128];
+ const gchar *name;
+ gint times_width;
+ PangoFontDescription *font_desc;
+ PangoContext *pango_context;
+ PangoFontMetrics *font_metrics;
+ PangoLayout *layout;
+ gint week_day, event_num;
+ GtkAdjustment *adjustment;
+ EDayViewEvent *event;
+ GdkColor color;
+
+ if (GTK_WIDGET_CLASS (e_day_view_parent_class)->style_set)
+ (*GTK_WIDGET_CLASS (e_day_view_parent_class)->style_set)(widget, previous_style);
+
+ day_view = E_DAY_VIEW (widget);
+ e_day_view_set_colors (day_view, widget);
+
+ for (week_day = 0; week_day < E_DAY_VIEW_MAX_DAYS; week_day++) {
+ for (event_num = 0; event_num < day_view->events[week_day]->len; event_num++) {
+ event = &g_array_index (day_view->events[week_day], EDayViewEvent, event_num);
+ if (event->canvas_item) {
+ color = e_day_view_get_text_color (day_view, event, widget);
+ gnome_canvas_item_set (
+ event->canvas_item,
+ "fill_color_gdk", &color,
+ NULL);
+ }
+ }
+ }
+ for (event_num = 0; event_num < day_view->long_events->len; event_num++) {
+ event = &g_array_index (day_view->long_events, EDayViewEvent, event_num);
+ if (event->canvas_item) {
+ color = e_day_view_get_text_color (day_view, event, widget);
+ gnome_canvas_item_set (
+ event->canvas_item,
+ "fill_color_gdk", &color,
+ NULL);
+ }
}
- /* See if we need to change the days shown. */
- if (lower != day_view->lower)
- e_day_view_recalc_day_starts (day_view, lower);
+ /* Set up Pango prerequisites */
+ font_desc = gtk_widget_get_style (widget)->font_desc;
+ pango_context = gtk_widget_get_pango_context (widget);
+ font_metrics = pango_context_get_metrics (
+ pango_context, font_desc,
+ pango_context_get_language (pango_context));
+ layout = pango_layout_new (pango_context);
- if (!E_CALENDAR_VIEW (day_view)->in_focus) {
- e_day_view_free_events (day_view);
- day_view->requires_update = TRUE;
- return;
+ /* Create the large font. */
+ if (day_view->large_font_desc != NULL)
+ pango_font_description_free (day_view->large_font_desc);
+
+ day_view->large_font_desc = pango_font_description_copy (font_desc);
+ pango_font_description_set_size (
+ day_view->large_font_desc,
+ E_DAY_VIEW_LARGE_FONT_PTSIZE * PANGO_SCALE);
+
+ /* Create the small fonts. */
+ if (day_view->small_font_desc != NULL)
+ pango_font_description_free (day_view->small_font_desc);
+
+ day_view->small_font_desc = pango_font_description_copy (font_desc);
+ pango_font_description_set_size (
+ day_view->small_font_desc,
+ E_DAY_VIEW_SMALL_FONT_PTSIZE * PANGO_SCALE);
+
+ /* Recalculate the height of each row based on the font size. */
+ day_view->row_height =
+ PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) +
+ PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) +
+ E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD * 2 + 2 /* FIXME */;
+ day_view->row_height = MAX (
+ day_view->row_height,
+ E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD + 2);
+
+ adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (day_view->main_canvas));
+ gtk_adjustment_set_step_increment (adjustment, day_view->row_height);
+
+ day_view->top_row_height =
+ PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) +
+ PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) +
+ E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT * 2 + E_DAY_VIEW_LONG_EVENT_Y_PAD * 2 +
+ E_DAY_VIEW_TOP_CANVAS_Y_GAP;
+ day_view->top_row_height =
+ MAX (
+ day_view->top_row_height,
+ E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD + 2 +
+ E_DAY_VIEW_TOP_CANVAS_Y_GAP);
+
+ adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (day_view->top_canvas));
+ gtk_adjustment_set_step_increment (adjustment, day_view->top_row_height);
+ gtk_widget_set_size_request (day_view->top_dates_canvas, -1, day_view->top_row_height - 2);
+
+ e_day_view_update_top_scroll (day_view, TRUE);
+
+ /* Find the longest full & abbreviated month names. */
+ longest_month_width = 0;
+ longest_abbreviated_month_width = 0;
+ for (month = 0; month < 12; month++) {
+ name = e_get_month_name (month + 1, FALSE);
+ pango_layout_set_text (layout, name, -1);
+ pango_layout_get_pixel_size (layout, &width, NULL);
+
+ if (width > longest_month_width) {
+ longest_month_width = width;
+ day_view->longest_month_name = month;
+ }
+
+ name = e_get_month_name (month + 1, TRUE);
+ pango_layout_set_text (layout, name, -1);
+ pango_layout_get_pixel_size (layout, &width, NULL);
+
+ if (width > longest_abbreviated_month_width) {
+ longest_abbreviated_month_width = width;
+ day_view->longest_abbreviated_month_name = month;
+ }
}
- /* If we don't show the new selection, don't preserve it */
- if (day_view->selection_start_day == -1 || day_view->days_shown <= day_view->selection_start_day)
- e_day_view_set_selected_time_range (E_CALENDAR_VIEW (day_view), start_time, end_time);
+ /* Find the longest full & abbreviated weekday names. */
+ longest_weekday_width = 0;
+ longest_abbreviated_weekday_width = 0;
+ for (day = 0; day < 7; day++) {
+ name = e_get_weekday_name (day + 1, FALSE);
+ pango_layout_set_text (layout, name, -1);
+ pango_layout_get_pixel_size (layout, &width, NULL);
- if (day_view->selection_start_row != -1)
- e_day_view_ensure_rows_visible (day_view, day_view->selection_start_row, day_view->selection_start_row);
+ if (width > longest_weekday_width) {
+ longest_weekday_width = width;
+ day_view->longest_weekday_name = day;
+ }
- /* update the time canvas to show proper date in it */
- eti = E_DAY_VIEW_TIME_ITEM (day_view->time_canvas_item);
- if (eti && e_day_view_time_item_get_second_zone (eti))
- gtk_widget_queue_draw (day_view->time_canvas);
+ name = e_get_weekday_name (day + 1, TRUE);
+ pango_layout_set_text (layout, name, -1);
+ pango_layout_get_pixel_size (layout, &width, NULL);
+
+ if (width > longest_abbreviated_weekday_width) {
+ longest_abbreviated_weekday_width = width;
+ day_view->longest_abbreviated_weekday_name = day;
+ }
+ }
+
+ /* Calculate the widths of all the time strings necessary. */
+ day_view->max_small_hour_width = 0;
+ for (hour = 0; hour < 24; hour++) {
+ g_snprintf (buffer, sizeof (buffer), "%02i", hour);
+ pango_layout_set_text (layout, buffer, -1);
+ pango_layout_get_pixel_size (layout, &day_view->small_hour_widths[hour], NULL);
+
+ day_view->max_small_hour_width = MAX (day_view->max_small_hour_width, day_view->small_hour_widths[hour]);
+ }
+
+ max_minute_width = 0;
+ for (minute = 0, i = 0; minute < 60; minute += 5, i++) {
+ gint minute_width;
+
+ g_snprintf (buffer, sizeof (buffer), "%02i", minute);
+ pango_layout_set_text (layout, buffer, -1);
+ pango_layout_get_pixel_size (layout, &minute_width, NULL);
+
+ max_minute_width = MAX (max_minute_width, minute_width);
+ }
+ day_view->max_minute_width = max_minute_width;
+
+ pango_layout_set_text (layout, ":", 1);
+ pango_layout_get_pixel_size (layout, &day_view->colon_width, NULL);
+ pango_layout_set_text (layout, "0", 1);
+ pango_layout_get_pixel_size (layout, &day_view->digit_width, NULL);
+
+ pango_layout_set_text (layout, day_view->am_string, -1);
+ pango_layout_get_pixel_size (layout, &day_view->am_string_width, NULL);
+ pango_layout_set_text (layout, day_view->pm_string, -1);
+ pango_layout_get_pixel_size (layout, &day_view->pm_string_width, NULL);
+
+ /* Calculate the width of the time column. */
+ times_width = e_day_view_time_item_get_column_width (E_DAY_VIEW_TIME_ITEM (day_view->time_canvas_item));
+ gtk_widget_set_size_request (day_view->time_canvas, times_width, -1);
+
+ g_object_unref (layout);
+ pango_font_metrics_unref (font_metrics);
}
-static void
-process_component (EDayView *day_view,
- ECalModelComponent *comp_data)
+static gboolean
+day_view_focus (GtkWidget *widget,
+ GtkDirectionType direction)
{
- const gchar *uid;
- gchar *rid = NULL;
- ECalModel *model;
- ECalComponent *comp;
- ESourceRegistry *registry;
- AddEventData add_event_data;
+ EDayView *day_view;
+ gint new_day;
+ gint new_event_num;
+ gint start_row, end_row;
- model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
- registry = e_cal_model_get_registry (model);
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE);
+ day_view = E_DAY_VIEW (widget);
- /* If our time hasn't been set yet, just return. */
- if (day_view->lower == 0 && day_view->upper == 0)
- return;
+ if (!e_day_view_get_next_tab_event (day_view, direction,
+ &new_day, &new_event_num))
+ return FALSE;
- comp = e_cal_component_new ();
- if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp))) {
- g_object_unref (comp);
+ if ((new_day == -1) && (new_event_num == -1)) {
+ /* focus should go to the day view widget itself
+ */
+ gtk_widget_grab_focus (GTK_WIDGET (day_view));
+ return TRUE;
+ }
- g_message (G_STRLOC ": Could not set icalcomponent on ECalComponent");
- return;
+ if (new_day != E_DAY_VIEW_LONG_EVENT && new_day != -1) {
+ if (e_day_view_get_event_rows (day_view, new_day,
+ new_event_num,
+ &start_row, &end_row))
+ /* ensure the event to be seen */
+ e_day_view_ensure_rows_visible (
+ day_view,
+ start_row, end_row);
}
+ e_day_view_start_editing_event (
+ day_view, new_day,
+ new_event_num, NULL);
- e_cal_component_get_uid (comp, &uid);
- if (e_cal_component_is_instance (comp))
- rid = e_cal_component_get_recurid_as_string (comp);
- else
- rid = NULL;
- /* rid is never used below here, why? */
+ return TRUE;
+}
- /* Add the object */
- add_event_data.day_view = day_view;
- add_event_data.comp_data = comp_data;
- e_day_view_add_event (
- registry, comp, comp_data->instance_start,
- comp_data->instance_end, &add_event_data);
+static gboolean
+day_view_key_press (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ gboolean handled = FALSE;
+ handled = e_day_view_do_key_press (widget, event);
- g_object_unref (comp);
- g_free (rid);
+ /* if not handled, try key bindings */
+ if (!handled)
+ handled = GTK_WIDGET_CLASS (e_day_view_parent_class)->key_press_event (widget, event);
+ return handled;
}
-static void
-update_row (EDayView *day_view,
- gint row)
+static gint
+day_view_focus_in (GtkWidget *widget,
+ GdkEventFocus *event)
{
- ECalModelComponent *comp_data;
- ECalModel *model;
- gint day, event_num;
- const gchar *uid = NULL;
- gchar *rid = NULL;
+ EDayView *day_view;
- e_day_view_stop_editing_event (day_view);
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
- model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
- comp_data = e_cal_model_get_component_at (model, row);
- g_return_if_fail (comp_data != NULL);
+ day_view = E_DAY_VIEW (widget);
- uid = icalcomponent_get_uid (comp_data->icalcomp);
- if (e_cal_util_component_is_instance (comp_data->icalcomp)) {
- icalproperty *prop;
+ /* XXX Can't access flags directly anymore, but is it really needed?
+ * If so, could we call gtk_widget_send_focus_change() instead? */
+#if 0
+ GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
+#endif
- prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_RECURRENCEID_PROPERTY);
- if (prop)
- rid = icaltime_as_ical_string_r (icalcomponent_get_recurrenceid (comp_data->icalcomp));
- }
+ if (E_CALENDAR_VIEW (day_view)->in_focus && day_view->requires_update) {
+ time_t my_start = 0, my_end = 0, model_start = 0, model_end = 0;
- if (e_day_view_find_event_from_uid (day_view, comp_data->client, uid, rid, &day, &event_num))
- e_day_view_remove_event_cb (day_view, day, event_num, NULL);
+ day_view->requires_update = FALSE;
- g_free (rid);
+ e_cal_model_get_time_range (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), &model_start, &model_end);
- process_component (day_view, comp_data);
+ if (e_calendar_view_get_visible_time_range (E_CALENDAR_VIEW (day_view), &my_start, &my_end) &&
+ model_start == my_start && model_end == my_end) {
+ /* update only when the same time range is set in a view and in a model;
+ * otherwise time range change invokes also query update */
+ e_day_view_recalc_day_starts (day_view, day_view->lower);
+ e_day_view_update_query (day_view);
+ }
+ }
gtk_widget_queue_draw (day_view->top_canvas);
gtk_widget_queue_draw (day_view->main_canvas);
- e_day_view_queue_layout (day_view);
+
+ return FALSE;
}
-static void
-model_row_changed_cb (ETableModel *etm,
- gint row,
- gpointer user_data)
+static gint
+day_view_focus_out (GtkWidget *widget,
+ GdkEventFocus *event)
{
- EDayView *day_view = E_DAY_VIEW (user_data);
+ EDayView *day_view;
- if (!E_CALENDAR_VIEW (day_view)->in_focus) {
- e_day_view_free_events (day_view);
- day_view->requires_update = TRUE;
- return;
- }
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
- update_row (day_view, row);
+ day_view = E_DAY_VIEW (widget);
+
+ /* XXX Can't access flags directly anymore, but is it really needed?
+ * If so, could we call gtk_widget_send_focus_change() instead? */
+#if 0
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+#endif
+
+ gtk_widget_queue_draw (day_view->top_canvas);
+ gtk_widget_queue_draw (day_view->main_canvas);
+
+ return FALSE;
}
-static void
-model_cell_changed_cb (ETableModel *etm,
- gint col,
- gint row,
- gpointer user_data)
+static gboolean
+day_view_popup_menu (GtkWidget *widget)
{
- EDayView *day_view = E_DAY_VIEW (user_data);
+ EDayView *day_view = E_DAY_VIEW (widget);
+ e_day_view_show_popup_menu (
+ day_view, NULL,
+ day_view->editing_event_day,
+ day_view->editing_event_num);
+ return TRUE;
+}
- if (!E_CALENDAR_VIEW (day_view)->in_focus) {
- e_day_view_free_events (day_view);
- day_view->requires_update = TRUE;
- return;
+/* Returns the currently-selected event, or NULL if none */
+static GList *
+day_view_get_selected_events (ECalendarView *cal_view)
+{
+ EDayViewEvent *event = NULL;
+ GList *list = NULL;
+ EDayView *day_view = (EDayView *) cal_view;
+
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL);
+
+ if (day_view->editing_event_num != -1) {
+ if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) {
+ if (!is_array_index_in_bounds (day_view->long_events, day_view->editing_event_num))
+ return NULL;
+
+ event = &g_array_index (day_view->long_events,
+ EDayViewEvent,
+ day_view->editing_event_num);
+ } else {
+ if (!is_array_index_in_bounds (day_view->events[day_view->editing_event_day], day_view->editing_event_num))
+ return NULL;
+
+ event = &g_array_index (day_view->events[day_view->editing_event_day],
+ EDayViewEvent,
+ day_view->editing_event_num);
+ }
+ } else if (day_view->popup_event_num != -1) {
+ if (day_view->popup_event_day == E_DAY_VIEW_LONG_EVENT) {
+ if (!is_array_index_in_bounds (day_view->long_events, day_view->popup_event_num))
+ return NULL;
+
+ event = &g_array_index (day_view->long_events,
+ EDayViewEvent,
+ day_view->popup_event_num);
+ } else {
+ if (!is_array_index_in_bounds (day_view->events[day_view->popup_event_day], day_view->popup_event_num))
+ return NULL;
+
+ event = &g_array_index (day_view->events[day_view->popup_event_day],
+ EDayViewEvent,
+ day_view->popup_event_num);
+ }
}
- update_row (day_view, row);
+ if (event)
+ list = g_list_append (list, event);
+
+ return list;
}
+/* This sets the selected time range. If the start_time & end_time are not equal
+ * and are both visible in the view, then the selection is set to those times,
+ * otherwise it is set to 1 hour from the start of the working day. */
static void
-model_rows_inserted_cb (ETableModel *etm,
- gint row,
- gint count,
- gpointer user_data)
+day_view_set_selected_time_range (ECalendarView *cal_view,
+ time_t start_time,
+ time_t end_time)
{
- EDayView *day_view = E_DAY_VIEW (user_data);
ECalModel *model;
- gint i;
+ EDayView *day_view;
+ gint work_day_start_hour;
+ gint work_day_start_minute;
+ gint start_row, start_col, end_row, end_col;
+ gboolean need_redraw = FALSE, start_in_grid, end_in_grid;
- if (!E_CALENDAR_VIEW (day_view)->in_focus) {
- e_day_view_free_events (day_view);
- day_view->requires_update = TRUE;
- return;
+ day_view = E_DAY_VIEW (cal_view);
+ model = e_calendar_view_get_model (cal_view);
+ work_day_start_hour = e_cal_model_get_work_day_start_hour (model);
+ work_day_start_minute = e_cal_model_get_work_day_start_minute (model);
+
+ if (start_time == end_time)
+ end_time += e_calendar_view_get_time_divisions (cal_view) * 60;
+
+ /* Set the selection. */
+ start_in_grid = e_day_view_convert_time_to_grid_position (
+ day_view,
+ start_time,
+ &start_col,
+ &start_row);
+ end_in_grid = e_day_view_convert_time_to_grid_position (
+ day_view,
+ end_time - 60,
+ &end_col,
+ &end_row);
+
+ /* If either of the times isn't in the grid, or the selection covers
+ * an entire day, we set the selection to 1 row from the start of the
+ * working day, in the day corresponding to the start time. */
+ if (!start_in_grid || !end_in_grid
+ || (start_row == 0 && end_row == day_view->rows - 1)) {
+ end_col = start_col;
+
+ start_row = e_day_view_convert_time_to_row (
+ day_view, work_day_start_hour, work_day_start_minute);
+ start_row = CLAMP (start_row, 0, day_view->rows - 1);
+ end_row = start_row;
}
- e_day_view_stop_editing_event (day_view);
+ if (start_row != day_view->selection_start_row
+ || start_col != day_view->selection_start_day) {
+ need_redraw = TRUE;
+ day_view->selection_in_top_canvas = FALSE;
+ day_view->selection_start_row = start_row;
+ day_view->selection_start_day = start_col;
+ }
- model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
- for (i = 0; i < count; i++) {
- ECalModelComponent *comp_data;
+ if (end_row != day_view->selection_end_row
+ || end_col != day_view->selection_end_day) {
+ need_redraw = TRUE;
+ day_view->selection_in_top_canvas = FALSE;
+ day_view->selection_end_row = end_row;
+ day_view->selection_end_day = end_col;
+ }
- comp_data = e_cal_model_get_component_at (model, row + i);
- if (comp_data == NULL) {
- g_warning ("comp_data is NULL\n");
- continue;
- }
- process_component (day_view, comp_data);
+ if (need_redraw) {
+ gtk_widget_queue_draw (day_view->top_canvas);
+ gtk_widget_queue_draw (day_view->top_dates_canvas);
+ gtk_widget_queue_draw (day_view->main_canvas);
}
+}
- gtk_widget_queue_draw (day_view->top_canvas);
- gtk_widget_queue_draw (day_view->main_canvas);
- e_day_view_queue_layout (day_view);
+/* Gets the visible time range. Returns FALSE if no time range has been set. */
+static gboolean
+day_view_get_visible_time_range (ECalendarView *cal_view,
+ time_t *start_time,
+ time_t *end_time)
+{
+ EDayView *day_view = E_DAY_VIEW (cal_view);
+
+ /* If the date isn't set, return FALSE. */
+ if (day_view->lower == 0 && day_view->upper == 0)
+ return FALSE;
+
+ *start_time = day_view->day_starts[0];
+ *end_time = day_view->day_starts[day_view->days_shown];
+ return TRUE;
}
static void
-model_comps_deleted_cb (ETableModel *etm,
- gpointer data,
- gpointer user_data)
+day_view_paste_text (ECalendarView *cal_view)
{
- EDayView *day_view = E_DAY_VIEW (user_data);
- GSList *l, *list = data;
-
- if (!E_CALENDAR_VIEW (day_view)->in_focus) {
- e_day_view_free_events (day_view);
- day_view->requires_update = TRUE;
- return;
- }
+ EDayView *day_view;
+ EDayViewEvent *event;
- e_day_view_stop_editing_event (day_view);
+ g_return_if_fail (E_IS_DAY_VIEW (cal_view));
- for (l = list; l != NULL; l = g_slist_next (l)) {
- ECalModelComponent *comp_data = l->data;
- gint day, event_num;
- const gchar *uid = NULL;
- gchar *rid = NULL;
+ day_view = E_DAY_VIEW (cal_view);
- uid = icalcomponent_get_uid (comp_data->icalcomp);
- if (e_cal_util_component_is_instance (comp_data->icalcomp)) {
- icalproperty *prop;
+ if (day_view->editing_event_num == -1 &&
+ !e_day_view_add_new_event_in_selected_range (day_view, NULL))
+ return;
- prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_RECURRENCEID_PROPERTY);
- if (prop)
- rid = icaltime_as_ical_string_r (icalcomponent_get_recurrenceid (comp_data->icalcomp));
- }
+ if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) {
+ if (!is_array_index_in_bounds (day_view->long_events, day_view->editing_event_num))
+ return;
- if (e_day_view_find_event_from_uid (day_view, comp_data->client, uid, rid, &day, &event_num))
- e_day_view_remove_event_cb (day_view, day, event_num, NULL);
+ event = &g_array_index (day_view->long_events,
+ EDayViewEvent,
+ day_view->editing_event_num);
+ } else {
+ if (!is_array_index_in_bounds (day_view->events[day_view->editing_event_day], day_view->editing_event_num))
+ return;
- g_free (rid);
+ event = &g_array_index (day_view->events[day_view->editing_event_day],
+ EDayViewEvent,
+ day_view->editing_event_num);
}
- gtk_widget_queue_draw (day_view->top_canvas);
- gtk_widget_queue_draw (day_view->main_canvas);
- e_day_view_queue_layout (day_view);
+ if (event->canvas_item &&
+ E_IS_TEXT (event->canvas_item) &&
+ E_TEXT (event->canvas_item)->editing) {
+ e_text_paste_clipboard (E_TEXT (event->canvas_item));
+ }
}
static void
-timezone_changed_cb (ECalModel *cal_model,
- icaltimezone *old_zone,
- icaltimezone *new_zone,
- gpointer user_data)
+e_day_view_class_init (EDayViewClass *class)
{
- struct icaltimetype tt;
- time_t lower;
- EDayView *day_view = (EDayView *) user_data;
- ECalendarView *cal_view = (ECalendarView *) day_view;
+ GObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+ ECalendarViewClass *view_class;
- g_return_if_fail (E_IS_DAY_VIEW (day_view));
+ g_type_class_add_private (class, sizeof (EDayViewPrivate));
- if (!cal_view->in_focus) {
- e_day_view_free_events (day_view);
- day_view->requires_update = TRUE;
- return;
- }
+ object_class = G_OBJECT_CLASS (class);
+ object_class->set_property = day_view_set_property;
+ object_class->get_property = day_view_get_property;
+ object_class->constructed = day_view_constructed;
+ object_class->dispose = day_view_dispose;
- /* If our time hasn't been set yet, just return. */
- if (day_view->lower == 0 && day_view->upper == 0)
- return;
+ widget_class = GTK_WIDGET_CLASS (class);
+ widget_class->realize = day_view_realize;
+ widget_class->unrealize = day_view_unrealize;
+ widget_class->size_allocate = day_view_size_allocate;
+ widget_class->style_set = day_view_style_set;
+ widget_class->focus = day_view_focus;
+ widget_class->key_press_event = day_view_key_press;
+ widget_class->focus_in_event = day_view_focus_in;
+ widget_class->focus_out_event = day_view_focus_out;
+ widget_class->popup_menu = day_view_popup_menu;
- /* Recalculate the new start of the first day. We just use exactly
- * the same time, but with the new timezone. */
- tt = icaltime_from_timet_with_zone (
- day_view->lower, FALSE,
- old_zone);
+ view_class = E_CALENDAR_VIEW_CLASS (class);
+ view_class->get_selected_events = day_view_get_selected_events;
+ view_class->get_selected_time_range = day_view_get_selected_time_range;
+ view_class->set_selected_time_range = day_view_set_selected_time_range;
+ view_class->get_visible_time_range = day_view_get_visible_time_range;
+ view_class->paste_text = day_view_paste_text;
- lower = icaltime_as_timet_with_zone (tt, new_zone);
+ /* XXX Should these be constructor properties? */
- e_day_view_recalc_day_starts (day_view, lower);
- e_day_view_update_query (day_view);
+ g_object_class_install_property (
+ object_class,
+ PROP_MARCUS_BAINS_SHOW_LINE,
+ g_param_spec_boolean (
+ "marcus-bains-show-line",
+ "Marcus Bains Show Line",
+ NULL,
+ TRUE,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MARCUS_BAINS_DAY_VIEW_COLOR,
+ g_param_spec_string (
+ "marcus-bains-day-view-color",
+ "Marcus Bains Day View Color",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ g_object_class_install_property (
+ object_class,
+ PROP_MARCUS_BAINS_TIME_BAR_COLOR,
+ g_param_spec_string (
+ "marcus-bains-time-bar-color",
+ "Marcus Bains Time Bar Color",
+ NULL,
+ NULL,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /* FIXME Make this a real GFlags type. */
+ g_object_class_install_property (
+ object_class,
+ PROP_WORKING_DAYS,
+ g_param_spec_int (
+ "working-days",
+ "Working Days",
+ NULL,
+ 0x00,
+ 0x7f,
+ 0,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /* init the accessibility support for e_day_view */
+ e_day_view_a11y_init ();
}
static void
@@ -941,6 +1494,8 @@ e_day_view_init (EDayView *day_view)
GtkScrollable *scrollable;
GtkWidget *w;
+ day_view->priv = E_DAY_VIEW_GET_PRIVATE (day_view);
+
gtk_widget_set_can_focus (GTK_WIDGET (day_view), TRUE);
day_view->long_events = g_array_new (
@@ -1286,6 +1841,278 @@ e_day_view_init (EDayView *day_view)
}
static void
+time_range_changed_cb (ECalModel *model,
+ time_t start_time,
+ time_t end_time,
+ gpointer user_data)
+{
+ EDayView *day_view = E_DAY_VIEW (user_data);
+ EDayViewTimeItem *eti;
+ time_t lower;
+
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ /* Calculate the first day that should be shown, based on start_time
+ * and the days_shown setting. If we are showing 1 day it is just the
+ * start of the day given by start_time, otherwise it is the previous
+ * work-week start day. */
+ if (!day_view->work_week_view) {
+ lower = time_day_begin_with_zone (start_time, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
+ } else {
+ lower = e_day_view_find_work_week_start (day_view, start_time);
+ }
+
+ /* See if we need to change the days shown. */
+ if (lower != day_view->lower)
+ e_day_view_recalc_day_starts (day_view, lower);
+
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ e_day_view_free_events (day_view);
+ day_view->requires_update = TRUE;
+ return;
+ }
+
+ /* If we don't show the new selection, don't preserve it */
+ if (day_view->selection_start_day == -1 || day_view->days_shown <= day_view->selection_start_day)
+ day_view_set_selected_time_range (E_CALENDAR_VIEW (day_view), start_time, end_time);
+
+ if (day_view->selection_start_row != -1)
+ e_day_view_ensure_rows_visible (day_view, day_view->selection_start_row, day_view->selection_start_row);
+
+ /* update the time canvas to show proper date in it */
+ eti = E_DAY_VIEW_TIME_ITEM (day_view->time_canvas_item);
+ if (eti && e_day_view_time_item_get_second_zone (eti))
+ gtk_widget_queue_draw (day_view->time_canvas);
+}
+
+static void
+process_component (EDayView *day_view,
+ ECalModelComponent *comp_data)
+{
+ const gchar *uid;
+ gchar *rid = NULL;
+ ECalModel *model;
+ ECalComponent *comp;
+ ESourceRegistry *registry;
+ AddEventData add_event_data;
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+ registry = e_cal_model_get_registry (model);
+
+ /* If our time hasn't been set yet, just return. */
+ if (day_view->lower == 0 && day_view->upper == 0)
+ return;
+
+ comp = e_cal_component_new ();
+ if (!e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (comp_data->icalcomp))) {
+ g_object_unref (comp);
+
+ g_message (G_STRLOC ": Could not set icalcomponent on ECalComponent");
+ return;
+ }
+
+ e_cal_component_get_uid (comp, &uid);
+ if (e_cal_component_is_instance (comp))
+ rid = e_cal_component_get_recurid_as_string (comp);
+ else
+ rid = NULL;
+ /* rid is never used below here, why? */
+
+ /* Add the object */
+ add_event_data.day_view = day_view;
+ add_event_data.comp_data = comp_data;
+ e_day_view_add_event (
+ registry, comp, comp_data->instance_start,
+ comp_data->instance_end, &add_event_data);
+
+ g_object_unref (comp);
+ g_free (rid);
+}
+
+static void
+update_row (EDayView *day_view,
+ gint row)
+{
+ ECalModelComponent *comp_data;
+ ECalModel *model;
+ gint day, event_num;
+ const gchar *uid = NULL;
+ gchar *rid = NULL;
+
+ e_day_view_stop_editing_event (day_view);
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+ comp_data = e_cal_model_get_component_at (model, row);
+ g_return_if_fail (comp_data != NULL);
+
+ uid = icalcomponent_get_uid (comp_data->icalcomp);
+ if (e_cal_util_component_is_instance (comp_data->icalcomp)) {
+ icalproperty *prop;
+
+ prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_RECURRENCEID_PROPERTY);
+ if (prop)
+ rid = icaltime_as_ical_string_r (icalcomponent_get_recurrenceid (comp_data->icalcomp));
+ }
+
+ if (e_day_view_find_event_from_uid (day_view, comp_data->client, uid, rid, &day, &event_num))
+ e_day_view_remove_event_cb (day_view, day, event_num, NULL);
+
+ g_free (rid);
+
+ process_component (day_view, comp_data);
+
+ gtk_widget_queue_draw (day_view->top_canvas);
+ gtk_widget_queue_draw (day_view->main_canvas);
+ e_day_view_queue_layout (day_view);
+}
+
+static void
+model_row_changed_cb (ETableModel *etm,
+ gint row,
+ gpointer user_data)
+{
+ EDayView *day_view = E_DAY_VIEW (user_data);
+
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ e_day_view_free_events (day_view);
+ day_view->requires_update = TRUE;
+ return;
+ }
+
+ update_row (day_view, row);
+}
+
+static void
+model_cell_changed_cb (ETableModel *etm,
+ gint col,
+ gint row,
+ gpointer user_data)
+{
+ EDayView *day_view = E_DAY_VIEW (user_data);
+
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ e_day_view_free_events (day_view);
+ day_view->requires_update = TRUE;
+ return;
+ }
+
+ update_row (day_view, row);
+}
+
+static void
+model_rows_inserted_cb (ETableModel *etm,
+ gint row,
+ gint count,
+ gpointer user_data)
+{
+ EDayView *day_view = E_DAY_VIEW (user_data);
+ ECalModel *model;
+ gint i;
+
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ e_day_view_free_events (day_view);
+ day_view->requires_update = TRUE;
+ return;
+ }
+
+ e_day_view_stop_editing_event (day_view);
+
+ model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
+ for (i = 0; i < count; i++) {
+ ECalModelComponent *comp_data;
+
+ comp_data = e_cal_model_get_component_at (model, row + i);
+ if (comp_data == NULL) {
+ g_warning ("comp_data is NULL\n");
+ continue;
+ }
+ process_component (day_view, comp_data);
+ }
+
+ gtk_widget_queue_draw (day_view->top_canvas);
+ gtk_widget_queue_draw (day_view->main_canvas);
+ e_day_view_queue_layout (day_view);
+
+}
+
+static void
+model_comps_deleted_cb (ETableModel *etm,
+ gpointer data,
+ gpointer user_data)
+{
+ EDayView *day_view = E_DAY_VIEW (user_data);
+ GSList *l, *list = data;
+
+ if (!E_CALENDAR_VIEW (day_view)->in_focus) {
+ e_day_view_free_events (day_view);
+ day_view->requires_update = TRUE;
+ return;
+ }
+
+ e_day_view_stop_editing_event (day_view);
+
+ for (l = list; l != NULL; l = g_slist_next (l)) {
+ ECalModelComponent *comp_data = l->data;
+ gint day, event_num;
+ const gchar *uid = NULL;
+ gchar *rid = NULL;
+
+ uid = icalcomponent_get_uid (comp_data->icalcomp);
+ if (e_cal_util_component_is_instance (comp_data->icalcomp)) {
+ icalproperty *prop;
+
+ prop = icalcomponent_get_first_property (comp_data->icalcomp, ICAL_RECURRENCEID_PROPERTY);
+ if (prop)
+ rid = icaltime_as_ical_string_r (icalcomponent_get_recurrenceid (comp_data->icalcomp));
+ }
+
+ if (e_day_view_find_event_from_uid (day_view, comp_data->client, uid, rid, &day, &event_num))
+ e_day_view_remove_event_cb (day_view, day, event_num, NULL);
+
+ g_free (rid);
+ }
+
+ gtk_widget_queue_draw (day_view->top_canvas);
+ gtk_widget_queue_draw (day_view->main_canvas);
+ e_day_view_queue_layout (day_view);
+}
+
+static void
+timezone_changed_cb (ECalModel *cal_model,
+ icaltimezone *old_zone,
+ icaltimezone *new_zone,
+ gpointer user_data)
+{
+ struct icaltimetype tt;
+ time_t lower;
+ EDayView *day_view = (EDayView *) user_data;
+ ECalendarView *cal_view = (ECalendarView *) day_view;
+
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ if (!cal_view->in_focus) {
+ e_day_view_free_events (day_view);
+ day_view->requires_update = TRUE;
+ return;
+ }
+
+ /* If our time hasn't been set yet, just return. */
+ if (day_view->lower == 0 && day_view->upper == 0)
+ return;
+
+ /* Recalculate the new start of the first day. We just use exactly
+ * the same time, but with the new timezone. */
+ tt = icaltime_from_timet_with_zone (
+ day_view->lower, FALSE,
+ old_zone);
+
+ lower = icaltime_as_timet_with_zone (tt, new_zone);
+
+ e_day_view_recalc_day_starts (day_view, lower);
+ e_day_view_update_query (day_view);
+}
+
+static void
init_model (EDayView *day_view,
ECalModel *model)
{
@@ -1342,111 +2169,6 @@ e_day_view_new (ECalModel *model)
}
static void
-e_day_view_dispose (GObject *object)
-{
- EDayView *day_view;
- gint day;
-
- day_view = E_DAY_VIEW (object);
-
- e_day_view_cancel_layout (day_view);
-
- e_day_view_stop_auto_scroll (day_view);
-
- if (day_view->large_font_desc) {
- pango_font_description_free (day_view->large_font_desc);
- day_view->large_font_desc = NULL;
- }
-
- if (day_view->small_font_desc) {
- pango_font_description_free (day_view->small_font_desc);
- day_view->small_font_desc = NULL;
- }
-
- if (day_view->normal_cursor) {
- g_object_unref (day_view->normal_cursor);
- day_view->normal_cursor = NULL;
- }
- if (day_view->move_cursor) {
- g_object_unref (day_view->move_cursor);
- day_view->move_cursor = NULL;
- }
- if (day_view->resize_width_cursor) {
- g_object_unref (day_view->resize_width_cursor);
- day_view->resize_width_cursor = NULL;
- }
- if (day_view->resize_height_cursor) {
- g_object_unref (day_view->resize_height_cursor);
- day_view->resize_height_cursor = NULL;
- }
-
- if (day_view->long_events) {
- e_day_view_free_events (day_view);
- g_array_free (day_view->long_events, TRUE);
- day_view->long_events = NULL;
- }
-
- for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) {
- if (day_view->events[day]) {
- g_array_free (day_view->events[day], TRUE);
- day_view->events[day] = NULL;
- }
- }
-
- if (day_view->grabbed_pointer != NULL) {
- gdk_device_ungrab (
- day_view->grabbed_pointer,
- GDK_CURRENT_TIME);
- g_object_unref (day_view->grabbed_pointer);
- day_view->grabbed_pointer = NULL;
- }
-
- /* Chain up to parent's dispose() method. */
- G_OBJECT_CLASS (e_day_view_parent_class)->dispose (object);
-}
-
-static void
-e_day_view_realize (GtkWidget *widget)
-{
- EDayView *day_view;
-
- if (GTK_WIDGET_CLASS (e_day_view_parent_class)->realize)
- (*GTK_WIDGET_CLASS (e_day_view_parent_class)->realize)(widget);
-
- day_view = E_DAY_VIEW (widget);
-
- /* Allocate the colors. */
-
- e_day_view_set_colors (day_view, widget);
-
- /* Create the pixmaps. */
- day_view->reminder_icon = e_icon_factory_get_icon ("stock_bell", GTK_ICON_SIZE_MENU);
- day_view->recurrence_icon = e_icon_factory_get_icon ("view-refresh", GTK_ICON_SIZE_MENU);
- day_view->timezone_icon = e_icon_factory_get_icon ("stock_timezone", GTK_ICON_SIZE_MENU);
- day_view->meeting_icon = e_icon_factory_get_icon ("stock_people", GTK_ICON_SIZE_MENU);
- day_view->attach_icon = e_icon_factory_get_icon ("mail-attachment", GTK_ICON_SIZE_MENU);
-
- /* Set the canvas item colors. */
- gnome_canvas_item_set (
- day_view->drag_long_event_rect_item,
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
- NULL);
-
- gnome_canvas_item_set (
- day_view->drag_rect_item,
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
- NULL);
-
- gnome_canvas_item_set (
- day_view->drag_bar_item,
- "fill_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_VBAR],
- "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER],
- NULL);
-}
-
-static void
e_day_view_set_colors (EDayView *day_view,
GtkWidget *widget)
{
@@ -1472,57 +2194,6 @@ e_day_view_set_colors (EDayView *day_view,
}
static void
-e_day_view_unrealize (GtkWidget *widget)
-{
- EDayView *day_view;
-
- day_view = E_DAY_VIEW (widget);
-
- g_object_unref (day_view->reminder_icon);
- day_view->reminder_icon = NULL;
- g_object_unref (day_view->recurrence_icon);
- day_view->recurrence_icon = NULL;
- g_object_unref (day_view->timezone_icon);
- day_view->timezone_icon = NULL;
- g_object_unref (day_view->meeting_icon);
- day_view->meeting_icon = NULL;
- g_object_unref (day_view->attach_icon);
- day_view->attach_icon = NULL;
-
- if (GTK_WIDGET_CLASS (e_day_view_parent_class)->unrealize)
- (*GTK_WIDGET_CLASS (e_day_view_parent_class)->unrealize)(widget);
-}
-
-static GdkColor
-e_day_view_get_text_color (EDayView *day_view,
- EDayViewEvent *event,
- GtkWidget *widget)
-{
- GtkStyle *style;
- GdkColor bg_color;
- guint16 red, green, blue;
- gdouble cc = 65535.0;
-
- red = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].red;
- green = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].green;
- blue = day_view->colors[E_DAY_VIEW_COLOR_EVENT_BACKGROUND].blue;
-
- if (is_comp_data_valid (event) && gdk_color_parse (e_cal_model_get_color_for_component (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), event->comp_data),
- &bg_color)) {
- red = bg_color.red;
- green = bg_color.green;
- blue = bg_color.blue;
- }
-
- style = gtk_widget_get_style (widget);
-
- if ((red / cc > 0.7) || (green / cc > 0.7) || (blue / cc > 0.7))
- return style->black;
- else
- return style->white;
-}
-
-static void
e_day_view_update_top_scroll (EDayView *day_view,
gboolean scroll_to_top)
{
@@ -1567,249 +2238,6 @@ e_day_view_update_top_scroll (EDayView *day_view,
}
static void
-e_day_view_style_set (GtkWidget *widget,
- GtkStyle *previous_style)
-{
- EDayView *day_view;
- gint hour;
- gint minute, max_minute_width, i;
- gint month, day, width;
- gint longest_month_width, longest_abbreviated_month_width;
- gint longest_weekday_width, longest_abbreviated_weekday_width;
- gchar buffer[128];
- const gchar *name;
- gint times_width;
- PangoFontDescription *font_desc;
- PangoContext *pango_context;
- PangoFontMetrics *font_metrics;
- PangoLayout *layout;
- gint week_day, event_num;
- GtkAdjustment *adjustment;
- EDayViewEvent *event;
- GdkColor color;
-
- if (GTK_WIDGET_CLASS (e_day_view_parent_class)->style_set)
- (*GTK_WIDGET_CLASS (e_day_view_parent_class)->style_set)(widget, previous_style);
-
- day_view = E_DAY_VIEW (widget);
- e_day_view_set_colors (day_view, widget);
-
- for (week_day = 0; week_day < E_DAY_VIEW_MAX_DAYS; week_day++) {
- for (event_num = 0; event_num < day_view->events[week_day]->len; event_num++) {
- event = &g_array_index (day_view->events[week_day], EDayViewEvent, event_num);
- if (event->canvas_item) {
- color = e_day_view_get_text_color (day_view, event, widget);
- gnome_canvas_item_set (
- event->canvas_item,
- "fill_color_gdk", &color,
- NULL);
- }
- }
- }
- for (event_num = 0; event_num < day_view->long_events->len; event_num++) {
- event = &g_array_index (day_view->long_events, EDayViewEvent, event_num);
- if (event->canvas_item) {
- color = e_day_view_get_text_color (day_view, event, widget);
- gnome_canvas_item_set (
- event->canvas_item,
- "fill_color_gdk", &color,
- NULL);
- }
- }
-
- /* Set up Pango prerequisites */
- font_desc = gtk_widget_get_style (widget)->font_desc;
- pango_context = gtk_widget_get_pango_context (widget);
- font_metrics = pango_context_get_metrics (
- pango_context, font_desc,
- pango_context_get_language (pango_context));
- layout = pango_layout_new (pango_context);
-
- /* Create the large font. */
- if (day_view->large_font_desc != NULL)
- pango_font_description_free (day_view->large_font_desc);
-
- day_view->large_font_desc = pango_font_description_copy (font_desc);
- pango_font_description_set_size (
- day_view->large_font_desc,
- E_DAY_VIEW_LARGE_FONT_PTSIZE * PANGO_SCALE);
-
- /* Create the small fonts. */
- if (day_view->small_font_desc != NULL)
- pango_font_description_free (day_view->small_font_desc);
-
- day_view->small_font_desc = pango_font_description_copy (font_desc);
- pango_font_description_set_size (
- day_view->small_font_desc,
- E_DAY_VIEW_SMALL_FONT_PTSIZE * PANGO_SCALE);
-
- /* Recalculate the height of each row based on the font size. */
- day_view->row_height =
- PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) +
- PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) +
- E_DAY_VIEW_EVENT_BORDER_HEIGHT + E_DAY_VIEW_EVENT_Y_PAD * 2 + 2 /* FIXME */;
- day_view->row_height = MAX (
- day_view->row_height,
- E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD + 2);
-
- adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (day_view->main_canvas));
- gtk_adjustment_set_step_increment (adjustment, day_view->row_height);
-
- day_view->top_row_height =
- PANGO_PIXELS (pango_font_metrics_get_ascent (font_metrics)) +
- PANGO_PIXELS (pango_font_metrics_get_descent (font_metrics)) +
- E_DAY_VIEW_LONG_EVENT_BORDER_HEIGHT * 2 + E_DAY_VIEW_LONG_EVENT_Y_PAD * 2 +
- E_DAY_VIEW_TOP_CANVAS_Y_GAP;
- day_view->top_row_height =
- MAX (
- day_view->top_row_height,
- E_DAY_VIEW_ICON_HEIGHT + E_DAY_VIEW_ICON_Y_PAD + 2 +
- E_DAY_VIEW_TOP_CANVAS_Y_GAP);
-
- adjustment = gtk_scrollable_get_vadjustment (GTK_SCROLLABLE (day_view->top_canvas));
- gtk_adjustment_set_step_increment (adjustment, day_view->top_row_height);
- gtk_widget_set_size_request (day_view->top_dates_canvas, -1, day_view->top_row_height - 2);
-
- e_day_view_update_top_scroll (day_view, TRUE);
-
- /* Find the longest full & abbreviated month names. */
- longest_month_width = 0;
- longest_abbreviated_month_width = 0;
- for (month = 0; month < 12; month++) {
- name = e_get_month_name (month + 1, FALSE);
- pango_layout_set_text (layout, name, -1);
- pango_layout_get_pixel_size (layout, &width, NULL);
-
- if (width > longest_month_width) {
- longest_month_width = width;
- day_view->longest_month_name = month;
- }
-
- name = e_get_month_name (month + 1, TRUE);
- pango_layout_set_text (layout, name, -1);
- pango_layout_get_pixel_size (layout, &width, NULL);
-
- if (width > longest_abbreviated_month_width) {
- longest_abbreviated_month_width = width;
- day_view->longest_abbreviated_month_name = month;
- }
- }
-
- /* Find the longest full & abbreviated weekday names. */
- longest_weekday_width = 0;
- longest_abbreviated_weekday_width = 0;
- for (day = 0; day < 7; day++) {
- name = e_get_weekday_name (day + 1, FALSE);
- pango_layout_set_text (layout, name, -1);
- pango_layout_get_pixel_size (layout, &width, NULL);
-
- if (width > longest_weekday_width) {
- longest_weekday_width = width;
- day_view->longest_weekday_name = day;
- }
-
- name = e_get_weekday_name (day + 1, TRUE);
- pango_layout_set_text (layout, name, -1);
- pango_layout_get_pixel_size (layout, &width, NULL);
-
- if (width > longest_abbreviated_weekday_width) {
- longest_abbreviated_weekday_width = width;
- day_view->longest_abbreviated_weekday_name = day;
- }
- }
-
- /* Calculate the widths of all the time strings necessary. */
- day_view->max_small_hour_width = 0;
- for (hour = 0; hour < 24; hour++) {
- g_snprintf (buffer, sizeof (buffer), "%02i", hour);
- pango_layout_set_text (layout, buffer, -1);
- pango_layout_get_pixel_size (layout, &day_view->small_hour_widths[hour], NULL);
-
- day_view->max_small_hour_width = MAX (day_view->max_small_hour_width, day_view->small_hour_widths[hour]);
- }
-
- max_minute_width = 0;
- for (minute = 0, i = 0; minute < 60; minute += 5, i++) {
- gint minute_width;
-
- g_snprintf (buffer, sizeof (buffer), "%02i", minute);
- pango_layout_set_text (layout, buffer, -1);
- pango_layout_get_pixel_size (layout, &minute_width, NULL);
-
- max_minute_width = MAX (max_minute_width, minute_width);
- }
- day_view->max_minute_width = max_minute_width;
-
- pango_layout_set_text (layout, ":", 1);
- pango_layout_get_pixel_size (layout, &day_view->colon_width, NULL);
- pango_layout_set_text (layout, "0", 1);
- pango_layout_get_pixel_size (layout, &day_view->digit_width, NULL);
-
- pango_layout_set_text (layout, day_view->am_string, -1);
- pango_layout_get_pixel_size (layout, &day_view->am_string_width, NULL);
- pango_layout_set_text (layout, day_view->pm_string, -1);
- pango_layout_get_pixel_size (layout, &day_view->pm_string_width, NULL);
-
- /* Calculate the width of the time column. */
- times_width = e_day_view_time_item_get_column_width (E_DAY_VIEW_TIME_ITEM (day_view->time_canvas_item));
- gtk_widget_set_size_request (day_view->time_canvas, times_width, -1);
-
- g_object_unref (layout);
- pango_font_metrics_unref (font_metrics);
-}
-
-static void
-e_day_view_recalc_main_canvas_size (EDayView *day_view)
-{
- ECalModel *model;
- gint work_day_start_hour;
- gint work_day_start_minute;
- gint day, scroll_y;
- gboolean need_reshape;
-
- model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
- work_day_start_hour = e_cal_model_get_work_day_start_hour (model);
- work_day_start_minute = e_cal_model_get_work_day_start_minute (model);
-
- /* Set the scroll region of the top canvas */
- e_day_view_update_top_scroll (day_view, TRUE);
-
- need_reshape = e_day_view_update_scroll_regions (day_view);
-
- e_day_view_recalc_cell_sizes (day_view);
-
- /* Scroll to the start of the working day, if this is the initial
- * allocation. */
- if (day_view->scroll_to_work_day) {
- scroll_y = e_day_view_convert_time_to_position (
- day_view, work_day_start_hour, work_day_start_minute);
- gnome_canvas_scroll_to (
- GNOME_CANVAS (day_view->main_canvas), 0, scroll_y);
- day_view->scroll_to_work_day = FALSE;
- }
-
- /* Flag that we need to reshape the events. Note that changes in height
- * don't matter, since the rows are always the same height. */
- if (need_reshape) {
- day_view->long_events_need_reshape = TRUE;
- for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++)
- day_view->need_reshape[day] = TRUE;
-
- e_day_view_check_layout (day_view);
- }
-}
-
-/* This recalculates the sizes of each column. */
-static void
-e_day_view_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- (*GTK_WIDGET_CLASS (e_day_view_parent_class)->size_allocate) (widget, allocation);
-
- e_day_view_recalc_main_canvas_size (E_DAY_VIEW (widget));
-}
-
-static void
e_day_view_recalc_cell_sizes (EDayView *day_view)
{
/* An array of dates, one for each month in the year 2000. They must
@@ -1914,70 +2342,6 @@ exit:
g_object_unref (layout);
}
-static gint
-e_day_view_focus_in (GtkWidget *widget,
- GdkEventFocus *event)
-{
- EDayView *day_view;
-
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- day_view = E_DAY_VIEW (widget);
-
- /* XXX Can't access flags directly anymore, but is it really needed?
- * If so, could we call gtk_widget_send_focus_change() instead? */
-#if 0
- GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
-#endif
-
- if (E_CALENDAR_VIEW (day_view)->in_focus && day_view->requires_update) {
- time_t my_start = 0, my_end = 0, model_start = 0, model_end = 0;
-
- day_view->requires_update = FALSE;
-
- e_cal_model_get_time_range (e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)), &model_start, &model_end);
-
- if (e_calendar_view_get_visible_time_range (E_CALENDAR_VIEW (day_view), &my_start, &my_end) &&
- model_start == my_start && model_end == my_end) {
- /* update only when the same time range is set in a view and in a model;
- * otherwise time range change invokes also query update */
- e_day_view_recalc_day_starts (day_view, day_view->lower);
- e_day_view_update_query (day_view);
- }
- }
-
- gtk_widget_queue_draw (day_view->top_canvas);
- gtk_widget_queue_draw (day_view->main_canvas);
-
- return FALSE;
-}
-
-static gint
-e_day_view_focus_out (GtkWidget *widget,
- GdkEventFocus *event)
-{
- EDayView *day_view;
-
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- day_view = E_DAY_VIEW (widget);
-
- /* XXX Can't access flags directly anymore, but is it really needed?
- * If so, could we call gtk_widget_send_focus_change() instead? */
-#if 0
- GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
-#endif
-
- gtk_widget_queue_draw (day_view->top_canvas);
- gtk_widget_queue_draw (day_view->main_canvas);
-
- return FALSE;
-}
-
/* This calls a given function for each event instance (in both views).
* If the callback returns FALSE the iteration is stopped.
* Note that it is safe for the callback to remove the event (since we
@@ -2554,137 +2918,6 @@ e_day_view_find_work_week_start (EDayView *day_view,
return icaltime_as_timet_with_zone (tt, e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
}
-/* This sets the selected time range. If the start_time & end_time are not equal
- * and are both visible in the view, then the selection is set to those times,
- * otherwise it is set to 1 hour from the start of the working day. */
-static void
-e_day_view_set_selected_time_range (ECalendarView *cal_view,
- time_t start_time,
- time_t end_time)
-{
- ECalModel *model;
- EDayView *day_view;
- gint work_day_start_hour;
- gint work_day_start_minute;
- gint start_row, start_col, end_row, end_col;
- gboolean need_redraw = FALSE, start_in_grid, end_in_grid;
-
- day_view = E_DAY_VIEW (cal_view);
- model = e_calendar_view_get_model (cal_view);
- work_day_start_hour = e_cal_model_get_work_day_start_hour (model);
- work_day_start_minute = e_cal_model_get_work_day_start_minute (model);
-
- if (start_time == end_time)
- end_time += e_calendar_view_get_time_divisions (cal_view) * 60;
-
- /* Set the selection. */
- start_in_grid = e_day_view_convert_time_to_grid_position (
- day_view,
- start_time,
- &start_col,
- &start_row);
- end_in_grid = e_day_view_convert_time_to_grid_position (
- day_view,
- end_time - 60,
- &end_col,
- &end_row);
-
- /* If either of the times isn't in the grid, or the selection covers
- * an entire day, we set the selection to 1 row from the start of the
- * working day, in the day corresponding to the start time. */
- if (!start_in_grid || !end_in_grid
- || (start_row == 0 && end_row == day_view->rows - 1)) {
- end_col = start_col;
-
- start_row = e_day_view_convert_time_to_row (
- day_view, work_day_start_hour, work_day_start_minute);
- start_row = CLAMP (start_row, 0, day_view->rows - 1);
- end_row = start_row;
- }
-
- if (start_row != day_view->selection_start_row
- || start_col != day_view->selection_start_day) {
- need_redraw = TRUE;
- day_view->selection_in_top_canvas = FALSE;
- day_view->selection_start_row = start_row;
- day_view->selection_start_day = start_col;
- }
-
- if (end_row != day_view->selection_end_row
- || end_col != day_view->selection_end_day) {
- need_redraw = TRUE;
- day_view->selection_in_top_canvas = FALSE;
- day_view->selection_end_row = end_row;
- day_view->selection_end_day = end_col;
- }
-
- if (need_redraw) {
- gtk_widget_queue_draw (day_view->top_canvas);
- gtk_widget_queue_draw (day_view->top_dates_canvas);
- gtk_widget_queue_draw (day_view->main_canvas);
- }
-}
-
-/* Returns the selected time range. */
-static gboolean
-e_day_view_get_selected_time_range (ECalendarView *cal_view,
- time_t *start_time,
- time_t *end_time)
-{
- gint start_col, start_row, end_col, end_row;
- time_t start, end;
- EDayView *day_view = E_DAY_VIEW (cal_view);
-
- start_col = day_view->selection_start_day;
- start_row = day_view->selection_start_row;
- end_col = day_view->selection_end_day;
- end_row = day_view->selection_end_row;
-
- if (start_col == -1) {
- start_col = 0;
- start_row = 0;
- end_col = 0;
- end_row = 0;
- }
-
- /* Check if the selection is only in the top canvas, in which case
- * we can simply use the day_starts array. */
- if (day_view->selection_in_top_canvas) {
- start = day_view->day_starts[start_col];
- end = day_view->day_starts[end_col + 1];
- } else {
- /* Convert the start col + row into a time. */
- start = e_day_view_convert_grid_position_to_time (day_view, start_col, start_row);
- end = e_day_view_convert_grid_position_to_time (day_view, end_col, end_row + 1);
- }
-
- if (start_time)
- *start_time = start;
-
- if (end_time)
- *end_time = end;
-
- return TRUE;
-}
-
-/* Gets the visible time range. Returns FALSE if no time range has been set. */
-static gboolean
-e_day_view_get_visible_time_range (ECalendarView *cal_view,
- time_t *start_time,
- time_t *end_time)
-{
- EDayView *day_view = E_DAY_VIEW (cal_view);
-
- /* If the date isn't set, return FALSE. */
- if (day_view->lower == 0 && day_view->upper == 0)
- return FALSE;
-
- *start_time = day_view->day_starts[0];
- *end_time = day_view->day_starts[day_view->days_shown];
-
- return TRUE;
-}
-
static void
e_day_view_recalc_day_starts (EDayView *day_view,
time_t start_time)
@@ -3163,11 +3396,11 @@ e_day_view_on_top_canvas_button_press (GtkWidget *widget,
if (button_event->type == GDK_2BUTTON_PRESS) {
time_t dtstart, dtend;
- e_day_view_get_selected_time_range ((ECalendarView *) day_view, &dtstart, &dtend);
+ day_view_get_selected_time_range ((ECalendarView *) day_view, &dtstart, &dtend);
if (dtstart < day_view->before_click_dtend && dtend > day_view->before_click_dtstart) {
dtstart = day_view->before_click_dtstart;
dtend = day_view->before_click_dtend;
- e_day_view_set_selected_time_range ((ECalendarView *) day_view, dtstart, dtend);
+ day_view_set_selected_time_range ((ECalendarView *) day_view, dtstart, dtend);
}
e_calendar_view_new_appointment_for (
@@ -3195,7 +3428,7 @@ e_day_view_on_top_canvas_button_press (GtkWidget *widget,
day_view->grabbed_pointer = g_object_ref (event_device);
if (event_time - day_view->bc_event_time > 250)
- e_day_view_get_selected_time_range (
+ day_view_get_selected_time_range (
E_CALENDAR_VIEW (day_view),
&day_view->before_click_dtstart,
&day_view->before_click_dtend);
@@ -3328,11 +3561,11 @@ e_day_view_on_main_canvas_button_press (GtkWidget *widget,
if (button_event->type == GDK_2BUTTON_PRESS) {
time_t dtstart, dtend;
- e_day_view_get_selected_time_range ((ECalendarView *) day_view, &dtstart, &dtend);
+ day_view_get_selected_time_range ((ECalendarView *) day_view, &dtstart, &dtend);
if (dtstart < day_view->before_click_dtend && dtend > day_view->before_click_dtstart) {
dtstart = day_view->before_click_dtstart;
dtend = day_view->before_click_dtend;
- e_day_view_set_selected_time_range ((ECalendarView *) day_view, dtstart, dtend);
+ day_view_set_selected_time_range ((ECalendarView *) day_view, dtstart, dtend);
}
e_calendar_view_new_appointment_for (
E_CALENDAR_VIEW (day_view),
@@ -3359,7 +3592,7 @@ e_day_view_on_main_canvas_button_press (GtkWidget *widget,
day_view->grabbed_pointer = g_object_ref (event_device);
if (event_time - day_view->bc_event_time > 250)
- e_day_view_get_selected_time_range (
+ day_view_get_selected_time_range (
E_CALENDAR_VIEW (day_view),
&day_view->before_click_dtstart,
&day_view->before_click_dtend);
@@ -3807,67 +4040,6 @@ e_day_view_show_popup_menu (EDayView *day_view,
e_calendar_view_popup_event (E_CALENDAR_VIEW (day_view), button_event);
}
-static gboolean
-e_day_view_popup_menu (GtkWidget *widget)
-{
- EDayView *day_view = E_DAY_VIEW (widget);
- e_day_view_show_popup_menu (
- day_view, NULL,
- day_view->editing_event_day,
- day_view->editing_event_num);
- return TRUE;
-}
-
-/* Returns the currently-selected event, or NULL if none */
-static GList *
-e_day_view_get_selected_events (ECalendarView *cal_view)
-{
- EDayViewEvent *event = NULL;
- GList *list = NULL;
- EDayView *day_view = (EDayView *) cal_view;
-
- g_return_val_if_fail (E_IS_DAY_VIEW (day_view), NULL);
-
- if (day_view->editing_event_num != -1) {
- if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) {
- if (!is_array_index_in_bounds (day_view->long_events, day_view->editing_event_num))
- return NULL;
-
- event = &g_array_index (day_view->long_events,
- EDayViewEvent,
- day_view->editing_event_num);
- } else {
- if (!is_array_index_in_bounds (day_view->events[day_view->editing_event_day], day_view->editing_event_num))
- return NULL;
-
- event = &g_array_index (day_view->events[day_view->editing_event_day],
- EDayViewEvent,
- day_view->editing_event_num);
- }
- } else if (day_view->popup_event_num != -1) {
- if (day_view->popup_event_day == E_DAY_VIEW_LONG_EVENT) {
- if (!is_array_index_in_bounds (day_view->long_events, day_view->popup_event_num))
- return NULL;
-
- event = &g_array_index (day_view->long_events,
- EDayViewEvent,
- day_view->popup_event_num);
- } else {
- if (!is_array_index_in_bounds (day_view->events[day_view->popup_event_day], day_view->popup_event_num))
- return NULL;
-
- event = &g_array_index (day_view->events[day_view->popup_event_day],
- EDayViewEvent,
- day_view->popup_event_num);
- }
- }
-
- if (event)
- list = g_list_append (list, event);
-
- return list;
-}
-
/* Restarts a query for the day view */
static void
e_day_view_update_query (EDayView *day_view)
@@ -3984,7 +4156,7 @@ e_day_view_update_calendar_selection_time (EDayView *day_view)
{
time_t start, end;
- e_day_view_get_selected_time_range ((ECalendarView *) day_view, &start, &end);
+ day_view_get_selected_time_range ((ECalendarView *) day_view, &start, &end);
}
static gboolean
@@ -5319,94 +5491,6 @@ e_day_view_event_sort_func (gconstpointer arg1,
}
static gboolean
-e_day_view_add_new_event_in_selected_range (EDayView *day_view,
- GdkEventKey *key_event)
-{
- icalcomponent *icalcomp;
- ECalClient *client;
- ECalModel *model;
- ECalComponent *comp;
- gint day, event_num;
- time_t dtstart, dtend;
- ECalComponentDateTime start_dt, end_dt;
- struct icaltimetype start_tt, end_tt;
- const gchar *uid;
- AddEventData add_event_data;
- ESourceRegistry *registry;
-
- model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view));
-
- registry = e_cal_model_get_registry (model);
- client = e_cal_model_get_default_client (model);
-
- /* Check if the client is read only */
- if (e_client_is_readonly (E_CLIENT (client)))
- return FALSE;
-
- icalcomp = e_cal_model_create_component_with_defaults (model, day_view->selection_in_top_canvas);
- if (!icalcomp)
- return FALSE;
-
- uid = icalcomponent_get_uid (icalcomp);
-
- comp = e_cal_component_new ();
- e_cal_component_set_icalcomponent (comp, icalcomp);
-
- e_day_view_get_selected_time_range ((ECalendarView *) day_view, &dtstart, &dtend);
-
- start_tt = icaltime_from_timet_with_zone (
- dtstart, FALSE,
- e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
-
- end_tt = icaltime_from_timet_with_zone (
- dtend, FALSE,
- e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
-
- if (day_view->selection_in_top_canvas) {
- start_dt.tzid = NULL;
- start_tt.is_date = 1;
- end_tt.is_date = 1;
-
- /* Editor default in day/work-week view - top canvas */
- e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_TRANSPARENT);
- } else {
- start_dt.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view)));
-
- /* Editor default in day/work-week view - main canvas */
- e_cal_component_set_transparency (comp, E_CAL_COMPONENT_TRANSP_OPAQUE);
- }
-
- start_dt.value = &start_tt;
- end_dt.value = &end_tt;
- end_dt.tzid = start_dt.tzid;
- e_cal_component_set_dtstart (comp, &start_dt);
- e_cal_component_set_dtend (comp, &end_dt);
-
- e_cal_component_set_categories (
- comp, e_calendar_view_get_default_category (E_CALENDAR_VIEW (day_view)));
-
- /* We add the event locally and start editing it. We don't send it
- * to the server until the user finishes editing it. */
- add_event_data.day_view = day_view;
- add_event_data.comp_data = NULL;
- e_day_view_add_event (registry, comp, dtstart, dtend, &add_event_data);
- e_day_view_check_layout (day_view);
- gtk_widget_queue_draw (day_view->top_canvas);
- gtk_widget_queue_draw (day_view->main_canvas);
-
- if (!e_day_view_find_event_from_uid (day_view, client, uid, NULL, &day, &event_num)) {
- g_warning ("Couldn't find event to start editing.\n");
- g_object_unref (comp);
- return FALSE;
- }
-
- e_day_view_start_editing_event (day_view, day, event_num, key_event);
-
- g_object_unref (comp);
- return TRUE;
-}
-
-static gboolean
e_day_view_do_key_press (GtkWidget *widget,
GdkEventKey *event)
{
@@ -5548,19 +5632,6 @@ e_day_view_do_key_press (GtkWidget *widget,
return e_day_view_add_new_event_in_selected_range (day_view, event);
}
-static gboolean
-e_day_view_key_press (GtkWidget *widget,
- GdkEventKey *event)
-{
- gboolean handled = FALSE;
- handled = e_day_view_do_key_press (widget, event);
-
- /* if not handled, try key bindings */
- if (!handled)
- handled = GTK_WIDGET_CLASS (e_day_view_parent_class)->key_press_event (widget, event);
- return handled;
-}
-
/* Select the time that begins a work day*/
static void
e_day_view_goto_start_of_work_day (EDayView *day_view)
@@ -5737,46 +5808,6 @@ e_day_view_cursor_key_up_shifted (EDayView *day_view,
gtk_widget_queue_draw (day_view->main_canvas);
}
-static gboolean
-e_day_view_focus (GtkWidget *widget,
- GtkDirectionType direction)
-{
- EDayView *day_view;
- gint new_day;
- gint new_event_num;
- gint start_row, end_row;
-
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (E_IS_DAY_VIEW (widget), FALSE);
- day_view = E_DAY_VIEW (widget);
-
- if (!e_day_view_get_next_tab_event (day_view, direction,
- &new_day, &new_event_num))
- return FALSE;
-
- if ((new_day == -1) && (new_event_num == -1)) {
- /* focus should go to the day view widget itself
- */
- gtk_widget_grab_focus (GTK_WIDGET (day_view));
- return TRUE;
- }
-
- if (new_day != E_DAY_VIEW_LONG_EVENT && new_day != -1) {
- if (e_day_view_get_event_rows (day_view, new_day,
- new_event_num,
- &start_row, &end_row))
- /* ensure the event to be seen */
- e_day_view_ensure_rows_visible (
- day_view,
- start_row, end_row);
- }
- e_day_view_start_editing_event (
- day_view, new_day,
- new_event_num, NULL);
-
- return TRUE;
-}
-
/**
* e_day_view_get_extreme_event
* @day_view: the day view widget operates on
@@ -8751,39 +8782,3 @@ e_day_view_get_num_events_selected (EDayView *day_view)
return (day_view->editing_event_day != -1) ? 1 : 0;
}
-static void
-e_day_view_paste_text (ECalendarView *cal_view)
-{
- EDayView *day_view;
- EDayViewEvent *event;
-
- g_return_if_fail (E_IS_DAY_VIEW (cal_view));
-
- day_view = E_DAY_VIEW (cal_view);
-
- if (day_view->editing_event_num == -1 &&
- !e_day_view_add_new_event_in_selected_range (day_view, NULL))
- return;
-
- if (day_view->editing_event_day == E_DAY_VIEW_LONG_EVENT) {
- if (!is_array_index_in_bounds (day_view->long_events, day_view->editing_event_num))
- return;
-
- event = &g_array_index (day_view->long_events,
- EDayViewEvent,
- day_view->editing_event_num);
- } else {
- if (!is_array_index_in_bounds (day_view->events[day_view->editing_event_day], day_view->editing_event_num))
- return;
-
- event = &g_array_index (day_view->events[day_view->editing_event_day],
- EDayViewEvent,
- day_view->editing_event_num);
- }
-
- if (event->canvas_item &&
- E_IS_TEXT (event->canvas_item) &&
- E_TEXT (event->canvas_item)->editing) {
- e_text_paste_clipboard (E_TEXT (event->canvas_item));
- }
-}