aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui')
-rw-r--r--calendar/gui/e-day-view-time-item.c95
-rw-r--r--calendar/gui/e-day-view.c425
-rw-r--r--calendar/gui/e-day-view.h32
-rw-r--r--calendar/gui/e-week-view-titles-item.c21
-rw-r--r--calendar/gui/e-week-view.c329
-rw-r--r--calendar/gui/e-week-view.h23
-rw-r--r--calendar/gui/event-editor.c89
-rw-r--r--calendar/gui/gnome-cal.c41
-rw-r--r--calendar/gui/tag-calendar.c8
9 files changed, 864 insertions, 199 deletions
diff --git a/calendar/gui/e-day-view-time-item.c b/calendar/gui/e-day-view-time-item.c
index 19d8d40317..e018daa472 100644
--- a/calendar/gui/e-day-view-time-item.c
+++ b/calendar/gui/e-day-view-time-item.c
@@ -189,25 +189,29 @@ gint
e_day_view_time_item_get_column_width (EDayViewTimeItem *dvtmitem)
{
EDayView *day_view;
+ gint column_width_default, column_width_60_min_rows;
day_view = dvtmitem->day_view;
g_return_val_if_fail (day_view != NULL, 0);
- /* Calculate the width of each time column. */
- if (day_view->mins_per_row == 60) {
- dvtmitem->column_width = day_view->max_small_hour_width
- + day_view->colon_width
- + day_view->max_minute_width
- + E_DVTMI_60_MIN_X_PAD * 2
- + E_DVTMI_TIME_GRID_X_PAD * 2;
- } else {
- dvtmitem->column_width = day_view->max_large_hour_width
+ /* Calculate the width of each time column, using the maximum of the
+ default format with large hour numbers, and the 60-min divisions
+ format which uses small text. */
+ column_width_default = day_view->max_large_hour_width
+ day_view->max_minute_width
+ E_DVTMI_MIN_X_PAD * 2
+ E_DVTMI_HOUR_L_PAD
+ E_DVTMI_HOUR_R_PAD
+ E_DVTMI_TIME_GRID_X_PAD * 2;
- }
+
+ column_width_60_min_rows = day_view->max_small_hour_width
+ + day_view->colon_width
+ + day_view->max_minute_width
+ + E_DVTMI_60_MIN_X_PAD * 2
+ + E_DVTMI_TIME_GRID_X_PAD * 2;
+
+ dvtmitem->column_width = MAX (column_width_default,
+ column_width_60_min_rows);
return dvtmitem->column_width;
}
@@ -228,12 +232,12 @@ e_day_view_time_item_draw (GnomeCanvasItem *canvas_item,
EDayView *day_view;
EDayViewTimeItem *dvtmitem;
gint time_hour_x1, time_hour_x2, time_min_x1;
- gint hour, minute, hour_y, min_y, hour_r, min_r, start_y;
- gint row, row_y, min_width, hour_width;
+ gint hour, display_hour, minute, hour_y, min_y, hour_r, min_r, start_y;
+ gint row, row_y, min_width, hour_width, suffix_width;
GtkStyle *style;
GdkFont *small_font, *large_font;
GdkGC *fg_gc, *dark_gc;
- gchar buffer[16];
+ gchar buffer[64], *suffix;
dvtmitem = E_DAY_VIEW_TIME_ITEM (canvas_item);
day_view = dvtmitem->day_view;
@@ -262,12 +266,6 @@ e_day_view_time_item_draw (GnomeCanvasItem *canvas_item,
}
hour = day_view->first_hour_shown;
- if (!day_view->use_24_hour_format) {
- if (hour == 0 || hour == 12)
- hour = 12;
- else
- hour %= 12;
- }
hour_y = large_font->ascent + 2; /* FIXME */
minute = day_view->first_minute_shown;
min_y = small_font->ascent + 2; /* FIXME */
@@ -280,12 +278,40 @@ e_day_view_time_item_draw (GnomeCanvasItem *canvas_item,
if (min_r <= 0)
continue;
+ /* Calculate the actual hour number to display. */
+ display_hour = hour;
+ if (!day_view->use_24_hour_format) {
+ if (display_hour < 12) {
+ suffix = day_view->am_string;
+ suffix_width = day_view->am_string_width;
+ } else {
+ display_hour -= 12;
+ suffix = day_view->pm_string;
+ suffix_width = day_view->pm_string_width;
+ }
+
+ /* 12-hour format uses 12:00 rather than 0:00.
+ */
+ if (display_hour == 0)
+ display_hour = 12;
+ }
+
if (day_view->mins_per_row == 60) {
gdk_draw_line (drawable, dark_gc,
time_hour_x1, row_y,
time_hour_x2, row_y);
- sprintf (buffer, "%02i:%02i", hour, minute);
- min_width = day_view->small_hour_widths[hour] + day_view->minute_widths[minute / 5] + day_view->colon_width;
+
+ if (day_view->use_24_hour_format) {
+ sprintf (buffer, "%i:%02i",
+ display_hour, minute);
+ /*min_width = day_view->small_hour_widths[display_hour] + day_view->minute_widths[minute / 5] + day_view->colon_width;*/
+ min_width = gdk_string_width (small_font, buffer);
+ } else {
+ sprintf (buffer, "%i %s",
+ display_hour, suffix);
+ /*min_width = day_view->small_hour_widths[display_hour] + suffix_width;*/
+ min_width = gdk_string_width (small_font, buffer);
+ }
gdk_draw_string (drawable, small_font, fg_gc,
min_r - min_width,
row_y + min_y, buffer);
@@ -294,8 +320,9 @@ e_day_view_time_item_draw (GnomeCanvasItem *canvas_item,
gdk_draw_line (drawable, dark_gc,
time_hour_x1, row_y,
time_hour_x2, row_y);
- sprintf (buffer, "%02i", hour);
- hour_width = day_view->large_hour_widths[hour];
+ sprintf (buffer, "%i", display_hour);
+ /*hour_width = day_view->large_hour_widths[display_hour];*/
+ hour_width = gdk_string_width (large_font, buffer);
gdk_draw_string (drawable, large_font,
fg_gc,
hour_r - hour_width,
@@ -309,8 +336,14 @@ e_day_view_time_item_draw (GnomeCanvasItem *canvas_item,
if (day_view->mins_per_row != 30
|| minute != 30) {
- sprintf (buffer, "%02i", minute);
- min_width = day_view->minute_widths[minute / 5];
+ if (minute == 0
+ && !day_view->use_24_hour_format) {
+ strcpy (buffer, suffix);
+ min_width = gdk_string_width (small_font, buffer);
+ } else {
+ sprintf (buffer, "%02i", minute);
+ min_width = day_view->minute_widths[minute / 5];
+ }
gdk_draw_string (drawable, small_font,
fg_gc,
min_r - min_width,
@@ -320,16 +353,14 @@ e_day_view_time_item_draw (GnomeCanvasItem *canvas_item,
}
}
+ /* Note that mins_per_row is never > 60, so we never have to
+ worry about adding more than 60 minutes. */
minute += day_view->mins_per_row;
if (minute >= 60) {
- hour++;
- if (!day_view->use_24_hour_format) {
- if (hour == 0 || hour == 12)
- hour = 12;
- else
- hour %= 12;
- }
minute -= 60;
+ /* Currently we never wrap around to the next day, but
+ we may do if we display extra timezones. */
+ hour = (hour + 1) % 24;
}
}
}
diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c
index c1da656ccd..9d7782462c 100644
--- a/calendar/gui/e-day-view.c
+++ b/calendar/gui/e-day-view.c
@@ -222,6 +222,9 @@ typedef gboolean (* EDayViewForeachEventCallback) (EDayView *day_view,
gint event_num,
gpointer data);
+static void e_day_view_foreach_event (EDayView *day_view,
+ EDayViewForeachEventCallback callback,
+ gpointer data);
static void e_day_view_foreach_event_with_uid (EDayView *day_view,
const gchar *uid,
EDayViewForeachEventCallback callback,
@@ -380,6 +383,14 @@ static gboolean e_day_view_remove_event_cb (EDayView *day_view,
gint event_num,
gpointer data);
static void e_day_view_normalize_selection (EDayView *day_view);
+static gboolean e_day_view_set_show_times_cb (EDayView *day_view,
+ gint day,
+ gint event_num,
+ gpointer data);
+static time_t e_day_view_find_work_week_start (EDayView *day_view,
+ time_t start_time);
+static void e_day_view_recalc_work_week (EDayView *day_view);
+static void e_day_view_recalc_work_week_days_shown (EDayView *day_view);
static GtkTableClass *parent_class;
@@ -463,7 +474,6 @@ e_day_view_init (EDayView *day_view)
day_view->lower = 0;
day_view->upper = 0;
- /* FIXME: Initialize day_starts. */
day_view->work_week_view = FALSE;
day_view->days_shown = 1;
@@ -490,6 +500,8 @@ e_day_view_init (EDayView *day_view)
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->editing_event_day = -1;
@@ -522,6 +534,12 @@ e_day_view_init (EDayView *day_view)
if (!day_view->large_font)
g_warning ("Couldn't load font");
+ /* 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
@@ -1065,6 +1083,11 @@ e_day_view_style_set (GtkWidget *widget,
day_view->max_minute_width = max_minute_width;
day_view->colon_width = gdk_string_width (font, ":");
+ day_view->am_string_width = gdk_string_width (font,
+ day_view->am_string);
+ day_view->pm_string_width = gdk_string_width (font,
+ day_view->pm_string);
+
/* 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);
@@ -1252,8 +1275,6 @@ e_day_view_set_calendar (EDayView *day_view,
g_return_if_fail (E_IS_DAY_VIEW (day_view));
day_view->calendar = calendar;
-
- /* FIXME: free current events? */
}
@@ -1285,6 +1306,9 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
day_view = E_DAY_VIEW (data);
+ /* Sanity check. */
+ g_return_if_fail (client == day_view->client);
+
/* If our time hasn't been set yet, just return. */
if (day_view->lower == 0 && day_view->upper == 0)
return;
@@ -1459,8 +1483,46 @@ e_day_view_update_event_cb (EDayView *day_view,
}
+/* This calls a given function for each event instance (in both views).
+ If the callback returns TRUE the iteration is stopped.
+ Note that it is safe for the callback to remove the event (since we
+ step backwards through the arrays). */
+static void
+e_day_view_foreach_event (EDayView *day_view,
+ EDayViewForeachEventCallback callback,
+ gpointer data)
+{
+ EDayViewEvent *event;
+ gint day, event_num;
+
+ for (day = 0; day < day_view->days_shown; day++) {
+ for (event_num = day_view->events[day]->len - 1;
+ event_num >= 0;
+ event_num--) {
+ event = &g_array_index (day_view->events[day],
+ EDayViewEvent, event_num);
+
+ if (!(*callback) (day_view, day, event_num, data))
+ return;
+ }
+ }
+
+ for (event_num = day_view->long_events->len - 1;
+ event_num >= 0;
+ event_num--) {
+ event = &g_array_index (day_view->long_events,
+ EDayViewEvent, event_num);
+
+ if (!(*callback) (day_view, E_DAY_VIEW_LONG_EVENT, event_num,
+ data))
+ return;
+ }
+}
+
+
/* This calls a given function for each event instance that matches the given
- uid. Note that it is safe for the callback to remove the event (since we
+ uid. If the callback returns TRUE the iteration is stopped.
+ Note that it is safe for the callback to remove the event (since we
step backwards through the arrays). */
static void
e_day_view_foreach_event_with_uid (EDayView *day_view,
@@ -1553,9 +1615,9 @@ e_day_view_update_event_label (EDayView *day_view,
gint event_num)
{
EDayViewEvent *event;
- char *text;
+ char *text, *start_suffix, *end_suffix;
gboolean free_text = FALSE, editing_event = FALSE;
- gint offset, start_minute, end_minute;
+ gint offset, start_hour, start_minute, end_hour, end_minute;
CalComponentText summary;
event = &g_array_index (day_view->events[day], EDayViewEvent,
@@ -1574,17 +1636,70 @@ e_day_view_update_event_label (EDayView *day_view,
if (!editing_event
&& (event->start_minute % day_view->mins_per_row != 0
- || event->end_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;
- text = g_strdup_printf ("%02i:%02i-%02i:%02i %s",
- start_minute / 60,
- start_minute % 60,
- end_minute / 60,
- end_minute % 60,
- text);
+
+ start_hour = start_minute / 60;
+ start_minute = start_minute % 60;
+
+ end_hour = end_minute / 60;
+ end_minute = end_minute % 60;
+
+ if (day_view->use_24_hour_format) {
+ if (day_view->show_event_end_times) {
+ /* 24 hour format with end time. */
+ text = g_strdup_printf
+ ("%02i:%02i-%02i:%02i %s",
+ start_hour, start_minute,
+ end_hour, end_minute,
+ text);
+ } else {
+ /* 24 hour format without end time. */
+ text = g_strdup_printf
+ ("%02i:%02i %s",
+ start_hour, start_minute,
+ text);
+ }
+ } else {
+ start_suffix = end_suffix = day_view->am_string;
+
+ if (start_hour >= 12) {
+ start_hour -= 12;
+ start_suffix = day_view->pm_string;
+ }
+ if (end_hour >= 12) {
+ end_hour -= 12;
+ end_suffix = day_view->pm_string;
+ }
+
+ /* We display 1-12 rather than 0-11 for hours. */
+ if (start_hour == 0)
+ start_hour = 12;
+ if (end_hour == 0)
+ end_hour = 12;
+
+ if (day_view->show_event_end_times) {
+ /* 12 hour format with end time. */
+ text = g_strdup_printf
+ ("%02i:%02i%s-%02i:%02i%s %s",
+ start_hour, start_minute,
+ start_suffix,
+ end_hour, end_minute,
+ end_suffix,
+ text);
+ } else {
+ /* 12 hour format without end time. */
+ text = g_strdup_printf
+ ("%02i:%02i%s %s",
+ start_hour % 12, start_minute,
+ start_suffix,
+ text);
+ }
+ }
free_text = TRUE;
}
@@ -1717,7 +1832,6 @@ e_day_view_set_selected_time_range (EDayView *day_view,
time_t start_time,
time_t end_time)
{
- GDate date;
time_t lower;
gint start_row, start_col, end_row, end_col;
gboolean need_redraw = FALSE, start_in_grid, end_in_grid;
@@ -1727,16 +1841,11 @@ e_day_view_set_selected_time_range (EDayView *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
- Monday. */
+ work-week start day. */
if (!day_view->work_week_view) {
lower = time_day_begin (start_time);
} else {
- g_date_clear (&date, 1);
- g_date_set_time (&date, start_time);
- g_date_subtract_days (&date, g_date_weekday (&date) - 1);
- lower = time_from_day (g_date_year (&date),
- g_date_month (&date) - 1,
- g_date_day (&date));
+ lower = e_day_view_find_work_week_start (day_view, start_time);
}
/* See if we need to change the days shown. */
@@ -1790,6 +1899,46 @@ e_day_view_set_selected_time_range (EDayView *day_view,
}
+/* Finds the start of the working week which includes the given time. */
+static time_t
+e_day_view_find_work_week_start (EDayView *day_view,
+ time_t start_time)
+{
+ GDate date;
+ gint weekday, day, i, offset;
+
+ g_date_clear (&date, 1);
+ g_date_set_time (&date, start_time);
+
+ /* The start of the work-week is the first working day after the
+ week start day. */
+
+ /* Get the weekday corresponding to start_time, 0 (Sun) to 6 (Sat). */
+ weekday = g_date_weekday (&date) % 7;
+
+ /* Calculate the first working day of the week, 0 (Sun) to 6 (Sat).
+ It will automatically default to the week start day if no days
+ are set as working days. */
+ day = (day_view->week_start_day + 1) % 7;
+ for (i = 0; i < 7; i++) {
+ if (day_view->working_days & (1 << day))
+ break;
+ day = (day + 1) % 7;
+ }
+
+ /* Calculate how many days we need to go back to the first workday. */
+ offset = (weekday + 7 - day) % 7;
+
+ g_print ("Weekday: %i Day: %i Offset: %i\n", weekday, day, offset);
+
+ g_date_subtract_days (&date, offset);
+
+ return time_from_day (g_date_year (&date),
+ g_date_month (&date) - 1,
+ g_date_day (&date));
+}
+
+
/* Returns the selected time range. */
void
e_day_view_get_selected_time_range (EDayView *day_view,
@@ -1868,7 +2017,8 @@ e_day_view_set_work_week_view (EDayView *day_view,
day_view->work_week_view = work_week_view;
- /* FIXME: need to recalc the first day shown if now work-week view. */
+ if (day_view->work_week_view)
+ e_day_view_recalc_work_week (day_view);
}
@@ -1889,12 +2039,18 @@ e_day_view_set_days_shown (EDayView *day_view,
g_return_if_fail (days_shown >= 1);
g_return_if_fail (days_shown <= E_DAY_VIEW_MAX_DAYS);
- if (day_view->days_shown != days_shown) {
- day_view->days_shown = days_shown;
- e_day_view_recalc_day_starts (day_view, day_view->lower);
- e_day_view_recalc_cell_sizes (day_view);
- e_day_view_queue_reload_events (day_view);
- }
+ if (day_view->days_shown = days_shown)
+ return;
+
+ day_view->days_shown = days_shown;
+
+ /* If the date isn't set, just return. */
+ if (day_view->lower == 0 && day_view->upper == 0)
+ return;
+
+ e_day_view_recalc_day_starts (day_view, day_view->lower);
+ e_day_view_recalc_cell_sizes (day_view);
+ e_day_view_queue_reload_events (day_view);
}
@@ -1934,6 +2090,11 @@ e_day_view_set_mins_per_row (EDayView *day_view,
for (day = 0; day < E_DAY_VIEW_MAX_DAYS; day++)
day_view->need_layout[day] = TRUE;
+ /* We need to update all the day event labels since the start & end
+ times may or may not be on row boundaries any more. */
+ e_day_view_foreach_event (day_view,
+ e_day_view_set_show_times_cb, NULL);
+
/* We must layout the events before updating the scroll region, since
that will result in a redraw which would crash otherwise. */
e_day_view_check_layout (day_view);
@@ -1961,10 +2122,55 @@ e_day_view_set_working_days (EDayView *day_view,
{
g_return_if_fail (E_IS_DAY_VIEW (day_view));
- if (day_view->working_days != days) {
- day_view->working_days = days;
- gtk_widget_queue_draw (day_view->main_canvas);
+ if (day_view->working_days == days)
+ return;
+
+ day_view->working_days = days;
+
+ if (day_view->work_week_view)
+ e_day_view_recalc_work_week (day_view);
+
+ /* We have to do this, as the new working days may have no effect on
+ the days shown, but we still want the background color to change. */
+ gtk_widget_queue_draw (day_view->main_canvas);
+}
+
+
+static void
+e_day_view_recalc_work_week_days_shown (EDayView *day_view)
+{
+ gint first_day, last_day, i, days_shown;
+ gboolean has_working_days = FALSE;
+
+ /* Find the first working day in the week, 0 (Sun) to 6 (Sat). */
+ first_day = (day_view->week_start_day + 1) % 7;
+ for (i = 0; i < 7; i++) {
+ if (day_view->working_days & (1 << first_day)) {
+ has_working_days = TRUE;
+ break;
+ }
+ first_day = (first_day + 1) % 7;
+ }
+
+ if (has_working_days) {
+ /* Now find the last working day of the week, backwards. */
+ last_day = day_view->week_start_day % 7;
+ for (i = 0; i < 7; i++) {
+ if (day_view->working_days & (1 << last_day))
+ break;
+ last_day = (last_day + 6) % 7;
+ }
+ /* Now calculate the days we need to show to include all the
+ working days in the week. Add 1 to make it inclusive. */
+ days_shown = (last_day + 7 - first_day) % 7 + 1;
+ g_print ("First day: %i Last: %i Days: %i\n",
+ first_day, last_day, days_shown);
+ } else {
+ /* If no working days are set, just use 7. */
+ days_shown = 7;
}
+
+ e_day_view_set_days_shown (day_view, days_shown);
}
@@ -2020,11 +2226,120 @@ e_day_view_set_24_hour_format (EDayView *day_view,
{
g_return_if_fail (E_IS_DAY_VIEW (day_view));
- if (day_view->use_24_hour_format != use_24_hour) {
- day_view->use_24_hour_format = use_24_hour;
+ if (day_view->use_24_hour_format == use_24_hour)
+ return;
- /* FIXME: Eventually we need to do a re-layout. */
- gtk_widget_queue_draw (day_view->main_canvas);
+ day_view->use_24_hour_format = use_24_hour;
+
+ /* We need to update all the text in the events since they may contain
+ the time in the old format. */
+ e_day_view_foreach_event (day_view, e_day_view_set_show_times_cb,
+ NULL);
+
+ /* FIXME: We need to re-layout the top canvas since the time
+ format affects the sizes. */
+ gtk_widget_queue_draw (day_view->time_canvas);
+ gtk_widget_queue_draw (day_view->top_canvas);
+}
+
+
+/* Whether we display event end times in the main canvas. */
+gboolean
+e_day_view_get_show_event_end_times (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), TRUE);
+
+ return day_view->show_event_end_times;
+}
+
+
+void
+e_day_view_set_show_event_end_times (EDayView *day_view,
+ gboolean show)
+{
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+
+ if (day_view->show_event_end_times != show) {
+ day_view->show_event_end_times = show;
+ e_day_view_foreach_event (day_view,
+ e_day_view_set_show_times_cb, NULL);
+ }
+}
+
+
+/* This is a callback used to update all day event labels. */
+static gboolean
+e_day_view_set_show_times_cb (EDayView *day_view,
+ gint day,
+ gint event_num,
+ gpointer data)
+{
+ g_print ("In e_day_view_set_show_times_cb day:%i event_num:%i\n",
+ day, event_num);
+
+ if (day != E_DAY_VIEW_LONG_EVENT) {
+ e_day_view_update_event_label (day_view, day, event_num);
+ }
+
+ return TRUE;
+}
+
+
+/* The first day of the week, 0 (Monday) to 6 (Sunday). */
+gint
+e_day_view_get_week_start_day (EDayView *day_view)
+{
+ g_return_val_if_fail (E_IS_DAY_VIEW (day_view), 0);
+
+ return day_view->week_start_day;
+}
+
+
+void
+e_day_view_set_week_start_day (EDayView *day_view,
+ gint week_start_day)
+{
+ g_return_if_fail (E_IS_DAY_VIEW (day_view));
+ g_return_if_fail (week_start_day >= 0);
+ g_return_if_fail (week_start_day < 7);
+
+ g_print ("In e_day_view_set_week_start_day day: %i\n", week_start_day);
+
+ if (day_view->week_start_day == week_start_day)
+ return;
+
+ day_view->week_start_day = week_start_day;
+
+ if (day_view->work_week_view)
+ e_day_view_recalc_work_week (day_view);
+}
+
+
+static void
+e_day_view_recalc_work_week (EDayView *day_view)
+{
+ time_t lower;
+
+ /* If we aren't showing the work week, just return. */
+ if (!day_view->work_week_view)
+ return;
+
+ /* If the date isn't set, just return. */
+ if (day_view->lower == 0 && day_view->upper == 0)
+ return;
+
+ e_day_view_recalc_work_week_days_shown (day_view);
+
+ lower = e_day_view_find_work_week_start (day_view, day_view->lower);
+ if (lower != day_view->lower) {
+ /* Reset the selection, as it may disappear. */
+ day_view->selection_start_day = -1;
+
+ e_day_view_recalc_day_starts (day_view, lower);
+ e_day_view_queue_reload_events (day_view);
+
+ /* This updates the date navigator. */
+ e_day_view_update_calendar_selection_time (day_view);
}
}
@@ -2719,7 +3034,11 @@ e_day_view_on_new_appointment (GtkWidget *widget, gpointer data)
cal_component_commit_sequence (comp);
- gnome_calendar_edit_object (day_view->calendar, comp);
+ if (day_view->calendar)
+ gnome_calendar_edit_object (day_view->calendar, comp);
+ else
+ g_warning ("Calendar not set");
+
gtk_object_unref (GTK_OBJECT (comp));
}
@@ -2736,7 +3055,10 @@ e_day_view_on_edit_appointment (GtkWidget *widget, gpointer data)
if (event == NULL)
return;
- gnome_calendar_edit_object (day_view->calendar, event->comp);
+ if (day_view->calendar)
+ gnome_calendar_edit_object (day_view->calendar, event->comp);
+ else
+ g_warning ("Calendar not set");
}
@@ -2805,6 +3127,9 @@ e_day_view_on_unrecur_appointment (GtkWidget *widget, gpointer data)
if (event == NULL)
return;
+ date.value = &itt;
+ date.tzid = NULL;
+
/* For the recurring object, we add an exception to get rid of the
instance. */
@@ -2917,8 +3242,13 @@ e_day_view_update_calendar_selection_time (EDayView *day_view)
time_t start, end;
e_day_view_get_selected_time_range (day_view, &start, &end);
- gnome_calendar_set_selected_time_range (day_view->calendar,
- start, end);
+
+ g_print ("Start: %s", ctime (&start));
+ g_print ("End : %s", ctime (&end));
+
+ if (day_view->calendar)
+ gnome_calendar_set_selected_time_range (day_view->calendar,
+ start, end);
}
@@ -3500,8 +3830,11 @@ e_day_view_reload_events (EDayView *day_view)
/* If both lower & upper are 0, then the time range hasn't been set,
so we don't try to load any events. */
- if (day_view->calendar
- && (day_view->lower != 0 || day_view->upper != 0)) {
+ if (day_view->lower != 0 || day_view->upper != 0) {
+#if 0
+ g_print ("EDayView (%s) generating instances\n",
+ day_view->work_week_view ? "Work Week" : "1 Day View");
+#endif
cal_client_generate_instances (day_view->client,
CALOBJ_TYPE_EVENT,
day_view->lower,
@@ -3969,7 +4302,9 @@ e_day_view_layout_day_events (EDayView *day_view,
rows. */
guint16 group_starts[12 * 24];
- /* Reset the cols_per_row array, and initialize the connected rows. */
+ /* Reset the cols_per_row array, and initialize the connected rows so
+ that all rows are not connected - each row is the start of a new
+ group. */
for (row = 0; row < day_view->rows; row++) {
day_view->cols_per_row[day][row] = 0;
group_starts[row] = row;
@@ -4647,7 +4982,8 @@ static void
e_day_view_cursor_key_left (EDayView *day_view, GdkEventKey *event)
{
if (day_view->selection_start_day == 0) {
- gnome_calendar_previous (day_view->calendar);
+ if (day_view->calendar)
+ gnome_calendar_previous (day_view->calendar);
} else {
day_view->selection_start_day--;
day_view->selection_end_day--;
@@ -4665,7 +5001,8 @@ static void
e_day_view_cursor_key_right (EDayView *day_view, GdkEventKey *event)
{
if (day_view->selection_end_day == day_view->days_shown - 1) {
- gnome_calendar_next (day_view->calendar);
+ if (day_view->calendar)
+ gnome_calendar_next (day_view->calendar);
} else {
day_view->selection_start_day++;
day_view->selection_end_day++;
diff --git a/calendar/gui/e-day-view.h b/calendar/gui/e-day-view.h
index bf72d47f46..f0118187e4 100644
--- a/calendar/gui/e-day-view.h
+++ b/calendar/gui/e-day-view.h
@@ -209,7 +209,7 @@ struct _EDayView
/* Calendar client object we are monitoring */
CalClient *client;
- /* The start and end of the day shown. */
+ /* The start and end of the days shown. */
time_t lower;
time_t upper;
@@ -218,7 +218,7 @@ struct _EDayView
/* The number of days we are showing. Usually 1 or 5, but can be up
to E_DAY_VIEW_MAX_DAYS, e.g. when the user selects a range of
- days in the mini calendar. */
+ days in the date navigator. */
gint days_shown;
/* The start of each day & an extra element to hold the last time. */
@@ -282,6 +282,12 @@ struct _EDayView
/* Whether we use 12-hour of 24-hour format. */
gboolean use_24_hour_format;
+ /* Whether we use show event end times in the main canvas. */
+ gboolean show_event_end_times;
+
+ /* The first day of the week, 0 (Monday) to 6 (Sunday). */
+ gint week_start_day;
+
/* This is set to TRUE when the widget is created, so it scrolls to
the start of the working day when first shown. */
gboolean scroll_to_work_day;
@@ -291,7 +297,9 @@ struct _EDayView
gint day_widths[E_DAY_VIEW_MAX_DAYS];
gint day_offsets[E_DAY_VIEW_MAX_DAYS + 1];
- /* An array holding the number of columns in each row, in each day. */
+ /* An array holding the number of columns in each row, in each day.
+ Note that there are a maximum of 12 * 24 rows (when a row is 5 mins)
+ but we don't always have that many rows. */
guint8 cols_per_row[E_DAY_VIEW_MAX_DAYS][12 * 24];
/* Sizes of the various time strings. */
@@ -313,7 +321,7 @@ struct _EDayView
gint longest_weekday_name;
gint longest_abbreviated_weekday_name;
- /* The large font use to display the hours. I don't think we need a
+ /* The large font used to display the hours. I don't think we need a
fontset since we only display numbers. */
GdkFont *large_font;
@@ -433,6 +441,12 @@ struct _EDayView
GnomeCanvasItem *drag_rect_item;
GnomeCanvasItem *drag_bar_item;
GnomeCanvasItem *drag_item;
+
+ /* "am" and "pm" in the current locale, and their widths. */
+ gchar *am_string;
+ gchar *pm_string;
+ gint am_string_width;
+ gint pm_string_width;
};
struct _EDayViewClass
@@ -515,6 +529,16 @@ gboolean e_day_view_get_24_hour_format (EDayView *day_view);
void e_day_view_set_24_hour_format (EDayView *day_view,
gboolean use_24_hour);
+/* Whether we display event end times in the main canvas. */
+gboolean e_day_view_get_show_event_end_times (EDayView *day_view);
+void e_day_view_set_show_event_end_times (EDayView *day_view,
+ gboolean show);
+
+/* The first day of the week, 0 (Monday) to 6 (Sunday). */
+gint e_day_view_get_week_start_day (EDayView *day_view);
+void e_day_view_set_week_start_day (EDayView *day_view,
+ gint week_start_day);
+
/*
* Internal functions called by the associated canvas items.
*/
diff --git a/calendar/gui/e-week-view-titles-item.c b/calendar/gui/e-week-view-titles-item.c
index 14f47e4bcf..5a2b9c164a 100644
--- a/calendar/gui/e-week-view-titles-item.c
+++ b/calendar/gui/e-week-view-titles-item.c
@@ -174,6 +174,7 @@ e_week_view_titles_item_draw (GnomeCanvasItem *canvas_item,
GDate date;
GdkRectangle clip_rect;
gboolean long_format;
+ gint weekday;
#if 0
g_print ("In e_week_view_titles_item_draw %i,%i %ix%i\n",
@@ -222,9 +223,12 @@ e_week_view_titles_item_draw (GnomeCanvasItem *canvas_item,
/* Draw the date. Set a clipping rectangle so we don't draw over the
next day. */
g_date_clear (&date, 1);
- g_date_set_dmy (&date, 27, 3, 2000); /* Must be a Monday. */
+ /* Note that 20th March 2000 is a Monday. We only care about the
+ weekday. */
+ weekday = week_view->display_start_day;
+ g_date_set_dmy (&date, 20 + weekday, 3, 2000);
for (col = 0; col < week_view->columns; col++) {
- if (col == 5 && week_view->compress_weekend) {
+ if (weekday == 5 && week_view->compress_weekend) {
g_date_strftime (buffer, 128, "%a/", &date);
g_date_add_days (&date, 1);
g_date_strftime (buffer + strlen (buffer), 100,
@@ -239,14 +243,14 @@ e_week_view_titles_item_draw (GnomeCanvasItem *canvas_item,
clip_rect.height = canvas_height - 2;
gdk_gc_set_clip_rectangle (fg_gc, &clip_rect);
- if (col == 5 && week_view->compress_weekend)
+ if (weekday == 5 && week_view->compress_weekend)
date_width = week_view->abbr_day_widths[5]
+ week_view->slash_width
+ week_view->abbr_day_widths[6];
else if (long_format)
- date_width = week_view->day_widths[col];
+ date_width = week_view->day_widths[weekday];
else
- date_width = week_view->abbr_day_widths[col];
+ date_width = week_view->abbr_day_widths[weekday];
date_x = week_view->col_offsets[col]
+ (week_view->col_widths[col] - date_width) / 2;
@@ -280,6 +284,13 @@ e_week_view_titles_item_draw (GnomeCanvasItem *canvas_item,
canvas_height - y);
}
+ if (weekday == 5 && week_view->compress_weekend)
+ weekday += 2;
+ else
+ weekday++;
+
+ weekday = weekday % 7;
+
g_date_add_days (&date, 1);
}
}
diff --git a/calendar/gui/e-week-view.c b/calendar/gui/e-week-view.c
index 48c9f147d3..ca93fd1a14 100644
--- a/calendar/gui/e-week-view.c
+++ b/calendar/gui/e-week-view.c
@@ -175,6 +175,7 @@ static gboolean e_week_view_update_event_cb (EWeekView *week_view,
static gboolean e_week_view_remove_event_cb (EWeekView *week_view,
gint event_num,
gpointer data);
+static gboolean e_week_view_recalc_display_start_day (EWeekView *week_view);
static GtkTableClass *parent_class;
@@ -256,6 +257,9 @@ e_week_view_init (EWeekView *week_view)
week_view->rows = 6;
week_view->columns = 2;
week_view->compress_weekend = TRUE;
+ week_view->show_event_end_times = TRUE;
+ week_view->week_start_day = 0; /* Monday. */
+ week_view->display_start_day = 0; /* Monday. */
g_date_clear (&week_view->base_date, 1);
g_date_clear (&week_view->first_day_shown, 1);
@@ -693,14 +697,16 @@ e_week_view_recalc_cell_sizes (EWeekView *week_view)
if (week_view->use_small_font && week_view->small_font) {
time_width = week_view->digit_width * 2
+ week_view->small_digit_width * 2;
- if (width / 2 > time_width * 2 + week_view->space_width)
+ if (week_view->show_event_end_times
+ && width / 2 > time_width * 2 + week_view->space_width)
week_view->time_format = E_WEEK_VIEW_TIME_BOTH_SMALL_MIN;
else if (width / 2 > time_width)
week_view->time_format = E_WEEK_VIEW_TIME_START_SMALL_MIN;
} else {
time_width = week_view->digit_width * 4
+ week_view->colon_width;
- if (width / 2 > time_width * 2 + week_view->space_width)
+ if (week_view->show_event_end_times
+ && width / 2 > time_width * 2 + week_view->space_width)
week_view->time_format = E_WEEK_VIEW_TIME_BOTH;
else if (width / 2 > time_width)
week_view->time_format = E_WEEK_VIEW_TIME_START;
@@ -812,8 +818,6 @@ e_week_view_set_calendar (EWeekView *week_view,
g_return_if_fail (E_IS_WEEK_VIEW (week_view));
week_view->calendar = calendar;
-
- /* FIXME: free current events? */
}
@@ -843,6 +847,9 @@ obj_updated_cb (CalClient *client, const char *uid, gpointer data)
week_view = E_WEEK_VIEW (data);
+ /* Sanity check. */
+ g_return_if_fail (client == week_view->client);
+
/* If we don't have a valid date set yet, just return. */
if (!g_date_valid (&week_view->first_day_shown))
return;
@@ -978,7 +985,7 @@ e_week_view_set_selected_time_range (EWeekView *week_view,
time_t end_time)
{
GDate date, base_date, end_date;
- gint day_offset, num_days;
+ gint day_offset, weekday, week_start_offset, num_days;
gboolean update_adjustment_value = FALSE;
g_return_if_fail (E_IS_WEEK_VIEW (week_view));
@@ -990,13 +997,30 @@ e_week_view_set_selected_time_range (EWeekView *week_view,
/* Find the number of days since the start of the month. */
day_offset = g_date_day (&date) - 1;
- /* Find the 1st Monday at or before the start of the month. */
+ /* Find the 1st week which starts at or before the start of
+ the month. */
base_date = date;
g_date_set_day (&base_date, 1);
- day_offset += g_date_weekday (&base_date) - 1;
+
+ /* Calculate the weekday of the 1st of the month, 0 = Mon. */
+ weekday = g_date_weekday (&base_date) - 1;
+
+ /* Convert it to an offset from the start of the display. */
+ week_start_offset = (weekday + 7 - week_view->display_start_day) % 7;
+
+ /* Add it to the day offset so we go back to the 1st week at
+ or before the start of the month. */
+ day_offset += week_start_offset;
} else {
- /* Find the 1st Monday at or before the given day. */
- day_offset = g_date_weekday (&date) - 1;
+ /* Calculate the weekday of the given date, 0 = Mon. */
+ weekday = g_date_weekday (&date) - 1;
+
+ /* Convert it to an offset from the start of the display. */
+ week_start_offset = (weekday + 7 - week_view->display_start_day) % 7;
+
+ /* Set the day_offset to the result, so we move back to the
+ start of the week. */
+ day_offset = week_start_offset;
}
/* Calculate the base date, i.e. the first day shown when the
@@ -1094,7 +1118,7 @@ e_week_view_set_first_day_shown (EWeekView *week_view,
GDate *date)
{
GDate base_date;
- gint day_offset, num_days;
+ gint weekday, day_offset, num_days;
gboolean update_adjustment_value = FALSE;
guint32 old_selection_start_julian = 0, old_selection_end_julian = 0;
struct tm start_tm;
@@ -1112,8 +1136,11 @@ e_week_view_set_first_day_shown (EWeekView *week_view,
+ week_view->selection_end_day;
}
- /* Find the 1st Monday at or before the given day. */
- day_offset = g_date_weekday (date) - 1;
+ /* Calculate the weekday of the given date, 0 = Mon. */
+ weekday = g_date_weekday (date) - 1;
+
+ /* Convert it to an offset from the start of the display. */
+ day_offset = (weekday + 7 - week_view->display_start_day) % 7;
/* Calculate the base date, i.e. the first day shown when the
scrollbar adjustment value is 0. */
@@ -1224,11 +1251,11 @@ e_week_view_set_multi_week_view (EWeekView *week_view,
adjustment->page_size = page_size;
gtk_adjustment_changed (adjustment);
- /* FIXME: Need to change start date and adjustment value? */
-
- e_week_view_recalc_day_starts (week_view, week_view->day_starts[0]);
e_week_view_recalc_cell_sizes (week_view);
- e_week_view_queue_reload_events (week_view);
+
+ if (g_date_valid (&week_view->first_day_shown))
+ e_week_view_set_first_day_shown (week_view,
+ &week_view->first_day_shown);
}
@@ -1266,11 +1293,10 @@ e_week_view_set_weeks_shown (EWeekView *week_view,
adjustment->page_size = page_size;
gtk_adjustment_changed (adjustment);
- /* FIXME: Need to change start date and adjustment value? */
- e_week_view_recalc_day_starts (week_view,
- week_view->day_starts[0]);
e_week_view_recalc_cell_sizes (week_view);
- e_week_view_queue_reload_events (week_view);
+
+ if (g_date_valid (&week_view->first_day_shown))
+ e_week_view_set_first_day_shown (week_view, &week_view->first_day_shown);
}
}
@@ -1288,6 +1314,8 @@ void
e_week_view_set_compress_weekend (EWeekView *week_view,
gboolean compress)
{
+ gboolean need_reload = FALSE;
+
g_return_if_fail (E_IS_WEEK_VIEW (week_view));
if (week_view->compress_weekend == compress)
@@ -1300,8 +1328,102 @@ e_week_view_set_compress_weekend (EWeekView *week_view,
return;
e_week_view_recalc_cell_sizes (week_view);
- week_view->events_need_reshape = TRUE;
- e_week_view_check_layout (week_view);
+
+ need_reload = e_week_view_recalc_display_start_day (week_view);
+
+ /* If the display_start_day has changed we need to recalculate the
+ date range shown and reload all events, otherwise we only need to
+ do a reshape. */
+ if (need_reload) {
+ /* Recalculate the days shown and reload if necessary. */
+ if (g_date_valid (&week_view->first_day_shown))
+ e_week_view_set_first_day_shown (week_view, &week_view->first_day_shown);
+ } else {
+ week_view->events_need_reshape = TRUE;
+ e_week_view_check_layout (week_view);
+ }
+}
+
+
+/* Whether we display event end times. */
+gboolean
+e_week_view_get_show_event_end_times (EWeekView *week_view)
+{
+ g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), TRUE);
+
+ return week_view->show_event_end_times;
+}
+
+
+void
+e_week_view_set_show_event_end_times (EWeekView *week_view,
+ gboolean show)
+{
+ g_return_if_fail (E_IS_WEEK_VIEW (week_view));
+
+ if (week_view->show_event_end_times != show) {
+ week_view->show_event_end_times = show;
+ e_week_view_recalc_cell_sizes (week_view);
+ week_view->events_need_reshape = TRUE;
+ e_week_view_check_layout (week_view);
+ }
+}
+
+
+/* The first day of the week, 0 (Monday) to 6 (Sunday). */
+gint
+e_week_view_get_week_start_day (EWeekView *week_view)
+{
+ g_return_val_if_fail (E_IS_WEEK_VIEW (week_view), 0);
+
+ return week_view->week_start_day;
+}
+
+
+void
+e_week_view_set_week_start_day (EWeekView *week_view,
+ gint week_start_day)
+{
+ g_return_if_fail (E_IS_WEEK_VIEW (week_view));
+ g_return_if_fail (week_start_day >= 0);
+ g_return_if_fail (week_start_day < 7);
+
+ g_print ("In e_week_view_set_week_start_day day: %i\n", week_start_day);
+
+ if (week_view->week_start_day == week_start_day)
+ return;
+
+ week_view->week_start_day = week_start_day;
+
+ e_week_view_recalc_display_start_day (week_view);
+
+ /* Recalculate the days shown and reload if necessary. */
+ if (g_date_valid (&week_view->first_day_shown))
+ e_week_view_set_first_day_shown (week_view,
+ &week_view->first_day_shown);
+}
+
+
+static gboolean
+e_week_view_recalc_display_start_day (EWeekView *week_view)
+{
+ gint display_start_day;
+
+ /* The display start day defaults to week_start_day, but we have
+ to use Saturday if the weekend is compressed and week_start_day
+ is Sunday. */
+ display_start_day = week_view->week_start_day;
+
+ if (display_start_day == 6
+ && (!week_view->multi_week_view || week_view->compress_weekend))
+ display_start_day = 5;
+
+ if (week_view->display_start_day != display_start_day) {
+ week_view->display_start_day = display_start_day;
+ return TRUE;
+ }
+
+ return FALSE;
}
@@ -1426,7 +1548,7 @@ e_week_view_get_day_position (EWeekView *week_view,
gint *day_w,
gint *day_h)
{
- gint week, day_of_week, row;
+ gint week, day_of_week, row, col, weekend_col, box, weekend_box;
*day_x = *day_y = *day_w = *day_h = 0;
g_return_if_fail (day >= 0);
@@ -1435,7 +1557,8 @@ e_week_view_get_day_position (EWeekView *week_view,
g_return_if_fail (day < week_view->weeks_shown * 7);
week = day / 7;
- day_of_week = day % 7;
+ col = day % 7;
+ day_of_week = (week_view->display_start_day + day) % 7;
if (week_view->compress_weekend && day_of_week >= 5) {
/* In the compressed view Saturday is above Sunday and
both have just one row as opposed to 2 for all the
@@ -1446,23 +1569,41 @@ e_week_view_get_day_position (EWeekView *week_view,
} else {
*day_y = week_view->row_offsets[week * 2 + 1];
*day_h = week_view->row_heights[week * 2 + 1];
+ col--;
}
- /* Both Saturday and Sunday are in the 6th column. */
- *day_x = week_view->col_offsets[5];
- *day_w = week_view->col_widths[5];
+ /* Both Saturday and Sunday are in the same column. */
+ *day_x = week_view->col_offsets[col];
+ *day_w = week_view->col_widths[col];
} else {
+ /* If the weekend is compressed and the day is after
+ the weekend we have to move back a column. */
+ if (week_view->compress_weekend) {
+ /* Calculate where the weekend column is.
+ Note that 5 is Saturday. */
+ weekend_col = (5 + 7 - week_view->display_start_day) % 7;
+ if (col > weekend_col)
+ col--;
+ }
+
*day_y = week_view->row_offsets[week * 2];
*day_h = week_view->row_heights[week * 2]
+ week_view->row_heights[week * 2 + 1];
- *day_x = week_view->col_offsets[day_of_week];
- *day_w = week_view->col_widths[day_of_week];
+ *day_x = week_view->col_offsets[col];
+ *day_w = week_view->col_widths[col];
}
} else {
g_return_if_fail (day < 7);
- /* The week view has Mon, Tue & Wed down the left column and
- Thu, Fri & Sat/Sun down the right. */
- if (day < 3) {
+ /* Calculate which box to place the day in, from 0-5.
+ Note that in the week view the weekends are always
+ compressed and share a box. */
+ box = day;
+ day_of_week = (week_view->display_start_day + day) % 7;
+ weekend_box = (5 + 7 - week_view->display_start_day) % 7;
+ if (box > weekend_box)
+ box--;
+
+ if (box < 3) {
*day_x = week_view->col_offsets[0];
*day_w = week_view->col_widths[0];
} else {
@@ -1470,15 +1611,20 @@ e_week_view_get_day_position (EWeekView *week_view,
*day_w = week_view->col_widths[1];
}
- if (day < 5) {
- row = (day % 3) * 2;
+ row = (box % 3) * 2;
+ if (day_of_week < 5) {
*day_y = week_view->row_offsets[row];
*day_h = week_view->row_heights[row]
+ week_view->row_heights[row + 1];
+ } else if (day_of_week == 5) {
+ /* Saturday. */
+ *day_y = week_view->row_offsets[row];
+ *day_h = week_view->row_heights[row];
+
} else {
- /* Saturday & Sunday. */
- *day_y = week_view->row_offsets[day - 1];
- *day_h = week_view->row_heights[day - 1];
+ /* Sunday. */
+ *day_y = week_view->row_offsets[row + 1];
+ *day_h = week_view->row_heights[row + 1];
}
}
}
@@ -1515,7 +1661,7 @@ e_week_view_get_span_position (EWeekView *week_view,
if (span->row >= week_view->rows_per_cell)
return FALSE;
- end_day_of_week = (span->start_day + span->num_days - 1) % 7;
+ end_day_of_week = (week_view->display_start_day + span->start_day + span->num_days - 1) % 7;
num_days = span->num_days;
/* Check if the row will not be visible in compressed cells. */
if (span->row >= week_view->rows_per_compressed_cell) {
@@ -1642,8 +1788,9 @@ e_week_view_on_button_release (GtkWidget *widget,
gdk_pointer_ungrab (event->time);
start = week_view->day_starts[week_view->selection_start_day];
end = week_view->day_starts[week_view->selection_end_day + 1];
- gnome_calendar_set_selected_time_range (week_view->calendar,
- start, end);
+
+ if (week_view->calendar)
+ gnome_calendar_set_selected_time_range (week_view->calendar, start, end);
}
return FALSE;
@@ -1685,6 +1832,7 @@ e_week_view_convert_position_to_day (EWeekView *week_view,
gint y)
{
gint col, row, grid_x = -1, grid_y = -1, week, day;
+ gint weekend_col, box, weekend_box;
/* First we convert it to a grid position. */
for (col = 0; col <= week_view->columns; col++) {
@@ -1708,19 +1856,23 @@ e_week_view_convert_position_to_day (EWeekView *week_view,
/* Now convert the grid position to a week and day. */
if (week_view->multi_week_view) {
week = grid_y / 2;
- if (week_view->compress_weekend && grid_x == 5
- && grid_y % 2 == 1)
- day = 6;
- else
- day = grid_x;
+ day = grid_x;
+
+ if (week_view->compress_weekend) {
+ weekend_col = (5 + 7 - week_view->display_start_day) % 7;
+ if (grid_x > weekend_col
+ || (grid_x == weekend_col && grid_y % 2 == 1))
+ day++;
+ }
} else {
week = 0;
- if (grid_x == 0)
- day = grid_y / 2;
- else if (grid_y == 5)
- day = 6;
- else
- day = grid_y / 2 + 3;
+
+ box = grid_x * 3 + grid_y / 2;
+ weekend_box = (5 + 7 - week_view->display_start_day) % 7;
+ day = box;
+ if (box > weekend_box
+ ||( box == weekend_box && grid_y % 2 == 1))
+ day++;
}
return week * 7 + day;
@@ -1814,11 +1966,15 @@ e_week_view_reload_events (EWeekView *week_view)
if (!(week_view->client && cal_client_is_loaded (week_view->client)))
return;
- if (week_view->calendar
- && g_date_valid (&week_view->first_day_shown)) {
+ /* Only load events if the date range has been set. */
+ if (g_date_valid (&week_view->first_day_shown)) {
num_days = week_view->multi_week_view
? week_view->weeks_shown * 7 : 7;
+#if 0
+ g_print ("EWeekView (%s) generating instances\n",
+ week_view->multi_week_view ? "Month View" : "Week View");
+#endif
cal_client_generate_instances (week_view->client,
CALOBJ_TYPE_EVENT,
week_view->day_starts[0],
@@ -2157,7 +2313,7 @@ e_week_view_reshape_events (EWeekView *week_view)
num_days = week_view->multi_week_view ? week_view->weeks_shown * 7 : 7;
for (day = 0; day < num_days; day++) {
- is_weekend = (day % 7 >= 5) ? TRUE : FALSE;
+ is_weekend = ((week_view->display_start_day + day) % 7 >= 5) ? TRUE : FALSE;
if (!is_weekend || (week_view->multi_week_view
&& !week_view->compress_weekend))
max_rows = week_view->rows_per_cell;
@@ -2385,8 +2541,7 @@ e_week_view_reshape_event_span (EWeekView *week_view,
"clip_width", (gdouble) text_w,
"clip_height", (gdouble) text_h,
NULL);
- e_canvas_item_move_absolute(span->text_item,
- text_x, text_y);
+ e_canvas_item_move_absolute (span->text_item, text_x, text_y);
}
@@ -2424,26 +2579,36 @@ e_week_view_find_day (EWeekView *week_view,
}
-/* This returns the last day in the same span as the given day. A span is all
- the days which are displayed next to each other from left to right.
- In the week view all spans are only 1 day, since Tuesday is below Monday
- rather than beside it etc. In the month view, if the weekends are not
- compressed then each week is a span, otherwise Monday to Saturday of each
- week is a span, and the Sundays are separate spans. */
+/* This returns the last possible day in the same span as the given day.
+ A span is all the days which are displayed next to each other from left to
+ right. In the week view all spans are only 1 day, since Tuesday is below
+ Monday rather than beside it etc. In the month view, if the weekends are not
+ compressed then each week is a span, otherwise we have to break a span up
+ on Saturday, use a separate span for Sunday, and start again on Monday. */
static gint
e_week_view_find_span_end (EWeekView *week_view,
gint day)
{
- gint week, day_of_week, end_day;
+ gint week, col, sat_col, end_col;
if (week_view->multi_week_view) {
week = day / 7;
- day_of_week = day % 7;
- if (week_view->compress_weekend && day_of_week <= 5)
- end_day = 5;
- else
- end_day = 6;
- return week * 7 + end_day;
+ col = day % 7;
+
+ /* We default to the last column in the row. */
+ end_col = 6;
+
+ /* If the weekend is compressed we must end any spans on
+ Saturday and Sunday. */
+ if (week_view->compress_weekend) {
+ sat_col = (5 + 7 - week_view->display_start_day) % 7;
+ if (col <= sat_col)
+ end_col = sat_col;
+ else if (col == sat_col + 1)
+ end_col = sat_col + 1;
+ }
+
+ return week * 7 + end_col;
} else {
return day;
}
@@ -2492,8 +2657,8 @@ e_week_view_on_adjustment_changed (GtkAdjustment *adjustment,
if (week_view->selection_start_day != -1) {
start = week_view->day_starts[week_view->selection_start_day];
end = week_view->day_starts[week_view->selection_end_day + 1];
- gnome_calendar_set_selected_time_range (week_view->calendar,
- start, end);
+ if (week_view->calendar)
+ gnome_calendar_set_selected_time_range (week_view->calendar, start, end);
}
gtk_widget_queue_draw (week_view->main_canvas);
@@ -2618,7 +2783,7 @@ e_week_view_on_text_item_event (GnomeCanvasItem *item,
g_warning ("No GdkEvent");
/* FIXME: Remember the day offset from the start of
- the event. */
+ the event, for DnD. */
return TRUE;
}
@@ -3014,7 +3179,11 @@ e_week_view_on_new_appointment (GtkWidget *widget, gpointer data)
cal_component_commit_sequence (comp);
- gnome_calendar_edit_object (week_view->calendar, comp);
+ if (week_view->calendar)
+ gnome_calendar_edit_object (week_view->calendar, comp);
+ else
+ g_warning ("Calendar not set");
+
gtk_object_unref (GTK_OBJECT (comp));
}
@@ -3033,7 +3202,10 @@ e_week_view_on_edit_appointment (GtkWidget *widget, gpointer data)
event = &g_array_index (week_view->events, EWeekViewEvent,
week_view->popup_event_num);
- gnome_calendar_edit_object (week_view->calendar, event->comp);
+ if (week_view->calendar)
+ gnome_calendar_edit_object (week_view->calendar, event->comp);
+ else
+ g_warning ("Calendar not set");
}
@@ -3154,9 +3326,12 @@ e_week_view_on_jump_button_event (GnomeCanvasItem *item,
if (event->type == GDK_BUTTON_PRESS) {
for (day = 0; day < E_WEEK_VIEW_MAX_WEEKS * 7; day++) {
if (item == week_view->jump_buttons[day]) {
- gnome_calendar_dayjump
- (week_view->calendar,
- week_view->day_starts[day]);
+ if (week_view->calendar)
+ gnome_calendar_dayjump
+ (week_view->calendar,
+ week_view->day_starts[day]);
+ else
+ g_warning ("Calendar not set");
return TRUE;
}
}
diff --git a/calendar/gui/e-week-view.h b/calendar/gui/e-week-view.h
index e4d5ee72db..ccd11bf84a 100644
--- a/calendar/gui/e-week-view.h
+++ b/calendar/gui/e-week-view.h
@@ -207,6 +207,17 @@ struct _EWeekView
they are always compressed into 1 cell in the week view. */
gboolean compress_weekend;
+ /* Whether we use show event end times. */
+ gboolean show_event_end_times;
+
+ /* The first day of the week, 0 (Monday) to 6 (Sunday). */
+ gint week_start_day;
+
+ /* The first day of the week we display, 0 (Monday) to 6 (Sunday).
+ This will usually be week_start_day, but if the weekend is
+ compressed, and week_start_day is Sunday we have to use Saturday. */
+ gint display_start_day;
+
/* The vertical offset of the events from the top of the cells. */
gint events_y_offset;
@@ -356,6 +367,18 @@ gboolean e_week_view_get_compress_weekend (EWeekView *week_view);
void e_week_view_set_compress_weekend (EWeekView *week_view,
gboolean compress);
+/* Whether we display event end times. */
+gboolean e_week_view_get_show_event_end_times (EWeekView *week_view);
+void e_week_view_set_show_event_end_times (EWeekView *week_view,
+ gboolean show);
+
+/* The first day of the week, 0 (Monday) to 6 (Sunday). */
+gint e_week_view_get_week_start_day (EWeekView *week_view);
+void e_week_view_set_week_start_day (EWeekView *week_view,
+ gint week_start_day);
+
+
+
/*
* Internal functions called by the associated canvas items.
*/
diff --git a/calendar/gui/event-editor.c b/calendar/gui/event-editor.c
index 707614e899..6e481c3103 100644
--- a/calendar/gui/event-editor.c
+++ b/calendar/gui/event-editor.c
@@ -1,3 +1,5 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
/* Evolution calendar - Event editor dialog
*
* Copyright (C) 2000 Helix Code, Inc.
@@ -31,6 +33,7 @@
#include "calendar-config.h"
#include "event-editor.h"
#include "e-meeting-edit.h"
+#include "calendar-config.h"
#include "tag-calendar.h"
#include "weekday-picker.h"
@@ -1434,7 +1437,6 @@ fill_recurrence_widgets (EventEditor *ee)
cal_component_get_rrule_list (priv->comp, &rrule_list);
len = g_slist_length (rrule_list);
-
if (len > 1
|| cal_component_has_rdates (priv->comp)
|| cal_component_has_exrules (priv->comp))
@@ -2099,24 +2101,35 @@ dialog_to_comp_object (EventEditor *ee, CalComponent *comp)
cal_component_set_description_list (comp, &l);
}
+ /* FIXME: Do we need to free str?? */
/* Dates */
date.value = g_new (struct icaltimetype, 1);
- t = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
- *date.value = icaltime_from_timet (t, FALSE, FALSE);
date.tzid = NULL;
- cal_component_set_dtstart (comp, &date);
+
+ t = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
+ if (t != -1) {
+ *date.value = icaltime_from_timet (t, FALSE, FALSE);
+ cal_component_set_dtstart (comp, &date);
+ } else {
+ /* FIXME: What do we do here? */
+ }
/* If the all_day toggle is set, the end date is inclusive of the
entire day on which it points to. */
all_day_event = e_dialog_toggle_get (priv->all_day_event);
t = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
- if (all_day_event)
- t = time_day_end (t);
+ if (t != -1) {
+ if (all_day_event)
+ t = time_day_end (t);
+
+ *date.value = icaltime_from_timet (t, FALSE, FALSE);
+ cal_component_set_dtend (comp, &date);
+ } else {
+ /* FIXME: What do we do here? */
+ }
- *date.value = icaltime_from_timet (t, FALSE, FALSE);
- cal_component_set_dtend (comp, &date);
g_free (date.value);
#if 0
@@ -2676,8 +2689,20 @@ check_all_day (EventEditor *ee)
priv = ee->priv;
+ /* Currently we just return if the date is not set or not valid.
+ I'm not entirely sure this is the corrent thing to do. */
ev_start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
+ g_return_if_fail (ev_start != -1);
+
ev_end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
+ g_return_if_fail (ev_end != -1);
+
+#if 0
+ /* all day event checkbox */
+ if (time_day_begin (ev_start) == ev_start
+ && time_day_begin (ev_end) == ev_end)
+ e_dialog_toggle_set (priv->all_day_event, TRUE);
+#endif
start_begin_day = time_day_begin (ev_start);
end_begin_day = time_day_begin (ev_end);
@@ -2685,6 +2710,8 @@ check_all_day (EventEditor *ee)
tm_start = *localtime (&start_begin_day);
tm_end = *localtime (&end_begin_day);
+ /* FIXME: This will only set all_day to TRUE if the event lasts 1 day.
+ But we also want it TRUE for multiple-day events. */
tm_end.tm_mday--;
if (mktime (&tm_start) == mktime (&tm_end))
all_day = TRUE;
@@ -2711,11 +2738,25 @@ set_all_day (GtkWidget *toggle, EventEditor *ee)
priv = ee->priv;
- /* If the all_day toggle is set, the end date is inclusive of the
- entire day on which it points to. */
+ /* When the all_day toggle is on, the start date is rounded down to
+ the start of the day, and end date is rounded down to the start of
+ the day on which the event ends. The event is then taken to be
+ inclusive of the days between the start and end days.
+ Note that if the event end is at midnight, we do not round it down
+ to the previous day, since if we do that and the user repeatedly
+ turns the all_day toggle on and off, the event keeps shrinking.
+ (We'd also need to make sure we didn't adjust the time when the
+ radio button is initially set.)
+
+ When the all_day_toggle is off, we set the event start to the start
+ of the working day, and if the event end is on or before the day
+ of the event start we set it to one hour after the event start. */
all_day = GTK_TOGGLE_BUTTON (toggle)->active;
+ /* Start time. */
start_t = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
+ g_return_if_fail (start_t != -1);
+
start_tm = *localtime (&start_t);
start_tm.tm_min = 0;
start_tm.tm_sec = 0;
@@ -2728,25 +2769,37 @@ set_all_day (GtkWidget *toggle, EventEditor *ee)
/* will set recur start too */
e_date_edit_set_time (E_DATE_EDIT (priv->start_time), mktime (&start_tm));
+ /* End time. */
end_t = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
+ g_return_if_fail (end_t != -1);
+
end_tm = *localtime (&end_t);
end_tm.tm_min = 0;
end_tm.tm_sec = 0;
if (all_day) {
- /* mktime() will fix this if we go past the end of the month.*/
end_tm.tm_hour = 0;
} else {
- if (end_tm.tm_year == start_tm.tm_year
- && end_tm.tm_mon == start_tm.tm_mon
- && end_tm.tm_mday == start_tm.tm_mday
- && end_tm.tm_hour <= start_tm.tm_hour)
+ /* If the event end is now before the event start, make it
+ end one hour after the start. mktime() will fix any
+ overflows. */
+ if (end_tm.tm_year < start_tm.tm_year
+ || (end_tm.tm_year == start_tm.tm_year
+ && end_tm.tm_mon < start_tm.tm_mon)
+ || (end_tm.tm_year == start_tm.tm_year
+ && end_tm.tm_mon == start_tm.tm_mon
+ && end_tm.tm_mday <= start_tm.tm_mday)) {
+ end_tm.tm_year = start_tm.tm_year;
+ end_tm.tm_mon = start_tm.tm_mon;
+ end_tm.tm_mday = start_tm.tm_mday;
end_tm.tm_hour = start_tm.tm_hour + 1;
+ }
}
+ e_date_edit_set_time (E_DATE_EDIT (priv->end_time), mktime (&end_tm));
+
e_date_edit_set_show_time (E_DATE_EDIT (priv->start_time), !all_day);
e_date_edit_set_show_time (E_DATE_EDIT (priv->end_time), !all_day);
- e_date_edit_set_time (E_DATE_EDIT (priv->end_time), mktime (&end_tm));
}
/* Callback used when the start or end date widgets change. We check that the
@@ -2766,7 +2819,9 @@ date_changed_cb (EDateEdit *dedit, gpointer data)
/* Ensure that start < end */
start = e_date_edit_get_time (E_DATE_EDIT (priv->start_time));
+ g_return_if_fail (start != -1);
end = e_date_edit_get_time (E_DATE_EDIT (priv->end_time));
+ g_return_if_fail (end != -1);
if (start > end) {
tm_start = *localtime (&start);
@@ -2943,7 +2998,7 @@ date_edit_new (time_t the_time, int show_time)
dedit = e_date_edit_new ();
/* FIXME: Set other options. */
e_date_edit_set_show_time (E_DATE_EDIT (dedit), show_time);
- e_date_edit_set_time_popup_range (E_DATE_EDIT (dedit), 8, 18);
+ e_date_edit_set_time_popup_range (E_DATE_EDIT (dedit), calendar_config_get_day_start_hour (), calendar_config_get_day_end_hour ());
return dedit;
}
diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c
index f29a27800c..802f76341c 100644
--- a/calendar/gui/gnome-cal.c
+++ b/calendar/gui/gnome-cal.c
@@ -310,10 +310,10 @@ gnome_calendar_init (GnomeCalendar *gcal)
priv->current_view_type = VIEW_NOT_SET;
priv->range_selected = FALSE;
+ setup_widgets (gcal);
+
priv->selection_start_time = time_day_begin (time (NULL));
priv->selection_end_time = time_add_day (priv->selection_start_time, 1);
-
- setup_widgets (gcal);
}
/* Used from g_hash_table_foreach(); frees an object alarms entry */
@@ -1582,19 +1582,21 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
/* Note that this is 0 (Sun) to 6 (Sat). */
week_start_day = calendar_config_get_week_start_day ();
- /* FIXME: Add support for these. */
-#if 0
+
+ /* Convert it to 0 (Mon) to 6 (Sun), which is what we use. */
+ week_start_day = (week_start_day + 6) % 7;
+
+ g_print ("Setting week start day to %i (0=Sun)\n", week_start_day);
e_day_view_set_week_start_day (E_DAY_VIEW (priv->day_view),
- week_start_day);
+ week_start_day);
e_day_view_set_week_start_day (E_DAY_VIEW (priv->work_week_view),
- week_start_day);
+ week_start_day);
e_week_view_set_week_start_day (E_WEEK_VIEW (priv->week_view),
week_start_day);
e_week_view_set_week_start_day (E_WEEK_VIEW (priv->month_view),
week_start_day);
-#endif
gnome_canvas_item_set (GNOME_CANVAS_ITEM (E_CALENDAR (priv->date_navigator)->calitem),
- "week_start_day", (week_start_day + 6) % 7,
+ "week_start_day", week_start_day,
NULL);
start_hour = calendar_config_get_day_start_hour ();
@@ -1628,17 +1630,14 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
time_divisions);
show_event_end = calendar_config_get_show_event_end ();
- /* FIXME: Add support for these. */
-#if 0
- e_day_view_set_show_event_end (E_DAY_VIEW (priv->day_view),
- show_event_end);
- e_day_view_set_show_event_end (E_DAY_VIEW (priv->work_week_view),
- show_event_end);
- e_week_view_set_show_event_end (E_WEEK_VIEW (priv->week_view),
- show_event_end);
- e_week_view_set_show_event_end (E_WEEK_VIEW (priv->month_view),
- show_event_end);
-#endif
+ e_day_view_set_show_event_end_times (E_DAY_VIEW (priv->day_view),
+ show_event_end);
+ e_day_view_set_show_event_end_times (E_DAY_VIEW (priv->work_week_view),
+ show_event_end);
+ e_week_view_set_show_event_end_times (E_WEEK_VIEW (priv->week_view),
+ show_event_end);
+ e_week_view_set_show_event_end_times (E_WEEK_VIEW (priv->month_view),
+ show_event_end);
compress_weekend = calendar_config_get_compress_weekend ();
e_week_view_set_compress_weekend (E_WEEK_VIEW (priv->month_view),
@@ -1657,6 +1656,10 @@ gnome_calendar_update_config_settings (GnomeCalendar *gcal,
} else {
gnome_calendar_update_paned_quanta (gcal);
}
+
+ /* The range of days shown may have changed, so we update the date
+ navigator if needed. */
+ gnome_calendar_update_date_navigator (gcal);
}
diff --git a/calendar/gui/tag-calendar.c b/calendar/gui/tag-calendar.c
index be77090f71..658bedc661 100644
--- a/calendar/gui/tag-calendar.c
+++ b/calendar/gui/tag-calendar.c
@@ -60,7 +60,7 @@ prepare_tag (ECalendar *ecal, struct calendar_tag_closure *c)
end_tm.tm_year = end_year - 1900;
end_tm.tm_mon = end_month;
- end_tm.tm_mday = end_day;
+ end_tm.tm_mday = end_day + 1;
end_tm.tm_hour = 0;
end_tm.tm_min = 0;
end_tm.tm_sec = 0;
@@ -125,6 +125,9 @@ tag_calendar_by_client (ECalendar *ecal, CalClient *client)
if (!cal_client_is_loaded (client))
return;
+#if 0
+ g_print ("DateNavigator generating instances\n");
+#endif
cal_client_generate_instances (client, CALOBJ_TYPE_EVENT,
c.start_time, c.end_time,
tag_calendar_cb, &c);
@@ -153,5 +156,8 @@ tag_calendar_by_comp (ECalendar *ecal, CalComponent *comp)
return;
prepare_tag (ecal, &c);
+#if 0
+ g_print ("DateNavigator generating instances\n");
+#endif
cal_recur_generate_instances (comp, c.start_time, c.end_time, tag_calendar_cb, &c);
}