diff options
Diffstat (limited to 'calendar/gui')
-rw-r--r-- | calendar/gui/e-calendar-view.h | 2 | ||||
-rw-r--r-- | calendar/gui/e-day-view.c | 1664 |
2 files changed, 1659 insertions, 7 deletions
diff --git a/calendar/gui/e-calendar-view.h b/calendar/gui/e-calendar-view.h index 2fae9350c8..bbf95da71e 100644 --- a/calendar/gui/e-calendar-view.h +++ b/calendar/gui/e-calendar-view.h @@ -29,8 +29,6 @@ #include "e-cal-model.h" #include "gnome-cal.h" -#define ENABLE_CAIRO - G_BEGIN_DECLS /* diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index 88f8aa5c80..5d3a552f44 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -649,6 +649,7 @@ timezone_changed_cb (ECalendarView *cal_view, icaltimezone *old_zone, e_day_view_update_query (day_view); } +#ifndef ENABLE_CAIRO static void e_day_view_init (EDayView *day_view) { @@ -783,6 +784,13 @@ e_day_view_init (EDayView *day_view) "EDayViewTopItem::day_view", day_view, NULL); + day_view->resize_long_event_rect_item = + gnome_canvas_item_new (canvas_group, + gnome_canvas_rect_get_type(), + "width_pixels", 1, + NULL); + gnome_canvas_item_hide (day_view->resize_long_event_rect_item); + day_view->drag_long_event_rect_item = gnome_canvas_item_new (canvas_group, gnome_canvas_rect_get_type (), @@ -856,6 +864,35 @@ e_day_view_init (EDayView *day_view) "EDayViewMainItem::day_view", day_view, NULL); + day_view->resize_rect_item = + gnome_canvas_item_new (canvas_group, + gnome_canvas_rect_get_type(), + "width_pixels", 1, + NULL); + gnome_canvas_item_hide (day_view->resize_rect_item); + + day_view->resize_bar_item = + gnome_canvas_item_new (canvas_group, + gnome_canvas_rect_get_type(), + "width_pixels", 1, + NULL); + gnome_canvas_item_hide (day_view->resize_bar_item); + + day_view->main_canvas_top_resize_bar_item = + gnome_canvas_item_new (canvas_group, + gnome_canvas_rect_get_type (), + "width_pixels", 1, + NULL); + gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); + + day_view->main_canvas_bottom_resize_bar_item = + gnome_canvas_item_new (canvas_group, + gnome_canvas_rect_get_type (), + "width_pixels", 1, + NULL); + gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); + + day_view->drag_rect_item = gnome_canvas_item_new (canvas_group, gnome_canvas_rect_get_type (), @@ -951,6 +988,312 @@ e_day_view_init (EDayView *day_view) g_signal_connect (G_OBJECT (day_view), "timezone_changed", G_CALLBACK (timezone_changed_cb), NULL); } +#endif + +#ifdef ENABLE_CAIRO +static void +e_day_view_init (EDayView *day_view) +{ + gint day; + GnomeCanvasGroup *canvas_group; + ECalModel *model; + + GTK_WIDGET_SET_FLAGS (day_view, GTK_CAN_FOCUS); + + day_view->long_events = g_array_new (FALSE, FALSE, + sizeof (EDayViewEvent)); + day_view->long_events_sorted = TRUE; + day_view->long_events_need_layout = FALSE; + day_view->long_events_need_reshape = FALSE; + + day_view->layout_timeout_id = 0; + + for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++) { + day_view->events[day] = g_array_new (FALSE, FALSE, + sizeof (EDayViewEvent)); + day_view->events_sorted[day] = TRUE; + day_view->need_layout[day] = FALSE; + day_view->need_reshape[day] = FALSE; + } + + /* These indicate that the times haven't been set. */ + day_view->lower = 0; + day_view->upper = 0; + + day_view->work_week_view = FALSE; + day_view->days_shown = 1; + + day_view->mins_per_row = 30; + day_view->date_format = E_DAY_VIEW_DATE_FULL; + day_view->rows_in_top_display = 0; + + /* Note that these don't work yet. It would need a few fixes to the + way event->start_minute and event->end_minute are used, and there + may be problems with events that go outside the visible times. */ + day_view->first_hour_shown = 0; + day_view->first_minute_shown = 0; + day_view->last_hour_shown = 24; + day_view->last_minute_shown = 0; + + day_view->main_gc = NULL; + e_day_view_recalc_num_rows (day_view); + + day_view->working_days = E_DAY_VIEW_MONDAY | E_DAY_VIEW_TUESDAY + | E_DAY_VIEW_WEDNESDAY | E_DAY_VIEW_THURSDAY + | E_DAY_VIEW_FRIDAY; + + day_view->work_day_start_hour = 9; + day_view->work_day_start_minute = 0; + day_view->work_day_end_hour = 17; + day_view->work_day_end_minute = 0; + day_view->show_event_end_times = TRUE; + day_view->week_start_day = 0; + day_view->scroll_to_work_day = TRUE; + + day_view->show_marcus_bains_line = TRUE; + day_view->marcus_bains_day_view_color = NULL; + day_view->marcus_bains_time_bar_color = NULL; + + day_view->editing_event_day = -1; + day_view->editing_event_num = -1; + + day_view->resize_event_num = -1; + day_view->resize_bars_event_day = -1; + day_view->resize_bars_event_num = -1; + + day_view->last_edited_comp_string = NULL; + + day_view->selection_start_row = -1; + day_view->selection_start_day = -1; + day_view->selection_end_row = -1; + day_view->selection_end_day = -1; + day_view->selection_is_being_dragged = FALSE; + day_view->selection_drag_pos = E_DAY_VIEW_DRAG_END; + day_view->selection_in_top_canvas = FALSE; + + day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; + + day_view->pressed_event_day = -1; + + day_view->drag_event_day = -1; + day_view->drag_last_day = -1; + + day_view->auto_scroll_timeout_id = 0; + + day_view->large_font_desc = NULL; + day_view->small_font_desc = NULL; + + /* String to use in 12-hour time format for times in the morning. */ + day_view->am_string = _("am"); + + /* String to use in 12-hour time format for times in the afternoon. */ + day_view->pm_string = _("pm"); + + + /* + * Top Canvas + */ + day_view->top_canvas = e_canvas_new (); + gtk_table_attach (GTK_TABLE (day_view), day_view->top_canvas, + 1, 2, 0, 1, GTK_EXPAND | GTK_FILL, GTK_FILL, 0, 0); + gtk_widget_show (day_view->top_canvas); + g_signal_connect_after (day_view->top_canvas, "button_press_event", + G_CALLBACK (e_day_view_on_top_canvas_button_press), day_view); + g_signal_connect (day_view->top_canvas, "button_release_event", + G_CALLBACK (e_day_view_on_top_canvas_button_release), day_view); + g_signal_connect (day_view->top_canvas, "motion_notify_event", + G_CALLBACK (e_day_view_on_top_canvas_motion), day_view); + g_signal_connect (day_view->top_canvas, "drag_motion", + G_CALLBACK (e_day_view_on_top_canvas_drag_motion), day_view); + g_signal_connect (day_view->top_canvas, "drag_leave", + G_CALLBACK (e_day_view_on_top_canvas_drag_leave), day_view); + + g_signal_connect (day_view->top_canvas, "drag_begin", + G_CALLBACK (e_day_view_on_drag_begin), day_view); + g_signal_connect (day_view->top_canvas, "drag_end", + G_CALLBACK (e_day_view_on_drag_end), day_view); + g_signal_connect (day_view->top_canvas, "drag_data_get", + G_CALLBACK (e_day_view_on_drag_data_get), day_view); + g_signal_connect (day_view->top_canvas, "drag_data_received", + G_CALLBACK (e_day_view_on_top_canvas_drag_data_received), day_view); + + canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->top_canvas)->root); + + day_view->top_canvas_item = + gnome_canvas_item_new (canvas_group, + e_day_view_top_item_get_type (), + "EDayViewTopItem::day_view", day_view, + NULL); + + day_view->drag_long_event_rect_item = + gnome_canvas_item_new (canvas_group, + gnome_canvas_rect_get_type (), + "width_pixels", 1, + NULL); + gnome_canvas_item_hide (day_view->drag_long_event_rect_item); + + day_view->drag_long_event_item = + gnome_canvas_item_new (canvas_group, + e_text_get_type (), + "anchor", GTK_ANCHOR_NW, + "line_wrap", TRUE, + "clip", TRUE, + "max_lines", 1, + "editable", TRUE, + "draw_background", FALSE, + "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0), + NULL); + gnome_canvas_item_hide (day_view->drag_long_event_item); + + /* + * Main Canvas + */ + day_view->main_canvas = e_canvas_new (); + gtk_table_attach (GTK_TABLE (day_view), day_view->main_canvas, + 1, 2, 1, 2, + GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_widget_show (day_view->main_canvas); + g_signal_connect (day_view->main_canvas, "realize", + G_CALLBACK (e_day_view_on_canvas_realized), day_view); + + g_signal_connect (day_view->main_canvas, + "button_press_event", + G_CALLBACK (e_day_view_on_main_canvas_button_press), + day_view); + g_signal_connect (day_view->main_canvas, + "button_release_event", + G_CALLBACK (e_day_view_on_main_canvas_button_release), + day_view); + g_signal_connect (day_view->main_canvas, + "scroll_event", + G_CALLBACK (e_day_view_on_main_canvas_scroll), + day_view); + g_signal_connect (day_view->main_canvas, + "motion_notify_event", + G_CALLBACK (e_day_view_on_main_canvas_motion), + day_view); + g_signal_connect (day_view->main_canvas, + "drag_motion", + G_CALLBACK (e_day_view_on_main_canvas_drag_motion), + day_view); + g_signal_connect (day_view->main_canvas, + "drag_leave", + G_CALLBACK (e_day_view_on_main_canvas_drag_leave), + day_view); + + g_signal_connect (day_view->main_canvas, "drag_begin", + G_CALLBACK (e_day_view_on_drag_begin), day_view); + g_signal_connect (day_view->main_canvas, "drag_end", + G_CALLBACK (e_day_view_on_drag_end), day_view); + g_signal_connect (day_view->main_canvas, "drag_data_get", + G_CALLBACK (e_day_view_on_drag_data_get), day_view); + g_signal_connect (day_view->main_canvas, "drag_data_received", + G_CALLBACK (e_day_view_on_main_canvas_drag_data_received), day_view); + + canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->main_canvas)->root); + + day_view->main_canvas_item = + gnome_canvas_item_new (canvas_group, + e_day_view_main_item_get_type (), + "EDayViewMainItem::day_view", day_view, + NULL); + + day_view->drag_rect_item = + gnome_canvas_item_new (canvas_group, + gnome_canvas_rect_get_type (), + "width_pixels", 1, + NULL); + gnome_canvas_item_hide (day_view->drag_rect_item); + + day_view->drag_bar_item = + gnome_canvas_item_new (canvas_group, + gnome_canvas_rect_get_type (), + "width_pixels", 1, + NULL); + gnome_canvas_item_hide (day_view->drag_bar_item); + + day_view->drag_item = + gnome_canvas_item_new (canvas_group, + e_text_get_type (), + "anchor", GTK_ANCHOR_NW, + "line_wrap", TRUE, + "clip", TRUE, + "editable", TRUE, + "draw_background", FALSE, + "fill_color_rgba", GNOME_CANVAS_COLOR(0, 0, 0), + NULL); + gnome_canvas_item_hide (day_view->drag_item); + + + /* + * Times Canvas + */ + day_view->time_canvas = e_canvas_new (); + gtk_layout_set_vadjustment (GTK_LAYOUT (day_view->time_canvas), + GTK_LAYOUT (day_view->main_canvas)->vadjustment); + gtk_table_attach (GTK_TABLE (day_view), day_view->time_canvas, + 0, 1, 1, 2, + GTK_FILL, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_widget_show (day_view->time_canvas); + g_signal_connect_after (day_view->time_canvas, "scroll_event", + G_CALLBACK (e_day_view_on_time_canvas_scroll), day_view); + + canvas_group = GNOME_CANVAS_GROUP (GNOME_CANVAS (day_view->time_canvas)->root); + + day_view->time_canvas_item = + gnome_canvas_item_new (canvas_group, + e_day_view_time_item_get_type (), + "EDayViewTimeItem::day_view", day_view, + NULL); + + + /* + * Scrollbar. + */ + day_view->vscrollbar = gtk_vscrollbar_new (GTK_LAYOUT (day_view->main_canvas)->vadjustment); + gtk_table_attach (GTK_TABLE (day_view), day_view->vscrollbar, + 2, 3, 1, 2, 0, GTK_EXPAND | GTK_FILL, 0, 0); + gtk_widget_show (day_view->vscrollbar); + + + /* Create the cursors. */ + day_view->normal_cursor = gdk_cursor_new (GDK_LEFT_PTR); + day_view->move_cursor = gdk_cursor_new (GDK_FLEUR); + day_view->resize_width_cursor = gdk_cursor_new (GDK_SB_H_DOUBLE_ARROW); + day_view->resize_height_cursor = gdk_cursor_new (GDK_SB_V_DOUBLE_ARROW); + day_view->last_cursor_set_in_top_canvas = NULL; + day_view->last_cursor_set_in_main_canvas = NULL; + + /* Set up the drop sites. */ + gtk_drag_dest_set (day_view->top_canvas, + GTK_DEST_DEFAULT_ALL, + target_table, n_targets, + GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK); + gtk_drag_dest_set (day_view->main_canvas, + GTK_DEST_DEFAULT_ALL, + target_table, n_targets, + GDK_ACTION_COPY | GDK_ACTION_MOVE | GDK_ACTION_ASK); + + /* Get the model */ + model = e_calendar_view_get_model (E_CALENDAR_VIEW (day_view)); + + /* connect to ECalModel's signals */ + g_signal_connect (G_OBJECT (model), "time_range_changed", + G_CALLBACK (time_range_changed_cb), day_view); + g_signal_connect (G_OBJECT (model), "model_row_changed", + G_CALLBACK (model_row_changed_cb), day_view); + g_signal_connect (G_OBJECT (model), "model_cell_changed", + G_CALLBACK (model_cell_changed_cb), day_view); + g_signal_connect (G_OBJECT (model), "model_rows_inserted", + G_CALLBACK (model_rows_inserted_cb), day_view); + g_signal_connect (G_OBJECT (model), "model_rows_deleted", + G_CALLBACK (model_rows_deleted_cb), day_view); + + /* connect to ECalendarView's signals */ + g_signal_connect (G_OBJECT (day_view), "timezone_changed", + G_CALLBACK (timezone_changed_cb), NULL); +} +#endif /* Turn off the background of the canvas windows. This reduces flicker @@ -1036,7 +1379,81 @@ e_day_view_destroy (GtkObject *object) GTK_OBJECT_CLASS (e_day_view_parent_class)->destroy (object); } +#ifndef ENABLE_CAIRO +static void +e_day_view_realize (GtkWidget *widget) +{ + EDayView *day_view; + GdkColormap *colormap; + + 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); + day_view->main_gc = gdk_gc_new (widget->window); + + colormap = gtk_widget_get_colormap (widget); + + /* Allocate the colors. */ + + e_day_view_set_colors(day_view, widget); + + gdk_gc_set_colormap (day_view->main_gc, colormap); + + /* Create the pixmaps. */ + day_view->reminder_icon = e_icon_factory_get_icon ("stock_bell", E_ICON_SIZE_MENU); + day_view->recurrence_icon = e_icon_factory_get_icon ("stock_refresh", E_ICON_SIZE_MENU); + day_view->timezone_icon = e_icon_factory_get_icon ("stock_timezone", E_ICON_SIZE_MENU); + day_view->meeting_icon = e_icon_factory_get_icon ("stock_people", E_ICON_SIZE_MENU); + day_view->attach_icon = e_icon_factory_get_icon ("stock_attach", E_ICON_SIZE_MENU); + + + /* Set the canvas item colors. */ + gnome_canvas_item_set (day_view->resize_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_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->resize_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->resize_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); + + gnome_canvas_item_set (day_view->main_canvas_top_resize_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); + + gnome_canvas_item_set (day_view->main_canvas_bottom_resize_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); + + + 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); +} +#endif +#ifdef ENABLE_CAIRO static void e_day_view_realize (GtkWidget *widget) { @@ -1081,6 +1498,7 @@ e_day_view_realize (GtkWidget *widget) "outline_color_gdk", &day_view->colors[E_DAY_VIEW_COLOR_EVENT_BORDER], NULL); } +#endif static void e_day_view_set_colors(EDayView *day_view, GtkWidget *widget) @@ -1160,6 +1578,7 @@ e_day_view_get_text_color (EDayView *day_view, EDayViewEvent *event, GtkWidget * return color; } +#ifndef ENABLE_CAIRO static void e_day_view_style_set (GtkWidget *widget, GtkStyle *previous_style) @@ -1208,6 +1627,14 @@ e_day_view_style_set (GtkWidget *widget, NULL); } } + gnome_canvas_item_set (day_view->main_canvas_top_resize_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); + gnome_canvas_item_set (day_view->main_canvas_bottom_resize_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); /* Set up Pango prerequisites */ font_desc = gtk_widget_get_style (widget)->font_desc; @@ -1354,7 +1781,204 @@ e_day_view_style_set (GtkWidget *widget, g_object_unref (layout); pango_font_metrics_unref (font_metrics); } +#endif + +#ifdef ENABLE_CAIRO +static void +e_day_view_style_set (GtkWidget *widget, + GtkStyle *previous_style) +{ + EDayView *day_view; + gint top_rows, top_canvas_height; + 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; + struct tm date_tm; + gchar buffer[128]; + gint times_width; + PangoFontDescription *font_desc; + PangoContext *pango_context; + PangoFontMetrics *font_metrics; + PangoLayout *layout; + gint week_day, event_num; + 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); + GTK_LAYOUT (day_view->main_canvas)->vadjustment->step_increment = 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); + + /* Set the height of the top canvas based on the row height and the + number of rows needed (min 1 + 1 for the dates + 1 space for DnD).*/ + top_rows = MAX (1, day_view->rows_in_top_display); + top_canvas_height = (top_rows + 2) * day_view->top_row_height; + gtk_widget_set_usize (day_view->top_canvas, -1, top_canvas_height); + + /* Find the longest full & abbreviated month names. */ + memset (&date_tm, 0, sizeof (date_tm)); + date_tm.tm_year = 100; + date_tm.tm_mday = 1; + date_tm.tm_isdst = -1; + + longest_month_width = 0; + longest_abbreviated_month_width = 0; + for (month = 0; month < 12; month++) { + date_tm.tm_mon = month; + + e_utf8_strftime (buffer, sizeof (buffer), "%B", &date_tm); + pango_layout_set_text (layout, buffer, -1); + pango_layout_get_pixel_size (layout, &width, NULL); + + if (width > longest_month_width) { + longest_month_width = width; + day_view->longest_month_name = month; + } + + e_utf8_strftime (buffer, sizeof (buffer), "%b", &date_tm); + pango_layout_set_text (layout, buffer, -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. */ + memset (&date_tm, 0, sizeof (date_tm)); + date_tm.tm_year = 100; + date_tm.tm_mon = 0; + date_tm.tm_isdst = -1; + + longest_weekday_width = 0; + longest_abbreviated_weekday_width = 0; + for (day = 0; day < 7; day++) { + date_tm.tm_mday = 2 + day; + date_tm.tm_wday = day; + + e_utf8_strftime (buffer, sizeof (buffer), "%A", &date_tm); + pango_layout_set_text (layout, buffer, -1); + pango_layout_get_pixel_size (layout, &width, NULL); + + if (width > longest_weekday_width) { + longest_weekday_width = width; + day_view->longest_weekday_name = day; + } + + e_utf8_strftime (buffer, sizeof (buffer), "%a", &date_tm); + pango_layout_set_text (layout, buffer, -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_usize (day_view->time_canvas, times_width, -1); + + g_object_unref (layout); + pango_font_metrics_unref (font_metrics); +} +#endif /* This recalculates the sizes of each column. */ static void @@ -1716,6 +2340,111 @@ set_text_as_bold (EDayViewEvent *event) /* This updates the text shown for an event. If the event start or end do not lie on a row boundary, the time is displayed before the summary. */ +#ifndef ENABLE_CAIRO +/* This updates the text shown for an event. If the event start or end do not + lie on a row boundary, the time is displayed before the summary. */ +static void +e_day_view_update_event_label (EDayView *day_view, + gint day, + gint event_num) +{ + EDayViewEvent *event; + char *text, *start_suffix, *end_suffix; + gboolean free_text = FALSE, editing_event = FALSE; + gint offset; + gint start_hour, start_display_hour, start_minute, start_suffix_width; + gint end_hour, end_display_hour, end_minute, end_suffix_width; + const gchar *summary; + + event = &g_array_index (day_view->events[day], EDayViewEvent, event_num); + + /* If the event isn't visible just return. */ + if (!event->canvas_item) + return; + + summary = icalcomponent_get_summary (event->comp_data->icalcomp); + text = summary ? (char *) summary : ""; + + if (day_view->editing_event_day == day + && day_view->editing_event_num == event_num) + editing_event = TRUE; + + if (!editing_event + && (event->start_minute % day_view->mins_per_row != 0 + || (day_view->show_event_end_times + && event->end_minute % day_view->mins_per_row != 0))) { + offset = day_view->first_hour_shown * 60 + + day_view->first_minute_shown; + start_minute = offset + event->start_minute; + end_minute = offset + event->end_minute; + + start_hour = start_minute / 60; + start_minute = start_minute % 60; + + end_hour = end_minute / 60; + end_minute = end_minute % 60; + + e_day_view_convert_time_to_display (day_view, start_hour, + &start_display_hour, + &start_suffix, + &start_suffix_width); + e_day_view_convert_time_to_display (day_view, end_hour, + &end_display_hour, + &end_suffix, + &end_suffix_width); + + if (e_calendar_view_get_use_24_hour_format (E_CALENDAR_VIEW (day_view))) { + if (day_view->show_event_end_times) { + /* 24 hour format with end time. */ + text = g_strdup_printf + ("%2i:%02i-%2i:%02i %s", + start_display_hour, start_minute, + end_display_hour, end_minute, + text); + } else { + /* 24 hour format without end time. */ + text = g_strdup_printf + ("%2i:%02i %s", + start_display_hour, start_minute, + text); + } + } else { + if (day_view->show_event_end_times) { + /* 12 hour format with end time. */ + text = g_strdup_printf + ("%2i:%02i%s-%2i:%02i%s %s", + start_display_hour, start_minute, + start_suffix, + end_display_hour, end_minute, + end_suffix, + text); + } else { + /* 12 hour format without end time. */ + text = g_strdup_printf + ("%2i:%02i%s %s", + start_display_hour, start_minute, + start_suffix, + text); + } + } + + free_text = TRUE; + } + + gnome_canvas_item_set (event->canvas_item, + "text", text, + NULL); + +/* if (e_cal_get_static_capability (event->comp_data->client, CAL_STATIC_CAPABILITY_HAS_UNACCEPTED_MEETING) + && e_cal_util_component_has_attendee (event->comp_data->icalcomp)) + set_text_as_bold (event); */ + + if (free_text) + g_free (text); +} +#endif + +#ifdef ENABLE_CAIRO static void e_day_view_update_event_label (EDayView *day_view, gint day, @@ -1769,6 +2498,7 @@ e_day_view_update_event_label (EDayView *day_view, if (free_text) g_free (text); } +#endif static void e_day_view_update_long_event_label (EDayView *day_view, @@ -2953,7 +3683,7 @@ e_day_view_on_event_button_press (EDayView *day_view, return FALSE; } - +#ifndef ENABLE_CAIRO static void e_day_view_on_long_event_click (EDayView *day_view, gint event_num, @@ -3003,6 +3733,9 @@ e_day_view_on_long_event_click (EDayView *day_view, /* Create the edit rect if necessary. */ e_day_view_reshape_resize_long_event_rect_item (day_view); + /* Make sure the text item is on top. */ + gnome_canvas_item_raise_to_top (day_view->resize_long_event_rect_item); + /* Raise the event's item, above the rect as well. */ gnome_canvas_item_raise_to_top (event->canvas_item); } @@ -3024,7 +3757,80 @@ e_day_view_on_long_event_click (EDayView *day_view, day_view->drag_event_offset = day - start_day; } } +#endif +#ifdef ENABLE_CAIRO +static void +e_day_view_on_long_event_click (EDayView *day_view, + gint event_num, + GdkEventButton *bevent, + ECalendarViewPosition pos, + gint event_x, + gint event_y) +{ + EDayViewEvent *event; + gint start_day, end_day, day; + gint item_x, item_y, item_w, item_h; + + event = &g_array_index (day_view->long_events, EDayViewEvent, + event_num); + + /* Ignore clicks on the EText while editing. */ + if (pos == E_CALENDAR_VIEW_POS_EVENT + && E_TEXT (event->canvas_item)->editing) + return; + + if ((e_cal_util_component_is_instance (event->comp_data->icalcomp) || + !e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) + && (pos == E_CALENDAR_VIEW_POS_LEFT_EDGE + || pos == E_CALENDAR_VIEW_POS_RIGHT_EDGE)) { + if (!e_day_view_find_long_event_days (event, + day_view->days_shown, + day_view->day_starts, + &start_day, &end_day)) + return; + + /* Grab the keyboard focus, so the event being edited is saved + and we can use the Escape key to abort the resize. */ + if (!GTK_WIDGET_HAS_FOCUS (day_view)) + gtk_widget_grab_focus (GTK_WIDGET (day_view)); + + if (gdk_pointer_grab (GTK_LAYOUT (day_view->top_canvas)->bin_window, FALSE, + GDK_POINTER_MOTION_MASK + | GDK_BUTTON_RELEASE_MASK, + FALSE, NULL, bevent->time) == 0) { + + day_view->resize_event_day = E_DAY_VIEW_LONG_EVENT; + day_view->resize_event_num = event_num; + day_view->resize_drag_pos = pos; + day_view->resize_start_row = start_day; + day_view->resize_end_row = end_day; + + /* Create the edit rect if necessary. */ + e_day_view_reshape_resize_long_event_rect_item (day_view); + + /* Raise the event's item, above the rect as well. */ + gnome_canvas_item_raise_to_top (event->canvas_item); + } + } else if (e_day_view_get_long_event_position (day_view, event_num, + &start_day, &end_day, + &item_x, &item_y, + &item_w, &item_h)) { + /* Remember the item clicked and the mouse position, + so we can start a drag if the mouse moves. */ + day_view->pressed_event_day = E_DAY_VIEW_LONG_EVENT; + day_view->pressed_event_num = event_num; + + day_view->drag_event_x = event_x; + day_view->drag_event_y = event_y; + + e_day_view_convert_position_in_top_canvas (day_view, + event_x, event_y, + &day, NULL); + day_view->drag_event_offset = day - start_day; + } +} +#endif static void e_day_view_on_event_click (EDayView *day_view, @@ -3098,7 +3904,7 @@ e_day_view_on_event_click (EDayView *day_view, } } - +#ifndef ENABLE_CAIRO static void e_day_view_reshape_resize_long_event_rect_item (EDayView *day_view) { @@ -3115,6 +3921,7 @@ e_day_view_reshape_resize_long_event_rect_item (EDayView *day_view) &start_day, &end_day, &item_x, &item_y, &item_w, &item_h)) { + gnome_canvas_item_hide (day_view->resize_long_event_rect_item); return; } @@ -3122,6 +3929,14 @@ e_day_view_reshape_resize_long_event_rect_item (EDayView *day_view) y1 = item_y; x2 = item_x + item_w - 1; y2 = item_y + item_h - 1; + + gnome_canvas_item_set (day_view->resize_long_event_rect_item, + "x1", x1, + "y1", y1, + "x2", x2, + "y2", y2, + NULL); + gnome_canvas_item_show (day_view->resize_long_event_rect_item); } @@ -3141,6 +3956,50 @@ e_day_view_reshape_resize_rect_item (EDayView *day_view) || !e_day_view_get_event_position (day_view, day, event_num, &item_x, &item_y, &item_w, &item_h)) { + gnome_canvas_item_hide (day_view->resize_rect_item); + return; + } + + x1 = item_x; + y1 = item_y; + x2 = item_x + item_w - 1; + y2 = item_y + item_h - 1; + + gnome_canvas_item_set (day_view->resize_rect_item, + "x1", x1 + E_DAY_VIEW_BAR_WIDTH - 1, + "y1", y1, + "x2", x2, + "y2", y2, + NULL); + gnome_canvas_item_show (day_view->resize_rect_item); + + gnome_canvas_item_set (day_view->resize_bar_item, + "x1", x1, + "y1", y1, + "x2", x1 + E_DAY_VIEW_BAR_WIDTH - 1, + "y2", y2, + NULL); + gnome_canvas_item_show (day_view->resize_bar_item); +} +#endif + +#ifdef ENABLE_CAIRO +static void +e_day_view_reshape_resize_long_event_rect_item (EDayView *day_view) +{ + gint event_num, start_day, end_day; + gint item_x, item_y, item_w, item_h; + gdouble x1, y1, x2, y2; + + event_num = day_view->resize_event_num; + + /* If we're not resizing an event, or the event is not shown, + hide the resize bars. */ + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_NONE + || !e_day_view_get_long_event_position (day_view, event_num, + &start_day, &end_day, + &item_x, &item_y, + &item_w, &item_h)) { return; } @@ -3152,6 +4011,32 @@ e_day_view_reshape_resize_rect_item (EDayView *day_view) static void +e_day_view_reshape_resize_rect_item (EDayView *day_view) +{ + gint day, event_num; + gint item_x, item_y, item_w, item_h; + gdouble x1, y1, x2, y2; + + day = day_view->resize_event_day; + event_num = day_view->resize_event_num; + + /* If we're not resizing an event, or the event is not shown, + hide the resize bars. */ + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_NONE + || !e_day_view_get_event_position (day_view, day, event_num, + &item_x, &item_y, + &item_w, &item_h)) { + return; + } + + x1 = item_x; + y1 = item_y; + x2 = item_x + item_w - 1; + y2 = item_y + item_h - 1; +} +#endif + +static void e_day_view_on_event_double_click (EDayView *day_view, gint day, gint event_num) @@ -3353,7 +4238,7 @@ e_day_view_update_calendar_selection_time (EDayView *day_view) #endif } - +#ifndef ENABLE_CAIRO static gboolean e_day_view_on_top_canvas_motion (GtkWidget *widget, GdkEventMotion *mevent, @@ -3413,6 +4298,8 @@ e_day_view_on_top_canvas_motion (GtkWidget *widget, if (day_view->resize_bars_event_day != -1) { day_view->resize_bars_event_day = -1; day_view->resize_bars_event_num = -1; + gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); + gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); } target_list = gtk_target_list_new (target_table, @@ -3514,6 +4401,8 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, if (day_view->resize_bars_event_day != -1) { day_view->resize_bars_event_day = -1; day_view->resize_bars_event_num = -1; + gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); + gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); } target_list = gtk_target_list_new (target_table, @@ -3549,7 +4438,205 @@ e_day_view_on_main_canvas_motion (GtkWidget *widget, return FALSE; } +#endif + +#ifdef ENABLE_CAIRO +static gboolean +e_day_view_on_top_canvas_motion (GtkWidget *widget, + GdkEventMotion *mevent, + EDayView *day_view) +{ + EDayViewEvent *event = NULL; + ECalendarViewPosition pos; + gint event_x, event_y, canvas_x, canvas_y; + gint day, event_num; + GdkCursor *cursor; + +#if 0 + g_print ("In e_day_view_on_top_canvas_motion\n"); +#endif + + /* Convert the coords to the main canvas window, or return if the + window is not found. */ + if (!e_day_view_convert_event_coords (day_view, (GdkEvent*) mevent, + GTK_LAYOUT (widget)->bin_window, + &event_x, &event_y)) + return FALSE; + + canvas_x = event_x; + canvas_y = event_y; + + pos = e_day_view_convert_position_in_top_canvas (day_view, + canvas_x, canvas_y, + &day, &event_num); + if (event_num != -1) + event = &g_array_index (day_view->long_events, EDayViewEvent, + event_num); + + if (day_view->selection_is_being_dragged) { + e_day_view_update_selection (day_view, day, -1); + return TRUE; + } else if (day_view->resize_drag_pos != E_CALENDAR_VIEW_POS_NONE) { + if (pos != E_CALENDAR_VIEW_POS_OUTSIDE) { + e_day_view_update_long_event_resize (day_view, day); + return TRUE; + } + } else if (day_view->pressed_event_day == E_DAY_VIEW_LONG_EVENT) { + GtkTargetList *target_list; + + event = &g_array_index (day_view->long_events, EDayViewEvent, + day_view->pressed_event_num); + + if (!e_cal_util_component_has_recurrences (event->comp_data->icalcomp) + && (abs (canvas_x - day_view->drag_event_x) + > E_DAY_VIEW_DRAG_START_OFFSET + || abs (canvas_y - day_view->drag_event_y) + > E_DAY_VIEW_DRAG_START_OFFSET)) { + day_view->drag_event_day = day_view->pressed_event_day; + day_view->drag_event_num = day_view->pressed_event_num; + day_view->pressed_event_day = -1; + + /* Hide the horizontal bars. */ + if (day_view->resize_bars_event_day != -1) { + day_view->resize_bars_event_day = -1; + day_view->resize_bars_event_num = -1; + } + + target_list = gtk_target_list_new (target_table, + n_targets); + gtk_drag_begin (widget, target_list, + GDK_ACTION_COPY | GDK_ACTION_MOVE, + 1, (GdkEvent*)mevent); + gtk_target_list_unref (target_list); + } + } else { + cursor = day_view->normal_cursor; + + /* Recurring events can't be resized. */ + if (event && !e_cal_util_component_has_recurrences (event->comp_data->icalcomp)) { + switch (pos) { + case E_CALENDAR_VIEW_POS_LEFT_EDGE: + case E_CALENDAR_VIEW_POS_RIGHT_EDGE: + cursor = day_view->resize_width_cursor; + break; + default: + break; + } + } + + /* Only set the cursor if it is different to last one set. */ + if (day_view->last_cursor_set_in_top_canvas != cursor) { + day_view->last_cursor_set_in_top_canvas = cursor; + gdk_window_set_cursor (widget->window, cursor); + } + + } + + return FALSE; +} + + +static gboolean +e_day_view_on_main_canvas_motion (GtkWidget *widget, + GdkEventMotion *mevent, + EDayView *day_view) +{ + EDayViewEvent *event = NULL; + ECalendarViewPosition pos; + gint event_x, event_y, canvas_x, canvas_y; + gint row, day, event_num; + GdkCursor *cursor; + +#if 0 + g_print ("In e_day_view_on_main_canvas_motion\n"); +#endif + + /* Convert the coords to the main canvas window, or return if the + window is not found. */ + if (!e_day_view_convert_event_coords (day_view, (GdkEvent*) mevent, + GTK_LAYOUT (widget)->bin_window, + &event_x, &event_y)) + return FALSE; + + canvas_x = event_x; + canvas_y = event_y; + pos = e_day_view_convert_position_in_main_canvas (day_view, + canvas_x, canvas_y, + &day, &row, + &event_num); + if (event_num != -1) + event = &g_array_index (day_view->events[day], EDayViewEvent, + event_num); + + if (day_view->selection_is_being_dragged) { + if (pos != E_CALENDAR_VIEW_POS_OUTSIDE) { + e_day_view_update_selection (day_view, day, row); + e_day_view_check_auto_scroll (day_view, + event_x, event_y); + return TRUE; + } + } else if (day_view->resize_drag_pos != E_CALENDAR_VIEW_POS_NONE) { + if (pos != E_CALENDAR_VIEW_POS_OUTSIDE) { + e_day_view_update_resize (day_view, row); + e_day_view_check_auto_scroll (day_view, + event_x, event_y); + return TRUE; + } + } else if (day_view->pressed_event_day != -1 + && day_view->pressed_event_day != E_DAY_VIEW_LONG_EVENT) { + GtkTargetList *target_list; + + event = &g_array_index (day_view->events[day_view->pressed_event_day], EDayViewEvent, day_view->pressed_event_num); + + if ((abs (canvas_x - day_view->drag_event_x) + > E_DAY_VIEW_DRAG_START_OFFSET + || abs (canvas_y - day_view->drag_event_y) + > E_DAY_VIEW_DRAG_START_OFFSET)) { + day_view->drag_event_day = day_view->pressed_event_day; + day_view->drag_event_num = day_view->pressed_event_num; + day_view->pressed_event_day = -1; + + /* Hide the horizontal bars. */ + if (day_view->resize_bars_event_day != -1) { + day_view->resize_bars_event_day = -1; + day_view->resize_bars_event_num = -1; + } + + target_list = gtk_target_list_new (target_table, + n_targets); + gtk_drag_begin (widget, target_list, + GDK_ACTION_COPY | GDK_ACTION_MOVE, + 1, (GdkEvent*)mevent); + gtk_target_list_unref (target_list); + } + } else { + cursor = day_view->normal_cursor; + + if (event) { + switch (pos) { + case E_CALENDAR_VIEW_POS_LEFT_EDGE: + cursor = day_view->move_cursor; + break; + case E_CALENDAR_VIEW_POS_TOP_EDGE: + case E_CALENDAR_VIEW_POS_BOTTOM_EDGE: + cursor = day_view->resize_height_cursor; + break; + default: + break; + } + } + + /* Only set the cursor if it is different to last one set. */ + if (day_view->last_cursor_set_in_main_canvas != cursor) { + day_view->last_cursor_set_in_main_canvas = cursor; + gdk_window_set_cursor (widget->window, cursor); + } + } + + return FALSE; +} +#endif /* This sets the selection to a single cell. If day is -1 then the current start day is reused. If row is -1 then the selection is in the top canvas. @@ -3743,6 +4830,7 @@ e_day_view_update_resize (EDayView *day_view, /* This converts the resize start or end row back to a time and updates the event. */ +#ifndef ENABLE_CAIRO static void e_day_view_finish_long_event_resize (EDayView *day_view) { @@ -3832,6 +4920,8 @@ e_day_view_finish_long_event_resize (EDayView *day_view) e_calendar_view_modify_and_send (comp, client, mod, toplevel, TRUE); out: + gnome_canvas_item_hide (day_view->resize_long_event_rect_item); + day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; g_object_unref (comp); @@ -3898,10 +4988,14 @@ e_day_view_finish_resize (EDayView *day_view) day_view->last_edited_comp_string = e_cal_component_get_as_string (comp); + gnome_canvas_item_hide (day_view->resize_rect_item); + gnome_canvas_item_hide (day_view->resize_bar_item); /* Hide the horizontal bars. */ day_view->resize_bars_event_day = -1; day_view->resize_bars_event_num = -1; + gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); + gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; @@ -3961,6 +5055,7 @@ e_day_view_abort_resize (EDayView *day_view) day_view->last_cursor_set_in_top_canvas = day_view->normal_cursor; gdk_window_set_cursor (day_view->top_canvas->window, day_view->normal_cursor); + gnome_canvas_item_hide (day_view->resize_long_event_rect_item); } else { e_day_view_reshape_day_event (day_view, day, event_num); e_day_view_reshape_main_canvas_resize_bars (day_view); @@ -3969,11 +5064,244 @@ e_day_view_abort_resize (EDayView *day_view) day_view->last_cursor_set_in_main_canvas = day_view->normal_cursor; gdk_window_set_cursor (day_view->main_canvas->window, day_view->normal_cursor); + gnome_canvas_item_hide (day_view->resize_rect_item); + gnome_canvas_item_hide (day_view->resize_bar_item); + } +} +#endif + +#ifdef ENABLE_CAIRO +static void +e_day_view_finish_long_event_resize (EDayView *day_view) +{ + EDayViewEvent *event; + gint event_num; + ECalComponent *comp; + ECalComponentDateTime date; + struct icaltimetype itt; + time_t dt; + ECal *client; + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; + int is_date; + + event_num = day_view->resize_event_num; + event = &g_array_index (day_view->long_events, EDayViewEvent, + event_num); + + client = event->comp_data->client; + + /* We use a temporary copy of the comp since we don't want to + change the original comp here. Otherwise we would not detect that + the event's time had changed in the "update_event" callback. */ + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + + if (e_cal_component_has_attendees (comp) && !itip_organizer_is_user (comp, client)) { + g_object_unref (comp); + e_day_view_abort_resize (day_view); + return; + } + + date.value = &itt; + date.tzid = NULL; + + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_LEFT_EDGE) { + e_cal_component_get_dtstart (comp, &date); + is_date = date.value->is_date; + if (!is_date) + date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + dt = day_view->day_starts[day_view->resize_start_row]; + *date.value = icaltime_from_timet_with_zone (dt, is_date, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtstart (comp, &date); + } else { + e_cal_component_get_dtend (comp, &date); + is_date = date.value->is_date; + if (!is_date) + date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + dt = day_view->day_starts[day_view->resize_end_row + 1]; + *date.value = icaltime_from_timet_with_zone (dt, is_date, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtend (comp, &date); + } + + e_cal_component_commit_sequence (comp); + if (e_cal_component_is_instance (comp)) { + if (!recur_component_dialog (client, comp, &mod, NULL, FALSE)) { + gtk_widget_queue_draw (day_view->top_canvas); + goto out; + } + + if (mod == CALOBJ_MOD_THIS) { + /* set the correct DTSTART/DTEND on the individual recurrence */ + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE) { + *date.value = icaltime_from_timet_with_zone ( + event->comp_data->instance_end, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtend (comp, &date); + } else { + *date.value = icaltime_from_timet_with_zone ( + event->comp_data->instance_start, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtstart (comp, &date); + } + + e_cal_component_set_rdate_list (comp, NULL); + e_cal_component_set_rrule_list (comp, NULL); + e_cal_component_set_exdate_list (comp, NULL); + e_cal_component_set_exrule_list (comp, NULL); + + e_cal_component_commit_sequence (comp); + } + } + + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); + e_calendar_view_modify_and_send (comp, client, mod, toplevel, TRUE); + + out: + day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; + + g_object_unref (comp); +} + + +/* This converts the resize start or end row back to a time and updates the + event. */ +static void +e_day_view_finish_resize (EDayView *day_view) +{ + EDayViewEvent *event; + gint day, event_num; + ECalComponent *comp; + ECalComponentDateTime date; + struct icaltimetype itt; + time_t dt; + ECal *client; + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; + + day = day_view->resize_event_day; + event_num = day_view->resize_event_num; + event = &g_array_index (day_view->events[day], EDayViewEvent, + event_num); + + client = event->comp_data->client; + + /* We use a temporary shallow copy of the ico since we don't want to + change the original ico here. Otherwise we would not detect that + the event's time had changed in the "update_event" callback. */ + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + + if (e_cal_component_has_attendees (comp) && !itip_organizer_is_user (comp, client)) { + g_object_unref (comp); + e_day_view_abort_resize (day_view); + return; + } + + date.value = &itt; + /* FIXME: Should probably keep the timezone of the original start + and end times. */ + date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE) { + dt = e_day_view_convert_grid_position_to_time (day_view, day, day_view->resize_start_row); + *date.value = icaltime_from_timet_with_zone (dt, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtstart (comp, &date); + } else { + dt = e_day_view_convert_grid_position_to_time (day_view, day, day_view->resize_end_row + 1); + *date.value = icaltime_from_timet_with_zone (dt, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtend (comp, &date); + } + + e_cal_component_commit_sequence (comp); + + if (day_view->last_edited_comp_string != NULL) { + g_free (day_view->last_edited_comp_string); + day_view->last_edited_comp_string = NULL; + } + + day_view->last_edited_comp_string = e_cal_component_get_as_string (comp); + + + /* Hide the horizontal bars. */ + day_view->resize_bars_event_day = -1; + day_view->resize_bars_event_num = -1; + + day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; + + if (e_cal_component_is_instance (comp)) { + if (!recur_component_dialog (client, comp, &mod, NULL, FALSE)) { + gtk_widget_queue_draw (day_view->top_canvas); + goto out; + } + + if (mod == CALOBJ_MOD_THIS) { + /* set the correct DTSTART/DTEND on the individual recurrence */ + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_TOP_EDGE) { + *date.value = icaltime_from_timet_with_zone ( + event->comp_data->instance_end, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtend (comp, &date); + } else { + *date.value = icaltime_from_timet_with_zone ( + event->comp_data->instance_start, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtstart (comp, &date); + } + + e_cal_component_set_rdate_list (comp, NULL); + e_cal_component_set_rrule_list (comp, NULL); + e_cal_component_set_exdate_list (comp, NULL); + e_cal_component_set_exrule_list (comp, NULL); + } } + + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); + + e_cal_component_commit_sequence (comp); + e_calendar_view_modify_and_send (comp, client, mod, toplevel, TRUE); + out: + g_object_unref (comp); } static void +e_day_view_abort_resize (EDayView *day_view) +{ + gint day, event_num; + + if (day_view->resize_drag_pos == E_CALENDAR_VIEW_POS_NONE) + return; + + day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; + + day = day_view->resize_event_day; + event_num = day_view->resize_event_num; + + if (day == E_DAY_VIEW_LONG_EVENT) { + e_day_view_reshape_long_event (day_view, event_num); + gtk_widget_queue_draw (day_view->top_canvas); + + day_view->last_cursor_set_in_top_canvas = day_view->normal_cursor; + gdk_window_set_cursor (day_view->top_canvas->window, + day_view->normal_cursor); + } else { + e_day_view_reshape_day_event (day_view, day, event_num); + e_day_view_reshape_main_canvas_resize_bars (day_view); + gtk_widget_queue_draw (day_view->main_canvas); + + day_view->last_cursor_set_in_main_canvas = day_view->normal_cursor; + gdk_window_set_cursor (day_view->main_canvas->window, + day_view->normal_cursor); + } +} +#endif + +static void e_day_view_free_events (EDayView *day_view) { gint day; @@ -4513,6 +5841,64 @@ e_day_view_reshape_day_event (EDayView *day_view, /* This creates or resizes the horizontal bars used to resize events in the main canvas. */ +#ifndef ENABLE_CAIRO +static void +e_day_view_reshape_main_canvas_resize_bars (EDayView *day_view) +{ + gint day, event_num; + gint item_x, item_y, item_w, item_h; + gdouble x, y, w, h; + + day = day_view->resize_bars_event_day; + event_num = day_view->resize_bars_event_num; + + /* If we're not editing an event, or the event is not shown, + hide the resize bars. */ + if (day != -1 && day == day_view->drag_event_day + && event_num == day_view->drag_event_num) { + g_object_get (G_OBJECT (day_view->drag_rect_item), + "x1", &x, + "y1", &y, + "x2", &w, + "y2", &h, + NULL); + w -= x; + x++; + h -= y; + } else if (day != -1 + && e_day_view_get_event_position (day_view, day, event_num, + &item_x, &item_y, + &item_w, &item_h)) { + x = item_x + E_DAY_VIEW_BAR_WIDTH; + y = item_y; + w = item_w - E_DAY_VIEW_BAR_WIDTH; + h = item_h; + } else { + gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); + gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); + return; + } + + gnome_canvas_item_set (day_view->main_canvas_top_resize_bar_item, + "x1", x - E_DAY_VIEW_BAR_WIDTH, + "y1", y - E_DAY_VIEW_BAR_HEIGHT, + "x2", x + w - 1, + "y2", y - 1, + NULL); + gnome_canvas_item_show (day_view->main_canvas_top_resize_bar_item); + + gnome_canvas_item_set (day_view->main_canvas_bottom_resize_bar_item, + "x1", x - E_DAY_VIEW_BAR_WIDTH, + "y1", y + h, + "x2", x + w - 1, + "y2", y + h + E_DAY_VIEW_BAR_HEIGHT - 1, + NULL); + + gnome_canvas_item_show (day_view->main_canvas_bottom_resize_bar_item); +} +#endif + +#ifdef ENABLE_CAIRO static void e_day_view_reshape_main_canvas_resize_bars (EDayView *day_view) { @@ -4550,7 +5936,7 @@ e_day_view_reshape_main_canvas_resize_bars (EDayView *day_view) return; } } - +#endif static void e_day_view_ensure_events_sorted (EDayView *day_view) @@ -5860,6 +7246,7 @@ e_day_view_event_move (ECalendarView *cal_view, ECalViewMoveDirection direction) return TRUE; } +#ifndef ENABLE_CAIRO static void e_day_view_change_event_time (EDayView *day_view, time_t start_dt, time_t end_dt) { @@ -5910,6 +7297,9 @@ e_day_view_change_event_time (EDayView *day_view, time_t start_dt, time_t end_dt day_view->last_edited_comp_string = e_cal_component_get_as_string (comp); + gnome_canvas_item_hide (day_view->resize_rect_item); + gnome_canvas_item_hide (day_view->resize_bar_item); + day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; if (e_cal_component_is_instance (comp)) { @@ -5934,6 +7324,84 @@ e_day_view_change_event_time (EDayView *day_view, time_t start_dt, time_t end_dt out: g_object_unref (comp); } +#endif + +#ifdef ENABLE_CAIRO +static void +e_day_view_change_event_time (EDayView *day_view, time_t start_dt, time_t end_dt) +{ + EDayViewEvent *event; + gint day, event_num; + ECalComponent *comp; + ECalComponentDateTime date; + struct icaltimetype itt; + ECal *client; + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; + + day = day_view->editing_event_day; + event_num = day_view->editing_event_num; + event = &g_array_index (day_view->events[day], EDayViewEvent, + event_num); + client = event->comp_data->client; + + /* We use a temporary shallow copy of the ico since we don't want to + change the original ico here. Otherwise we would not detect that + the event's time had changed in the "update_event" callback. */ + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + + if (e_cal_component_has_attendees (comp) && !itip_organizer_is_user (comp, client)) { + g_object_unref (comp); + return; + } + + date.value = &itt; + /* FIXME: Should probably keep the timezone of the original start + and end times. */ + date.tzid = icaltimezone_get_tzid (e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + + *date.value = icaltime_from_timet_with_zone (start_dt, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtstart (comp, &date); + *date.value = icaltime_from_timet_with_zone (end_dt, FALSE, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + e_cal_component_set_dtend (comp, &date); + + e_cal_component_commit_sequence (comp); + + if (day_view->last_edited_comp_string != NULL) { + g_free (day_view->last_edited_comp_string); + day_view->last_edited_comp_string = NULL; + } + + day_view->last_edited_comp_string = e_cal_component_get_as_string (comp); + + day_view->resize_drag_pos = E_CALENDAR_VIEW_POS_NONE; + + if (e_cal_component_is_instance (comp)) { + if (!recur_component_dialog (client, comp, &mod, NULL, FALSE)) { + gtk_widget_queue_draw (day_view->top_canvas); + goto out; + } + + if (mod == CALOBJ_MOD_THIS) { + e_cal_component_set_rdate_list (comp, NULL); + e_cal_component_set_rrule_list (comp, NULL); + e_cal_component_set_exdate_list (comp, NULL); + e_cal_component_set_exrule_list (comp, NULL); + } + } + + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); + + e_cal_component_commit_sequence (comp); + e_calendar_view_modify_and_send (comp, client, mod, toplevel, TRUE); + +out: + g_object_unref (comp); +} +#endif static void e_day_view_change_event_end_time_up (EDayView *day_view) @@ -6035,6 +7503,167 @@ e_day_view_on_editing_started (EDayView *day_view, g_signal_emit_by_name (day_view, "selection_changed"); } +#ifndef ENABLE_CAIRO +static void +e_day_view_on_editing_stopped (EDayView *day_view, + GnomeCanvasItem *item) +{ + gint day, event_num; + EDayViewEvent *event; + gchar *text = NULL; + ECalComponentText summary; + ECalComponent *comp; + ECal *client; + gboolean on_server; + + /* Note: the item we are passed here isn't reliable, so we just stop + the edit of whatever item was being edited. We also receive this + event twice for some reason. */ + day = day_view->editing_event_day; + event_num = day_view->editing_event_num; + +#if 0 + g_print ("In e_day_view_on_editing_stopped Day:%i Event:%i\n", + day, event_num); +#endif + + /* If no item is being edited, just return. */ + if (day == -1) + return; + + if (day == E_DAY_VIEW_LONG_EVENT) { + event = &g_array_index (day_view->long_events, EDayViewEvent, + event_num); + } else { + event = &g_array_index (day_view->events[day], EDayViewEvent, + event_num); + + /* Hide the horizontal bars. */ + gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); + gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); + } + + /* Reset the edit fields. */ + day_view->editing_event_day = -1; + day_view->editing_event_num = -1; + + day_view->resize_bars_event_day = -1; + day_view->resize_bars_event_num = -1; + + g_object_set (event->canvas_item, "handle_popup", FALSE, NULL); + g_object_get (G_OBJECT (event->canvas_item), + "text", &text, + NULL); + g_assert (text != NULL); + + comp = e_cal_component_new (); + e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (event->comp_data->icalcomp)); + + client = event->comp_data->client; + on_server = cal_comp_is_on_server (comp, client); + + if (string_is_empty (text) && !on_server) { + const char *uid; + + e_cal_component_get_uid (comp, &uid); + + e_day_view_foreach_event_with_uid (day_view, uid, + e_day_view_remove_event_cb, NULL); + e_day_view_check_layout (day_view); + gtk_widget_queue_draw (day_view->top_canvas); + gtk_widget_queue_draw (day_view->main_canvas); + goto out; + } + + /* Only update the summary if necessary. */ + e_cal_component_get_summary (comp, &summary); + if (summary.value && !strcmp (text, summary.value)) { + if (day == E_DAY_VIEW_LONG_EVENT) + e_day_view_reshape_long_event (day_view, event_num); + else + e_day_view_update_event_label (day_view, day, + event_num); + } else if (summary.value || !string_is_empty (text)) { + icalcomponent *icalcomp = e_cal_component_get_icalcomponent (comp); + + summary.value = text; + summary.altrep = NULL; + e_cal_component_set_summary (comp, &summary); + e_cal_component_commit_sequence (comp); + + if (!on_server) { + if (!e_cal_create_object (client, icalcomp, NULL, NULL)) + g_message (G_STRLOC ": Could not create the object!"); + else + g_signal_emit_by_name (day_view, "user_created"); + + /* we remove the object since we either got the update from the server or failed */ + e_day_view_remove_event_cb (day_view, day, event_num, NULL); + } else { + CalObjModType mod = CALOBJ_MOD_ALL; + GtkWindow *toplevel; + if (e_cal_component_is_instance (comp)) { + if (!recur_component_dialog (client, comp, &mod, NULL, FALSE)) { + goto out; + } + + if (mod == CALOBJ_MOD_THIS) { + ECalComponentDateTime dt; + + e_cal_component_get_dtstart (comp, &dt); + if (dt.value->zone) { + *dt.value = icaltime_from_timet_with_zone ( + event->comp_data->instance_start, + dt.value->is_date, + dt.value->zone); + } else { + *dt.value = icaltime_from_timet_with_zone ( + event->comp_data->instance_start, + dt.value->is_date, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + } + e_cal_component_set_dtstart (comp, &dt); + + e_cal_component_get_dtend (comp, &dt); + if (dt.value->zone) { + *dt.value = icaltime_from_timet_with_zone ( + event->comp_data->instance_end, + dt.value->is_date, + dt.value->zone); + } else { + *dt.value = icaltime_from_timet_with_zone ( + event->comp_data->instance_end, + dt.value->is_date, + e_calendar_view_get_timezone (E_CALENDAR_VIEW (day_view))); + } + e_cal_component_set_dtend (comp, &dt); + + e_cal_component_set_rdate_list (comp, NULL); + e_cal_component_set_rrule_list (comp, NULL); + e_cal_component_set_exdate_list (comp, NULL); + e_cal_component_set_exrule_list (comp, NULL); + + e_cal_component_commit_sequence (comp); + } + } + + /* FIXME When sending here, what exactly should we send? */ + toplevel = GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (day_view))); + e_calendar_view_modify_and_send (comp, client, mod, toplevel, FALSE); + } + + } + + out: + + g_object_unref (comp); + g_free (text); + + g_signal_emit_by_name (day_view, "selection_changed"); +} +#endif + +#ifdef ENABLE_CAIRO static void e_day_view_on_editing_stopped (EDayView *day_view, GnomeCanvasItem *item) @@ -6190,6 +7819,7 @@ e_day_view_on_editing_stopped (EDayView *day_view, g_signal_emit_by_name (day_view, "selection_changed"); } +#endif /* FIXME: It is possible that we may produce an invalid time due to daylight @@ -7018,7 +8648,7 @@ e_day_view_on_top_canvas_drag_leave (GtkWidget *widget, gnome_canvas_item_hide (day_view->drag_long_event_item); } - +#ifndef ENABLE_CAIRO static void e_day_view_on_main_canvas_drag_leave (GtkWidget *widget, GdkDragContext *context, @@ -7036,9 +8666,33 @@ e_day_view_on_main_canvas_drag_leave (GtkWidget *widget, /* Hide the resize bars if they are being used in the drag. */ if (day_view->drag_event_day == day_view->resize_bars_event_day && day_view->drag_event_num == day_view->resize_bars_event_num) { + gnome_canvas_item_hide (day_view->main_canvas_top_resize_bar_item); + gnome_canvas_item_hide (day_view->main_canvas_bottom_resize_bar_item); } } +#endif + +#ifdef ENABLE_CAIRO +static void +e_day_view_on_main_canvas_drag_leave (GtkWidget *widget, + GdkDragContext *context, + guint time, + EDayView *day_view) +{ + day_view->drag_last_day = -1; + e_day_view_stop_auto_scroll (day_view); + + gnome_canvas_item_hide (day_view->drag_rect_item); + gnome_canvas_item_hide (day_view->drag_bar_item); + gnome_canvas_item_hide (day_view->drag_item); + + /* Hide the resize bars if they are being used in the drag. */ + if (day_view->drag_event_day == day_view->resize_bars_event_day + && day_view->drag_event_num == day_view->resize_bars_event_num) { + } +} +#endif static void e_day_view_on_drag_begin (GtkWidget *widget, |