[gnome-calendar] event: rewrite timezone support
- From: Georges Basile Stavracas Neto <gbsneto src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calendar] event: rewrite timezone support
- Date: Fri, 14 Sep 2018 23:17:24 +0000 (UTC)
commit a799678f682d994759e563a4aab55e7926f8fa1f
Author: Georges Basile Stavracas Neto <georges stavracas gmail com>
Date: Fri Sep 14 17:08:46 2018 -0300
event: rewrite timezone support
Now with something that hopefully works.
https://gitlab.gnome.org/GNOME/gnome-calendar/issues/43
https://gitlab.gnome.org/GNOME/gnome-calendar/issues/302
doc/reference/gnome-calendar-decl-list.txt | 2 -
doc/reference/gnome-calendar-decl.txt | 10 --
doc/reference/gnome-calendar-sections.txt | 2 -
src/gcal-edit-dialog.c | 253 +++++++++++++++------------
src/gcal-edit-dialog.h | 4 -
src/gcal-event.c | 271 ++++++++++++++++++-----------
src/gcal-event.h | 11 +-
src/gcal-quick-add-popover.c | 1 -
src/views/gcal-month-view.c | 3 +-
src/views/gcal-week-header.c | 2 +-
10 files changed, 322 insertions(+), 237 deletions(-)
---
diff --git a/doc/reference/gnome-calendar-decl-list.txt b/doc/reference/gnome-calendar-decl-list.txt
index 393afce2..e30e526f 100644
--- a/doc/reference/gnome-calendar-decl-list.txt
+++ b/doc/reference/gnome-calendar-decl-list.txt
@@ -192,8 +192,6 @@ gcal_event_get_source
gcal_event_set_source
gcal_event_get_summary
gcal_event_set_summary
-gcal_event_get_timezone
-gcal_event_set_timezone
gcal_event_get_uid
gcal_event_is_multiday
gcal_event_compare
diff --git a/doc/reference/gnome-calendar-decl.txt b/doc/reference/gnome-calendar-decl.txt
index 77d0ee19..d9ceee01 100644
--- a/doc/reference/gnome-calendar-decl.txt
+++ b/doc/reference/gnome-calendar-decl.txt
@@ -413,16 +413,6 @@ GcalEvent *self
GcalEvent *self, const gchar *summary
</FUNCTION>
<FUNCTION>
-<NAME>gcal_event_get_timezone</NAME>
-<RETURNS>GTimeZone * </RETURNS>
-GcalEvent *self
-</FUNCTION>
-<FUNCTION>
-<NAME>gcal_event_set_timezone</NAME>
-<RETURNS>void </RETURNS>
-GcalEvent *self, GTimeZone *timezone
-</FUNCTION>
-<FUNCTION>
<NAME>gcal_event_get_uid</NAME>
<RETURNS>const gchar * </RETURNS>
GcalEvent *self
diff --git a/doc/reference/gnome-calendar-sections.txt b/doc/reference/gnome-calendar-sections.txt
index 8b273956..5ae522d3 100644
--- a/doc/reference/gnome-calendar-sections.txt
+++ b/doc/reference/gnome-calendar-sections.txt
@@ -195,8 +195,6 @@ gcal_event_get_source
gcal_event_set_source
gcal_event_get_summary
gcal_event_set_summary
-gcal_event_get_timezone
-gcal_event_set_timezone
gcal_event_get_uid
gcal_event_is_multiday
gcal_event_compare
diff --git a/src/gcal-edit-dialog.c b/src/gcal-edit-dialog.c
index a2478dc0..1cd467bb 100644
--- a/src/gcal-edit-dialog.c
+++ b/src/gcal-edit-dialog.c
@@ -260,6 +260,132 @@ on_calendar_selected (GSimpleAction *action,
GCAL_EXIT;
}
+static void
+find_best_timezones_for_event (GcalEditDialog *self,
+ GTimeZone **out_tz_start,
+ GTimeZone **out_tz_end)
+{
+ gboolean was_all_day;
+ gboolean all_day;
+
+ /* Update all day */
+ all_day = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->all_day_check));
+ was_all_day = gcal_event_get_all_day (self->event);
+
+ GCAL_TRACE_MSG ("Finding best timezone with all_day=%d, was_all_day=%d, event_is_new=%d",
+ all_day,
+ was_all_day,
+ self->event_is_new);
+
+ if (!self->event_is_new && was_all_day && !all_day)
+ {
+ GCAL_TRACE_MSG ("Using original event timezones");
+
+ gcal_event_get_original_timezones (self->event, out_tz_start, out_tz_end);
+ return;
+ }
+
+ if (all_day)
+ {
+ GCAL_TRACE_MSG ("Using UTC timezones");
+
+ if (out_tz_start)
+ *out_tz_start = g_time_zone_new_utc ();
+
+ if (out_tz_end)
+ *out_tz_end = g_time_zone_new_utc ();
+ }
+ else
+ {
+ g_autoptr (GTimeZone) tz_start = NULL;
+ g_autoptr (GTimeZone) tz_end = NULL;
+
+ if (self->event_is_new)
+ {
+ GCAL_TRACE_MSG ("Using the local timezone");
+
+ tz_start = g_time_zone_new_local ();
+ tz_end = g_time_zone_new_local ();
+ }
+ else
+ {
+ GCAL_TRACE_MSG ("Using the current timezones");
+
+ tz_start = g_time_zone_ref (g_date_time_get_timezone (gcal_event_get_date_start (self->event)));
+ tz_end = g_time_zone_ref (g_date_time_get_timezone (gcal_event_get_date_end (self->event)));
+ }
+
+ if (out_tz_start)
+ *out_tz_start = g_steal_pointer (&tz_start);
+
+ if (out_tz_end)
+ *out_tz_end = g_steal_pointer (&tz_end);
+ }
+}
+
+static GDateTime*
+return_datetime_for_widgets (GcalEditDialog *self,
+ GTimeZone *timezone,
+ GcalDateSelector *date_selector,
+ GcalTimeSelector *time_selector)
+{
+ g_autoptr (GDateTime) date_in_local_tz = NULL;
+ g_autoptr (GDateTime) date_in_best_tz = NULL;
+ GDateTime *date;
+ GDateTime *time;
+ GDateTime *retval;
+ gboolean all_day;
+
+ all_day = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->all_day_check));
+ date = gcal_date_selector_get_date (date_selector);
+ time = gcal_time_selector_get_time (time_selector);
+
+ date_in_local_tz = g_date_time_new_local (g_date_time_get_year (date),
+ g_date_time_get_month (date),
+ g_date_time_get_day_of_month (date),
+ all_day ? 0 : g_date_time_get_hour (time),
+ all_day ? 0 : g_date_time_get_minute (time),
+ 0);
+
+ date_in_best_tz = g_date_time_to_timezone (date_in_local_tz, timezone);
+
+ retval = g_date_time_new (timezone,
+ g_date_time_get_year (date_in_best_tz),
+ g_date_time_get_month (date_in_best_tz),
+ g_date_time_get_day_of_month (date_in_best_tz),
+ all_day ? 0 : g_date_time_get_hour (date_in_best_tz),
+ all_day ? 0 : g_date_time_get_minute (date_in_best_tz),
+ 0);
+
+ return retval;
+}
+
+static GDateTime*
+get_date_start (GcalEditDialog *self)
+{
+ g_autoptr (GTimeZone) start_tz = NULL;
+
+ find_best_timezones_for_event (self, &start_tz, NULL);
+
+ return return_datetime_for_widgets (self,
+ start_tz,
+ GCAL_DATE_SELECTOR (self->start_date_selector),
+ GCAL_TIME_SELECTOR (self->start_time_selector));
+}
+
+static GDateTime*
+get_date_end (GcalEditDialog *self)
+{
+ g_autoptr (GTimeZone) end_tz = NULL;
+
+ find_best_timezones_for_event (self, NULL, &end_tz);
+
+ return return_datetime_for_widgets (self,
+ end_tz,
+ GCAL_DATE_SELECTOR (self->end_date_selector),
+ GCAL_TIME_SELECTOR (self->end_time_selector));
+}
+
static void
gcal_edit_dialog_set_writable (GcalEditDialog *dialog,
gboolean writable)
@@ -382,8 +508,8 @@ sync_datetimes (GcalEditDialog *self,
is_start = (widget == self->start_time_selector || widget == self->start_date_selector);
is_all_day = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (self->all_day_check));
- start = gcal_edit_dialog_get_date_start (self);
- end = gcal_edit_dialog_get_date_end (self);
+ start = get_date_start (self);
+ end = get_date_end (self);
/* The date is valid, no need to update the fields */
if (g_date_time_compare (end, start) >= 0)
@@ -469,28 +595,30 @@ action_button_clicked (GtkWidget *widget,
gcal_event_set_description (dialog->event, note_text);
g_free (note_text);
- /* Update all day */
all_day = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->all_day_check));
was_all_day = gcal_event_get_all_day (dialog->event);
- gcal_event_set_all_day (dialog->event, all_day);
-
- /* By definition, all day events are always UTC */
- if (all_day)
- {
- GTimeZone *utc = g_time_zone_new_utc ();
-
- gcal_event_set_timezone (dialog->event, utc);
-
- g_clear_pointer (&utc, g_time_zone_unref);
- }
+ if (!was_all_day && all_day)
+ gcal_event_save_original_timezones (dialog->event);
/*
* Update start & end dates. The dates are already translated to the current
* timezone (unless the event used to be all day, but no longer is).
*/
- start_date = gcal_edit_dialog_get_date_start (dialog);
- end_date = gcal_edit_dialog_get_date_end (dialog);
+ start_date = get_date_start (dialog);
+ end_date = get_date_end (dialog);
+
+#ifdef GCAL_ENABLE_TRACE
+ {
+ g_autofree gchar *start_dt_string = g_date_time_format (start_date, "%x %X %z");
+ g_autofree gchar *end_dt_string = g_date_time_format (end_date, "%x %X %z");
+
+ g_debug ("New start date: %s", start_dt_string);
+ g_debug ("New end date: %s", end_dt_string);
+ }
+#endif
+
+ gcal_event_set_all_day (dialog->event, all_day);
/*
* The end date for multi-day events is exclusive, so we bump it by a day.
@@ -1454,99 +1582,6 @@ gcal_edit_dialog_set_manager (GcalEditDialog *dialog,
g_object_notify_by_pspec (G_OBJECT (dialog), properties[PROP_MANAGER]);
}
-static GDateTime*
-return_datetime_for_widgets (GcalEditDialog *dialog,
- GcalDateSelector *date_selector,
- GcalTimeSelector *time_selector)
-{
- GTimeZone *tz;
- GDateTime *date;
- GDateTime *time;
- GDateTime *retval;
- gboolean all_day;
-
- /* Use UTC timezone for All Day events, otherwise use the event's timezone */
- all_day = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->all_day_check));
- if (all_day)
- {
- tz = g_time_zone_new_utc ();
- }
- else
- {
- if (gcal_event_get_timezone (dialog->event))
- tz = g_time_zone_ref (gcal_event_get_timezone (dialog->event));
- else
- tz = g_time_zone_new_local ();
- }
-
- date = gcal_date_selector_get_date (date_selector);
- time = gcal_time_selector_get_time (time_selector);
-
- retval = g_date_time_new (tz,
- g_date_time_get_year (date),
- g_date_time_get_month (date),
- g_date_time_get_day_of_month (date),
- g_date_time_get_hour (time),
- g_date_time_get_minute (time),
- 0);
-
- /*
- * If the event is not all day, the timezone may be different from UTC or
- * local. In any case, since we're editing the event in the current timezone,
- * we should always correct the timezone to the event's timezone.
- */
- if (!all_day)
- {
- GDateTime *aux = retval;
-
- retval = g_date_time_to_timezone (aux, gcal_event_get_timezone (dialog->event));
-
- g_clear_pointer (&aux, g_date_time_unref);
- }
-
- g_clear_pointer (&tz, g_time_zone_unref);
-
- return retval;
-}
-
-/**
- * gcal_edit_dialog_get_date_start:
- * @dialog: a #GcalEditDialog
- *
- * Retrieves the start date of the edit dialog.
- *
- * Returns: (transfer full): a #GDateTime
- */
-GDateTime*
-gcal_edit_dialog_get_date_start (GcalEditDialog *dialog)
-{
-
- g_return_val_if_fail (GCAL_IS_EDIT_DIALOG (dialog), NULL);
-
- return return_datetime_for_widgets (dialog,
- GCAL_DATE_SELECTOR (dialog->start_date_selector),
- GCAL_TIME_SELECTOR (dialog->start_time_selector));
-}
-
-/**
- * gcal_edit_dialog_get_date_end:
- * @dialog: a #GcalEditDialog
- *
- * Retrieves the end date of the edit dialog.
- *
- * Returns: (transfer full): a #GDateTime
- */
-GDateTime*
-gcal_edit_dialog_get_date_end (GcalEditDialog *dialog)
-{
- g_return_val_if_fail (GCAL_IS_EDIT_DIALOG (dialog), NULL);
-
- return return_datetime_for_widgets (dialog,
- GCAL_DATE_SELECTOR (dialog->end_date_selector),
- GCAL_TIME_SELECTOR (dialog->end_time_selector));
-}
-
-
gboolean
gcal_edit_dialog_get_recurrence_changed (GcalEditDialog *self)
{
diff --git a/src/gcal-edit-dialog.h b/src/gcal-edit-dialog.h
index 73222d21..dfac6b52 100644
--- a/src/gcal-edit-dialog.h
+++ b/src/gcal-edit-dialog.h
@@ -51,10 +51,6 @@ void gcal_edit_dialog_set_manager (GcalEditDialog *d
void gcal_edit_dialog_set_time_format (GcalEditDialog *dialog,
GcalTimeFormat time_format);
-GDateTime* gcal_edit_dialog_get_date_end (GcalEditDialog *dialog);
-
-GDateTime* gcal_edit_dialog_get_date_start (GcalEditDialog *dialog);
-
gboolean gcal_edit_dialog_get_recurrence_changed (GcalEditDialog *self);
GcalRecurrenceModType gcal_edit_dialog_get_recurrence_mod_type (GcalEditDialog *self);
diff --git a/src/gcal-event.c b/src/gcal-event.c
index c318f830..e8eada98 100644
--- a/src/gcal-event.c
+++ b/src/gcal-event.c
@@ -19,6 +19,7 @@
#define G_LOG_DOMAIN "GcalEvent"
#include "gconstructor.h"
+#include "gcal-debug.h"
#include "gcal-event.h"
#include "gcal-utils.h"
#include "gcal-recurrence.h"
@@ -45,19 +46,6 @@
* can generate an error. At the moment, the only error that
* can be generate is #GCAL_EVENT_ERROR_INVALID_START_DATE.
*
- * ## Timezones
- *
- * When a #GcalEvent is created, the timezone is parsed from
- * the #ECalComponent. The start and end dates can possibly
- * have different timezones, e.g. when the user is traveling
- * across timezones and the departure time is in a different
- * timezone of the arrival time.
- *
- * For the sake of sanity, gcal_event_get_timezone() returns
- * the timezone of the start date. If you need to precisely
- * check the timezones of the start and end dates, you have
- * to use g_date_time_get_timezone_identifier().
- *
* ## Example:
* |[<!-- language="C" -->
* GcalEvent *event;
@@ -91,7 +79,6 @@ struct _GcalEvent
*/
gchar *description;
- GTimeZone *timezone;
GDateTime *dt_start;
GDateTime *dt_end;
@@ -177,8 +164,11 @@ destroy_event_cache_map (void)
static GTimeZone*
get_timezone_from_ical (ECalComponentDateTime *comp)
{
+ const icaltimezone *zone;
GTimeZone *tz;
+ zone = icaltime_get_timezone (*comp->value);
+
if (comp->value->is_date)
{
/*
@@ -188,30 +178,25 @@ get_timezone_from_ical (ECalComponentDateTime *comp)
*/
tz = g_time_zone_new_utc ();
}
- else if (icaltime_get_timezone (*comp->value))
+ else if (comp->tzid)
{
- g_autofree gchar *tzid = NULL;
- gint offset;
+ const gchar *real_tzid;
- offset = icaltimezone_get_utc_offset ((icaltimezone*) icaltime_get_timezone (*comp->value),
- comp->value, NULL);
- tzid = format_utc_offset (offset);
- tz = g_time_zone_new (tzid);
+ real_tzid = comp->tzid;
+
+ if (g_str_has_prefix (comp->tzid, LIBICAL_TZID_PREFIX))
+ real_tzid += strlen (LIBICAL_TZID_PREFIX);
+
+ tz = g_time_zone_new (real_tzid);
}
- else if (comp->tzid)
+ else if (zone)
{
g_autofree gchar *tzid = NULL;
- icaltimezone *zone;
gint offset;
- if (g_str_has_prefix (comp->tzid, LIBICAL_TZID_PREFIX))
- zone = icaltimezone_get_builtin_timezone_from_tzid (comp->tzid);
- else
- zone = icaltimezone_get_builtin_timezone (comp->tzid);
-
- offset = icaltimezone_get_utc_offset (zone, comp->value, NULL);
+ offset = icaltimezone_get_utc_offset ((icaltimezone*) icaltime_get_timezone (*comp->value),
+ comp->value, NULL);
tzid = format_utc_offset (offset);
-
tz = g_time_zone_new (tzid);
}
else
@@ -219,6 +204,10 @@ get_timezone_from_ical (ECalComponentDateTime *comp)
tz = g_time_zone_new_utc ();
}
+ g_assert (tz != NULL);
+
+ GCAL_TRACE_MSG ("%s (%p)", g_time_zone_get_identifier (tz), tz);
+
return tz;
}
@@ -360,6 +349,8 @@ gcal_event_set_component_internal (GcalEvent *self,
*start.value = icaltime_today ();
}
+ GCAL_TRACE_MSG ("Retrieving start timezone");
+
date = icaltime_normalize (*start.value);
zone_start = get_timezone_from_ical (&start);
date_start = g_date_time_new (zone_start,
@@ -371,10 +362,6 @@ gcal_event_set_component_internal (GcalEvent *self,
self->dt_start = date_start;
-
- /* The timezone of the event is the timezone of the start date */
- self->timezone = g_time_zone_ref (zone_start);
-
/* Setup end date */
e_cal_component_get_dtend (component, &end);
@@ -384,6 +371,8 @@ gcal_event_set_component_internal (GcalEvent *self,
}
else
{
+ GCAL_TRACE_MSG ("Retrieving end timezone");
+
date = icaltime_normalize (*end.value);
zone_end = get_timezone_from_ical (&end);
date_end = g_date_time_new (zone_end,
@@ -473,7 +462,6 @@ gcal_event_finalize (GObject *object)
g_clear_pointer (&self->dt_start, g_date_time_unref);
g_clear_pointer (&self->dt_end, g_date_time_unref);
- g_clear_pointer (&self->timezone, g_time_zone_unref);
g_clear_pointer (&self->description, g_free);
g_clear_pointer (&self->alarms, g_hash_table_unref);
g_clear_pointer (&self->uid, g_free);
@@ -531,10 +519,6 @@ gcal_event_get_property (GObject *object,
g_value_set_string (value, gcal_event_get_summary (self));
break;
- case PROP_TIMEZONE:
- g_value_set_boxed (value, self->timezone);
- break;
-
case PROP_UID:
g_value_set_string (value, self->uid);
break;
@@ -598,10 +582,6 @@ gcal_event_set_property (GObject *object,
gcal_event_set_summary (self, g_value_get_string (value));
break;
- case PROP_TIMEZONE:
- gcal_event_set_timezone (self, g_value_get_boxed (value));
- break;
-
case PROP_RECURRENCE:
gcal_event_set_recurrence (self, g_value_get_boxed (value));
break;
@@ -1410,65 +1390,6 @@ gcal_event_set_summary (GcalEvent *self,
}
}
-/**
- * gcal_event_get_timezone:
- * @self: a #GcalEvent
- *
- * Retrieves the event's timezone.
- *
- * Returns: (transfer none): a #GTimeZone
- */
-GTimeZone*
-gcal_event_get_timezone (GcalEvent *self)
-{
- g_return_val_if_fail (GCAL_IS_EVENT (self), NULL);
-
- return self->timezone;
-}
-
-/**
- * gcal_event_set_timezone:
- * @self: a #GcalEvent
- * @timezone: a #GTimeZone
- *
- * Sets the timezone of the event to @timezone.
- */
-void
-gcal_event_set_timezone (GcalEvent *self,
- GTimeZone *timezone)
-{
- g_return_if_fail (GCAL_IS_EVENT (self));
-
- if (self->timezone != timezone)
- {
- g_clear_pointer (&self->timezone, g_time_zone_unref);
- self->timezone = g_time_zone_ref (timezone);
-
- /* Swap the timezone from the component start & end dates*/
- if (!self->all_day)
- {
- GDateTime *new_dtstart;
-
- new_dtstart = g_date_time_to_timezone (self->dt_start, timezone);
- gcal_event_set_date_start (self, new_dtstart);
-
- if (self->dt_end)
- {
- GDateTime *new_dtend;
-
- new_dtend = g_date_time_to_timezone (self->dt_end, timezone);
- gcal_event_set_date_end (self, new_dtend);
-
- g_clear_pointer (&new_dtend, g_date_time_unref);
- }
-
- g_clear_pointer (&new_dtstart, g_date_time_unref);
- }
-
- g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TIMEZONE]);
- }
-}
-
/**
* gcal_event_get_uid:
* @self: a #GcalEvent
@@ -1705,3 +1626,149 @@ gcal_event_get_recurrence (GcalEvent *self)
return self->recurrence;
}
+
+/**
+ * gcal_event_get_original_timezones:
+ * @self: a #GcalEvent
+ * @out_start_timezone: (direction out)(nullable): the return location for the
+ * previously stored start date timezone
+ * @out_end_timezone: (direction out)(nullable): the return location for the
+ * previously stored end date timezone
+ *
+ * Retrieves the start and end date timezones previously stored by
+ * gcal_event_save_original_timezones().
+ *
+ * If gcal_event_save_original_timezones() wasn't called before,
+ * it will use local timezones instead.
+ */
+void
+gcal_event_get_original_timezones (GcalEvent *self,
+ GTimeZone **out_start_timezone,
+ GTimeZone **out_end_timezone)
+{
+ g_autoptr (GTimeZone) original_start_tz = NULL;
+ g_autoptr (GTimeZone) original_end_tz = NULL;
+ icalcomponent *ical_comp;
+ icalproperty *property;
+
+ g_return_if_fail (GCAL_IS_EVENT (self));
+ g_assert (self->component != NULL);
+
+ ical_comp = e_cal_component_get_icalcomponent (self->component);
+
+ for (property = icalcomponent_get_first_property (ical_comp, ICAL_X_PROPERTY);
+ property;
+ property = icalcomponent_get_next_property (ical_comp, ICAL_X_PROPERTY))
+ {
+ const gchar *value;
+
+ if (original_start_tz && original_end_tz)
+ break;
+
+ if (g_strcmp0 (icalproperty_get_x_name (property), "X-GNOME-CALENDAR-ORIGINAL-TZ-START") == 0)
+ {
+ value = icalproperty_get_x (property);
+ original_start_tz = g_time_zone_new (value);
+
+ GCAL_TRACE_MSG ("Found X-GNOME-CALENDAR-ORIGINAL-TZ-START=%s", value);
+ }
+ else if (g_strcmp0 (icalproperty_get_x_name (property), "X-GNOME-CALENDAR-ORIGINAL-TZ-END") == 0)
+ {
+ value = icalproperty_get_x (property);
+ original_end_tz = g_time_zone_new (value);
+
+ GCAL_TRACE_MSG ("Found X-GNOME-CALENDAR-ORIGINAL-TZ-END=%s", value);
+ }
+ }
+
+ if (!original_start_tz)
+ original_start_tz = g_time_zone_new_local ();
+
+ if (!original_end_tz)
+ original_end_tz = g_time_zone_new_local ();
+
+ g_assert (original_start_tz != NULL);
+ g_assert (original_end_tz != NULL);
+
+ if (out_start_timezone)
+ *out_start_timezone = g_steal_pointer (&original_start_tz);
+
+ if (out_end_timezone)
+ *out_end_timezone = g_steal_pointer (&original_end_tz);
+}
+
+/**
+ * gcal_event_save_original_timezones:
+ * @self: a #GcalEvent
+ *
+ * Stores the current timezones of the start and end dates of @self
+ * into separate, GNOME Calendar specific fields. These fields can
+ * be used by gcal_event_get_original_timezones() to retrieve the
+ * previous timezones of the event later.
+ */
+void
+gcal_event_save_original_timezones (GcalEvent *self)
+{
+ icalcomponent *ical_comp;
+ icalproperty *property;
+ GTimeZone *tz;
+ gboolean has_original_start_tz;
+ gboolean has_original_end_tz;
+
+ GCAL_ENTRY;
+
+ g_return_if_fail (GCAL_IS_EVENT (self));
+ g_assert (self->component != NULL);
+
+ has_original_start_tz = FALSE;
+ has_original_end_tz = FALSE;
+ ical_comp = e_cal_component_get_icalcomponent (self->component);
+
+ for (property = icalcomponent_get_first_property (ical_comp, ICAL_X_PROPERTY);
+ property;
+ property = icalcomponent_get_next_property (ical_comp, ICAL_X_PROPERTY))
+ {
+ if (g_strcmp0 (icalproperty_get_x_name (property), "X-GNOME-CALENDAR-ORIGINAL-TZ-START") == 0)
+ {
+ tz = g_date_time_get_timezone (self->dt_start);
+ icalproperty_set_x (property, g_time_zone_get_identifier (tz));
+
+ GCAL_TRACE_MSG ("Reusing X-GNOME-CALENDAR-ORIGINAL-TZ-START property with %s", icalproperty_get_x
(property));
+
+ has_original_start_tz = TRUE;
+ }
+ else if (g_strcmp0 (icalproperty_get_x_name (property), "X-GNOME-CALENDAR-ORIGINAL-TZ-END") == 0)
+ {
+ tz = g_date_time_get_timezone (self->dt_end);
+ icalproperty_set_x (property, g_time_zone_get_identifier (tz));
+
+ GCAL_TRACE_MSG ("Reusing X-GNOME-CALENDAR-ORIGINAL-TZ-END property with %s", icalproperty_get_x
(property));
+
+ has_original_end_tz = TRUE;
+ }
+ }
+
+ if (!has_original_start_tz)
+ {
+ tz = g_date_time_get_timezone (self->dt_start);
+ property = icalproperty_new_x (g_time_zone_get_identifier (tz));
+ icalproperty_set_x_name (property, "X-GNOME-CALENDAR-ORIGINAL-TZ-START");
+
+ icalcomponent_add_property (ical_comp, property);
+
+ GCAL_TRACE_MSG ("Added new X-GNOME-CALENDAR-ORIGINAL-TZ-START property with %s", icalproperty_get_x
(property));
+ }
+
+ if (!has_original_end_tz)
+ {
+ tz = g_date_time_get_timezone (self->dt_end);
+ property = icalproperty_new_x (g_time_zone_get_identifier (tz));
+ icalproperty_set_x_name (property, "X-GNOME-CALENDAR-ORIGINAL-TZ-END");
+
+ icalcomponent_add_property (ical_comp, property);
+
+ GCAL_TRACE_MSG ("Added new X-GNOME-CALENDAR-ORIGINAL-TZ-END property with %s", icalproperty_get_x
(property));
+ }
+
+ GCAL_EXIT;
+}
diff --git a/src/gcal-event.h b/src/gcal-event.h
index f5514d0a..dd6b26ff 100644
--- a/src/gcal-event.h
+++ b/src/gcal-event.h
@@ -106,11 +106,6 @@ const gchar* gcal_event_get_summary (GcalEvent
void gcal_event_set_summary (GcalEvent *self,
const gchar *summary);
-GTimeZone* gcal_event_get_timezone (GcalEvent *self);
-
-void gcal_event_set_timezone (GcalEvent *self,
- GTimeZone *timezone);
-
const gchar* gcal_event_get_uid (GcalEvent *self);
/* Utilities */
@@ -129,6 +124,12 @@ void gcal_event_set_recurrence (GcalEvent
GcalRecurrence* gcal_event_get_recurrence (GcalEvent *self);
+void gcal_event_save_original_timezones (GcalEvent *self);
+
+void gcal_event_get_original_timezones (GcalEvent *self,
+ GTimeZone **start_tz,
+ GTimeZone **end_tz);
+
G_END_DECLS
#endif /* GCAL_EVENT_H */
diff --git a/src/gcal-quick-add-popover.c b/src/gcal-quick-add-popover.c
index f5fd7ada..59567a62 100644
--- a/src/gcal-quick-add-popover.c
+++ b/src/gcal-quick-add-popover.c
@@ -686,7 +686,6 @@ edit_or_create_event (GcalQuickAddPopover *self,
event = gcal_event_new (source, component, NULL);
gcal_event_set_all_day (event, all_day);
- gcal_event_set_timezone (event, tz);
/* If we clicked edit button, send a signal; otherwise, create the event */
if (button == self->add_button)
diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c
index 18d27044..9f2c6201 100644
--- a/src/views/gcal-month-view.c
+++ b/src/views/gcal-month-view.c
@@ -687,12 +687,13 @@ allocate_multiday_events (GcalMonthView *self,
* have to worry about the dates, since GcalEventWidget performs
* some checks and only applies the dates when it's valid.
*/
- dt_start = g_date_time_new (gcal_event_get_timezone (event),
+ dt_start = g_date_time_new (g_date_time_get_timezone (gcal_event_get_date_start (event)),
self->date->year,
self->date->month,
day,
0, 0, 0);
+ /* FIXME: use end date's timezone here */
dt_end = g_date_time_add_days (dt_start, length);
gcal_event_widget_set_date_start (GCAL_EVENT_WIDGET (child_widget), dt_start);
diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c
index c2ef011d..d9b3084a 100644
--- a/src/views/gcal-week-header.c
+++ b/src/views/gcal-week-header.c
@@ -1547,7 +1547,7 @@ gcal_week_header_drag_drop (GtkWidget *widget,
* The only case where we don't touch the timezone is for
* timed, multiday events.
*/
- tmp_dt = g_date_time_new (gcal_event_get_timezone (event),
+ tmp_dt = g_date_time_new (g_date_time_get_timezone (start_date),
g_date_time_get_year (week_start),
g_date_time_get_month (week_start),
g_date_time_get_day_of_month (week_start),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]