aboutsummaryrefslogtreecommitdiffstats
path: root/calendar/gui/dialogs/event-page.c
diff options
context:
space:
mode:
Diffstat (limited to 'calendar/gui/dialogs/event-page.c')
-rw-r--r--calendar/gui/dialogs/event-page.c408
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);
}