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
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
+144
-109
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
+170
-103
@@ -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,7 +178,18 @@ get_timezone_from_ical (ECalComponentDateTime *comp)
|
||||
*/
|
||||
tz = g_time_zone_new_utc ();
|
||||
}
|
||||
else if (icaltime_get_timezone (*comp->value))
|
||||
else if (comp->tzid)
|
||||
{
|
||||
const gchar *real_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 (zone)
|
||||
{
|
||||
g_autofree gchar *tzid = NULL;
|
||||
gint offset;
|
||||
@@ -196,22 +197,6 @@ get_timezone_from_ical (ECalComponentDateTime *comp)
|
||||
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 if (comp->tzid)
|
||||
{
|
||||
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);
|
||||
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;
|
||||
}
|
||||
|
||||
+6
-5
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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),
|
||||
|
||||
Reference in New Issue
Block a user