[evolution] I#208 - Task Completed time should be in UTC



commit 06ef2f22379274c918f6336a416eb9c15659a6a5
Author: Milan Crha <mcrha redhat com>
Date:   Mon Nov 5 16:58:45 2018 +0100

    I#208 - Task Completed time should be in UTC
    
    Closes https://gitlab.gnome.org/GNOME/evolution/issues/208

 src/calendar/gui/e-comp-editor-event.c          |  9 ++-
 src/calendar/gui/e-comp-editor-property-part.c  | 93 ++++++++++++++++++++++++-
 src/calendar/gui/e-comp-editor-property-parts.c | 18 +++--
 src/calendar/gui/e-comp-editor-task.c           | 10 ++-
 src/calendar/gui/e-comp-editor.c                | 30 ++++++++
 src/calendar/gui/e-comp-editor.h                |  2 +
 6 files changed, 150 insertions(+), 12 deletions(-)
---
diff --git a/src/calendar/gui/e-comp-editor-event.c b/src/calendar/gui/e-comp-editor-event.c
index d4bb9f7493..361c1e3d3d 100644
--- a/src/calendar/gui/e-comp-editor-event.c
+++ b/src/calendar/gui/e-comp-editor-event.c
@@ -366,16 +366,17 @@ ece_event_fill_widgets (ECompEditor *comp_editor,
        g_return_if_fail (E_IS_COMP_EDITOR_EVENT (comp_editor));
        g_return_if_fail (component != NULL);
 
-       E_COMP_EDITOR_CLASS (e_comp_editor_event_parent_class)->fill_widgets (comp_editor, component);
-
        event_editor = E_COMP_EDITOR_EVENT (comp_editor);
 
        flags = e_comp_editor_get_flags (comp_editor);
        dtstart = icaltime_null_time ();
        dtend = icaltime_null_time ();
 
+       /* Set timezone before the times, because they are converted into this timezone */
        ece_event_update_timezone (event_editor, &dtstart, &dtend);
 
+       E_COMP_EDITOR_CLASS (e_comp_editor_event_parent_class)->fill_widgets (comp_editor, component);
+
        if (icaltime_is_valid_time (dtstart) && !icaltime_is_null_time (dtstart) &&
            (!icaltime_is_valid_time (dtend) || icaltime_is_null_time (dtend))) {
                dtend = dtstart;
@@ -888,9 +889,13 @@ e_comp_editor_event_constructed (GObject *object)
        e_comp_editor_property_part_datetime_attach_timezone_entry (
                E_COMP_EDITOR_PROPERTY_PART_DATETIME (event_editor->priv->dtstart),
                E_TIMEZONE_ENTRY (widget));
+       g_signal_connect_swapped (event_editor->priv->dtstart, "lookup-timezone",
+               G_CALLBACK (e_comp_editor_lookup_timezone), event_editor);
        e_comp_editor_property_part_datetime_attach_timezone_entry (
                E_COMP_EDITOR_PROPERTY_PART_DATETIME (event_editor->priv->dtend),
                E_TIMEZONE_ENTRY (widget));
+       g_signal_connect_swapped (event_editor->priv->dtend, "lookup-timezone",
+               G_CALLBACK (e_comp_editor_lookup_timezone), event_editor);
 
        e_comp_editor_set_time_parts (comp_editor, event_editor->priv->dtstart, event_editor->priv->dtend);
 
diff --git a/src/calendar/gui/e-comp-editor-property-part.c b/src/calendar/gui/e-comp-editor-property-part.c
index 094b978c49..3b661d7f43 100644
--- a/src/calendar/gui/e-comp-editor-property-part.c
+++ b/src/calendar/gui/e-comp-editor-property-part.c
@@ -586,8 +586,29 @@ struct _ECompEditorPropertyPartDatetimePrivate {
        GWeakRef timezone_entry;
 };
 
+enum {
+       ECEPP_DATETIME_LOOKUP_TIMEZONE,
+       ECEPP_DATETIME_LAST_SIGNAL
+};
+
+static guint ecepp_datetime_signals[ECEPP_DATETIME_LAST_SIGNAL];
+
 G_DEFINE_ABSTRACT_TYPE (ECompEditorPropertyPartDatetime, e_comp_editor_property_part_datetime, 
E_TYPE_COMP_EDITOR_PROPERTY_PART)
 
+static icaltimezone *
+ecepp_datetime_lookup_timezone (ECompEditorPropertyPartDatetime *part_datetime,
+                               const gchar *tzid)
+{
+       icaltimezone *zone = NULL;
+
+       if (!tzid || !*tzid)
+               return NULL;
+
+       g_signal_emit (part_datetime, ecepp_datetime_signals[ECEPP_DATETIME_LOOKUP_TIMEZONE], 0, tzid, &zone);
+
+       return zone;
+}
+
 static void
 ecepp_datetime_create_widgets (ECompEditorPropertyPart *property_part,
                               GtkWidget **out_label_widget,
@@ -645,10 +666,41 @@ ecepp_datetime_fill_widget (ECompEditorPropertyPart *property_part,
        part_datetime = E_COMP_EDITOR_PROPERTY_PART_DATETIME (property_part);
 
        prop = icalcomponent_get_first_property (component, klass->ical_prop_kind);
-       if (prop)
+       if (prop) {
+               ETimezoneEntry *timezone_entry = g_weak_ref_get (&part_datetime->priv->timezone_entry);
+
                value = klass->ical_get_func (prop);
-       else
+
+               if (timezone_entry && !value.is_date) {
+                       icaltimezone *editor_zone = e_timezone_entry_get_timezone (timezone_entry);
+
+                       /* Attempt to convert time to the zone used in the editor */
+                       if (editor_zone && !value.zone && !icaltime_is_utc (value)) {
+                               icalparameter *param;
+
+                               param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
+                               if (param) {
+                                       const gchar *tzid;
+
+                                       tzid = icalparameter_get_tzid (param);
+
+                                       if (tzid && *tzid) {
+                                               if (editor_zone &&
+                                                   (g_strcmp0 (icaltimezone_get_tzid (editor_zone), tzid) == 
0 ||
+                                                   g_strcmp0 (icaltimezone_get_location (editor_zone), tzid) 
== 0)) {
+                                                       value.zone = editor_zone;
+                                               } else {
+                                                       value.zone = ecepp_datetime_lookup_timezone 
(part_datetime, tzid);
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               g_clear_object (&timezone_entry);
+       } else {
                value = icaltime_null_time ();
+       }
 
        e_comp_editor_property_part_datetime_set_value (part_datetime, value);
 }
@@ -675,6 +727,7 @@ ecepp_datetime_fill_component (ECompEditorPropertyPart *property_part,
        g_return_if_fail (klass != NULL);
        g_return_if_fail (klass->ical_prop_kind != ICAL_NO_PROPERTY);
        g_return_if_fail (klass->ical_new_func != NULL);
+       g_return_if_fail (klass->ical_get_func != NULL);
        g_return_if_fail (klass->ical_set_func != NULL);
 
        part_datetime = E_COMP_EDITOR_PROPERTY_PART_DATETIME (property_part);
@@ -696,9 +749,17 @@ ecepp_datetime_fill_component (ECompEditorPropertyPart *property_part,
                        icalproperty_remove_parameter_by_kind (prop, ICAL_VALUE_PARAMETER);
 
                        klass->ical_set_func (prop, value);
+
+                       /* Re-read the value, because it could be changed by the descendant */
+                       value = klass->ical_get_func (prop);
+
                        cal_comp_util_update_tzid_parameter (prop, value);
                } else {
                        prop = klass->ical_new_func (value);
+
+                       /* Re-read the value, because it could be changed by the descendant */
+                       value = klass->ical_get_func (prop);
+
                        cal_comp_util_update_tzid_parameter (prop, value);
                        icalcomponent_add_property (component, prop);
                }
@@ -745,6 +806,16 @@ e_comp_editor_property_part_datetime_class_init (ECompEditorPropertyPartDatetime
 
        object_class = G_OBJECT_CLASS (klass);
        object_class->finalize = ecepp_datetime_finalize;
+
+       /* icaltimezone *lookup_timezone (datetime, const gchar *tzid); */
+       ecepp_datetime_signals[ECEPP_DATETIME_LOOKUP_TIMEZONE] = g_signal_new (
+               "lookup-timezone",
+               G_OBJECT_CLASS_TYPE (object_class),
+               G_SIGNAL_ACTION,
+               0,
+               NULL, NULL, NULL,
+               G_TYPE_POINTER, 1,
+               G_TYPE_STRING);
 }
 
 void
@@ -838,6 +909,24 @@ e_comp_editor_property_part_datetime_set_value (ECompEditorPropertyPartDatetime
            !icaltime_is_valid_time (value)) {
                e_date_edit_set_time (date_edit, (time_t) -1);
        } else {
+               /* Convert to the same time zone as the editor uses, if different */
+               if (!value.is_date && value.zone) {
+                       ETimezoneEntry *timezone_entry = g_weak_ref_get 
(&part_datetime->priv->timezone_entry);
+
+                       if (timezone_entry) {
+                               icaltimezone *editor_zone = e_timezone_entry_get_timezone (timezone_entry);
+
+                               if (editor_zone && value.zone != editor_zone &&
+                                   g_strcmp0 (icaltimezone_get_tzid (editor_zone), icaltimezone_get_tzid 
((icaltimezone *) value.zone)) != 0 &&
+                                   g_strcmp0 (icaltimezone_get_location (editor_zone), 
icaltimezone_get_location ((icaltimezone *) value.zone)) != 0) {
+                                       icaltimezone_convert_time (&value, (icaltimezone *) value.zone, 
editor_zone);
+                                       value.zone = editor_zone;
+                               }
+                       }
+
+                       g_clear_object (&timezone_entry);
+               }
+
                e_date_edit_set_date (date_edit, value.year, value.month, value.day);
 
                if (!value.is_date)
diff --git a/src/calendar/gui/e-comp-editor-property-parts.c b/src/calendar/gui/e-comp-editor-property-parts.c
index b279a0ba2d..967651f20f 100644
--- a/src/calendar/gui/e-comp-editor-property-parts.c
+++ b/src/calendar/gui/e-comp-editor-property-parts.c
@@ -1094,14 +1094,20 @@ G_DEFINE_TYPE (ECompEditorPropertyPartCompleted, e_comp_editor_property_part_com
 static void
 e_comp_editor_property_part_completed_ensure_date_time (struct icaltimetype *pvalue)
 {
-       if (!pvalue || !pvalue->is_date)
+       if (!pvalue)
                return;
 
-       pvalue->is_date = 0;
-       pvalue->hour = 0;
-       pvalue->minute = 0;
-       pvalue->second = 0;
-       pvalue->zone = icaltimezone_get_utc_timezone ();
+       if (pvalue->is_date) {
+               pvalue->is_date = 0;
+               pvalue->hour = 0;
+               pvalue->minute = 0;
+               pvalue->second = 0;
+               pvalue->zone = icaltimezone_get_utc_timezone ();
+       } else if (!icaltime_is_utc (*pvalue)) {
+               /* Make sure the time is in UTC */
+               icaltimezone_convert_time (pvalue, (icaltimezone *) pvalue->zone, 
icaltimezone_get_utc_timezone ());
+               pvalue->zone = icaltimezone_get_utc_timezone ();
+       }
 }
 
 static icalproperty *
diff --git a/src/calendar/gui/e-comp-editor-task.c b/src/calendar/gui/e-comp-editor-task.c
index ca05ad2885..0493cecb0e 100644
--- a/src/calendar/gui/e-comp-editor-task.c
+++ b/src/calendar/gui/e-comp-editor-task.c
@@ -514,10 +514,10 @@ ece_task_fill_widgets (ECompEditor *comp_editor,
        g_return_if_fail (E_IS_COMP_EDITOR_TASK (comp_editor));
        g_return_if_fail (component != NULL);
 
-       E_COMP_EDITOR_CLASS (e_comp_editor_task_parent_class)->fill_widgets (comp_editor, component);
-
        ece_task_update_timezone (E_COMP_EDITOR_TASK (comp_editor), &force_allday);
 
+       E_COMP_EDITOR_CLASS (e_comp_editor_task_parent_class)->fill_widgets (comp_editor, component);
+
        if (force_allday) {
                GtkAction *action;
 
@@ -833,12 +833,18 @@ e_comp_editor_task_constructed (GObject *object)
        e_comp_editor_property_part_datetime_attach_timezone_entry (
                E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor->priv->dtstart),
                E_TIMEZONE_ENTRY (edit_widget));
+       g_signal_connect_swapped (task_editor->priv->dtstart, "lookup-timezone",
+               G_CALLBACK (e_comp_editor_lookup_timezone), task_editor);
        e_comp_editor_property_part_datetime_attach_timezone_entry (
                E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor->priv->due_date),
                E_TIMEZONE_ENTRY (edit_widget));
+       g_signal_connect_swapped (task_editor->priv->due_date, "lookup-timezone",
+               G_CALLBACK (e_comp_editor_lookup_timezone), task_editor);
        e_comp_editor_property_part_datetime_attach_timezone_entry (
                E_COMP_EDITOR_PROPERTY_PART_DATETIME (task_editor->priv->completed_date),
                E_TIMEZONE_ENTRY (edit_widget));
+       g_signal_connect_swapped (task_editor->priv->completed_date, "lookup-timezone",
+               G_CALLBACK (e_comp_editor_lookup_timezone), task_editor);
 
        e_comp_editor_set_time_parts (comp_editor, task_editor->priv->dtstart, task_editor->priv->due_date);
 
diff --git a/src/calendar/gui/e-comp-editor.c b/src/calendar/gui/e-comp-editor.c
index f2309f904a..455a897eaa 100644
--- a/src/calendar/gui/e-comp-editor.c
+++ b/src/calendar/gui/e-comp-editor.c
@@ -3427,3 +3427,33 @@ e_comp_editor_find_existing_for (ESource *origin_source,
 
        return NULL;
 }
+
+/* Returned pointer is owned by libical or ECalClient; can return NULL */
+icaltimezone *
+e_comp_editor_lookup_timezone (ECompEditor *comp_editor,
+                              const gchar *tzid)
+{
+       icaltimezone *zone;
+
+       g_return_val_if_fail (E_IS_COMP_EDITOR (comp_editor), NULL);
+
+       if (!tzid || !*tzid)
+               return NULL;
+
+       zone = icaltimezone_get_builtin_timezone_from_tzid (tzid);
+
+       if (!zone)
+               zone = icaltimezone_get_builtin_timezone (tzid);
+
+       if (!zone && comp_editor->priv->source_client) {
+               if (!e_cal_client_get_timezone_sync (comp_editor->priv->source_client, tzid, &zone, NULL, 
NULL))
+                       zone = NULL;
+       }
+
+       if (!zone && comp_editor->priv->target_client && comp_editor->priv->source_client != 
comp_editor->priv->target_client) {
+               if (!e_cal_client_get_timezone_sync (comp_editor->priv->target_client, tzid, &zone, NULL, 
NULL))
+                       zone = NULL;
+       }
+
+       return zone;
+}
diff --git a/src/calendar/gui/e-comp-editor.h b/src/calendar/gui/e-comp-editor.h
index f5876c4fb3..76a06405a2 100644
--- a/src/calendar/gui/e-comp-editor.h
+++ b/src/calendar/gui/e-comp-editor.h
@@ -180,6 +180,8 @@ ECompEditor *       e_comp_editor_open_for_component
                                                 guint32 flags /* bit-or of ECompEditorFlags */);
 ECompEditor *  e_comp_editor_find_existing_for (ESource *origin_source,
                                                 const icalcomponent *component);
+icaltimezone * e_comp_editor_lookup_timezone   (ECompEditor *comp_editor,
+                                                const gchar *tzid);
 
 G_END_DECLS
 


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