[evolution-ews] Make it possible to disable Reminders for Tasks



commit 3d17e2cfd247f12488367ad7129c71be883d40e5
Author: Milan Crha <mcrha redhat com>
Date:   Fri Mar 16 12:55:25 2018 +0100

    Make it possible to disable Reminders for Tasks

 src/calendar/e-cal-backend-ews-utils.c |   37 ++++++++++++++++++---
 src/calendar/e-cal-backend-ews-utils.h |    2 +-
 src/calendar/e-cal-backend-ews.c       |   57 ++++++++++++++++++++++++++++++++
 src/server/e-ews-item.c                |   46 +++++++++++++++++++++++++-
 src/server/e-ews-item.h                |    4 ++
 5 files changed, 139 insertions(+), 7 deletions(-)
---
diff --git a/src/calendar/e-cal-backend-ews-utils.c b/src/calendar/e-cal-backend-ews-utils.c
index 8edbde6..eec1544 100644
--- a/src/calendar/e-cal-backend-ews-utils.c
+++ b/src/calendar/e-cal-backend-ews-utils.c
@@ -308,7 +308,8 @@ ews_get_alarm (ECalComponent *comp)
 
 void
 ews_set_alarm (ESoapMessage *msg,
-               ECalComponent *comp)
+               ECalComponent *comp,
+              gboolean with_due_by)
 {
        /* We know there would be only a single alarm in EWS calendar item */
        GList *alarm_uids = e_cal_component_get_alarm_uids (comp);
@@ -319,14 +320,23 @@ ews_set_alarm (ESoapMessage *msg,
        e_cal_component_alarm_get_action (alarm, &action);
        if (action == E_CAL_COMPONENT_ALARM_DISPLAY) {
                ECalComponentAlarmTrigger trigger;
-               gchar buf[20];
                gint dur_int = 0;
+
                e_cal_component_alarm_get_trigger (alarm, &trigger);
                switch (trigger.type) {
                case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START:
                        dur_int = ((icaldurationtype_as_int (trigger.u.rel_duration)) / SECS_IN_MINUTE) * -1;
-                       snprintf (buf, 20, "%d", dur_int);
-                       e_ews_message_write_string_parameter (msg, "ReminderMinutesBeforeStart", NULL, buf);
+                       e_ews_message_write_int_parameter (msg, "ReminderMinutesBeforeStart", NULL, dur_int);
+                       if (with_due_by) {
+                               struct icaltimetype dtstart;
+
+                               dtstart = icalcomponent_get_dtstart (e_cal_component_get_icalcomponent 
(comp));
+
+                               if (!icaltime_is_null_time (dtstart)) {
+                                       e_ews_message_write_time_parameter (msg, "ReminderDueBy", NULL,
+                                               icaltime_as_timet_with_zone (dtstart, 
icaltimezone_get_utc_timezone ()));
+                               }
+                       }
                        break;
                default:
                        break;
@@ -1088,7 +1098,7 @@ convert_vevent_calcomp_to_xml (ESoapMessage *msg,
        /* set alarms */
        has_alarms = e_cal_component_has_alarms (comp);
        if (has_alarms)
-               ews_set_alarm (msg, comp);
+               ews_set_alarm (msg, comp, FALSE);
        else
                e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "false");
 
@@ -1215,6 +1225,7 @@ convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
        icaltimetype dt;
        gint value;
        gchar buffer[16];
+       /* gboolean has_alarms; */
 
        e_soap_message_start_element (msg, "Task", NULL, NULL);
 
@@ -1259,6 +1270,22 @@ convert_vtodo_calcomp_to_xml (ESoapMessage *msg,
                }
        }
 
+       /* has_alarms = icalcomponent_get_first_component (icalcomp, ICAL_VALARM_COMPONENT) != NULL;
+       if (has_alarms) {
+               ECalComponent *comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone 
(icalcomp));
+
+               if (comp && e_cal_component_has_alarms (comp)) {
+                       ews_set_alarm (msg, comp, TRUE);
+               } else {
+                       has_alarms = FALSE;
+               }
+
+               g_clear_object (&comp);
+       }
+
+       if (!has_alarms)
+               e_ews_message_write_string_parameter (msg, "ReminderIsSet", NULL, "false");*/
+
        e_soap_message_end_element (msg); /* "Task" */
 }
 
diff --git a/src/calendar/e-cal-backend-ews-utils.h b/src/calendar/e-cal-backend-ews-utils.h
index 521e0e8..4aea6d2 100644
--- a/src/calendar/e-cal-backend-ews-utils.h
+++ b/src/calendar/e-cal-backend-ews-utils.h
@@ -62,7 +62,7 @@ void ewscal_set_meeting_timezone (ESoapMessage *msg, icaltimezone *icaltz);
 void ewscal_set_reccurence (ESoapMessage *msg, icalproperty *rrule, icaltimetype *dtstart);
 void ewscal_set_reccurence_exceptions (ESoapMessage *msg, icalcomponent *comp);
 gchar *e_ews_extract_attachment_id_from_uri (const gchar *uri);
-void ews_set_alarm (ESoapMessage *msg, ECalComponent *comp);
+void ews_set_alarm (ESoapMessage *msg, ECalComponent *comp, gboolean with_due_by);
 gint ews_get_alarm (ECalComponent *comp);
 void e_ews_clean_icalcomponent (icalcomponent *icalcomp);
 
diff --git a/src/calendar/e-cal-backend-ews.c b/src/calendar/e-cal-backend-ews.c
index e4eea0f..447732e 100644
--- a/src/calendar/e-cal-backend-ews.c
+++ b/src/calendar/e-cal-backend-ews.c
@@ -476,6 +476,62 @@ ecb_ews_item_to_component_sync (ECalBackendEws *cbews,
                                priority = 7;
                        icalprop = icalproperty_new_priority (priority);
                        icalcomponent_add_property (icalcomp, icalprop);
+
+                       /* reminders */
+                       /* The Exchange server stores start of the Task reminder and Start of the Task
+                          itself in separate properties, which doesn't work for evolution at the moment. */
+                       /* if (e_ews_item_get_reminder_is_set (item)) {
+                               time_t reminder_due_by = e_ews_item_get_reminder_due_by (item);
+                               gint minutes_before_start = e_ews_item_get_reminder_minutes_before_start 
(item);
+
+                               if (minutes_before_start >= 0 && reminder_due_by > (time_t) 0) {
+                                       ECalComponentAlarmTrigger trigger;
+                                       ECalComponentAlarmRepeat repeat;
+                                       ECalComponentAlarm *alarm;
+                                       icalcomponent *alarm_icalcomp;
+                                       struct icaltimetype dtstart, due_by;
+
+                                       dtstart = icalcomponent_get_dtstart (icalcomp);
+                                       due_by = icaltime_from_timet_with_zone (reminder_due_by, 0, utc_zone);
+
+                                       if (icaltime_is_null_time (dtstart)) {
+                                               dtstart = due_by;
+                                               dtstart.is_date = 1;
+
+                                               icalcomponent_set_dtstart (icalcomp, dtstart);
+                                       }
+
+                                       dtstart.is_date = 0;
+                                       dtstart.hour = 0;
+                                       dtstart.minute = 0;
+                                       dtstart.second = 0;
+                                       dtstart.zone = utc_zone;
+
+                                       minutes_before_start = minutes_before_start + (
+                                               (icaltime_as_timet_with_zone (dtstart, utc_zone) -
+                                                icaltime_as_timet_with_zone (due_by, utc_zone)) / 60);
+
+                                       alarm = e_cal_component_alarm_new ();
+                                       memset (&trigger, 0, sizeof (ECalComponentAlarmTrigger));
+
+                                       trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
+                                       trigger.u.rel_duration.is_neg = minutes_before_start < 0 ? 0 : 1; / * 
negative 'before start' means 'after start' * /
+                                       trigger.u.rel_duration.minutes = minutes_before_start < 0 ? 
-minutes_before_start : minutes_before_start;
+
+                                       memset (&repeat, 0, sizeof (repeat));
+                                       repeat.repetitions = 0;
+
+                                       e_cal_component_alarm_set_trigger (alarm, trigger);
+                                       e_cal_component_alarm_set_action (alarm, 
E_CAL_COMPONENT_ALARM_DISPLAY);
+                                       e_cal_component_alarm_set_repeat (alarm, repeat);
+
+                                       alarm_icalcomp = e_cal_component_alarm_get_icalcomponent (alarm);
+                                       if (alarm_icalcomp)
+                                               icalcomponent_add_component (icalcomp, alarm_icalcomp);
+
+                                       e_cal_component_alarm_free (alarm);
+                               }
+                       } */
                }
 
                icalcomponent_add_component (vcomp, icalcomp);
@@ -3645,6 +3701,7 @@ ecb_ews_get_backend_property (ECalBackend *cal_backend,
                        CAL_STATIC_CAPABILITY_NO_MEMO_START_DATE,
                        CAL_STATIC_CAPABILITY_ALL_DAY_EVENT_AS_TIME,
                        CAL_STATIC_CAPABILITY_TASK_DATE_ONLY,
+                       CAL_STATIC_CAPABILITY_TASK_NO_ALARM,
                        e_cal_meta_backend_get_capabilities (E_CAL_META_BACKEND (cbews)),
                        NULL);
        } else if (g_str_equal (prop_name, CAL_BACKEND_PROPERTY_CAL_EMAIL_ADDRESS)) {
diff --git a/src/server/e-ews-item.c b/src/server/e-ews-item.c
index 4fbfed7..e92475a 100644
--- a/src/server/e-ews-item.c
+++ b/src/server/e-ews-item.c
@@ -148,6 +148,10 @@ struct _EEwsItemPrivate {
         * <Categories> which is a string array valued XML element */
        GSList *categories;
 
+       gboolean reminder_is_set;
+       time_t reminder_due_by;
+       gint reminder_minutes_before_start;
+
        struct _EEwsContactFields *contact_fields;
        struct _EEwsTaskFields *task_fields;
 };
@@ -305,6 +309,9 @@ e_ews_item_init (EEwsItem *item)
 
        item->priv->mapi_extended_tags = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, g_free);
        item->priv->mapi_extended_sets = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, 
(GDestroyNotify) g_hash_table_destroy);
+
+       item->priv->reminder_is_set = FALSE;
+       item->priv->reminder_minutes_before_start = -1;
 }
 
 static void
@@ -1133,6 +1140,16 @@ e_ews_item_set_from_soap_parameter (EEwsItem *item,
                        g_free (value);
                } else if (!g_ascii_strcasecmp (name, "TimeZone")) {
                        priv->timezone = e_soap_parameter_get_string_value (subparam);
+               } else if (!g_ascii_strcasecmp (name, "ReminderIsSet")) {
+                       value = e_soap_parameter_get_string_value (subparam);
+                       priv->reminder_is_set = (!g_ascii_strcasecmp (value, "true"));
+                       g_free (value);
+               } else if (!g_ascii_strcasecmp (name, "ReminderDueBy")) {
+                       value = e_soap_parameter_get_string_value (subparam);
+                       priv->reminder_due_by = ews_item_parse_date (value);
+                       g_free (value);
+               } else if (!g_ascii_strcasecmp (name, "ReminderMinutesBeforeStart")) {
+                       priv->reminder_minutes_before_start = e_soap_parameter_get_int_value (subparam);
                } else if (priv->item_type == E_EWS_ITEM_TYPE_TASK || priv->item_type == 
E_EWS_ITEM_TYPE_MEMO) {
                        parse_task_field (item, name, subparam);
                        /* fields below are not relevant for task, so skip them */
@@ -1889,6 +1906,32 @@ e_ews_item_get_calendar_item_accept_id (EEwsItem *item)
        return (const EwsId *) item->priv->calendar_item_accept_id;
 }
 
+gboolean
+e_ews_item_get_reminder_is_set (EEwsItem *item)
+{
+       g_return_val_if_fail (E_IS_EWS_ITEM (item), FALSE);
+
+       return item->priv->reminder_is_set;
+}
+
+time_t
+e_ews_item_get_reminder_due_by (EEwsItem *item)
+{
+       g_return_val_if_fail (E_IS_EWS_ITEM (item), -1);
+
+       return item->priv->reminder_due_by;
+}
+
+/* -1 when not set, but should really check also
+   e_ews_item_get_reminder_is_set() before using the value */
+gint
+e_ews_item_get_reminder_minutes_before_start (EEwsItem *item)
+{
+       g_return_val_if_fail (E_IS_EWS_ITEM (item), -1);
+
+       return item->priv->reminder_minutes_before_start;
+}
+
 const gchar *
 e_ews_item_get_fileas (EEwsItem *item)
 {
@@ -2170,7 +2213,8 @@ e_ews_item_get_status (EEwsItem *item)
        return item->priv->task_fields->status;
 }
 
-const gchar *  e_ews_item_get_percent_complete (EEwsItem *item)
+const gchar *
+e_ews_item_get_percent_complete (EEwsItem *item)
 {
        g_return_val_if_fail (E_IS_EWS_ITEM (item), NULL);
        g_return_val_if_fail (item->priv->task_fields != NULL, NULL);
diff --git a/src/server/e-ews-item.h b/src/server/e-ews-item.h
index f5ee3df..a2f3ce1 100644
--- a/src/server/e-ews-item.h
+++ b/src/server/e-ews-item.h
@@ -210,6 +210,10 @@ EwsImportance
                e_ews_item_get_importance       (EEwsItem *item);
 const GSList *
                e_ews_item_get_categories       (EEwsItem *item);
+gboolean       e_ews_item_get_reminder_is_set  (EEwsItem *item);
+time_t         e_ews_item_get_reminder_due_by  (EEwsItem *item);
+gint           e_ews_item_get_reminder_minutes_before_start
+                                               (EEwsItem *item);
 EwsMailbox *
                e_ews_item_mailbox_from_soap_param
                                                (ESoapParameter *param);


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