[evolution-ews/gnome-3-36] I#45 - Event time shifted by an hour after edit for some time zones



commit c2ff0fa71f538f8ddbcfbe5c0d01ac11335dcda5
Author: Milan Crha <mcrha redhat com>
Date:   Wed Apr 1 13:50:53 2020 +0200

    I#45 - Event time shifted by an hour after edit for some time zones
    
    Closes https://gitlab.gnome.org/GNOME/evolution-ews/-/issues/45

 src/calendar/e-cal-backend-ews.c | 56 +++++++++++++++++++++++++++++++++++-----
 src/server/e-ews-item.c          | 22 ++++++++++++++++
 src/server/e-ews-item.h          |  2 ++
 3 files changed, 73 insertions(+), 7 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index 6869f44b..443839c4 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -85,6 +85,8 @@ struct _ECalBackendEwsPrivate {
        " item:HasAttachments" \
        " item:MimeContent" \
        " calendar:UID" \
+       " calendar:Start" \
+       " calendar:End" \
        " calendar:Resources" \
        " calendar:ModifiedOccurrences" \
        " calendar:IsMeeting" \
@@ -359,6 +361,41 @@ ecb_ews_responsetype_to_partstat (const gchar *responsetype)
        return param;
 }
 
+static void
+ecb_ews_maybe_update_datetime (ETimezoneCache *timezone_cache,
+                              ICalComponent *vcomp,
+                              ICalComponent *icomp,
+                              ICalPropertyKind prop_kind,
+                              ICalTime * (* get_func) (ICalProperty *prop),
+                              void (* set_func) (ICalProperty *prop,
+                                                 ICalTime *v),
+                              time_t utc_value)
+{
+       ICalProperty *prop;
+       ICalTime *dt, *val;
+
+       g_return_if_fail (I_CAL_IS_COMPONENT (icomp));
+       g_return_if_fail (get_func != NULL);
+       g_return_if_fail (set_func != NULL);
+
+       if (utc_value == (time_t) -1)
+               return;
+
+       prop = i_cal_component_get_first_property (icomp, prop_kind);
+       if (!prop)
+               return;
+
+       dt = e_cal_backend_ews_get_datetime_with_zone (timezone_cache, vcomp, icomp, prop_kind, get_func);
+
+       val = i_cal_time_new_from_timet_with_zone (utc_value, i_cal_time_is_date (dt), 
i_cal_timezone_get_utc_timezone ());
+       i_cal_time_convert_to_zone_inplace (val, i_cal_time_get_timezone (dt));
+       set_func (prop, val);
+
+       g_clear_object (&prop);
+       g_clear_object (&val);
+       g_clear_object (&dt);
+}
+
 static ECalComponent *
 ecb_ews_item_to_component_sync (ECalBackendEws *cbews,
                                EEwsItem *item,
@@ -629,6 +666,16 @@ ecb_ews_item_to_component_sync (ECalBackendEws *cbews,
                        return NULL;
                }
 
+               icomp = i_cal_component_get_first_component (vcomp, kind);
+
+               ecb_ews_maybe_update_datetime (timezone_cache, vcomp, icomp,
+                       I_CAL_DTSTART_PROPERTY, i_cal_property_get_dtstart, i_cal_property_set_dtstart,
+                       e_ews_item_get_start (item));
+
+               ecb_ews_maybe_update_datetime (timezone_cache, vcomp, icomp,
+                       I_CAL_DTEND_PROPERTY, i_cal_property_get_dtend, i_cal_property_set_dtend,
+                       e_ews_item_get_end (item));
+
                tzid = e_ews_item_get_tzid (item);
                if (tzid == NULL) {
                        /*
@@ -680,8 +727,6 @@ ecb_ews_item_to_component_sync (ECalBackendEws *cbews,
                                evo_ews_end_tzid);
 
                        if (start_zone != NULL) {
-                               icomp = i_cal_component_get_first_component (vcomp, kind);
-
                                dt = e_cal_backend_ews_get_datetime_with_zone (timezone_cache, vcomp, icomp, 
I_CAL_DTSTART_PROPERTY, i_cal_property_get_dtstart);
                                i_cal_time_convert_to_zone_inplace (dt, start_zone);
                                i_cal_component_set_dtstart (icomp, dt);
@@ -698,8 +743,6 @@ ecb_ews_item_to_component_sync (ECalBackendEws *cbews,
 
                                        e_timezone_cache_add_timezone (timezone_cache, end_zone);
                                }
-
-                               g_clear_object (&icomp);
                        }
 
                        if (!timezone_set)
@@ -717,8 +760,6 @@ ecb_ews_item_to_component_sync (ECalBackendEws *cbews,
                        ICalTimezone *zone;
                        gchar *new_tzid = NULL;
 
-                       icomp = i_cal_component_get_first_component (vcomp, kind);
-
                        if (!i_cal_timezone_get_builtin_timezone (tzid) &&
                            i_cal_component_get_uid (icomp)) {
                                ICalComponent *vtimezone, *clone;
@@ -780,9 +821,10 @@ ecb_ews_item_to_component_sync (ECalBackendEws *cbews,
                                g_object_unref (dt);
                        }
 
-                       g_clear_object (&icomp);
                        g_free (new_tzid);
                }
+
+               g_clear_object (&icomp);
        }
 
        /* Vevent or Vtodo */
diff --git a/src/server/e-ews-item.c b/src/server/e-ews-item.c
index a2df1bd5..aba32b53 100644
--- a/src/server/e-ews-item.c
+++ b/src/server/e-ews-item.c
@@ -126,6 +126,8 @@ struct _EEwsItemPrivate {
 
        gchar *uid;
        gchar *timezone;
+       time_t calendar_start;
+       time_t calendar_end;
        gchar *start_timezone;
        gchar *end_timezone;
        gchar *contact_photo_id;
@@ -1648,6 +1650,10 @@ e_ews_item_set_from_soap_parameter (EEwsItem *item,
                        priv->calendar_item_accept_id = g_new0 (EwsId, 1);
                        priv->calendar_item_accept_id->id = e_soap_parameter_get_property (subparam, "Id");
                        priv->calendar_item_accept_id->change_key = e_soap_parameter_get_property (subparam, 
"ChangeKey");
+               } else if (!g_ascii_strcasecmp (name, "Start")) {
+                       priv->calendar_start = ews_item_parse_date (subparam);
+               } else if (!g_ascii_strcasecmp (name, "End")) {
+                       priv->calendar_end = ews_item_parse_date (subparam);
                } else if (!g_ascii_strcasecmp (name, "StartTimeZone")) {
                        priv->start_timezone = e_soap_parameter_get_property (subparam, "Id");
                } else if (!g_ascii_strcasecmp (name, "EndTimeZone")) {
@@ -2857,6 +2863,22 @@ e_ews_item_get_end_tzid (EEwsItem *item)
        return item->priv->end_timezone;
 }
 
+time_t
+e_ews_item_get_start (EEwsItem *item)
+{
+       g_return_val_if_fail (E_IS_EWS_ITEM (item), -1);
+
+       return item->priv->calendar_start;
+}
+
+time_t
+e_ews_item_get_end (EEwsItem *item)
+{
+       g_return_val_if_fail (E_IS_EWS_ITEM (item), -1);
+
+       return item->priv->calendar_end;
+}
+
 const gchar *
 e_ews_item_get_contact_photo_id (EEwsItem *item)
 {
diff --git a/src/server/e-ews-item.h b/src/server/e-ews-item.h
index f5ce6166..32c54e02 100644
--- a/src/server/e-ews-item.h
+++ b/src/server/e-ews-item.h
@@ -448,6 +448,8 @@ gboolean    e_ews_item_task_has_complete_date
 const gchar *  e_ews_item_get_tzid             (EEwsItem *item);
 const gchar *  e_ews_item_get_start_tzid       (EEwsItem *item);
 const gchar *  e_ews_item_get_end_tzid         (EEwsItem *item);
+time_t         e_ews_item_get_start            (EEwsItem *item);
+time_t         e_ews_item_get_end              (EEwsItem *item);
 const gchar *  e_ews_item_get_contact_photo_id (EEwsItem *item);
 const gchar *  e_ews_item_get_iana_start_time_zone
                                                (EEwsItem *item);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]