diff options
Diffstat (limited to 'calendar/gui/dialogs/event-page.c')
-rw-r--r-- | calendar/gui/dialogs/event-page.c | 408 |
1 files changed, 204 insertions, 204 deletions
diff --git a/calendar/gui/dialogs/event-page.c b/calendar/gui/dialogs/event-page.c index a3c8041933..f4a849db11 100644 --- a/calendar/gui/dialogs/event-page.c +++ b/calendar/gui/dialogs/event-page.c @@ -268,29 +268,15 @@ event_page_focus_main_widget (CompEditorPage *page) gtk_widget_grab_focus (priv->summary); } -/* Checks if the event's time starts and ends at midnight, and sets the - *"all day event" box accordingly. - */ +/* Sets the 'All Day Event' flag to the given value (without emitting signals), + * and shows or hides the widgets as appropriate. */ static void -check_all_day (EventPage *epage) +set_all_day (EventPage *epage, gboolean all_day) { EventPagePrivate *priv; - gboolean all_day = FALSE, start_set, end_set; - gint start_hour, start_minute, end_hour, end_minute; priv = epage->priv; - start_set = e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), - &start_hour, &start_minute); - - end_set = e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time), - &end_hour, &end_minute); - - /* all day event checkbox */ - if ((!start_set || (start_hour == 0 && start_minute == 0)) - && (!end_set || (end_hour == 0 && end_minute == 0))) - all_day = TRUE; - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->all_day_event), epage); e_dialog_toggle_set (priv->all_day_event, all_day); @@ -300,8 +286,7 @@ check_all_day (EventPage *epage) 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); - /* We will use DATE values for all-day events eventually, in which - case timezones can't be used. */ + /* DATE values do not have timezones, so we hide the fields. */ if (all_day) { gtk_widget_hide (priv->start_timezone); gtk_widget_hide (priv->end_timezone); @@ -318,6 +303,7 @@ update_time (EventPage *epage, CalComponentDateTime *start_date, CalComponentDat struct icaltimetype *start_tt, *end_tt; icaltimezone *start_zone = NULL, *end_zone = NULL; CalClientGetStatus status; + gboolean all_day_event; priv = epage->priv; @@ -346,15 +332,28 @@ update_time (EventPage *epage, CalComponentDateTime *start_date, CalComponentDat end_date->tzid ? end_date->tzid : ""); } - /* All-day events are inclusive, i.e. if the end date shown is 2nd Feb - then the event includes all of the 2nd Feb. We would normally show - 3rd Feb as the end date, since it really ends at midnight on 3rd, - so we have to subtract a day so we only show the 2nd. */ + /* 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. */ + all_day_event = FALSE; start_tt = start_date->value; end_tt = end_date->value; - if (start_tt->hour == 0 && start_tt->minute == 0 && start_tt->second == 0 - && end_tt->hour == 0 && end_tt->minute == 0 && end_tt->second == 0) - icaltime_adjust (end_tt, -1, 0, 0, 0); + 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); + } + + set_all_day (epage, all_day_event); + + /* If it is an all day event, we set both timezones to the current + timezone, so that if the user toggles the 'All Day Event' checkbox + the event uses the current timezone rather than none at all. */ + if (all_day_event) { + char *location = calendar_config_get_timezone (); + start_zone = end_zone = icaltimezone_get_builtin_timezone (location); + } + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), epage); @@ -377,13 +376,20 @@ update_time (EventPage *epage, CalComponentDateTime *start_date, CalComponentDat /* Set the timezones, and set sync_timezones to TRUE if both timezones are the same. */ + /* FIXME: JPR - why did you add the if check here? It looks like it + won't work for floating times, where start_zone or end_zone may be + NULL. */ +#if 0 if (start_zone && end_zone) { +#endif e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->start_timezone), start_zone); e_timezone_entry_set_timezone (E_TIMEZONE_ENTRY (priv->end_timezone), end_zone); priv->sync_timezones = (start_zone == end_zone) ? TRUE : FALSE; +#if 0 } +#endif } /* Fills the widgets with default values */ @@ -411,7 +417,7 @@ clear_widgets (EventPage *epage) gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage); - check_all_day (epage); + set_all_day (epage, FALSE); /* Classification */ e_dialog_radio_set (priv->classification_public, @@ -486,13 +492,12 @@ event_page_fill_widgets (CompEditorPage *page, CalComponent *comp) cal_component_get_dtstart (comp, &start_date); cal_component_get_dtend (comp, &end_date); + update_time (epage, &start_date, &end_date); cal_component_free_datetime (&start_date); cal_component_free_datetime (&end_date); - check_all_day (epage); - /* Classification */ cal_component_get_classification (comp, &cl); @@ -549,7 +554,7 @@ event_page_fill_widgets (CompEditorPage *page, CalComponent *comp) comp_editor_contacts_to_widget (priv->contacts_entry, comp); /* We connect the contacts changed signal here, as we have to be a bit - more careful with it due to the use or Corba. The priv->updating + more careful with it due to the use of Corba. The priv->updating flag won't work as we won't get the changed event immediately. FIXME: Unfortunately this doesn't work either. We never get the changed event now. */ @@ -565,13 +570,12 @@ event_page_fill_component (CompEditorPage *page, CalComponent *comp) { EventPage *epage; EventPagePrivate *priv; - CalComponentDateTime date; - struct icaltimetype icaltime; - gboolean all_day_event, date_set; + CalComponentDateTime start_date, end_date; + struct icaltimetype start_tt, end_tt; + gboolean all_day_event, start_date_set, end_date_set; char *cat, *str; CalComponentClassification classif; CalComponentTransparency transparency; - icaltimezone *start_zone, *end_zone; epage = EVENT_PAGE (page); priv = epage->priv; @@ -615,56 +619,50 @@ event_page_fill_component (CompEditorPage *page, CalComponent *comp) /* Dates */ - icaltime = icaltime_null_time (); + start_tt = icaltime_null_time (); + start_date.value = &start_tt; + start_date.tzid = NULL; + + end_tt = icaltime_null_time (); + end_date.value = &end_tt; + end_date.tzid = NULL; - date.value = &icaltime; - date.tzid = NULL; + start_date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time), + &start_tt.year, + &start_tt.month, + &start_tt.day); + g_assert (start_date_set); - /* FIXME: We should use is_date at some point. */ + end_date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time), + &end_tt.year, + &end_tt.month, + &end_tt.day); + g_assert (end_date_set); - /* If the all_day toggle is set, the end date is inclusive of the - entire day on which it points to. Also, we will use DATE values - eventually, which can't have timezones. So for now we just use - the default timezone. */ + /* If the all_day toggle is set, we use DATE values for DTSTART and + DTEND. If not, we fetch the hour & minute from the widgets. */ all_day_event = e_dialog_toggle_get (priv->all_day_event); if (all_day_event) { - char *location = calendar_config_get_timezone (); - start_zone = end_zone = icaltimezone_get_builtin_timezone (location); + start_tt.is_date = TRUE; + end_tt.is_date = TRUE; } else { + icaltimezone *start_zone, *end_zone; + + e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), + &start_tt.hour, + &start_tt.minute); + e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time), + &end_tt.hour, + &end_tt.minute); start_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->start_timezone)); + start_date.tzid = icaltimezone_get_tzid (start_zone); end_zone = e_timezone_entry_get_timezone (E_TIMEZONE_ENTRY (priv->end_timezone)); + end_date.tzid = icaltimezone_get_tzid (end_zone); } - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time), - &icaltime.year, - &icaltime.month, - &icaltime.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), - &icaltime.hour, - &icaltime.minute); - g_assert (date_set); - date.tzid = icaltimezone_get_tzid (start_zone); - cal_component_set_dtstart (comp, &date); - - date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time), - &icaltime.year, - &icaltime.month, - &icaltime.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time), - &icaltime.hour, - &icaltime.minute); - g_assert (date_set); - - if (all_day_event) { - icaltime.hour = 0; - icaltime.minute = 0; - icaltime.second = 0; - icaltime_adjust (&icaltime, 1, 0, 0, 0); - } - - date.tzid = icaltimezone_get_tzid (end_zone); - cal_component_set_dtend (comp, &date); + cal_component_set_dtstart (comp, &start_date); + cal_component_set_dtend (comp, &end_date); /* Categories */ @@ -802,7 +800,7 @@ notify_dates_changed (EventPage *epage, struct icaltimetype *start_tt, CompEditorPageDates dates; CalComponentDateTime start_dt, end_dt; gboolean all_day_event; - icaltimezone *start_zone, *end_zone; + icaltimezone *start_zone = NULL, *end_zone = NULL; priv = epage->priv; @@ -811,14 +809,7 @@ notify_dates_changed (EventPage *epage, struct icaltimetype *start_tt, start_dt.value = start_tt; end_dt.value = end_tt; - if (all_day_event) { - /* FIXME: When we switch to using DATE values we'll set the - TZIDs to NULL. */ - char *location; - - location = calendar_config_get_timezone (); - start_zone = end_zone = icaltimezone_get_builtin_timezone (location); - } else { + if (!all_day_event) { 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)); } @@ -836,12 +827,48 @@ notify_dates_changed (EventPage *epage, struct icaltimetype *start_tt, } +static gboolean +check_start_before_end (struct icaltimetype *start_tt, + icaltimezone *start_zone, + struct icaltimetype *end_tt, + icaltimezone *end_zone, + gboolean adjust_end_time) +{ + struct icaltimetype end_tt_copy; + int cmp; + + /* Convert the end time to the same timezone as the start time. */ + end_tt_copy = *end_tt; + icaltimezone_convert_time (&end_tt_copy, end_zone, start_zone); + + /* Now check if the start time is after the end time. If it is, + we need to modify one of the times. */ + cmp = icaltime_compare (*start_tt, end_tt_copy); + if (cmp > 0) { + if (adjust_end_time) { + /* Modify the end time, to be the start + 1 hour. */ + *end_tt = *start_tt; + icaltime_adjust (end_tt, 0, 1, 0, 0); + icaltimezone_convert_time (end_tt, start_zone, + end_zone); + } else { + /* Modify the start time, to be the end - 1 hour. */ + *start_tt = *end_tt; + icaltime_adjust (start_tt, 0, -1, 0, 0); + icaltimezone_convert_time (start_tt, end_zone, + start_zone); + } + return TRUE; + } + + return FALSE; +} + + /* * This is called whenever the start or end dates or timezones is changed. - * It makes sure that the start date < end date, and currently sets the - * "all day event" checkbox as appropriate (but won't when we use DATE values). - * It also emits the notification signals so the other event editor pages - * update their labels etc. + * It makes sure that the start date < end date. It also emits the notification + * signals so the other event editor pages update their labels etc. * * If adjust_end_time is TRUE, if the start time < end time it will adjust * the end time. If FALSE it will adjust the start time. If the user sets the @@ -853,9 +880,8 @@ times_updated (EventPage *epage, gboolean adjust_end_time) EventPagePrivate *priv; struct icaltimetype start_tt = icaltime_null_time(); struct icaltimetype end_tt = icaltime_null_time(); - struct icaltimetype end_tt_copy; - int cmp; gboolean date_set, all_day_event; + gboolean set_start_date = FALSE, set_end_date = FALSE; icaltimezone *start_zone, *end_zone; priv = epage->priv; @@ -870,88 +896,69 @@ times_updated (EventPage *epage, gboolean adjust_end_time) &start_tt.year, &start_tt.month, &start_tt.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), - &start_tt.hour, - &start_tt.minute); g_assert (date_set); date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time), &end_tt.year, &end_tt.month, &end_tt.day); - e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time), - &end_tt.hour, - &end_tt.minute); g_assert (date_set); if (all_day_event) { - char *location = calendar_config_get_timezone (); - start_zone = end_zone = icaltimezone_get_builtin_timezone (location); + /* All Day Events are simple. We just compare the dates and if + start > end we copy one of them to the other. */ + int cmp = icaltime_compare_date_only (start_tt, end_tt); + if (cmp > 0) { + if (adjust_end_time) { + end_tt = start_tt; + set_end_date = TRUE; + } else { + start_tt = end_tt; + set_start_date = TRUE; + } + } } else { + /* For DATE-TIME events, we have to convert to the same + timezone before comparing. */ + e_date_edit_get_time_of_day (E_DATE_EDIT (priv->start_time), + &start_tt.hour, + &start_tt.minute); + e_date_edit_get_time_of_day (E_DATE_EDIT (priv->end_time), + &end_tt.hour, + &end_tt.minute); + 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)); - } - - - /* Convert the end time to the same timezone as the start time. */ - end_tt_copy = end_tt; - icaltimezone_convert_time (&end_tt_copy, end_zone, start_zone); - /* Now check if the start time is after the end time. If it is, we need - to modify one of the times. */ - cmp = icaltime_compare (start_tt, end_tt_copy); - if (cmp > 0) { - if (adjust_end_time) { - /* Modify the end time, to be the start + 1 hour, - or the same as the start time for all-day events. - We copy the start time, add on one hour, then - convert it to the original end timezone. */ - end_tt = start_tt; - if (!all_day_event) { - icaltime_adjust (&end_tt, 0, 1, 0, 0); - icaltimezone_convert_time (&end_tt, start_zone, - end_zone); - } - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage); - - e_date_edit_set_date (E_DATE_EDIT (priv->end_time), - end_tt.year, - end_tt.month, - end_tt.day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->end_time), - end_tt.hour, - end_tt.minute); - - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage); - } else { - /* Modify the start time, to be the end - 1 hour, - or the same as the start time for all-day events. - We copy the end time, subtract one hour, then - convert it to the original start timezone. */ - start_tt = end_tt; - if (!all_day_event) { - icaltime_adjust (&start_tt, 0, -1, 0, 0); - icaltimezone_convert_time (&start_tt, end_zone, - start_zone); - } - - gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), epage); + if (check_start_before_end (&start_tt, start_zone, + &end_tt, end_zone, + adjust_end_time)) { + if (adjust_end_time) + set_end_date = TRUE; + else + set_start_date = TRUE; + } + } - e_date_edit_set_date (E_DATE_EDIT (priv->start_time), - start_tt.year, - start_tt.month, - start_tt.day); - e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_time), - start_tt.hour, - start_tt.minute); - gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), epage); - } + if (set_start_date) { + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), epage); + e_date_edit_set_date (E_DATE_EDIT (priv->start_time), + start_tt.year, start_tt.month, + start_tt.day); + e_date_edit_set_time_of_day (E_DATE_EDIT (priv->start_time), + start_tt.hour, start_tt.minute); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->start_time), epage); } - /* Set the "all day event" button as appropriate */ - check_all_day (epage); + if (set_end_date) { + gtk_signal_handler_block_by_data (GTK_OBJECT (priv->end_time), epage); + e_date_edit_set_date (E_DATE_EDIT (priv->end_time), + end_tt.year, end_tt.month, end_tt.day); + e_date_edit_set_time_of_day (E_DATE_EDIT (priv->end_time), + end_tt.hour, end_tt.minute); + gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage); + } /* Notify upstream */ notify_dates_changed (epage, &start_tt, &end_tt); @@ -1040,21 +1047,22 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data) * 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.) + * is at midnight, we round it down to the previous day, so the + * event times stay the same. + * + * When the all_day_toggle is turned off, then if the event is within + * one day, we set the event start to the start of the working day, + * and set the event end to one hour after it. If the event is longer + * than one day, we set the event end to the end of the day it is on, + * so that the actual event times remain the same. * - * When the all_day_toggle is turned 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. + * This may need tweaking to work well with different timezones used + * in the event start & end. */ all_day = GTK_TOGGLE_BUTTON (toggle)->active; - /* - * Start time. - */ + set_all_day (epage, all_day); + date_set = e_date_edit_get_date (E_DATE_EDIT (priv->start_time), &start_tt.year, &start_tt.month, @@ -1064,21 +1072,6 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data) &start_tt.minute); g_assert (date_set); - if (all_day) { - /* Round down to the start of the day. */ - start_tt.hour = 0; - start_tt.minute = 0; - start_tt.second = 0; - } else { - /* Set to the start of the working day. */ - start_tt.hour = calendar_config_get_day_start_hour (); - start_tt.minute = calendar_config_get_day_start_minute (); - start_tt.second = 0; - } - - /* - * End time. - */ date_set = e_date_edit_get_date (E_DATE_EDIT (priv->end_time), &end_tt.year, &end_tt.month, @@ -1090,24 +1083,44 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data) if (all_day) { /* Round down to the start of the day. */ + start_tt.hour = 0; + start_tt.minute = 0; + start_tt.second = 0; + + /* Round down to the start of the day, or the start of the + previous day if it is midnight. */ + icaltime_adjust (&end_tt, 0, 0, 0, -1); end_tt.hour = 0; end_tt.minute = 0; end_tt.second = 0; } else { - /* If the event end is now on or before the event start day, - * make it end one hour after the start. */ - if (end_tt.year < start_tt.year - || (end_tt.year == start_tt.year - && end_tt.month < start_tt.month) - || (end_tt.year == start_tt.year - && end_tt.month == start_tt.month - && end_tt.day <= start_tt.day)) { - end_tt.year = start_tt.year; - end_tt.month = start_tt.month; - end_tt.day = start_tt.day; - end_tt.hour = start_tt.hour; + icaltimezone *start_zone, *end_zone; + + if (end_tt.year == start_tt.year + && end_tt.month == start_tt.month + && end_tt.day == start_tt.day) { + /* The event is within one day, so we set the event + start to the start of the working day, and the end + to one hour later. */ + start_tt.hour = calendar_config_get_day_start_hour (); + start_tt.minute = calendar_config_get_day_start_minute (); + start_tt.second = 0; + + end_tt = start_tt; icaltime_adjust (&end_tt, 0, 1, 0, 0); + } else { + /* The event is longer than 1 day, so we keep exactly + the same times, just using DATE-TIME rather than + DATE. */ + icaltime_adjust (&end_tt, 1, 0, 0, 0); } + + /* Make sure that end > start using the timezones. */ + 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)); + check_start_before_end (&start_tt, start_zone, + &end_tt, end_zone, + TRUE); } gtk_signal_handler_block_by_data (GTK_OBJECT (priv->start_time), @@ -1130,19 +1143,6 @@ all_day_event_toggled_cb (GtkWidget *toggle, gpointer data) gtk_signal_handler_unblock_by_data (GTK_OBJECT (priv->end_time), epage); - 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); - - /* We will use DATE values for all-day events eventually, in which - case timezones can't be used. */ - if (all_day) { - gtk_widget_hide (priv->start_timezone); - gtk_widget_hide (priv->end_timezone); - } else { - gtk_widget_show (priv->start_timezone); - gtk_widget_show (priv->end_timezone); - } - /* Notify upstream */ notify_dates_changed (epage, &start_tt, &end_tt); } |