From 6cc1ca709616dafc050dc29e10f26686ac3e4caa Mon Sep 17 00:00:00 2001 From: Damon Chaplin Date: Tue, 30 Oct 2001 12:59:28 +0000 Subject: updated code to handle DATE values. 2001-10-30 Damon Chaplin * gui/dialogs/schedule-page.c: * gui/dialogs/event-page.c: * gui/dialogs/comp-editor-util.c: updated code to handle DATE values. * gui/gnome-cal.c (gnome_calendar_new_appointment_for): * gui/e-day-view.c (e_day_view_key_press): updated DATE code. * gui/e-cell-date-edit-text.c: * gui/calendar-model.c: updated to support DATE values. * cal-util/cal-recur.c (cal_recur_generate_instances_of_rule): updated to use DATE values in same way as Outlook - i.e. the DTEND date is not included entirely. Though I did make it so that if the DTSTART and DTEND used the same DATE value, it includes the entire day. So 1-day events should be the same. Long All-Day events will be 1 day shorter. * cal-util/cal-component.c (cal_component_get_start_plus_duration): don't subtract a day from the end date. * gui/tasks-control.c: updated the EPixmap paths for Cut/Copy etc. Removed Print & Print Preview paths, since we don't have menu commands for these any more. svn path=/trunk/; revision=14456 --- calendar/ChangeLog | 26 +++++++++++++++++++++ calendar/cal-util/cal-component.c | 5 +---- calendar/cal-util/cal-recur.c | 29 ++++++++++++++++++++---- calendar/gui/calendar-model.c | 30 +++++++++++++++++++------ calendar/gui/dialogs/comp-editor-util.c | 40 ++++++++++++++++++++------------- calendar/gui/dialogs/event-page.c | 21 ++++++++++++----- calendar/gui/dialogs/schedule-page.c | 14 +++++++++--- calendar/gui/e-cell-date-edit-text.c | 29 +++++++++++++++++------- calendar/gui/e-day-view.c | 2 -- calendar/gui/gnome-cal.c | 8 +++---- calendar/gui/tasks-control.c | 10 ++++----- 11 files changed, 156 insertions(+), 58 deletions(-) (limited to 'calendar') diff --git a/calendar/ChangeLog b/calendar/ChangeLog index f66e527185..4981373c07 100644 --- a/calendar/ChangeLog +++ b/calendar/ChangeLog @@ -1,3 +1,29 @@ +2001-10-30 Damon Chaplin + + * gui/dialogs/schedule-page.c: + * gui/dialogs/event-page.c: + * gui/dialogs/comp-editor-util.c: updated code to handle DATE values. + + * gui/gnome-cal.c (gnome_calendar_new_appointment_for): + * gui/e-day-view.c (e_day_view_key_press): updated DATE code. + + * gui/e-cell-date-edit-text.c: + * gui/calendar-model.c: updated to support DATE values. + + * cal-util/cal-recur.c (cal_recur_generate_instances_of_rule): updated + to use DATE values in same way as Outlook - i.e. the DTEND date is + not included entirely. Though I did make it so that if the DTSTART + and DTEND used the same DATE value, it includes the entire day. + So 1-day events should be the same. Long All-Day events will be + 1 day shorter. + + * cal-util/cal-component.c (cal_component_get_start_plus_duration): + don't subtract a day from the end date. + + * gui/tasks-control.c: updated the EPixmap paths for Cut/Copy etc. + Removed Print & Print Preview paths, since we don't have menu commands + for these any more. + 2001-10-30 Federico Mena Quintero Fix bug #10016. diff --git a/calendar/cal-util/cal-component.c b/calendar/cal-util/cal-component.c index 6e652b4851..5fc5addf19 100644 --- a/calendar/cal-util/cal-component.c +++ b/calendar/cal-util/cal-component.c @@ -2078,15 +2078,12 @@ cal_component_get_start_plus_duration (CalComponent *comp, /* If DTSTART is a DATE value, then we need to check if the DURATION includes any hours, minutes or seconds. If it does, we need to - make the DTEND/DUE a DATE-TIME value. If not, we need to subtract - one from the days, since the end date will be inclusive. */ + make the DTEND/DUE a DATE-TIME value. */ duration.days += duration.weeks * 7; if (dt->value->is_date) { if (duration.hours != 0 || duration.minutes != 0 || duration.seconds != 0) { dt->value->is_date = 0; - } else { - duration.days--; } } diff --git a/calendar/cal-util/cal-recur.c b/calendar/cal-util/cal-recur.c index d17c626274..cfccdaf19f 100644 --- a/calendar/cal-util/cal-recur.c +++ b/calendar/cal-util/cal-recur.c @@ -707,18 +707,38 @@ cal_recur_generate_instances_of_rule (CalComponent *comp, if (start == -1) start = dtstart_time; - /* If there is no DTEND, then use the same as the DTSTART. For - DATE-TIME values that means we will just have a single point in - time. For DATE values it means we end up with the entire day. */ - if (!dtend.value) + if (dtend.value) { + /* If both DTSTART and DTEND are DATE values, and they are the + same day, we add 1 day to DTEND. This means that most + events created with the old Evolution behavior will still + work OK. I'm not sure what Outlook does in this case. */ + if (dtstart.value->is_date && dtend.value->is_date) { + if (icaltime_compare_date_only (*dtstart.value, + *dtend.value) == 0) { + icaltime_adjust (dtend.value, 1, 0, 0, 0); + } + } + } else { + /* If there is no DTEND, then if DTSTART is a DATE-TIME value + we use the same time (so we have a single point in time). + If DTSTART is a DATE value we add 1 day. */ + dtend.value = g_new (struct icaltimetype, 1); *dtend.value = *dtstart.value; + if (dtstart.value->is_date) { + icaltime_adjust (dtend.value, 1, 0, 0, 0); + } + } + if (dtend.tzid && !dtend.value->is_date) { end_zone = (*tz_cb) (dtend.tzid, tz_cb_data); } else { end_zone = default_timezone; } + /* We don't do this any more, since Outlook assumes that the DTEND + date is not included. */ +#if 0 /* If DTEND is a DATE value, we add 1 day to it so that it includes the entire day. */ if (dtend.value->is_date) { @@ -727,6 +747,7 @@ cal_recur_generate_instances_of_rule (CalComponent *comp, dtend.value->second = 0; icaltime_adjust (dtend.value, 1, 0, 0, 0); } +#endif dtend_time = icaltime_as_timet_with_zone (*dtend.value, end_zone); /* If there is no recurrence, just call the callback if the event diff --git a/calendar/gui/calendar-model.c b/calendar/gui/calendar-model.c index 62d04a0d70..3d62857b82 100644 --- a/calendar/gui/calendar-model.c +++ b/calendar/gui/calendar-model.c @@ -495,6 +495,13 @@ get_date_edit_value (CalendarModel *model, CalComponent *comp, CalClientGetStatus status; icaltimezone *zone; + /* For a DTEND with a DATE value, we subtract 1 from + the day to display it. */ + if (col == CAL_COMPONENT_FIELD_DTEND + && dt.value->is_date) { + icaltime_adjust (dt.value, -1, 0, 0, 0); + } + *value = g_new (ECellDateEditValue, 1); (*value)->tt = *dt.value; @@ -1008,7 +1015,8 @@ set_completed (CalendarModel *model, CalComponent *comp, const void *value) /* Sets a CalComponentDateTime value */ static void set_datetime (CalendarModel *model, CalComponent *comp, const void *value, - void (* set_func) (CalComponent *comp, CalComponentDateTime *dt)) + void (* set_func) (CalComponent *comp, CalComponentDateTime *dt), + gboolean is_dtend) { ECellDateEditValue *dv = (ECellDateEditValue*) value; @@ -1020,6 +1028,11 @@ set_datetime (CalendarModel *model, CalComponent *comp, const void *value, dt.value = &dv->tt; dt.tzid = icaltimezone_get_tzid (dv->zone); + /* For a DTEND with a DATE value, we add 1 day to it. */ + if (is_dtend && dt.value->is_date) { + icaltime_adjust (dt.value, 1, 0, 0, 0); + } + (* set_func) (comp, &dt); } } @@ -1242,16 +1255,19 @@ calendar_model_set_value_at (ETableModel *etm, int col, int row, const void *val case CAL_COMPONENT_FIELD_DTEND: /* FIXME: Need to reset dtstart if dtend happens before it */ - set_datetime (model, comp, value, cal_component_set_dtend); + set_datetime (model, comp, value, cal_component_set_dtend, + TRUE); break; case CAL_COMPONENT_FIELD_DTSTART: /* FIXME: Need to reset dtend if dtstart happens after it */ - set_datetime (model, comp, value, cal_component_set_dtstart); + set_datetime (model, comp, value, cal_component_set_dtstart, + FALSE); break; case CAL_COMPONENT_FIELD_DUE: - set_datetime (model, comp, value, cal_component_set_due); + set_datetime (model, comp, value, cal_component_set_due, + FALSE); break; case CAL_COMPONENT_FIELD_GEO: @@ -1362,10 +1378,10 @@ calendar_model_append_row (ETableModel *etm, ETableModel *source, gint row) set_classification (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_CLASSIFICATION, row)); set_completed (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_COMPLETED, row)); /* FIXME: Need to reset dtstart if dtend happens before it */ - set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DTEND, row), cal_component_set_dtend); + set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DTEND, row), cal_component_set_dtend, TRUE); /* FIXME: Need to reset dtend if dtstart happens after it */ - set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DTSTART, row), cal_component_set_dtstart); - set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DUE, row), cal_component_set_due); + set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DTSTART, row), cal_component_set_dtstart, FALSE); + set_datetime (model, comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_DUE, row), cal_component_set_due, FALSE); set_geo (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_GEO, row)); set_percent (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_PERCENT, row)); set_priority (comp, e_table_model_value_at(source, CAL_COMPONENT_FIELD_PRIORITY, row)); diff --git a/calendar/gui/dialogs/comp-editor-util.c b/calendar/gui/dialogs/comp-editor-util.c index 751e23dbcf..34d4e71e81 100644 --- a/calendar/gui/dialogs/comp-editor-util.c +++ b/calendar/gui/dialogs/comp-editor-util.c @@ -112,11 +112,13 @@ comp_editor_free_dates (CompEditorPageDates *dates) } +/* dtstart is only passed in if tt is the dtend. */ static void write_label_piece (struct icaltimetype *tt, char *buffer, int size, - char *stext, char *etext) + char *stext, char *etext, struct icaltimetype *dtstart) { struct tm tmp_tm = { 0 }; + struct icaltimetype tt_copy = *tt; int len; /* FIXME: May want to convert the time to an appropriate zone. */ @@ -124,20 +126,28 @@ write_label_piece (struct icaltimetype *tt, char *buffer, int size, if (stext != NULL) strcat (buffer, stext); - tmp_tm.tm_year = tt->year - 1900; - tmp_tm.tm_mon = tt->month - 1; - tmp_tm.tm_mday = tt->day; - tmp_tm.tm_hour = tt->hour; - tmp_tm.tm_min = tt->minute; - tmp_tm.tm_sec = tt->second; + /* If we are writing the DTEND (i.e. DTSTART is set), and + DTEND > DTSTART, subtract 1 day. The DTEND date is not inclusive. */ + if (tt_copy.is_date && dtstart + && icaltime_compare_date_only (tt_copy, *dtstart) > 0) { + icaltime_adjust (&tt_copy, -1, 0, 0, 0); + } + + tmp_tm.tm_year = tt_copy.year - 1900; + tmp_tm.tm_mon = tt_copy.month - 1; + tmp_tm.tm_mday = tt_copy.day; + tmp_tm.tm_hour = tt_copy.hour; + tmp_tm.tm_min = tt_copy.minute; + tmp_tm.tm_sec = tt_copy.second; tmp_tm.tm_isdst = -1; - tmp_tm.tm_wday = time_day_of_week (tt->day, tt->month - 1, tt->year); + tmp_tm.tm_wday = time_day_of_week (tt_copy.day, tt_copy.month - 1, + tt_copy.year); len = strlen (buffer); e_time_format_date_and_time (&tmp_tm, calendar_config_get_24_hour_format (), - FALSE, FALSE, + !tt_copy.is_date, FALSE, &buffer[len], size - len); if (etext != NULL) strcat (buffer, etext); @@ -171,24 +181,24 @@ comp_editor_date_label (CompEditorPageDates *dates, GtkWidget *label) if (start_set) write_label_piece (dates->start->value, buffer, 1024, - NULL, NULL); + NULL, NULL, NULL); if (start_set && end_set) write_label_piece (dates->end->value, buffer, 1024, - _(" to "), NULL); + _(" to "), NULL, dates->start->value); if (complete_set) { if (start_set) - write_label_piece (dates->complete, buffer, 1024, _(" (Completed "), ")"); + write_label_piece (dates->complete, buffer, 1024, _(" (Completed "), ")", NULL); else - write_label_piece (dates->complete, buffer, 1024, _("Completed "), NULL); + write_label_piece (dates->complete, buffer, 1024, _("Completed "), NULL, NULL); } if (due_set && dates->complete == NULL) { if (start_set) - write_label_piece (dates->due->value, buffer, 1024, _(" (Due "), ")"); + write_label_piece (dates->due->value, buffer, 1024, _(" (Due "), ")", NULL); else - write_label_piece (dates->due->value, buffer, 1024, _("Due "), NULL); + write_label_piece (dates->due->value, buffer, 1024, _("Due "), NULL, NULL); } gtk_label_set_text (GTK_LABEL (label), buffer); diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c index 72b6fe9871..191f87e306 100644 --- a/calendar/gui/dialogs/event-page.c +++ b/calendar/gui/dialogs/event-page.c @@ -332,15 +332,15 @@ update_time (EventPage *epage, CalComponentDateTime *start_date, CalComponentDat } /* If both times are DATE values, we set the 'All Day Event' checkbox. - If not, if the end time is a DATE we convert it to the end of the - day. */ + Also, if DTEND is after DTSTART, we subtract 1 day from it. */ all_day_event = FALSE; start_tt = start_date->value; end_tt = end_date->value; if (start_tt->is_date && end_tt->is_date) { all_day_event = TRUE; - } else if (end_tt->is_date) { - icaltime_adjust (end_tt, 1, 0, 0, 0); + if (icaltime_compare_date_only (*end_tt, *start_tt) > 0) { + icaltime_adjust (end_tt, -1, 0, 0, 0); + } } set_all_day (epage, all_day_event); @@ -647,6 +647,9 @@ event_page_fill_component (CompEditorPage *page, CalComponent *comp) if (all_day_event) { start_tt.is_date = TRUE; end_tt.is_date = TRUE; + + /* We have to add 1 day to DTEND, as it is not inclusive. */ + icaltime_adjust (&end_tt, 1, 0, 0, 0); } else { icaltimezone *start_zone, *end_zone; @@ -805,6 +808,9 @@ summary_changed_cb (GtkEditable *editable, gpointer data) } +/* Note that this assumes that the start_tt and end_tt passed to it are the + dates visible to the user. For DATE values, we have to add 1 day to the + end_tt before emitting the signal. */ static void notify_dates_changed (EventPage *epage, struct icaltimetype *start_tt, struct icaltimetype *end_tt) @@ -822,7 +828,11 @@ notify_dates_changed (EventPage *epage, struct icaltimetype *start_tt, start_dt.value = start_tt; end_dt.value = end_tt; - if (!all_day_event) { + if (all_day_event) { + /* The actual DTEND is 1 day after the displayed date for + DATE values. */ + icaltime_adjust (end_tt, 1, 0, 0, 0); + } else { start_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); end_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->end_timezone)); } @@ -835,6 +845,7 @@ notify_dates_changed (EventPage *epage, struct icaltimetype *start_tt, dates.due = NULL; dates.complete = NULL; + comp_editor_page_notify_dates_changed (COMP_EDITOR_PAGE (epage), &dates); } diff --git a/calendar/gui/dialogs/schedule-page.c b/calendar/gui/dialogs/schedule-page.c index 08cc57e48b..df7ca0c702 100644 --- a/calendar/gui/dialogs/schedule-page.c +++ b/calendar/gui/dialogs/schedule-page.c @@ -268,7 +268,14 @@ update_time (SchedulePage *spage, CalComponentDateTime *start_date, CalComponent all_day = (start_tt.is_date && end_tt.is_date) ? TRUE : FALSE; - /* For All-Day events, we set the time field to empty. */ + /* For All Day Events, if DTEND is after DTSTART, we subtract 1 day + from it. */ + if (all_day) { + if (icaltime_compare_date_only (end_tt, start_tt) > 0) { + icaltime_adjust (&end_tt, -1, 0, 0, 0); + } + } + e_date_edit_set_date (E_DATE_EDIT (priv->sel->start_date_edit), start_tt.year, start_tt.month, start_tt.day); e_date_edit_set_time_of_day (E_DATE_EDIT (priv->sel->start_date_edit), @@ -484,7 +491,6 @@ time_changed_cb (GtkWidget *widget, gpointer data) CalComponentDateTime start_dt, end_dt; struct icaltimetype start_tt = icaltime_null_time (); struct icaltimetype end_tt = icaltime_null_time (); - gboolean start_time_set, end_time_set; priv = spage->priv; @@ -514,10 +520,12 @@ time_changed_cb (GtkWidget *widget, gpointer data) start_dt.tzid = icaltimezone_get_tzid (priv->zone); end_dt.tzid = start_dt.tzid; } else { - /* For All-Day Events, we set the timezone to NULL. */ + /* For All-Day Events, we set the timezone to NULL, and add + 1 day to DTEND. */ start_dt.value->is_date = TRUE; start_dt.tzid = NULL; end_dt.value->is_date = TRUE; + icaltime_adjust (&end_tt, 1, 0, 0, 0); end_dt.tzid = NULL; } diff --git a/calendar/gui/e-cell-date-edit-text.c b/calendar/gui/e-cell-date-edit-text.c index 027db3b2a8..679e203d23 100644 --- a/calendar/gui/e-cell-date-edit-text.c +++ b/calendar/gui/e-cell-date-edit-text.c @@ -73,7 +73,6 @@ ecd_get_text (ECellText *cell, ETableModel *model, int col, int row) { ECellDateEditText *ecd = E_CELL_DATE_EDIT_TEXT (cell); ECellDateEditValue *dv = e_table_model_value_at (model, col, row); - struct icaltimetype tt; struct tm tmp_tm; char buffer[64]; @@ -87,7 +86,7 @@ ecd_get_text (ECellText *cell, ETableModel *model, int col, int row) tmp_tm = icaltimetype_to_tm_with_zone (&dv->tt, dv->zone, ecd->zone); e_time_format_date_and_time (&tmp_tm, ecd->use_24_hour_format, - TRUE, FALSE, + !dv->tt.is_date, FALSE, buffer, sizeof (buffer)); return g_strdup (buffer); } @@ -142,13 +141,22 @@ ecd_set_value (ECellText *cell, ETableModel *model, int col, int row, ETimeParseStatus status; struct tm tmp_tm; ECellDateEditValue *value; + gboolean is_date = TRUE; - status = e_time_parse_date_and_time (text, &tmp_tm); - + /* Try to parse just a date first. If the value is only a date, we + use a DATE value. */ + status = e_time_parse_date (text, &tmp_tm); if (status == E_TIME_PARSE_INVALID) { - show_date_warning (ecd); - return; - } else if (status == E_TIME_PARSE_NONE) { + is_date = FALSE; + status = e_time_parse_date_and_time (text, &tmp_tm); + + if (status == E_TIME_PARSE_INVALID) { + show_date_warning (ecd); + return; + } + } + + if (status == E_TIME_PARSE_NONE) { value = NULL; } else { ECellDateEditValue dv; @@ -161,10 +169,15 @@ ecd_set_value (ECellText *cell, ETableModel *model, int col, int row, dv.tt.hour = tmp_tm.tm_hour; dv.tt.minute = tmp_tm.tm_min; dv.tt.second = tmp_tm.tm_sec; + dv.tt.is_date = is_date; /* FIXME: We assume it is being set to the current timezone. Is that OK? */ - dv.zone = ecd->zone; + if (is_date) { + dv.zone = NULL; + } else { + dv.zone = ecd->zone; + } value = &dv; } diff --git a/calendar/gui/e-day-view.c b/calendar/gui/e-day-view.c index a0b7d09681..57547febb7 100644 --- a/calendar/gui/e-day-view.c +++ b/calendar/gui/e-day-view.c @@ -5126,8 +5126,6 @@ e_day_view_key_press (GtkWidget *widget, GdkEventKey *event) start_dt.tzid = NULL; start_tt.is_date = 1; end_tt.is_date = 1; - /* We have to take a day off the end time as it is a DATE. */ - icaltime_adjust (&end_tt, -1, 0, 0, 0); } else { start_dt.tzid = icaltimezone_get_tzid (day_view->zone); } diff --git a/calendar/gui/gnome-cal.c b/calendar/gui/gnome-cal.c index a3f2345865..b0a044b239 100644 --- a/calendar/gui/gnome-cal.c +++ b/calendar/gui/gnome-cal.c @@ -2027,10 +2027,10 @@ gnome_calendar_new_appointment_for (GnomeCalendar *cal, itt = icaltime_from_timet_with_zone (dtend, FALSE, priv->zone); if (all_day) { - /* We round it down to the start of the day, or the start of - the previous day if it is midnight. */ - if (itt.hour == 0 && itt.minute == 0 && itt.second == 0) { - icaltime_adjust (&itt, -1, 0, 0, 0); + /* We round it up to the end of the day, unless it is already + set to midnight. */ + if (itt.hour != 0 || itt.minute != 0 || itt.second != 0) { + icaltime_adjust (&itt, 1, 0, 0, 0); } itt.hour = itt.minute = itt.second = 0; itt.is_date = TRUE; diff --git a/calendar/gui/tasks-control.c b/calendar/gui/tasks-control.c index fa427e20ef..57d3623090 100644 --- a/calendar/gui/tasks-control.c +++ b/calendar/gui/tasks-control.c @@ -245,12 +245,10 @@ static BonoboUIVerb verbs [] = { static EPixmap pixmaps [] = { E_PIXMAP ("/menu/File/New/NewFirstItem/NewTask", "new_task-16.png"), - E_PIXMAP ("/menu/Edit/TasksCut", "16_cut.png"), - E_PIXMAP ("/menu/Edit/TasksCopy", "16_copy.png"), - E_PIXMAP ("/menu/Edit/TasksPaste", "16_paste.png"), - E_PIXMAP ("/menu/Edit/TasksDelete", "evolution-trash-mini.png"), - E_PIXMAP ("/menu/File/Print/Print", "print.xpm"), - E_PIXMAP ("/menu/File/Print/Print Preview", "print-preview.xpm"), + E_PIXMAP ("/menu/EditPlaceholder/Edit/TasksCut", "16_cut.png"), + E_PIXMAP ("/menu/EditPlaceholder/Edit/TasksCopy", "16_copy.png"), + E_PIXMAP ("/menu/EditPlaceholder/Edit/TasksPaste", "16_paste.png"), + E_PIXMAP ("/menu/EditPlaceholder/Edit/TasksDelete", "evolution-trash-mini.png"), E_PIXMAP ("/menu/Tools/ComponentPlaceholder/TasksSettings", "configure_16_calendar.xpm"), E_PIXMAP ("/Toolbar/New", "buttons/new_task.png"), E_PIXMAP ("/Toolbar/Cut", "buttons/cut.png"), -- cgit v1.2.3