[gnome-calendar/wip/mcrha/eds-libical-glib] Port to libecal-2.0



commit 8483862575b62dc6bc52ac8c10554c6104226da7
Author: Milan Crha <mcrha redhat com>
Date:   Wed Apr 17 18:05:54 2019 +0200

    Port to libecal-2.0

 contrib/evolution/e-cal-data-model-subscriber.c |   2 +-
 contrib/evolution/e-cal-data-model.c            | 500 ++++++++++++++++--------
 contrib/evolution/e-cal-data-model.h            |   9 +-
 data/ui/window.ui                               |   4 -
 meson.build                                     |   2 +-
 src/gcal-application.c                          |  24 +-
 src/gcal-edit-dialog.c                          |  16 +-
 src/gcal-event-widget.c                         |  16 +-
 src/gcal-event-widget.h                         |   2 -
 src/gcal-event.c                                | 297 ++++++++------
 src/gcal-manager.c                              |  31 +-
 src/gcal-manager.h                              |   8 +-
 src/gcal-recurrence.c                           | 119 +++---
 src/gcal-recurrence.h                           |   2 +-
 src/gcal-search-popover.c                       |  28 +-
 src/gcal-shell-search-provider.c                |  16 +-
 src/gcal-utils.c                                | 239 ++++++-----
 src/gcal-utils.h                                |  23 +-
 src/gcal-window.c                               |  99 ++---
 src/gcal-window.h                               |   2 +-
 src/views/gcal-month-popover.c                  |   7 +-
 src/views/gcal-month-view.c                     |  91 ++---
 src/views/gcal-view.c                           |  20 +-
 src/views/gcal-view.h                           |  16 +-
 src/views/gcal-week-grid.c                      |  10 +-
 src/views/gcal-week-grid.h                      |   2 +-
 src/views/gcal-week-header.c                    |  22 +-
 src/views/gcal-week-header.h                    |   2 +-
 src/views/gcal-week-view.c                      |  18 +-
 src/views/gcal-year-view.c                      | 193 +++++----
 src/views/gcal-year-view.h                      |   4 +-
 31 files changed, 1027 insertions(+), 797 deletions(-)
---
diff --git a/contrib/evolution/e-cal-data-model-subscriber.c b/contrib/evolution/e-cal-data-model-subscriber.c
index 04af1ae1..328b58ac 100644
--- a/contrib/evolution/e-cal-data-model-subscriber.c
+++ b/contrib/evolution/e-cal-data-model-subscriber.c
@@ -29,7 +29,7 @@ e_cal_data_model_subscriber_default_init (ECalDataModelSubscriberInterface *ifac
  * e_cal_data_model_subscriber_component_added:
  * @subscriber: an #ECalDataModelSubscriber
  * @client: an #ECalClient, which notifies about the component addition
- * @icalcomp: an #ECalComponent which was added
+ * @comp: an #ECalComponent which was added
  *
  * Notifies the @subscriber about an added component which belongs
  * to the time range used by the @subscriber.
diff --git a/contrib/evolution/e-cal-data-model.c b/contrib/evolution/e-cal-data-model.c
index 7ab6169d..077e3ae8 100644
--- a/contrib/evolution/e-cal-data-model.c
+++ b/contrib/evolution/e-cal-data-model.c
@@ -17,92 +17,106 @@
  */
 
 #include <glib.h>
-/*#include <glib/gi18n-lib.h>*/
+/* #include <glib/gi18n-lib.h> */
 
 #include "e-cal-data-model.h"
 
-#define LOCK_PROPS() g_rec_mutex_lock (&data_model->priv->props_lock)
-#define UNLOCK_PROPS() g_rec_mutex_unlock (&data_model->priv->props_lock)
-
-static void
+void
 cal_comp_get_instance_times (ECalClient *client,
-                            icalcomponent *icalcomp,
-                            const icaltimezone *default_zone,
-                            time_t *instance_start,
-                            gboolean *start_is_date,
-                            time_t *instance_end,
-                            gboolean *end_is_date,
+                            ICalComponent *icomp,
+                            const ICalTimezone *default_zone,
+                            ICalTime **out_instance_start,
+                            ICalTime **out_instance_end,
                             GCancellable *cancellable)
 {
-       struct icaltimetype start_time, end_time;
-       const icaltimezone *zone = default_zone;
+       ICalTime *start_time, *end_time;
+       const ICalTimezone *zone = default_zone;
 
        g_return_if_fail (E_IS_CAL_CLIENT (client));
-       g_return_if_fail (icalcomp != NULL);
-       g_return_if_fail (instance_start != NULL);
-       g_return_if_fail (instance_end != NULL);
+       g_return_if_fail (icomp != NULL);
+       g_return_if_fail (out_instance_start != NULL);
+       g_return_if_fail (out_instance_end != NULL);
+
+       start_time = i_cal_component_get_dtstart (icomp);
+       end_time = i_cal_component_get_dtend (icomp);
 
-       start_time = icalcomponent_get_dtstart (icalcomp);
-       end_time = icalcomponent_get_dtend (icalcomp);
-       if (icaltime_is_null_time (end_time))
-         end_time = start_time;
+       /* Some event can have missing DTEND, then use the start_time for them */
+       if (!end_time || i_cal_time_is_null_time (end_time)) {
+               g_clear_object (&end_time);
+
+               end_time = i_cal_time_new_clone (start_time);
+       }
 
-       if (start_time.zone) {
-               zone = start_time.zone;
+       if (i_cal_time_get_timezone (start_time)) {
+               zone = i_cal_time_get_timezone (start_time);
        } else {
-               icalparameter *param = NULL;
-               icalproperty *prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY);
+               ICalParameter *param = NULL;
+               ICalProperty *prop = i_cal_component_get_first_property (icomp, I_CAL_DTSTART_PROPERTY);
 
                if (prop) {
-                       param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
+                       param = i_cal_property_get_first_parameter (prop, I_CAL_TZID_PARAMETER);
 
                        if (param) {
                                const gchar *tzid = NULL;
-                               icaltimezone *st_zone = NULL;
+                               ICalTimezone *st_zone = NULL;
 
-                               tzid = icalparameter_get_tzid (param);
-                               if (tzid)
-                                       e_cal_client_get_timezone_sync (client, tzid, &st_zone, cancellable, 
NULL);
+                               tzid = i_cal_parameter_get_tzid (param);
+                               if (tzid && !e_cal_client_get_timezone_sync (client, tzid, &st_zone, 
cancellable, NULL))
+                                       st_zone = NULL;
 
                                if (st_zone)
                                        zone = st_zone;
+
+                               g_object_unref (param);
                        }
-              }
+
+                       g_object_unref (prop);
+               }
        }
 
-       *instance_start = icaltime_as_timet_with_zone (start_time, zone);
-       if (start_is_date)
-               *start_is_date = start_time.is_date;
+       *out_instance_start = i_cal_time_new_clone (start_time);
+       i_cal_time_set_timezone (*out_instance_start, zone);
 
-       if (end_time.zone) {
-               zone = end_time.zone;
+       if (i_cal_time_get_timezone (end_time)) {
+               zone = i_cal_time_get_timezone (end_time);
        } else {
-               icalparameter *param = NULL;
-               icalproperty *prop = icalcomponent_get_first_property (icalcomp, ICAL_DTSTART_PROPERTY);
+               ICalParameter *param = NULL;
+               ICalProperty *prop = i_cal_component_get_first_property (icomp, I_CAL_DTEND_PROPERTY);
+
+               if (!prop)
+                       prop = i_cal_component_get_first_property (icomp, I_CAL_DTSTART_PROPERTY);
 
                if (prop) {
-                       param = icalproperty_get_first_parameter (prop, ICAL_TZID_PARAMETER);
+                       param = i_cal_property_get_first_parameter (prop, I_CAL_TZID_PARAMETER);
 
                        if (param) {
                                const gchar *tzid = NULL;
-                               icaltimezone *end_zone = NULL;
+                               ICalTimezone *end_zone = NULL;
 
-                               tzid = icalparameter_get_tzid (param);
-                               if (tzid)
-                                       e_cal_client_get_timezone_sync (client, tzid, &end_zone, cancellable, 
NULL);
+                               tzid = i_cal_parameter_get_tzid (param);
+                               if (tzid && !e_cal_client_get_timezone_sync (client, tzid, &end_zone, 
cancellable, NULL))
+                                       end_zone = NULL;
 
                                if (end_zone)
                                        zone = end_zone;
+
+                               g_object_unref (param);
                        }
-              }
 
+                       g_object_unref (prop);
+               }
        }
 
-       *instance_end = icaltime_as_timet_with_zone (end_time, zone);
-       if (end_is_date)
-               *end_is_date = end_time.is_date;
+       *out_instance_end = i_cal_time_new_clone (end_time);
+       i_cal_time_set_timezone (*out_instance_end, zone);
+
+       g_clear_object (&start_time);
+       g_clear_object (&end_time);
 }
 
+#define LOCK_PROPS() g_rec_mutex_lock (&data_model->priv->props_lock)
+#define UNLOCK_PROPS() g_rec_mutex_unlock (&data_model->priv->props_lock)
+
 struct _ECalDataModelPrivate {
        GThread *main_thread;
        ECalDataModelSubmitThreadJobFunc submit_thread_job_func;
@@ -113,9 +127,10 @@ struct _ECalDataModelPrivate {
 
        gboolean disposing;
        gboolean expand_recurrences;
+       gboolean skip_cancelled;
        gchar *filter;
        gchar *full_filter;     /* to be used with views */
-       icaltimezone *zone;
+       ICalTimezone *zone;
        time_t range_start;
        time_t range_end;
 
@@ -130,7 +145,8 @@ struct _ECalDataModelPrivate {
 enum {
        PROP_0,
        PROP_EXPAND_RECURRENCES,
-       PROP_TIMEZONE
+       PROP_TIMEZONE,
+       PROP_SKIP_CANCELLED
 };
 
 enum {
@@ -165,7 +181,7 @@ typedef struct _ViewData {
        GHashTable *components; /* ECalComponentId ~> ComponentData */
        GHashTable *lost_components; /* ECalComponentId ~> ComponentData; when re-running view, valid till 
'complete' is received */
        gboolean received_complete;
-       GSList *to_expand_recurrences; /* icalcomponent */
+       GSList *to_expand_recurrences; /* ICalComponent */
        GSList *expanded_recurrences; /* ComponentData */
        gint pending_expand_recurrences; /* how many is waiting to be processed */
 
@@ -212,8 +228,8 @@ static gboolean
 component_data_equal (ComponentData *comp_data1,
                      ComponentData *comp_data2)
 {
-       icalcomponent *icomp1, *icomp2;
-       struct icaltimetype tt1, tt2;
+       ICalComponent *icomp1, *icomp2;
+       ICalTime *tt1, *tt2;
        gchar *as_str1, *as_str2;
        gboolean equal;
 
@@ -231,28 +247,40 @@ component_data_equal (ComponentData *comp_data1,
        icomp2 = e_cal_component_get_icalcomponent (comp_data2->component);
 
        if (!icomp1 || !icomp2 ||
-           icalcomponent_get_sequence (icomp1) != icalcomponent_get_sequence (icomp2) ||
-           g_strcmp0 (icalcomponent_get_uid (icomp1), icalcomponent_get_uid (icomp2)) != 0)
+           i_cal_component_get_sequence (icomp1) != i_cal_component_get_sequence (icomp2) ||
+           g_strcmp0 (i_cal_component_get_uid (icomp1), i_cal_component_get_uid (icomp2)) != 0)
                return FALSE;
 
-       tt1 = icalcomponent_get_recurrenceid (icomp1);
-       tt2 = icalcomponent_get_recurrenceid (icomp2);
-       if ((icaltime_is_valid_time (tt1) ? 1 : 0) != (icaltime_is_valid_time (tt2) ? 1 : 0) ||
-           (icaltime_is_null_time (tt1) ? 1 : 0) != (icaltime_is_null_time (tt2) ? 1 : 0) ||
-           icaltime_compare (tt1, tt2) != 0)
+       tt1 = i_cal_component_get_recurrenceid (icomp1);
+       tt2 = i_cal_component_get_recurrenceid (icomp2);
+       if (((!tt1 || i_cal_time_is_valid_time (tt1)) ? 1 : 0) != ((!tt2 || i_cal_time_is_valid_time (tt2)) ? 
1 : 0) ||
+           ((!tt1 || i_cal_time_is_null_time (tt1)) ? 1 : 0) != ((!tt2 || i_cal_time_is_null_time (tt2)) ? 1 
: 0) ||
+           i_cal_time_compare (tt1, tt2) != 0) {
+               g_clear_object (&tt1);
+               g_clear_object (&tt2);
                return FALSE;
+       }
+
+       g_clear_object (&tt1);
+       g_clear_object (&tt2);
 
-       tt1 = icalcomponent_get_dtstamp (icomp1);
-       tt2 = icalcomponent_get_dtstamp (icomp2);
-       if ((icaltime_is_valid_time (tt1) ? 1 : 0) != (icaltime_is_valid_time (tt2) ? 1 : 0) ||
-           (icaltime_is_null_time (tt1) ? 1 : 0) != (icaltime_is_null_time (tt2) ? 1 : 0) ||
-           icaltime_compare (tt1, tt2) != 0)
+       tt1 = i_cal_component_get_dtstamp (icomp1);
+       tt2 = i_cal_component_get_dtstamp (icomp2);
+       if (((!tt1 || i_cal_time_is_valid_time (tt1)) ? 1 : 0) != ((!tt2 || i_cal_time_is_valid_time (tt2)) ? 
1 : 0) ||
+           ((!tt1 || i_cal_time_is_null_time (tt1)) ? 1 : 0) != ((!tt2 || i_cal_time_is_null_time (tt2)) ? 1 
: 0) ||
+           i_cal_time_compare (tt1, tt2) != 0) {
+               g_clear_object (&tt1);
+               g_clear_object (&tt2);
                return FALSE;
+       }
+
+       g_clear_object (&tt1);
+       g_clear_object (&tt2);
 
        /* Maybe not so effective compare, but might be still more effective
           than updating whole UI with false notifications */
-       as_str1 = icalcomponent_as_ical_string_r (icomp1);
-       as_str2 = icalcomponent_as_ical_string_r (icomp2);
+       as_str1 = i_cal_component_as_ical_string_r (icomp1);
+       as_str2 = i_cal_component_as_ical_string_r (icomp2);
 
        equal = g_strcmp0 (as_str1, as_str2) == 0;
 
@@ -275,8 +303,8 @@ view_data_new (ECalClient *client)
        view_data->is_used = TRUE;
        view_data->client = g_object_ref (client);
        view_data->components = g_hash_table_new_full (
-               (GHashFunc) e_cal_component_id_hash, (GEqualFunc) e_cal_component_id_equal,
-               (GDestroyNotify) e_cal_component_free_id, component_data_free);
+               e_cal_component_id_hash, e_cal_component_id_equal,
+               e_cal_component_id_free, component_data_free);
 
        return view_data;
 }
@@ -328,7 +356,7 @@ view_data_unref (gpointer ptr)
                        g_hash_table_destroy (view_data->components);
                        if (view_data->lost_components)
                                g_hash_table_destroy (view_data->lost_components);
-                       g_slist_free_full (view_data->to_expand_recurrences, (GDestroyNotify) 
icalcomponent_free);
+                       g_slist_free_full (view_data->to_expand_recurrences, g_object_unref);
                        g_slist_free_full (view_data->expanded_recurrences, component_data_free);
                        g_rec_mutex_clear (&view_data->lock);
                        g_free (view_data);
@@ -519,13 +547,6 @@ cal_data_model_call_submit_thread_job (gpointer user_data)
 /**
  * e_cal_data_model_submit_thread_job:
  * @data_model: an #ECalDataModel
- * @description: user-friendly description of the job, to be shown in UI
- * @alert_ident: in case of an error, this alert identificator is used
- *    for EAlert construction
- * @alert_arg_0: (allow-none): in case of an error, use this string as
- *    the first argument to the EAlert construction; the second argument
- *    is the actual error message; can be #NULL, in which case only
- *    the error message is passed to the EAlert construction
  * @func: function to be run in a dedicated thread
  * @user_data: (allow-none): custom data passed into @func; can be #NULL
  * @free_user_data: (allow-none): function to be called on @user_data,
@@ -615,7 +636,7 @@ cal_data_model_foreach_subscriber_in_range (ECalDataModel *data_model,
 
                if ((in_range_start == (time_t) 0 && in_range_end == (time_t) 0) ||
                    (subs_data->range_start == (time_t) 0 && subs_data->range_end == (time_t) 0) ||
-                   (subs_data->range_start < in_range_end && subs_data->range_end > in_range_start))
+                   (subs_data->range_start <= in_range_end && subs_data->range_end >= in_range_start))
                        func (data_model, client, subs_data->subscriber, user_data);
        }
 
@@ -712,7 +733,9 @@ cal_data_model_remove_one_view_component_cb (ECalDataModel *data_model,
 
        g_return_if_fail (id != NULL);
 
-       e_cal_data_model_subscriber_component_removed (subscriber, client, id->uid, id->rid);
+       e_cal_data_model_subscriber_component_removed (subscriber, client,
+               e_cal_component_id_get_uid (id),
+               e_cal_component_id_get_rid (id));
 }
 
 static void
@@ -818,8 +841,8 @@ cal_data_model_update_full_filter (ECalDataModel *data_model)
                iso_start = isodate_from_time_t (range_start);
                iso_end = isodate_from_time_t (range_end);
 
-               if (data_model->priv->zone && data_model->priv->zone != icaltimezone_get_utc_timezone ())
-                       default_tzloc = icaltimezone_get_location (data_model->priv->zone);
+               if (data_model->priv->zone && data_model->priv->zone != i_cal_timezone_get_utc_timezone ())
+                       default_tzloc = i_cal_timezone_get_location (data_model->priv->zone);
                if (!default_tzloc)
                        default_tzloc = "";
 
@@ -945,7 +968,9 @@ cal_data_model_process_added_component (ECalDataModel *data_model,
                                if (g_hash_table_remove (new_subscribers, subscriber))
                                        e_cal_data_model_subscriber_component_modified (subscriber, 
view_data->client, comp_data->component);
                                else if (old_id)
-                                       e_cal_data_model_subscriber_component_removed (subscriber, 
view_data->client, old_id->uid, old_id->rid);
+                                       e_cal_data_model_subscriber_component_removed (subscriber, 
view_data->client,
+                                               e_cal_component_id_get_uid (old_id),
+                                               e_cal_component_id_get_rid (old_id));
                        }
 
                        /* Those which left in the new_subscribers have the component added. */
@@ -967,8 +992,7 @@ cal_data_model_process_added_component (ECalDataModel *data_model,
 
        view_data_unlock (view_data);
 
-       if (old_id)
-               e_cal_component_free_id (old_id);
+       e_cal_component_id_free (old_id);
 }
 
 typedef struct _GatherComponentsData {
@@ -994,7 +1018,7 @@ cal_data_model_gather_components (gpointer key,
        g_return_if_fail (gather_data->pcomponent_ids != NULL || gather_data->component_ids_hash != NULL);
        g_return_if_fail (gather_data->pcomponent_ids == NULL || gather_data->component_ids_hash == NULL);
 
-       if ((gather_data->all_instances || !comp_data->is_detached) && g_strcmp0 (id->uid, gather_data->uid) 
== 0) {
+       if ((gather_data->all_instances || !comp_data->is_detached) && g_strcmp0 (e_cal_component_id_get_uid 
(id), gather_data->uid) == 0) {
                if (gather_data->component_ids_hash) {
                        ComponentData *comp_data_copy;
 
@@ -1055,21 +1079,21 @@ cal_data_model_notify_recurrences_cb (gpointer user_data)
                gathered_uids = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
                known_instances = g_hash_table_new_full (
                        (GHashFunc) e_cal_component_id_hash, (GEqualFunc) e_cal_component_id_equal,
-                       (GDestroyNotify) e_cal_component_free_id, component_data_free);
+                       (GDestroyNotify) e_cal_component_id_free, component_data_free);
 
                for (link = expanded_recurrences; link && view_data->is_used; link = g_slist_next (link)) {
                        ComponentData *comp_data = link->data;
-                       icalcomponent *icomp;
+                       ICalComponent *icomp;
                        const gchar *uid;
 
                        if (!comp_data)
                                continue;
 
                        icomp = e_cal_component_get_icalcomponent (comp_data->component);
-                       if (!icomp || !icalcomponent_get_uid (icomp))
+                       if (!icomp || !i_cal_component_get_uid (icomp))
                                continue;
 
-                       uid = icalcomponent_get_uid (icomp);
+                       uid = i_cal_component_get_uid (icomp);
 
                        if (!g_hash_table_contains (gathered_uids, uid)) {
                                GatherComponentsData gather_data;
@@ -1126,27 +1150,79 @@ cal_data_model_notify_recurrences_cb (gpointer user_data)
 typedef struct
 {
        ECalClient *client;
-       icaltimezone *zone;
+       ICalTimezone *zone;
        GSList **pexpanded_recurrences;
+       gboolean skip_cancelled;
 } GenerateInstancesData;
 
 static gboolean
-cal_data_model_instance_generated (ECalComponent *comp,
-                                  time_t instance_start,
-                                  time_t instance_end,
-                                  gpointer data)
+cal_data_model_instance_generated (ICalComponent *icomp,
+                                  ICalTime *instance_start,
+                                  ICalTime *instance_end,
+                                  gpointer user_data,
+                                  GCancellable *cancellable,
+                                  GError **error)
 {
-       GenerateInstancesData *gid = data;
+       GenerateInstancesData *gid = user_data;
        ComponentData *comp_data;
+       ECalComponent *comp_copy;
+       ICalTime *tt, *tt2;
+       time_t start_tt, end_tt;
 
        g_return_val_if_fail (gid != NULL, FALSE);
 
-       cal_comp_get_instance_times (gid->client, e_cal_component_get_icalcomponent (comp),
-               gid->zone, &instance_start, NULL, &instance_end, NULL, NULL);
+       if (gid->skip_cancelled) {
+               ICalProperty *prop;
 
-       comp_data = component_data_new (comp, instance_start, instance_end, FALSE);
+               prop = i_cal_component_get_first_property (icomp, I_CAL_STATUS_PROPERTY);
+               if (prop && i_cal_property_get_status (prop) == I_CAL_STATUS_CANCELLED) {
+                       g_object_unref (prop);
+                       return TRUE;
+               }
+
+               g_clear_object (&prop);
+       }
+
+       comp_copy = e_cal_component_new_from_icalcomponent (i_cal_component_new_clone (icomp));
+       g_return_val_if_fail (comp_copy != NULL, FALSE);
+
+       tt = i_cal_component_get_dtstart (e_cal_component_get_icalcomponent (comp_copy));
+       tt2 = i_cal_time_convert_to_zone (instance_start, gid->zone);
+       if (i_cal_time_is_date (tt) || !i_cal_time_get_timezone (tt) || i_cal_time_is_utc (tt))
+               i_cal_time_set_timezone (tt2, NULL);
+       else
+               i_cal_time_set_timezone (tt2, gid->zone);
+       i_cal_component_set_dtstart (e_cal_component_get_icalcomponent (comp_copy), tt2);
+       g_clear_object (&tt);
+       g_clear_object (&tt2);
+
+       tt = i_cal_component_get_dtend (e_cal_component_get_icalcomponent (comp_copy));
+       tt2 = i_cal_time_convert_to_zone (instance_end, gid->zone);
+       if (i_cal_time_is_date (tt) || !i_cal_time_get_timezone (tt) || i_cal_time_is_utc (tt))
+               i_cal_time_set_timezone (tt2, NULL);
+       else
+               i_cal_time_set_timezone (tt2, gid->zone);
+       i_cal_component_set_dtend (e_cal_component_get_icalcomponent (comp_copy), tt2);
+       g_clear_object (&tt);
+       g_clear_object (&tt2);
+
+       cal_comp_get_instance_times (gid->client, e_cal_component_get_icalcomponent (comp_copy),
+               gid->zone, &tt, &tt2, cancellable);
+
+       start_tt = i_cal_time_as_timet (tt);
+       end_tt = i_cal_time_as_timet (tt2);
+
+       g_clear_object (&tt);
+       g_clear_object (&tt2);
+
+       if (end_tt > start_tt)
+               end_tt--;
+
+       comp_data = component_data_new (comp_copy, start_tt, end_tt, FALSE);
        *gid->pexpanded_recurrences = g_slist_prepend (*gid->pexpanded_recurrences, comp_data);
 
+       g_object_unref (comp_copy);
+
        return TRUE;
 }
 
@@ -1197,7 +1273,7 @@ cal_data_model_expand_recurrences_thread (ECalDataModel *data_model,
        view_data_unlock (view_data);
 
        for (link = to_expand_recurrences; link && view_data->is_used; link = g_slist_next (link)) {
-               icalcomponent *icomp = link->data;
+               ICalComponent *icomp = link->data;
                GenerateInstancesData gid;
 
                if (!icomp)
@@ -1205,13 +1281,16 @@ cal_data_model_expand_recurrences_thread (ECalDataModel *data_model,
 
                gid.client = client;
                gid.pexpanded_recurrences = &expanded_recurrences;
-               gid.zone = data_model->priv->zone;
+               gid.zone = g_object_ref (data_model->priv->zone);
+               gid.skip_cancelled = data_model->priv->skip_cancelled;
 
-               e_cal_client_generate_instances_for_object_sync (client, icomp, range_start, range_end,
+               e_cal_client_generate_instances_for_object_sync (client, icomp, range_start, range_end, NULL,
                        cal_data_model_instance_generated, &gid);
+
+               g_clear_object (&gid.zone);
        }
 
-       g_slist_free_full (to_expand_recurrences, (GDestroyNotify) icalcomponent_free);
+       g_slist_free_full (to_expand_recurrences, g_object_unref);
 
        view_data_lock (view_data);
        if (expanded_recurrences)
@@ -1245,17 +1324,23 @@ cal_data_model_process_modified_or_added_objects (ECalClientView *view,
        LOCK_PROPS ();
 
        client = e_cal_client_view_ref_client (view);
+       if (!client) {
+               UNLOCK_PROPS ();
+               return;
+       }
+
        view_data = g_hash_table_lookup (data_model->priv->views, client);
        if (view_data) {
                view_data_ref (view_data);
                g_warn_if_fail (view_data->view == view);
        }
-       g_object_unref (client);
 
        UNLOCK_PROPS ();
 
-       if (!view_data)
+       if (!view_data) {
+               g_clear_object (&client);
                return;
+       }
 
        view_data_lock (view_data);
 
@@ -1277,9 +1362,9 @@ cal_data_model_process_modified_or_added_objects (ECalClientView *view,
                cal_data_model_freeze_all_subscribers (data_model);
 
                for (link = objects; link; link = g_slist_next (link)) {
-                       icalcomponent *icomp = link->data;
+                       ICalComponent *icomp = link->data;
 
-                       if (!icomp || !icalcomponent_get_uid (icomp))
+                       if (!icomp || !i_cal_component_get_uid (icomp))
                                continue;
 
                        if (data_model->priv->expand_recurrences &&
@@ -1288,18 +1373,32 @@ cal_data_model_process_modified_or_added_objects (ECalClientView *view,
                                /* This component requires an expand of recurrences, which
                                   will be done in a dedicated thread, thus remember it */
                                to_expand_recurrences = g_slist_prepend (to_expand_recurrences,
-                                       icalcomponent_new_clone (icomp));
+                                       i_cal_component_new_clone (icomp));
                        } else {
                                /* Single or detached instance, the simple case */
                                ECalComponent *comp;
                                ComponentData *comp_data;
+                               ICalTime *start_tt = NULL, *end_tt = NULL;
                                time_t instance_start, instance_end;
 
-                               comp = e_cal_component_new_from_icalcomponent (icalcomponent_new_clone 
(icomp));
+                               if (data_model->priv->skip_cancelled &&
+                                   i_cal_component_get_status (icomp) == I_CAL_STATUS_CANCELLED)
+                                       continue;
+
+                               comp = e_cal_component_new_from_icalcomponent (i_cal_component_new_clone 
(icomp));
                                if (!comp)
                                        continue;
 
-                               cal_comp_get_instance_times (client, icomp, data_model->priv->zone, 
&instance_start, NULL, &instance_end, NULL, NULL);
+                               cal_comp_get_instance_times (client, icomp, data_model->priv->zone, 
&start_tt, &end_tt, NULL);
+
+                               instance_start = i_cal_time_as_timet (start_tt);
+                               instance_end = i_cal_time_as_timet (end_tt);
+
+                               g_clear_object (&start_tt);
+                               g_clear_object (&end_tt);
+
+                               if (instance_end > instance_start)
+                                       instance_end--;
 
                                comp_data = component_data_new (comp, instance_start, instance_end,
                                        e_cal_util_component_is_instance (icomp));
@@ -1313,8 +1412,6 @@ cal_data_model_process_modified_or_added_objects (ECalClientView *view,
                cal_data_model_thaw_all_subscribers (data_model);
 
                if (to_expand_recurrences) {
-                       ECalClient *rclient = e_cal_client_view_ref_client (view);
-
                        view_data_lock (view_data);
                        view_data->to_expand_recurrences = g_slist_concat (
                                view_data->to_expand_recurrences, to_expand_recurrences);
@@ -1322,12 +1419,14 @@ cal_data_model_process_modified_or_added_objects (ECalClientView *view,
                        view_data_unlock (view_data);
 
                        cal_data_model_submit_internal_thread_job (data_model,
-                               cal_data_model_expand_recurrences_thread, rclient);
+                               cal_data_model_expand_recurrences_thread, g_object_ref (client));
                }
        }
 
        view_data_unlock (view_data);
        view_data_unref (view_data);
+
+       g_clear_object (&client);
 }
 
 static void
@@ -1352,22 +1451,27 @@ cal_data_model_view_objects_removed (ECalClientView *view,
                                     ECalDataModel *data_model)
 {
        ViewData *view_data;
-       const GSList *link;
        ECalClient *client;
+       const GSList *link;
 
        g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model));
 
        LOCK_PROPS ();
 
        client = e_cal_client_view_ref_client (view);
-       view_data =
-         g_hash_table_lookup (data_model->priv->views, client);
+       if (!client) {
+               UNLOCK_PROPS ();
+               return;
+       }
+
+       view_data = g_hash_table_lookup (data_model->priv->views, client);
+
+       g_clear_object (&client);
 
        if (view_data) {
                view_data_ref (view_data);
                g_warn_if_fail (view_data->view == view);
        }
-       g_object_unref (client);
 
        UNLOCK_PROPS ();
 
@@ -1385,11 +1489,11 @@ cal_data_model_view_objects_removed (ECalClientView *view,
                        const ECalComponentId *id = link->data;
 
                        if (id) {
-                               if (!id->rid || !*id->rid) {
-                                       if (!g_hash_table_contains (gathered_uids, id->uid)) {
+                               if (!e_cal_component_id_get_rid (id)) {
+                                       if (!g_hash_table_contains (gathered_uids, e_cal_component_id_get_uid 
(id))) {
                                                GatherComponentsData gather_data;
 
-                                               gather_data.uid = id->uid;
+                                               gather_data.uid = e_cal_component_id_get_uid (id);
                                                gather_data.pcomponent_ids = &removed;
                                                gather_data.component_ids_hash = NULL;
                                                gather_data.copy_ids = TRUE;
@@ -1401,7 +1505,7 @@ cal_data_model_view_objects_removed (ECalClientView *view,
                                                        g_hash_table_foreach (view_data->lost_components,
                                                                cal_data_model_gather_components, 
&gather_data);
 
-                                               g_hash_table_insert (gathered_uids, id->uid, GINT_TO_POINTER 
(1));
+                                               g_hash_table_insert (gathered_uids, (gpointer) 
e_cal_component_id_get_uid (id), GINT_TO_POINTER (1));
                                        }
                                } else {
                                        removed = g_list_prepend (removed, e_cal_component_id_copy (id));
@@ -1443,7 +1547,7 @@ cal_data_model_view_objects_removed (ECalClientView *view,
 
                cal_data_model_thaw_all_subscribers (data_model);
 
-               g_list_free_full (removed, (GDestroyNotify) e_cal_component_free_id);
+               g_list_free_full (removed, (GDestroyNotify) e_cal_component_id_free);
                g_hash_table_destroy (gathered_uids);
        }
        view_data_unlock (view_data);
@@ -1630,11 +1734,8 @@ static void
 cal_data_model_update_client_view (ECalDataModel *data_model,
                                   ECalClient *client)
 {
-       /*ESource *source;*/
        ViewData *view_data;
        CreateViewData *cv_data;
-       /*const gchar *alert_ident;
-       gchar *description;*/
 
        LOCK_PROPS ();
 
@@ -1696,7 +1797,7 @@ cal_data_model_update_client_view (ECalDataModel *data_model,
                view_data->lost_components = view_data->components;
                view_data->components = g_hash_table_new_full (
                        (GHashFunc) e_cal_component_id_hash, (GEqualFunc) e_cal_component_id_equal,
-                       (GDestroyNotify) e_cal_component_free_id, component_data_free);
+                       (GDestroyNotify) e_cal_component_id_free, component_data_free);
        }
 
        view_data_unlock (view_data);
@@ -1706,27 +1807,6 @@ cal_data_model_update_client_view (ECalDataModel *data_model,
                return;
        }
 
-       /*source = e_client_get_source (E_CLIENT (client));
-
-       switch (e_cal_client_get_source_type (client)) {
-               case E_CAL_CLIENT_SOURCE_TYPE_EVENTS:
-                       alert_ident = "calendar:failed-create-view-calendar";
-                       description = g_strdup_printf (_("Creating view for calendar '%s'"), 
e_source_get_display_name (source));
-                       break;
-               case E_CAL_CLIENT_SOURCE_TYPE_TASKS:
-                       alert_ident = "calendar:failed-create-view-tasks";
-                       description = g_strdup_printf (_("Creating view for task list '%s'"), 
e_source_get_display_name (source));
-                       break;
-               case E_CAL_CLIENT_SOURCE_TYPE_MEMOS:
-                       alert_ident = "calendar:failed-create-view-memos";
-                       description = g_strdup_printf (_("Creating view for memo list '%s'"), 
e_source_get_display_name (source));
-                       break;
-               case E_CAL_CLIENT_SOURCE_TYPE_LAST:
-                       g_warn_if_reached ();
-                       UNLOCK_PROPS ();
-                       return;
-       }*/
-
        cv_data = g_new0 (CreateViewData, 1);
        cv_data->data_model = g_object_ref (data_model);
        cv_data->client = g_object_ref (client);
@@ -1735,8 +1815,6 @@ cal_data_model_update_client_view (ECalDataModel *data_model,
        view_data->cancellable = e_cal_data_model_submit_thread_job (data_model,
                cal_data_model_create_view_thread, cv_data, create_view_data_free);
 
-       /*g_free (description);*/
-
        UNLOCK_PROPS ();
 }
 
@@ -1820,8 +1898,8 @@ cal_data_model_add_to_subscriber_except_its_range (ECalDataModel *data_model,
        /* subs_data should have set the old time range, which
           means only components which didn't fit into the old
           time range will be added */
-       if (!(instance_start < subs_data->range_end &&
-           instance_end > subs_data->range_start))
+       if (!(instance_start <= subs_data->range_end &&
+           instance_end >= subs_data->range_start))
                e_cal_data_model_subscriber_component_added (subs_data->subscriber, client, component);
 
        return TRUE;
@@ -1844,9 +1922,11 @@ cal_data_model_remove_from_subscriber_except_its_range (ECalDataModel *data_mode
        /* subs_data should have set the new time range, which
           means only components which don't fit into this new
           time range will be removed */
-       if (!(instance_start < subs_data->range_end &&
-           instance_end > subs_data->range_start))
-               e_cal_data_model_subscriber_component_removed (subs_data->subscriber, client, id->uid, 
id->rid);
+       if (!(instance_start <= subs_data->range_end &&
+           instance_end >= subs_data->range_start))
+               e_cal_data_model_subscriber_component_removed (subs_data->subscriber, client,
+                       e_cal_component_id_get_uid (id),
+                       e_cal_component_id_get_rid (id));
 
        return TRUE;
 }
@@ -1857,7 +1937,7 @@ cal_data_model_set_client_default_zone_cb (gpointer key,
                                           gpointer user_data)
 {
        ECalClient *client = value;
-       icaltimezone *zone = user_data;
+       ICalTimezone *zone = user_data;
 
        g_return_if_fail (E_IS_CAL_CLIENT (client));
        g_return_if_fail (zone != NULL);
@@ -1946,9 +2026,15 @@ cal_data_model_set_property (GObject *object,
                                E_CAL_DATA_MODEL (object),
                                g_value_get_pointer (value));
                        return;
-               default:
-                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+
+               case PROP_SKIP_CANCELLED:
+                       e_cal_data_model_set_skip_cancelled (
+                               E_CAL_DATA_MODEL (object),
+                               g_value_get_boolean (value));
+                       return;
        }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
 
 static void
@@ -1971,9 +2057,16 @@ cal_data_model_get_property (GObject *object,
                                e_cal_data_model_get_timezone (
                                E_CAL_DATA_MODEL (object)));
                        return;
-               default:
-                       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+
+               case PROP_SKIP_CANCELLED:
+                       g_value_set_boolean (
+                               value,
+                               e_cal_data_model_get_skip_cancelled (
+                               E_CAL_DATA_MODEL (object)));
+                       return;
        }
+
+       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
 }
 
 static void
@@ -1998,6 +2091,7 @@ cal_data_model_finalize (GObject *object)
        g_slist_free_full (data_model->priv->subscribers, subscriber_data_free);
        g_free (data_model->priv->filter);
        g_free (data_model->priv->full_filter);
+       g_clear_object (&data_model->priv->zone);
 
        g_rec_mutex_clear (&data_model->priv->props_lock);
 
@@ -2037,6 +2131,16 @@ e_cal_data_model_class_init (ECalDataModelClass *class)
                        NULL,
                        G_PARAM_READWRITE));
 
+       g_object_class_install_property (
+               object_class,
+               PROP_SKIP_CANCELLED,
+               g_param_spec_boolean (
+                       "skip-cancelled",
+                       "Skip Cancelled",
+                       NULL,
+                       FALSE,
+                       G_PARAM_READWRITE));
+
        signals[VIEW_STATE_CHANGED] = g_signal_new (
                "view-state-changed",
                G_TYPE_FROM_CLASS (class),
@@ -2063,7 +2167,8 @@ e_cal_data_model_init (ECalDataModel *data_model)
 
        data_model->priv->disposing = FALSE;
        data_model->priv->expand_recurrences = FALSE;
-       data_model->priv->zone = icaltimezone_get_utc_timezone ();
+       data_model->priv->skip_cancelled = FALSE;
+       data_model->priv->zone = g_object_ref (i_cal_timezone_get_utc_timezone ());
 
        data_model->priv->views_update_freeze = 0;
        data_model->priv->views_update_required = FALSE;
@@ -2118,6 +2223,7 @@ e_cal_data_model_new_clone (ECalDataModel *src_data_model)
        clone = e_cal_data_model_new (src_data_model->priv->submit_thread_job_func);
 
        e_cal_data_model_set_expand_recurrences (clone, e_cal_data_model_get_expand_recurrences 
(src_data_model));
+       e_cal_data_model_set_skip_cancelled (clone, e_cal_data_model_get_skip_cancelled (src_data_model));
        e_cal_data_model_set_timezone (clone, e_cal_data_model_get_timezone (src_data_model));
        e_cal_data_model_set_filter (clone, src_data_model->priv->filter);
 
@@ -2247,6 +2353,62 @@ e_cal_data_model_set_expand_recurrences (ECalDataModel *data_model,
        UNLOCK_PROPS ();
 }
 
+/**
+ * e_cal_data_model_get_skip_cancelled:
+ * @data_model: an #EDataModel instance
+ *
+ * Obtains whether the @data_model skips cancelled components.
+ * The default value is #FALSE, to not skip cancelled components.
+ *
+ * Returns: Whether the @data_model skips cancelled components.
+ *
+ * Since: 3.32
+ **/
+gboolean
+e_cal_data_model_get_skip_cancelled (ECalDataModel *data_model)
+{
+       gboolean skip_cancelled;
+
+       g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), FALSE);
+
+       LOCK_PROPS ();
+
+       skip_cancelled = data_model->priv->skip_cancelled;
+
+       UNLOCK_PROPS ();
+
+       return skip_cancelled;
+}
+
+/**
+ * e_cal_data_model_set_skip_cancelled:
+ * @data_model: an #EDataModel instance
+ * @skip_cancelled: whether to skip cancelled components
+ *
+ * Sets whether the @data_model should skip cancelled components.
+ *
+ * Since: 3.32
+ **/
+void
+e_cal_data_model_set_skip_cancelled (ECalDataModel *data_model,
+                                    gboolean skip_cancelled)
+{
+       g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model));
+
+       LOCK_PROPS ();
+
+       if ((data_model->priv->skip_cancelled ? 1 : 0) == (skip_cancelled ? 1 : 0)) {
+               UNLOCK_PROPS ();
+               return;
+       }
+
+       data_model->priv->skip_cancelled = skip_cancelled;
+
+       cal_data_model_rebuild_everything (data_model, TRUE);
+
+       UNLOCK_PROPS ();
+}
+
 /**
  * e_cal_data_model_get_timezone:
  * @data_model: an #EDataModel instance
@@ -2254,14 +2416,14 @@ e_cal_data_model_set_expand_recurrences (ECalDataModel *data_model,
  * Obtains a timezone being used for calendar views. The returned
  * timezone is owned by the @data_model.
  *
- * Returns: (transfer none): An #icaltimezone being used for calendar views.
+ * Returns: (transfer none): An #ICalTimezone being used for calendar views.
  *
  * Since: 3.14
  **/
-icaltimezone *
+ICalTimezone *
 e_cal_data_model_get_timezone (ECalDataModel *data_model)
 {
-       icaltimezone *zone;
+       ICalTimezone *zone;
 
        g_return_val_if_fail (E_IS_CAL_DATA_MODEL (data_model), NULL);
 
@@ -2273,10 +2435,11 @@ e_cal_data_model_get_timezone (ECalDataModel *data_model)
 
        return zone;
 }
+
 /**
  * e_cal_data_model_set_timezone:
  * @data_model: an #EDataModel instance
- * @zone: an #icaltimezone
+ * @zone: an #ICalTimezone
  *
  * Sets a trimezone to be used for calendar views. This change
  * regenerates all views.
@@ -2285,7 +2448,7 @@ e_cal_data_model_get_timezone (ECalDataModel *data_model)
  **/
 void
 e_cal_data_model_set_timezone (ECalDataModel *data_model,
-                              icaltimezone *zone)
+                              ICalTimezone *zone)
 {
        g_return_if_fail (E_IS_CAL_DATA_MODEL (data_model));
        g_return_if_fail (zone != NULL);
@@ -2293,7 +2456,8 @@ e_cal_data_model_set_timezone (ECalDataModel *data_model,
        LOCK_PROPS ();
 
        if (data_model->priv->zone != zone) {
-               data_model->priv->zone = zone;
+               g_clear_object (&data_model->priv->zone);
+               data_model->priv->zone = g_object_ref (zone);
 
                g_hash_table_foreach (data_model->priv->clients, cal_data_model_set_client_default_zone_cb, 
zone);
 
@@ -2603,8 +2767,8 @@ cal_data_model_foreach_component (ECalDataModel *data_model,
                                continue;
 
                        if ((in_range_start == in_range_end && in_range_start == (time_t) 0) ||
-                           (comp_data->instance_start < in_range_end &&
-                            comp_data->instance_end > in_range_start)) {
+                           (comp_data->instance_start < in_range_end && comp_data->instance_end > 
in_range_start) ||
+                           (comp_data->instance_start == comp_data->instance_end && comp_data->instance_end 
== in_range_start)) {
                                if (!func (data_model, view_data->client, id, comp_data->component,
                                           comp_data->instance_start, comp_data->instance_end, user_data))
                                        checked_all = FALSE;
@@ -2621,8 +2785,8 @@ cal_data_model_foreach_component (ECalDataModel *data_model,
                                        continue;
 
                                if ((in_range_start == in_range_end && in_range_start == (time_t) 0) ||
-                                   (comp_data->instance_start < in_range_end &&
-                                    comp_data->instance_end > in_range_start)) {
+                                   (comp_data->instance_start < in_range_end && comp_data->instance_end > 
in_range_start) ||
+                                   (comp_data->instance_start == comp_data->instance_end && 
comp_data->instance_end == in_range_start)) {
                                        if (!func (data_model, view_data->client, id, comp_data->component,
                                                   comp_data->instance_start, comp_data->instance_end, 
user_data))
                                                checked_all = FALSE;
@@ -2711,7 +2875,7 @@ e_cal_data_model_subscribe (ECalDataModel *data_model,
        LOCK_PROPS ();
 
        for (link = data_model->priv->subscribers; link; link = g_slist_next (link)) {
-               subs_data = link->data;
+               SubscriberData *subs_data = link->data;
 
                if (!subs_data)
                        continue;
diff --git a/contrib/evolution/e-cal-data-model.h b/contrib/evolution/e-cal-data-model.h
index 5ddea296..ba79c4de 100644
--- a/contrib/evolution/e-cal-data-model.h
+++ b/contrib/evolution/e-cal-data-model.h
@@ -96,9 +96,14 @@ gboolean     e_cal_data_model_get_expand_recurrences
 void           e_cal_data_model_set_expand_recurrences
                                                (ECalDataModel *data_model,
                                                 gboolean expand_recurrences);
-icaltimezone * e_cal_data_model_get_timezone   (ECalDataModel *data_model);
+gboolean       e_cal_data_model_get_skip_cancelled
+                                               (ECalDataModel *data_model);
+void           e_cal_data_model_set_skip_cancelled
+                                               (ECalDataModel *data_model,
+                                                gboolean expand_recurrences);
+ICalTimezone * e_cal_data_model_get_timezone   (ECalDataModel *data_model);
 void           e_cal_data_model_set_timezone   (ECalDataModel *data_model,
-                                                icaltimezone *zone);
+                                                ICalTimezone *zone);
 void           e_cal_data_model_set_filter     (ECalDataModel *data_model,
                                                 const gchar *sexp);
 gchar *                e_cal_data_model_dup_filter     (ECalDataModel *data_model);
diff --git a/data/ui/window.ui b/data/ui/window.ui
index 7c82b259..cfa0e476 100644
--- a/data/ui/window.ui
+++ b/data/ui/window.ui
@@ -9,7 +9,6 @@
     <property name="show_menubar">False</property>
     <signal name="key-press-event" handler="key_pressed" object="GcalWindow" swapped="no"/>
     <signal name="window-state-event" handler="window_state_changed" object="GcalWindow" swapped="no"/>
-    <property name="active-date" bind-source="search_popover" bind-property="active-date" 
bind-flags="default|sync-create"/>
     <style>
       <class name="org-gnome-Calendar"/>
     </style>    
@@ -58,7 +57,6 @@
                 <child>
                   <object class="GcalWeekView" id="week_view">
                     <property name="visible">True</property>
-                    <property name="active-date" bind-source="GcalWindow" bind-property="active-date" 
bind-flags="bidirectional"/>
                     <signal name="create-event" handler="show_new_event_widget" object="GcalWindow" 
swapped="no"/>
                     <signal name="event-activated" handler="event_activated" object="GcalWindow" 
swapped="no"/>
                   </object>
@@ -71,7 +69,6 @@
                   <object class="GcalMonthView" id="month_view">
                     <property name="visible">True</property>
                     <property name="can_focus">True</property>
-                    <property name="active-date" bind-source="GcalWindow" bind-property="active-date" 
bind-flags="bidirectional"/>
                     <signal name="create-event" handler="show_new_event_widget" object="GcalWindow" 
swapped="no"/>
                     <signal name="create-event-detailed" handler="create_event_detailed_cb" 
object="GcalWindow" swapped="no"/>
                     <signal name="event-activated" handler="event_activated" object="GcalWindow" 
swapped="no"/>
@@ -85,7 +82,6 @@
                 <child>
                   <object class="GcalYearView" id="year_view">
                     <property name="visible">True</property>
-                    <property name="active-date" bind-source="GcalWindow" bind-property="active-date" 
bind-flags="bidirectional"/>
                     <signal name="create-event" handler="show_new_event_widget" object="GcalWindow" 
swapped="no"/>
                     <signal name="create-event-detailed" handler="create_event_detailed_cb" 
object="GcalWindow" swapped="no"/>
                     <signal name="event-activated" handler="event_activated" object="GcalWindow" 
swapped="no"/>
diff --git a/meson.build b/meson.build
index 996e0979..d4ee0348 100644
--- a/meson.build
+++ b/meson.build
@@ -140,7 +140,7 @@ assert(cc.has_function('icaltime_days_in_year', dependencies: libical_dep),
 gsettings_desktop_schemas_dep = dependency('gsettings-desktop-schemas', version: '>= 3.21.2')
 libedataserverui_dep = dependency('libedataserverui-1.2', version: '>= 3.17.1')
 libedataserver_dep = dependency('libedataserver-1.2', version: '>= 3.17.1')
-libecal_dep = dependency('libecal-1.2', version: '>= 3.13.90')
+libecal_dep = dependency('libecal-2.0', version: '>= 3.33.1')
 libsoup_dep = dependency('libsoup-2.4')
 libdazzle_dep = dependency('libdazzle-1.0', version: '>= 3.26.1')
 glib_dep = dependency('glib-2.0', version: '>= 2.58.0')
diff --git a/src/gcal-application.c b/src/gcal-application.c
index 9037dc32..4899b110 100644
--- a/src/gcal-application.c
+++ b/src/gcal-application.c
@@ -48,7 +48,7 @@ struct _GcalApplication
   GtkCssProvider     *colors_provider;
 
   gchar              *uuid;
-  icaltimetype       *initial_date;
+  ICalTime           *initial_date;
 
   GSettings          *desktop_settings;
   GcalTimeFormat      time_format;
@@ -225,8 +225,8 @@ gcal_application_finalize (GObject *object)
 
   GCAL_ENTRY;
 
-  g_clear_pointer (&self->initial_date, g_free);
   g_clear_pointer (&self->uuid, g_free);
+  g_clear_object (&self->initial_date);
   g_clear_object (&self->colors_provider);
   g_clear_object (&self->clock);
   g_clear_object (&self->desktop_settings);
@@ -302,13 +302,12 @@ gcal_application_activate (GApplication *application)
     {
       if (!self->initial_date)
         {
-          icaltimezone *tz;
+          ICalTimezone *tz;
 
           tz = gcal_manager_get_system_timezone (self->manager);
 
-          self->initial_date = g_new0 (icaltimetype, 1);
-          *self->initial_date = icaltime_current_time_with_zone (tz);
-          *self->initial_date = icaltime_set_timezone (self->initial_date, tz);
+          self->initial_date = i_cal_time_current_time_with_zone (tz);
+          i_cal_time_set_timezone (self->initial_date, tz);
         }
 
       self->window =  g_object_new (GCAL_TYPE_WINDOW,
@@ -330,7 +329,7 @@ gcal_application_activate (GApplication *application)
   if (self->initial_date)
     g_object_set (self->window, "active-date", self->initial_date, NULL);
 
-  g_clear_pointer (&self->initial_date, g_free);
+  g_clear_object (&self->initial_date);
 
   if (self->uuid != NULL)
     {
@@ -421,12 +420,9 @@ gcal_application_command_line (GApplication            *app,
 
       if (e_time_parse_date_and_time (date, &result) == E_TIME_PARSE_OK)
         {
-          if (!self->initial_date)
-            self->initial_date = g_new0 (icaltimetype, 1);
-
-          *self->initial_date = tm_to_icaltimetype (&result, FALSE);
-          *self->initial_date = icaltime_set_timezone (self->initial_date,
-                                                       gcal_manager_get_system_timezone (self->manager));
+          self->initial_date = e_cal_util_tm_to_icaltime (&result, FALSE);
+          i_cal_time_set_timezone (self->initial_date,
+                                   gcal_manager_get_system_timezone (self->manager));
         }
 
       g_variant_unref (option);
@@ -734,7 +730,7 @@ gcal_application_set_initial_date (GcalApplication *self,
 {
   g_return_if_fail (GCAL_IS_APPLICATION (self));
 
-  g_clear_pointer (&self->initial_date, g_free);
+  g_clear_object (&self->initial_date);
   self->initial_date = datetime_to_icaltime (initial_date);
 }
 
diff --git a/src/gcal-edit-dialog.c b/src/gcal-edit-dialog.c
index 051816fd..c8b8a68c 100644
--- a/src/gcal-edit-dialog.c
+++ b/src/gcal-edit-dialog.c
@@ -380,23 +380,11 @@ static void
 remove_recurrence_properties (GcalEvent *event)
 {
   ECalComponent *comp;
-  icalcomponent *icalcomp;
-  icalproperty *prop;
 
   comp = gcal_event_get_component (event);
-  icalcomp = e_cal_component_get_icalcomponent (comp);
 
   e_cal_component_set_recurid (comp, NULL);
-
-  prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
-
-  if (prop)
-    {
-      icalcomponent_remove_property (icalcomp, prop);
-      icalproperty_free (prop);
-    }
-
-  e_cal_component_rescan (comp);
+  e_cal_component_set_rrules (comp, NULL);
 }
 
 static void
@@ -582,7 +570,7 @@ create_row_for_alarm (GcalEvent          *event,
   gtk_label_set_label (GTK_LABEL (label), text);
 
   /* Retrieves the actions associated to the alarm */
-  e_cal_component_alarm_get_action (alarm, &action);
+  action = e_cal_component_alarm_get_action (alarm);
 
   /* Updates the volume button to match the action */
   has_sound = action == E_CAL_COMPONENT_ALARM_AUDIO;
diff --git a/src/gcal-event-widget.c b/src/gcal-event-widget.c
index 01c726ef..cd7f38a6 100644
--- a/src/gcal-event-widget.c
+++ b/src/gcal-event-widget.c
@@ -1186,7 +1186,7 @@ gcal_event_widget_sort_events (GcalEventWidget *widget1,
 {
   g_autoptr (GDateTime) dt_time1 = NULL;
   g_autoptr (GDateTime) dt_time2 = NULL;
-  icaltimetype *ical_dt;
+  ICalTime *itt;
   gint diff;
 
   diff = gcal_event_is_multiday (widget2->event) - gcal_event_is_multiday (widget1->event);
@@ -1204,13 +1204,15 @@ gcal_event_widget_sort_events (GcalEventWidget *widget1,
   if (diff != 0)
     return diff;
 
-  e_cal_component_get_last_modified (gcal_event_get_component (widget1->event), &ical_dt);
-  if (ical_dt)
-    dt_time1 = icaltime_to_datetime (ical_dt);
+  itt = e_cal_component_get_last_modified (gcal_event_get_component (widget1->event));
+  if (itt)
+    dt_time1 = icaltime_to_datetime (itt);
+  g_clear_object (&itt);
 
-  e_cal_component_get_last_modified (gcal_event_get_component (widget2->event), &ical_dt);
-  if (ical_dt)
-    dt_time2 = icaltime_to_datetime (ical_dt);
+  itt = e_cal_component_get_last_modified (gcal_event_get_component (widget2->event));
+  if (itt)
+    dt_time2 = icaltime_to_datetime (itt);
+  g_clear_object (&itt);
 
   return dt_time1 && dt_time2 ? g_date_time_compare (dt_time2, dt_time1) : 0;
 }
diff --git a/src/gcal-event-widget.h b/src/gcal-event-widget.h
index 854d8894..4ba769de 100644
--- a/src/gcal-event-widget.h
+++ b/src/gcal-event-widget.h
@@ -24,8 +24,6 @@
 
 #include <gtk/gtk.h>
 
-#include <libical/icaltime.h>
-
 G_BEGIN_DECLS
 
 #define GCAL_TYPE_EVENT_WIDGET                    (gcal_event_widget_get_type ())
diff --git a/src/gcal-event.c b/src/gcal-event.c
index e8eada98..635dfe6e 100644
--- a/src/gcal-event.c
+++ b/src/gcal-event.c
@@ -72,6 +72,10 @@ struct _GcalEvent
   gchar              *uid;
   gboolean            has_recurrence;
 
+  /* These are cached, because ECalComponent returns newly allocated data for them */
+  gchar              *summary;
+  gchar              *location;
+
   /*
    * The description is cached in the class because it
    * may come as a GSList of descriptions, in which
@@ -164,12 +168,14 @@ destroy_event_cache_map (void)
 static GTimeZone*
 get_timezone_from_ical (ECalComponentDateTime *comp)
 {
-  const icaltimezone *zone;
+  ICalTimezone *zone;
+  ICalTime *itt;
   GTimeZone *tz;
 
-  zone = icaltime_get_timezone (*comp->value);
+  itt = e_cal_component_datetime_get_value (comp);
+  zone = i_cal_time_get_timezone (itt);
 
-  if (comp->value->is_date)
+  if (i_cal_time_is_date (itt))
     {
       /*
        * When loading an all day event, the timezone must not be taken into account
@@ -178,13 +184,13 @@ get_timezone_from_ical (ECalComponentDateTime *comp)
        */
       tz = g_time_zone_new_utc ();
     }
-  else if (comp->tzid)
+  else if (e_cal_component_datetime_get_tzid (comp))
     {
       const gchar *real_tzid;
 
-      real_tzid = comp->tzid;
+      real_tzid = e_cal_component_datetime_get_tzid (comp);
 
-      if (g_str_has_prefix (comp->tzid, LIBICAL_TZID_PREFIX))
+      if (g_str_has_prefix (real_tzid, LIBICAL_TZID_PREFIX))
         real_tzid += strlen (LIBICAL_TZID_PREFIX);
 
       tz = g_time_zone_new (real_tzid);
@@ -194,8 +200,7 @@ get_timezone_from_ical (ECalComponentDateTime *comp)
       g_autofree gchar *tzid = NULL;
       gint offset;
 
-      offset = icaltimezone_get_utc_offset ((icaltimezone*) icaltime_get_timezone (*comp->value),
-                                            comp->value, NULL);
+      offset = i_cal_timezone_get_utc_offset (zone, itt, NULL);
       tzid = format_utc_offset (offset);
       tz = g_time_zone_new (tzid);
     }
@@ -215,27 +220,32 @@ static ECalComponentDateTime*
 build_component_from_datetime (GcalEvent *self,
                                GDateTime *dt)
 {
-  ECalComponentDateTime *comp_dt;
+  ICalTime *itt;
+  gchar *tzid;
 
   if (!dt)
     return NULL;
 
-  comp_dt = g_new0 (ECalComponentDateTime, 1);
-  comp_dt->value = datetime_to_icaltime (dt);
-  comp_dt->value->is_date = self->all_day;
+  itt = datetime_to_icaltime (dt);
 
   if (self->all_day)
     {
-      comp_dt->value->zone = icaltimezone_get_utc_timezone ();
-      comp_dt->tzid = g_strdup ("UTC");
+      i_cal_time_set_timezone (itt, i_cal_timezone_get_utc_timezone ());
+      tzid = g_strdup ("UTC");
     }
   else
     {
-      comp_dt->value->zone = e_cal_util_get_system_timezone ();
-      comp_dt->tzid = g_strdup (icaltimezone_get_tzid ((icaltimezone *) comp_dt->value->zone));
+      ICalTimezone *zone;
+
+      zone = e_cal_util_get_system_timezone ();
+      i_cal_time_set_timezone (itt, zone);
+      tzid = zone ? g_strdup (i_cal_timezone_get_tzid (zone)) : NULL;
     }
 
-  return comp_dt;
+  /* Call it after setting the timezone, because the DATE values do not let set the timezone */
+  i_cal_time_set_is_date (itt, self->all_day);
+
+  return e_cal_component_datetime_new_take (itt, tzid);
 }
 
 static gboolean
@@ -267,28 +277,28 @@ gcal_event_update_uid_internal (GcalEvent *self)
   /* Clear the previous uid */
   g_clear_pointer (&self->uid, g_free);
 
-  if (id->rid != NULL)
+  if (e_cal_component_id_get_rid (id) != NULL)
     {
       self->uid = g_strdup_printf ("%s:%s:%s",
                                    source_id,
-                                   id->uid,
-                                   id->rid);
+                                   e_cal_component_id_get_uid (id),
+                                   e_cal_component_id_get_rid (id));
     }
   else
     {
       self->uid = g_strdup_printf ("%s:%s",
                                    source_id,
-                                   id->uid);
+                                   e_cal_component_id_get_uid (id));
     }
 
-  e_cal_component_free_id (id);
+  e_cal_component_id_free (id);
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_UID]);
 }
 
 static void
 load_alarms (GcalEvent *self)
 {
-  GList *alarm_uids, *l;
+  GSList *alarm_uids, *l;
 
   alarm_uids = e_cal_component_get_alarm_uids (self->component);
 
@@ -311,7 +321,7 @@ load_alarms (GcalEvent *self)
       e_cal_component_alarm_free (alarm);
     }
 
-  cal_obj_uid_list_free (alarm_uids);
+  g_slist_free_full (alarm_uids, g_free);
 }
 
 static void
@@ -320,24 +330,25 @@ gcal_event_set_component_internal (GcalEvent     *self,
 {
   if (g_set_object (&self->component, component))
     {
-      ECalComponentDateTime start;
-      ECalComponentDateTime end;
-      icaltimetype date;
+      ECalComponentDateTime *start;
+      ECalComponentDateTime *end;
+      ECalComponentText *text;
+      ICalTime *date;
       GDateTime *date_start;
       GTimeZone *zone_start = NULL;
       GDateTime *date_end;
       GTimeZone *zone_end = NULL;
       gboolean start_is_all_day, end_is_all_day;
-      gchar *description;
+      gchar *description, *location;
 
       /* Setup start date */
-      e_cal_component_get_dtstart (component, &start);
+      start = e_cal_component_get_dtstart (component);
 
       /*
        * A NULL start date is invalid. We set something bogus to proceed, and make
        * it set a GError and return NULL.
        */
-      if (!start.value)
+      if (!start || !e_cal_component_datetime_get_value (start))
         {
           self->is_valid = FALSE;
           g_set_error (&self->initialization_error,
@@ -345,27 +356,31 @@ gcal_event_set_component_internal (GcalEvent     *self,
                        GCAL_EVENT_ERROR_INVALID_START_DATE,
                        "Event '%s' has an invalid start date", gcal_event_get_uid (self));
 
-          start.value = g_new0 (icaltimetype, 1);
-          *start.value = icaltime_today ();
+          e_cal_component_datetime_free (start);
+          start = e_cal_component_datetime_new_take (i_cal_time_today (), NULL);
         }
 
       GCAL_TRACE_MSG ("Retrieving start timezone");
 
-      date = icaltime_normalize (*start.value);
-      zone_start = get_timezone_from_ical (&start);
+      date = i_cal_time_normalize (e_cal_component_datetime_get_value (start));
+      zone_start = get_timezone_from_ical (start);
       date_start = g_date_time_new (zone_start,
-                                    date.year, date.month, date.day,
-                                    date.is_date ? 0 : date.hour,
-                                    date.is_date ? 0 : date.minute,
-                                    date.is_date ? 0 : date.second);
+                                    i_cal_time_get_year (date),
+                                    i_cal_time_get_month (date),
+                                    i_cal_time_get_day (date),
+                                    i_cal_time_is_date (date) ? 0 : i_cal_time_get_hour (date),
+                                    i_cal_time_is_date (date) ? 0 : i_cal_time_get_minute (date),
+                                    i_cal_time_is_date (date) ? 0 : i_cal_time_get_second (date));
       start_is_all_day = datetime_is_date (date_start);
 
       self->dt_start = date_start;
 
+      g_clear_object (&date);
+
       /* Setup end date */
-      e_cal_component_get_dtend (component, &end);
+      end = e_cal_component_get_dtend (component);
 
-      if(!end.value)
+      if (!end || !e_cal_component_datetime_get_value (end))
         {
           self->all_day = TRUE;
         }
@@ -373,13 +388,15 @@ gcal_event_set_component_internal (GcalEvent     *self,
         {
           GCAL_TRACE_MSG ("Retrieving end timezone");
 
-          date = icaltime_normalize (*end.value);
-          zone_end = get_timezone_from_ical (&end);
+          date = i_cal_time_normalize (e_cal_component_datetime_get_value (end));
+          zone_end = get_timezone_from_ical (end);
           date_end = g_date_time_new (zone_end,
-                                      date.year, date.month, date.day,
-                                      date.is_date ? 0 : date.hour,
-                                      date.is_date ? 0 : date.minute,
-                                      date.is_date ? 0 : date.second);
+                                      i_cal_time_get_year (date),
+                                      i_cal_time_get_month (date),
+                                      i_cal_time_get_day (date),
+                                      i_cal_time_is_date (date) ? 0 : i_cal_time_get_hour (date),
+                                      i_cal_time_is_date (date) ? 0 : i_cal_time_get_minute (date),
+                                      i_cal_time_is_date (date) ? 0 : i_cal_time_get_second (date));
           end_is_all_day = datetime_is_date (date_end);
 
           self->dt_end = g_date_time_ref (date_end);
@@ -387,9 +404,20 @@ gcal_event_set_component_internal (GcalEvent     *self,
           /* Setup all day */
           self->all_day = start_is_all_day && end_is_all_day;
 
-          e_cal_component_free_datetime (&end);
+          g_clear_object (&date);
         }
 
+      /* Summary */
+      text = e_cal_component_get_summary (component);
+      if (text && e_cal_component_text_get_value (text))
+        gcal_event_set_summary (self, e_cal_component_text_get_value (text));
+      else
+        gcal_event_set_summary (self, "");
+
+      /* Location */
+      location = e_cal_component_get_location (component);
+      gcal_event_set_location (self, location ? location : "");
+
       /* Setup description */
       description = get_desc_from_component (component, "\n\n");
       gcal_event_set_description (self, description);
@@ -409,14 +437,15 @@ gcal_event_set_component_internal (GcalEvent     *self,
       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HAS_RECURRENCE]);
       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RECURRENCE]);
       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COMPONENT]);
-      g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LOCATION]);
-      g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SUMMARY]);
 
       g_clear_pointer (&zone_start, g_time_zone_unref);
       g_clear_pointer (&zone_end, g_time_zone_unref);
       g_clear_pointer (&description, g_free);
+      g_clear_pointer (&location, g_free);
 
-      e_cal_component_free_datetime (&start);
+      e_cal_component_text_free (text);
+      e_cal_component_datetime_free (start);
+      e_cal_component_datetime_free (end);
     }
 }
 
@@ -462,6 +491,8 @@ 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->summary, g_free);
+  g_clear_pointer (&self->location, g_free);
   g_clear_pointer (&self->description, g_free);
   g_clear_pointer (&self->alarms, g_hash_table_unref);
   g_clear_pointer (&self->uid, g_free);
@@ -950,8 +981,7 @@ gcal_event_set_date_end (GcalEvent *self,
 
       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DATE_END]);
 
-      e_cal_component_free_datetime (component_dt);
-      g_free (component_dt);
+      e_cal_component_datetime_free (component_dt);
     }
 }
 
@@ -999,8 +1029,7 @@ gcal_event_set_date_start (GcalEvent *self,
 
       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DATE_START]);
 
-      e_cal_component_free_datetime (component_dt);
-      g_free (component_dt);
+      e_cal_component_datetime_free (component_dt);
     }
 }
 
@@ -1033,21 +1062,32 @@ gcal_event_set_description (GcalEvent   *self,
 {
   g_return_if_fail (GCAL_IS_EVENT (self));
 
+  if (description && !*description)
+    description = NULL;
+
   if (g_strcmp0 (self->description, description) != 0)
     {
-      ECalComponentText text_component;
-      GSList list;
-
       g_clear_pointer (&self->description, g_free);
       self->description = g_strdup (description);
 
-      text_component.value = description;
-      text_component.altrep = NULL;
+      if (description)
+        {
+          ECalComponentText* text_component;
+          GSList list;
 
-      list.data = &text_component;
-      list.next = NULL;
+          text_component = e_cal_component_text_new (description, NULL);
+
+          list.data = text_component;
+          list.next = NULL;
+
+          e_cal_component_set_descriptions (self->component, &list);
+          e_cal_component_text_free (text_component);
+        }
+      else
+        {
+          e_cal_component_set_descriptions (self->component, NULL);
+        }
 
-      e_cal_component_set_description_list (self->component, &list);
       e_cal_component_commit_sequence (self->component);
 
       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_DESCRIPTION]);
@@ -1098,7 +1138,8 @@ GList*
 gcal_event_get_alarms (GcalEvent *self)
 {
   GHashTable *tmp;
-  GList *alarm_uids, *alarms, *l;
+  GSList *alarm_uids, *l;
+  GList *alarms;
 
   g_return_val_if_fail (GCAL_IS_EVENT (self), NULL);
 
@@ -1127,7 +1168,7 @@ gcal_event_get_alarms (GcalEvent *self)
         }
     }
 
-  cal_obj_uid_list_free (alarm_uids);
+  g_slist_free_full (alarm_uids, g_free);
   g_hash_table_destroy (tmp);
 
   return alarms;
@@ -1149,9 +1190,10 @@ gcal_event_add_alarm (GcalEvent *self,
                       guint      type,
                       gboolean   has_sound)
 {
-  ECalComponentAlarmTrigger trigger;
+  ECalComponentAlarmTrigger *trigger;
   ECalComponentAlarmAction action;
   ECalComponentAlarm *alarm;
+  ICalDuration *duration;
   gchar *alarm_uid;
 
   g_return_if_fail (GCAL_IS_EVENT (self));
@@ -1168,13 +1210,15 @@ gcal_event_add_alarm (GcalEvent *self,
   alarm = e_cal_component_alarm_new ();
 
   /* Setup the alarm trigger */
-  trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START;
+  duration = i_cal_duration_null_duration ();
+  i_cal_duration_set_is_neg (duration, TRUE);
+  i_cal_duration_set_minutes (duration, type);
+
+  trigger = e_cal_component_alarm_trigger_new_relative (E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START, 
duration);
 
-  trigger.u.rel_duration = icaldurationtype_null_duration ();
-  trigger.u.rel_duration.is_neg = TRUE;
-  trigger.u.rel_duration.minutes = type;
+  g_clear_object (&duration);
 
-  e_cal_component_alarm_set_trigger (alarm, trigger);
+  e_cal_component_alarm_take_trigger (alarm, trigger);
 
   /* Action */
   if (has_sound)
@@ -1236,13 +1280,9 @@ gcal_event_remove_alarm (GcalEvent *self,
 const gchar*
 gcal_event_get_location (GcalEvent *self)
 {
-  const gchar *location;
-
   g_return_val_if_fail (GCAL_IS_EVENT (self), NULL);
 
-  e_cal_component_get_location (self->component, &location);
-
-  return location ? location : "";
+  return self->location;
 }
 
 /**
@@ -1264,7 +1304,10 @@ gcal_event_set_location (GcalEvent   *self,
 
   if (g_strcmp0 (current_location, location) != 0)
     {
-      e_cal_component_set_location (self->component, location);
+      e_cal_component_set_location (self->component, (location && *location) ? location : NULL);
+
+      g_clear_pointer (&self->location, g_free);
+      self->location = g_strdup (location ? location : "");
 
       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_LOCATION]);
     }
@@ -1350,13 +1393,9 @@ gcal_event_set_source (GcalEvent *self,
 const gchar*
 gcal_event_get_summary (GcalEvent *self)
 {
-  ECalComponentText summary;
-
   g_return_val_if_fail (GCAL_IS_EVENT (self), NULL);
 
-  e_cal_component_get_summary (self->component, &summary);
-
-  return summary.value ? summary.value : "";
+  return self->summary;
 }
 
 /**
@@ -1378,14 +1417,18 @@ gcal_event_set_summary (GcalEvent   *self,
 
   if (g_strcmp0 (current_summary, summary) != 0)
     {
-      ECalComponentText text_component;
+      ECalComponentText *text_component;
 
-      text_component.value = summary ? summary : "";
-      text_component.altrep = NULL;
+      text_component = e_cal_component_text_new (summary ? summary : "", NULL);
 
-      e_cal_component_set_summary (self->component, &text_component);
+      e_cal_component_set_summary (self->component, text_component);
       e_cal_component_commit_sequence (self->component);
 
+      e_cal_component_text_free (text_component);
+
+      g_clear_pointer (&self->summary, g_free);
+      self->summary = g_strdup (summary ? summary : "");
+
       g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SUMMARY]);
     }
 }
@@ -1581,9 +1624,9 @@ gcal_event_set_recurrence (GcalEvent      *self,
                            GcalRecurrence *recur)
 {
   ECalComponent *comp;
-  icalcomponent *icalcomp;
-  icalproperty *prop;
-  struct icalrecurrencetype *rrule;
+  ICalComponent *icalcomp;
+  ICalProperty *prop;
+  ICalRecurrence *rrule;
 
   g_return_if_fail (GCAL_IS_EVENT (self));
 
@@ -1595,20 +1638,20 @@ gcal_event_set_recurrence (GcalEvent      *self,
   g_clear_pointer (&self->recurrence, gcal_recurrence_unref);
   self->recurrence = gcal_recurrence_copy (recur);
 
-  prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+  prop = i_cal_component_get_first_property (icalcomp, I_CAL_RRULE_PROPERTY);
 
   if (prop)
     {
-      icalproperty_set_rrule (prop, *rrule);
+      i_cal_property_set_rrule (prop, rrule);
     }
   else
     {
-      prop = icalproperty_new_rrule (*rrule);
-      icalcomponent_add_property (icalcomp, prop);
+      prop = i_cal_property_new_rrule (rrule);
+      i_cal_component_add_property (icalcomp, prop);
     }
 
-  /* Rescan the component for the changes to be detected and registered */
-  e_cal_component_rescan (comp);
+  g_clear_object (&rrule);
+  g_clear_object (&prop);
 }
 
 /**
@@ -1648,33 +1691,36 @@ gcal_event_get_original_timezones (GcalEvent  *self,
 {
   g_autoptr (GTimeZone) original_start_tz = NULL;
   g_autoptr (GTimeZone) original_end_tz = NULL;
-  icalcomponent *ical_comp;
-  icalproperty *property;
+  ICalComponent *icalcomp;
+  ICalProperty *property;
 
   g_return_if_fail (GCAL_IS_EVENT (self));
   g_assert (self->component != NULL);
 
-  ical_comp = e_cal_component_get_icalcomponent (self->component);
+  icalcomp = e_cal_component_get_icalcomponent (self->component);
 
-  for (property = icalcomponent_get_first_property (ical_comp, ICAL_X_PROPERTY);
+  for (property = i_cal_component_get_first_property (icalcomp, I_CAL_X_PROPERTY);
        property;
-       property = icalcomponent_get_next_property (ical_comp, ICAL_X_PROPERTY))
+       g_object_unref (property), property = i_cal_component_get_next_property (icalcomp, I_CAL_X_PROPERTY))
     {
       const gchar *value;
 
       if (original_start_tz && original_end_tz)
-        break;
+        {
+          g_object_unref (property);
+          break;
+        }
 
-      if (g_strcmp0 (icalproperty_get_x_name (property), "X-GNOME-CALENDAR-ORIGINAL-TZ-START") == 0)
+      if (g_strcmp0 (i_cal_property_get_x_name (property), "X-GNOME-CALENDAR-ORIGINAL-TZ-START") == 0)
         {
-          value = icalproperty_get_x (property);
+          value = i_cal_property_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)
+      else if (g_strcmp0 (i_cal_property_get_x_name (property), "X-GNOME-CALENDAR-ORIGINAL-TZ-END") == 0)
         {
-          value = icalproperty_get_x (property);
+          value = i_cal_property_get_x (property);
           original_end_tz = g_time_zone_new (value);
 
           GCAL_TRACE_MSG ("Found X-GNOME-CALENDAR-ORIGINAL-TZ-END=%s", value);
@@ -1709,8 +1755,8 @@ gcal_event_get_original_timezones (GcalEvent  *self,
 void
 gcal_event_save_original_timezones (GcalEvent *self)
 {
-  icalcomponent *ical_comp;
-  icalproperty *property;
+  ICalComponent *icalcomp;
+  ICalProperty *property;
   GTimeZone *tz;
   gboolean has_original_start_tz;
   gboolean has_original_end_tz;
@@ -1722,52 +1768,55 @@ gcal_event_save_original_timezones (GcalEvent *self)
 
   has_original_start_tz = FALSE;
   has_original_end_tz = FALSE;
-  ical_comp = e_cal_component_get_icalcomponent (self->component);
+  icalcomp = 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))
+  for (property = i_cal_component_get_first_property (icalcomp, I_CAL_X_PROPERTY);
+       property && (!has_original_start_tz || !has_original_end_tz);
+       g_object_unref (property), property = i_cal_component_get_next_property (icalcomp, I_CAL_X_PROPERTY))
     {
-      if (g_strcmp0 (icalproperty_get_x_name (property), "X-GNOME-CALENDAR-ORIGINAL-TZ-START") == 0)
+      if (g_strcmp0 (i_cal_property_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));
+          i_cal_property_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));
+          GCAL_TRACE_MSG ("Reusing X-GNOME-CALENDAR-ORIGINAL-TZ-START property with %s", 
i_cal_property_get_x (property));
 
           has_original_start_tz = TRUE;
         }
-      else if (g_strcmp0 (icalproperty_get_x_name (property), "X-GNOME-CALENDAR-ORIGINAL-TZ-END") == 0)
+      else if (g_strcmp0 (i_cal_property_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));
+          i_cal_property_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));
+          GCAL_TRACE_MSG ("Reusing X-GNOME-CALENDAR-ORIGINAL-TZ-END property with %s", i_cal_property_get_x 
(property));
 
           has_original_end_tz = TRUE;
         }
     }
 
+  g_clear_object (&property);
+
   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");
+      property = i_cal_property_new_x (g_time_zone_get_identifier (tz));
+      i_cal_property_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", i_cal_property_get_x 
(property));
+      GCAL_TRACE_MSG ("Added new X-GNOME-CALENDAR-ORIGINAL-TZ-START property with %s", i_cal_property_get_x 
(property));
 
-      GCAL_TRACE_MSG ("Added new X-GNOME-CALENDAR-ORIGINAL-TZ-START property with %s", icalproperty_get_x 
(property));
+      i_cal_component_take_property (icalcomp, 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");
+      property = i_cal_property_new_x (g_time_zone_get_identifier (tz));
+      i_cal_property_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", i_cal_property_get_x 
(property));
 
-      GCAL_TRACE_MSG ("Added new X-GNOME-CALENDAR-ORIGINAL-TZ-END property with %s", icalproperty_get_x 
(property));
+      i_cal_component_take_property (icalcomp, property);
     }
 
   GCAL_EXIT;
diff --git a/src/gcal-manager.c b/src/gcal-manager.c
index 54131aa8..fd7e153f 100644
--- a/src/gcal-manager.c
+++ b/src/gcal-manager.c
@@ -95,7 +95,7 @@ struct _GcalManager
   gint                sources_at_launch;
 
   /* timezone */
-  icaltimezone       *system_timezone;
+  ICalTimezone       *system_timezone;
 
   /* property */
   GSettings          *settings;
@@ -1091,7 +1091,7 @@ gcal_manager_set_default_source (GcalManager *self,
  *
  * Returns: (transfer none): the default timezone
  */
-icaltimezone*
+ICalTimezone*
 gcal_manager_get_system_timezone (GcalManager *self)
 {
   g_return_val_if_fail (GCAL_IS_MANAGER (self), NULL);
@@ -1580,7 +1580,7 @@ gcal_manager_create_event (GcalManager *self,
                            GcalEvent   *event)
 {
   GcalManagerUnit *unit;
-  icalcomponent *new_event_icalcomp;
+  ICalComponent *new_event_icalcomp;
   ECalComponent *component;
   AsyncOpsData *data;
   ESource *source;
@@ -1604,6 +1604,7 @@ gcal_manager_create_event (GcalManager *self,
 
   e_cal_client_create_object (unit->client,
                               new_event_icalcomp,
+                              E_CAL_OPERATION_FLAG_NONE,
                               self->async_ops,
                               on_event_created,
                               data);
@@ -1654,6 +1655,7 @@ gcal_manager_update_event (GcalManager           *self,
   e_cal_client_modify_object (unit->client,
                               e_cal_component_get_icalcomponent (component),
                               (ECalObjModType) mod,
+                              E_CAL_OPERATION_FLAG_NONE,
                               NULL,
                               on_event_updated,
                               component);
@@ -1688,7 +1690,7 @@ gcal_manager_remove_event (GcalManager           *self,
   unit = g_hash_table_lookup (self->clients, gcal_event_get_source (event));
   rid = NULL;
 
-  e_cal_component_get_uid (component, &uid);
+  uid = e_cal_component_get_uid (component);
 
   if (gcal_event_has_recurrence (event))
     rid = e_cal_component_get_recurid_as_string (component);
@@ -1697,6 +1699,7 @@ gcal_manager_remove_event (GcalManager           *self,
                               uid,
                               mod == GCAL_RECURRENCE_MOD_ALL ? NULL : rid,
                               (ECalObjModType) mod,
+                              E_CAL_OPERATION_FLAG_NONE,
                               self->async_ops,
                               on_event_removed,
                               g_object_ref (event));
@@ -1723,7 +1726,7 @@ gcal_manager_move_event_to_source (GcalManager *self,
 {
   ECalComponent *ecomponent;
   ECalComponent *clone;
-  icalcomponent *comp;
+  ICalComponent *comp;
   GcalManagerUnit *unit;
   ECalComponentId *id;
   GError *error;
@@ -1745,6 +1748,7 @@ gcal_manager_move_event_to_source (GcalManager *self,
 
   e_cal_client_create_object_sync (unit->client,
                                    comp,
+                                   E_CAL_OPERATION_FLAG_NONE,
                                    NULL,
                                    NULL,
                                    &error);
@@ -1767,9 +1771,10 @@ gcal_manager_move_event_to_source (GcalManager *self,
   id = e_cal_component_get_id (ecomponent);
 
   e_cal_client_remove_object_sync (unit->client,
-                                   id->uid,
-                                   id->rid,
+                                   e_cal_component_id_get_uid (id),
+                                   e_cal_component_id_get_rid (id),
                                    E_CAL_OBJ_MOD_THIS,
+                                   E_CAL_OPERATION_FLAG_NONE,
                                    self->async_ops,
                                    &error);
 
@@ -1781,7 +1786,7 @@ gcal_manager_move_event_to_source (GcalManager *self,
       return;
     }
 
-  e_cal_component_free_id (id);
+  e_cal_component_id_free (id);
 
   GCAL_EXIT;
 }
@@ -1799,9 +1804,9 @@ gcal_manager_move_event_to_source (GcalManager *self,
  * Returns: (nullable)(transfer full)(content-type GcalEvent):a #GList
  */
 GList*
-gcal_manager_get_events (GcalManager  *self,
-                         icaltimetype *start_date,
-                         icaltimetype *end_date)
+gcal_manager_get_events (GcalManager *self,
+                         ICalTime    *start_date,
+                         ICalTime    *end_date)
 {
   time_t range_start, range_end;
   GList *list = NULL;
@@ -1810,8 +1815,8 @@ gcal_manager_get_events (GcalManager  *self,
 
   g_return_val_if_fail (GCAL_IS_MANAGER (self), NULL);
 
-  range_start = icaltime_as_timet_with_zone (*start_date, self->system_timezone);
-  range_end = icaltime_as_timet_with_zone (*end_date, self->system_timezone);
+  range_start = i_cal_time_as_timet_with_zone (start_date, self->system_timezone);
+  range_end = i_cal_time_as_timet_with_zone (end_date, self->system_timezone);
 
   e_cal_data_model_foreach_component (self->e_data_model,
                                       range_start,
diff --git a/src/gcal-manager.h b/src/gcal-manager.h
index ce47016e..49559891 100644
--- a/src/gcal-manager.h
+++ b/src/gcal-manager.h
@@ -22,7 +22,7 @@
 #include "e-cal-data-model.h"
 #include "gcal-event.h"
 
-#include <libical/icaltime.h>
+#include <libecal/libecal.h>
 #include <goa/goa.h>
 
 G_BEGIN_DECLS
@@ -47,7 +47,7 @@ ESource*             gcal_manager_get_default_source             (GcalManager
 void                 gcal_manager_set_default_source             (GcalManager        *self,
                                                                   ESource            *source);
 
-icaltimezone*        gcal_manager_get_system_timezone            (GcalManager        *self);
+ICalTimezone*        gcal_manager_get_system_timezone            (GcalManager        *self);
 
 void                 gcal_manager_set_subscriber                 (GcalManager        *self,
                                                                   ECalDataModelSubscriber *subscriber,
@@ -101,8 +101,8 @@ void                 gcal_manager_save_source                    (GcalManager
                                                                   ESource            *source);
 
 GList*               gcal_manager_get_events                     (GcalManager        *self,
-                                                                  icaltimetype       *range_start,
-                                                                  icaltimetype       *range_end);
+                                                                  ICalTime           *range_start,
+                                                                  ICalTime           *range_end);
 
 gboolean             gcal_manager_get_loading                    (GcalManager        *self);
 
diff --git a/src/gcal-recurrence.c b/src/gcal-recurrence.c
index cc68a9b4..d2b3ffb6 100644
--- a/src/gcal-recurrence.c
+++ b/src/gcal-recurrence.c
@@ -160,9 +160,9 @@ GcalRecurrence*
 gcal_recurrence_parse_recurrence_rules (ECalComponent *comp)
 {
   GcalRecurrence *recur;
-  icalproperty *prop;
-  icalcomponent *icalcomp;
-  struct icalrecurrencetype rrule;
+  ICalProperty *prop;
+  ICalComponent *icalcomp;
+  ICalRecurrence *rrule;
 
   if (!e_cal_component_has_recurrences (comp))
     return NULL;
@@ -170,26 +170,28 @@ gcal_recurrence_parse_recurrence_rules (ECalComponent *comp)
   recur = gcal_recurrence_new ();
   icalcomp = e_cal_component_get_icalcomponent (comp);
 
-  prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+  prop = i_cal_component_get_first_property (icalcomp, I_CAL_RRULE_PROPERTY);
   g_return_val_if_fail (prop != NULL, NULL);
 
-  rrule = icalproperty_get_rrule (prop);
+  rrule = i_cal_property_get_rrule (prop);
 
-  switch (rrule.freq)
+  g_clear_object (&prop);
+
+  switch (i_cal_recurrence_get_freq (rrule))
     {
-      case ICAL_DAILY_RECURRENCE:
+      case I_CAL_DAILY_RECURRENCE:
         recur->frequency = GCAL_RECURRENCE_DAILY;
         break;
 
-      case ICAL_WEEKLY_RECURRENCE:
+      case I_CAL_WEEKLY_RECURRENCE:
         {
-          if (rrule.by_day[0] == ICAL_MONDAY_WEEKDAY &&
-              rrule.by_day[1] == ICAL_TUESDAY_WEEKDAY &&
-              rrule.by_day[2] == ICAL_WEDNESDAY_WEEKDAY &&
-              rrule.by_day[3] == ICAL_THURSDAY_WEEKDAY &&
-              rrule.by_day[4] == ICAL_FRIDAY_WEEKDAY &&
-              rrule.by_day[5] != ICAL_SATURDAY_WEEKDAY &&
-              rrule.by_day[6] != ICAL_SUNDAY_WEEKDAY)
+          if (i_cal_recurrence_get_by_day (rrule, 0) == I_CAL_MONDAY_WEEKDAY &&
+              i_cal_recurrence_get_by_day (rrule, 1) == I_CAL_TUESDAY_WEEKDAY &&
+              i_cal_recurrence_get_by_day (rrule, 2) == I_CAL_WEDNESDAY_WEEKDAY &&
+              i_cal_recurrence_get_by_day (rrule, 3) == I_CAL_THURSDAY_WEEKDAY &&
+              i_cal_recurrence_get_by_day (rrule, 4) == I_CAL_FRIDAY_WEEKDAY &&
+              i_cal_recurrence_get_by_day (rrule, 5) != I_CAL_SATURDAY_WEEKDAY &&
+              i_cal_recurrence_get_by_day (rrule, 6) != I_CAL_SUNDAY_WEEKDAY)
             {
               recur->frequency = GCAL_RECURRENCE_MON_FRI;
             }
@@ -200,11 +202,11 @@ gcal_recurrence_parse_recurrence_rules (ECalComponent *comp)
           break;
         }
 
-      case ICAL_MONTHLY_RECURRENCE:
+      case I_CAL_MONTHLY_RECURRENCE:
         recur->frequency = GCAL_RECURRENCE_MONTHLY;
         break;
 
-      case ICAL_YEARLY_RECURRENCE:
+      case I_CAL_YEARLY_RECURRENCE:
         recur->frequency = GCAL_RECURRENCE_YEARLY;
         break;
 
@@ -212,21 +214,32 @@ gcal_recurrence_parse_recurrence_rules (ECalComponent *comp)
         recur->frequency = GCAL_RECURRENCE_OTHER;
     }
 
-  if (rrule.count > 0)
+  if (i_cal_recurrence_get_count (rrule) > 0)
     {
       recur->limit_type = GCAL_RECURRENCE_COUNT;
-      recur->limit.count = rrule.count;
-    }
-  else if (rrule.until.year != 0)
-    {
-      recur->limit_type = GCAL_RECURRENCE_UNTIL;
-      recur->limit.until = icaltime_to_datetime (&rrule.until);
+      recur->limit.count = i_cal_recurrence_get_count (rrule);
     }
   else
     {
-      recur->limit_type = GCAL_RECURRENCE_FOREVER;
+      ICalTime *until;
+
+      until = i_cal_recurrence_get_until (rrule);
+
+      if (i_cal_time_get_year (until) != 0)
+        {
+          recur->limit_type = GCAL_RECURRENCE_UNTIL;
+          recur->limit.until = icaltime_to_datetime (until);
+        }
+      else
+        {
+          recur->limit_type = GCAL_RECURRENCE_FOREVER;
+        }
+
+      g_clear_object (&until);
     }
 
+  g_clear_object (&rrule);
+
   return recur;
 }
 
@@ -236,72 +249,80 @@ gcal_recurrence_parse_recurrence_rules (ECalComponent *comp)
  *
  * Converts @recur into corresponding rrule.
  *
- * Returns: (transfer full): a #struct icalrecurrencetype
+ * Returns: (transfer full): an #ICalRecurrence
  */
-struct icalrecurrencetype*
+ICalRecurrence*
 gcal_recurrence_to_rrule (GcalRecurrence *recur)
 {
-  struct icalrecurrencetype *rrule;
+  ICalRecurrence *rrule;
 
   if (!recur)
     return NULL;
 
   /* Initialize and clear the rrule to get rid of unwanted fields */
-  rrule = g_new0 (struct icalrecurrencetype, 1);
-  icalrecurrencetype_clear (rrule);
+  rrule = i_cal_recurrence_new ();
 
   switch (recur->frequency)
     {
     case GCAL_RECURRENCE_DAILY:
-      rrule->freq = ICAL_DAILY_RECURRENCE;
+      i_cal_recurrence_set_freq (rrule, I_CAL_DAILY_RECURRENCE);
       break;
 
     case GCAL_RECURRENCE_WEEKLY:
-      rrule->freq = ICAL_WEEKLY_RECURRENCE;
+      i_cal_recurrence_set_freq (rrule, I_CAL_WEEKLY_RECURRENCE);
       break;
 
     case GCAL_RECURRENCE_MONTHLY:
-      rrule->freq = ICAL_MONTHLY_RECURRENCE;
+      i_cal_recurrence_set_freq (rrule, I_CAL_MONTHLY_RECURRENCE);
       break;
 
     case GCAL_RECURRENCE_YEARLY:
-      rrule->freq = ICAL_YEARLY_RECURRENCE;
+      i_cal_recurrence_set_freq (rrule, I_CAL_YEARLY_RECURRENCE);
       break;
 
     case GCAL_RECURRENCE_NO_REPEAT:
-      rrule->freq = ICAL_NO_RECURRENCE;
+      i_cal_recurrence_set_freq (rrule, I_CAL_NO_RECURRENCE);
       break;
 
     case GCAL_RECURRENCE_MON_FRI:
       {
-        rrule->freq = ICAL_WEEKLY_RECURRENCE;
-        rrule->by_day[0] = ICAL_MONDAY_WEEKDAY;
-        rrule->by_day[1] = ICAL_TUESDAY_WEEKDAY;
-        rrule->by_day[2] = ICAL_WEDNESDAY_WEEKDAY;
-        rrule->by_day[3] = ICAL_THURSDAY_WEEKDAY;
-        rrule->by_day[4] = ICAL_FRIDAY_WEEKDAY;
+        i_cal_recurrence_set_freq (rrule, I_CAL_WEEKLY_RECURRENCE);
+        i_cal_recurrence_set_by_day (rrule, 0, I_CAL_MONDAY_WEEKDAY);
+        i_cal_recurrence_set_by_day (rrule, 1, I_CAL_TUESDAY_WEEKDAY);
+        i_cal_recurrence_set_by_day (rrule, 2, I_CAL_WEDNESDAY_WEEKDAY);
+        i_cal_recurrence_set_by_day (rrule, 3, I_CAL_THURSDAY_WEEKDAY);
+        i_cal_recurrence_set_by_day (rrule, 4, I_CAL_FRIDAY_WEEKDAY);
         break;
       }
 
     default:
-      rrule->freq = ICAL_NO_RECURRENCE;
+      i_cal_recurrence_set_freq (rrule, I_CAL_NO_RECURRENCE);
       break;
     }
 
   switch (recur->limit_type)
     {
     case GCAL_RECURRENCE_COUNT:
-      rrule->count = recur->limit.count;
+      i_cal_recurrence_set_count (rrule, recur->limit.count);
       break;
 
     case GCAL_RECURRENCE_UNTIL:
       {
-        rrule->until.second = g_date_time_get_second (recur->limit.until);
-        rrule->until.minute = g_date_time_get_minute (recur->limit.until);
-        rrule->until.hour = g_date_time_get_hour (recur->limit.until);
-        rrule->until.day = g_date_time_get_day_of_month (recur->limit.until);
-        rrule->until.month = g_date_time_get_month (recur->limit.until);
-        rrule->until.year = g_date_time_get_year (recur->limit.until);
+        ICalTime *until;
+
+        until = i_cal_time_null_time ();
+        i_cal_time_set_date (until,
+                             g_date_time_get_year (recur->limit.until),
+                             g_date_time_get_month (recur->limit.until),
+                             g_date_time_get_day_of_month (recur->limit.until));
+        i_cal_time_set_time (until,
+                             g_date_time_get_hour (recur->limit.until),
+                             g_date_time_get_minute (recur->limit.until),
+                             g_date_time_get_second (recur->limit.until));
+
+        i_cal_recurrence_set_until (rrule, until);
+
+        g_clear_object (&until);
         break;
       }
 
diff --git a/src/gcal-recurrence.h b/src/gcal-recurrence.h
index 13a6935d..340db66a 100644
--- a/src/gcal-recurrence.h
+++ b/src/gcal-recurrence.h
@@ -84,7 +84,7 @@ gboolean             gcal_recurrence_is_equal                    (GcalRecurrence
 
 GcalRecurrence*      gcal_recurrence_parse_recurrence_rules      (ECalComponent      *comp);
 
-struct icalrecurrencetype* gcal_recurrence_to_rrule              (GcalRecurrence     *recur);
+ICalRecurrence*      gcal_recurrence_to_rrule              (GcalRecurrence     *recur);
 
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GcalRecurrence, gcal_recurrence_unref)
 
diff --git a/src/gcal-search-popover.c b/src/gcal-search-popover.c
index 4eaa6e4c..c2d28543 100644
--- a/src/gcal-search-popover.c
+++ b/src/gcal-search-popover.c
@@ -57,7 +57,7 @@ struct _GcalSearchPopover
   guint               search_timeout_id;
 
   /* property */
-  icaltimetype       *date;
+  ICalTime           *date;
   GcalManager        *manager; /* weak reference */
 
   /* flags */
@@ -122,7 +122,7 @@ display_header_func (GtkListBoxRow *row,
  * when the @row is activated by the user.
  *
  * It is up to #GcalWindow to hear the signal,
- * retrieve the #icaltimetype passed as parameter
+ * retrieve the #ICalTime passed as parameter
  * and select the day from the last view.
  *
  * Returns:
@@ -133,14 +133,14 @@ open_event (GtkListBox    *list,
             gpointer       user_data)
 {
   RowEventData *data;
-  icaltimetype *date_start;
+  ICalTime *date_start;
 
   data = g_object_get_data (G_OBJECT (row), "event-data");
   date_start = datetime_to_icaltime (gcal_event_get_date_start (data->event));
 
   g_signal_emit_by_name (user_data, "event-activated", date_start);
 
-  g_free (date_start);
+  g_clear_object (&date_start);
 }
 
 /**
@@ -582,8 +582,8 @@ gcal_search_popover_set_property (GObject      *object,
   switch (property_id)
     {
     case PROP_DATE:
-      g_clear_pointer (&self->date, g_free);
-      self->date = g_value_dup_boxed (value);
+      g_clear_object (&self->date);
+      self->date = g_value_dup_object (value);
       break;
 
     case PROP_TIME_FORMAT:
@@ -607,7 +607,7 @@ gcal_search_popover_get_property (GObject    *object,
   switch (property_id)
     {
     case PROP_DATE:
-      g_value_set_boxed (value, self->date);
+      g_value_set_object (value, self->date);
       break;
 
     case PROP_TIME_FORMAT:
@@ -625,7 +625,7 @@ gcal_search_popover_finalize (GObject *object)
 {
   GcalSearchPopover *self = GCAL_SEARCH_POPOVER (object);
 
-  g_clear_pointer (&self->date, g_free);
+  g_clear_object (&self->date);
   g_clear_pointer (&self->uuid_to_event, g_hash_table_unref);
 
   /* Chain up to parent's finalize() method. */
@@ -656,7 +656,7 @@ gcal_search_popover_class_init (GcalSearchPopoverClass *klass)
   signals[EVENT_ACTIVATED] = g_signal_new ("event-activated", GCAL_TYPE_SEARCH_POPOVER, G_SIGNAL_RUN_LAST,
                                            0,
                                            NULL, NULL, NULL,
-                                           G_TYPE_NONE, 1, ICAL_TIME_TYPE);
+                                           G_TYPE_NONE, 1, I_CAL_TYPE_TIME);
 
   /* properties */
   /**
@@ -668,11 +668,11 @@ gcal_search_popover_class_init (GcalSearchPopoverClass *klass)
    */
   g_object_class_install_property (object_class,
                                    PROP_DATE,
-                                   g_param_spec_boxed ("active-date",
-                                                       "The active date",
-                                                       "The active/selected date in the view",
-                                                       ICAL_TIME_TYPE,
-                                                       G_PARAM_READWRITE));
+                                   g_param_spec_object ("active-date",
+                                                        "The active date",
+                                                        "The active/selected date in the view",
+                                                        I_CAL_TYPE_TIME,
+                                                        G_PARAM_READWRITE));
 
   g_object_class_install_property (object_class,
                                    PROP_TIME_FORMAT,
diff --git a/src/gcal-shell-search-provider.c b/src/gcal-shell-search-provider.c
index b5f67da7..33b9ee45 100644
--- a/src/gcal-shell-search-provider.c
+++ b/src/gcal-shell-search-provider.c
@@ -31,7 +31,6 @@ typedef struct
 {
   GDBusMethodInvocation    *invocation;
   gchar                   **terms;
-  icaltimetype              date;
 } PendingSearch;
 
 struct _GcalShellSearchProvider
@@ -76,7 +75,8 @@ sort_event_data (GcalEvent *a,
 static gboolean
 execute_search (GcalShellSearchProvider *self)
 {
-  icaltimezone *zone;
+  ICalTimezone *zone;
+  ICalTime *date;
   g_autofree gchar *search_query = NULL;
   time_t range_start, range_end;
   guint i;
@@ -87,12 +87,14 @@ execute_search (GcalShellSearchProvider *self)
     GCAL_RETURN (TRUE);
 
   zone = gcal_manager_get_system_timezone (self->manager);
-  self->pending_search->date = icaltime_current_time_with_zone (zone);
-  icaltime_adjust (&(self->pending_search->date), -7, 0, 0, 0); /* -1 weeks from today */
-  range_start = icaltime_as_timet_with_zone (self->pending_search->date, zone);
+  date = i_cal_time_current_time_with_zone (zone);
+  i_cal_time_adjust (date, -7, 0, 0, 0); /* -1 week from today */
+  range_start = i_cal_time_as_timet_with_zone (date, zone);
 
-  icaltime_adjust (&(self->pending_search->date), 21 * 2, 0, 0, 0); /* +3 weeks from today */
-  range_end = icaltime_as_timet_with_zone (self->pending_search->date, zone);
+  i_cal_time_adjust (date, 21 * 2, 0, 0, 0); /* +3 weeks from today */
+  range_end = i_cal_time_as_timet_with_zone (date, zone);
+
+  g_clear_object (&date);
 
   gcal_manager_set_shell_search_subscriber (self->manager, E_CAL_DATA_MODEL_SUBSCRIBER (self),
                                             range_start, range_end);
diff --git a/src/gcal-utils.c b/src/gcal-utils.c
index c7646565..cd75cc73 100644
--- a/src/gcal-utils.c
+++ b/src/gcal-utils.c
@@ -100,8 +100,6 @@ month_item[12] =
 
 #define SCROLL_HARDNESS 10.0
 
-G_DEFINE_BOXED_TYPE (icaltimetype, icaltime, gcal_dup_icaltime, g_free)
-
 /**
  * datetime_compare_date:
  * @dt1: (nullable): a #GDateTime
@@ -139,56 +137,61 @@ datetime_compare_date (GDateTime *dt1,
  * datetime_to_icaltime:
  * @dt: a #GDateTime
  *
- * Converts the #GDateTime's @dt to an #icaltimetype.
+ * Converts the #GDateTime's @dt to an #ICalTime.
  *
- * Returns: (transfer full): a #icaltimetype.
+ * Returns: (transfer full): an #ICalTime.
  */
-icaltimetype*
+ICalTime*
 datetime_to_icaltime (GDateTime *dt)
 {
-  icaltimetype *idt;
+  ICalTime *idt;
 
   if (!dt)
     return NULL;
 
-  idt = g_new0 (icaltimetype, 1);
-
-  idt->year = g_date_time_get_year (dt);
-  idt->month = g_date_time_get_month (dt);
-  idt->day = g_date_time_get_day_of_month (dt);
-  idt->hour = g_date_time_get_hour (dt);
-  idt->minute = g_date_time_get_minute (dt);
-  idt->second = g_date_time_get_seconds (dt);
-  idt->is_date = (idt->hour == 0 &&
-                  idt->minute == 0 &&
-                  idt->second == 0);
+  idt = i_cal_time_null_time ();
+
+  i_cal_time_set_date (idt,
+                       g_date_time_get_year (dt),
+                       g_date_time_get_month (dt),
+                       g_date_time_get_day_of_month (dt));
+  i_cal_time_set_time (idt,
+                       g_date_time_get_hour (dt),
+                       g_date_time_get_minute (dt),
+                       g_date_time_get_seconds (dt));
+  i_cal_time_set_is_date (idt,
+                  i_cal_time_get_hour (idt) == 0 &&
+                  i_cal_time_get_minute (idt) == 0 &&
+                  i_cal_time_get_second (idt) == 0);
 
   return idt;
 }
 
 /**
  * icaltime_to_datetime:
- * @date: an #icaltimetype
+ * @date: an #ICalTime
  *
- * Converts the #icaltimetype's @date to a #GDateTime. The
+ * Converts the #ICalTime's @date to a #GDateTime. The
  * timezone is preserved.
  *
  * Returns: (transfer full): a #GDateTime.
  */
 GDateTime*
-icaltime_to_datetime (const icaltimetype  *date)
+icaltime_to_datetime (const ICalTime *date)
 {
   GDateTime *dt;
   GTimeZone *tz;
+  ICalTimezone *zone;
 
-  tz = date->zone ? g_time_zone_new (icaltime_get_tzid (*date)) : g_time_zone_new_utc ();
+  zone = i_cal_time_get_timezone (date);
+  tz = (zone && i_cal_timezone_get_location (zone)) ? g_time_zone_new (i_cal_timezone_get_location (zone)) : 
g_time_zone_new_utc ();
   dt = g_date_time_new (tz,
-                        date->year,
-                        date->month,
-                        date->day,
-                        date->is_date ? 0 : date->hour,
-                        date->is_date ? 0 : date->minute,
-                        date->is_date ? 0 : date->second);
+                        i_cal_time_get_year (date),
+                        i_cal_time_get_month (date),
+                        i_cal_time_get_day (date),
+                        i_cal_time_is_date (date) ? 0 : i_cal_time_get_hour (date),
+                        i_cal_time_is_date (date) ? 0 : i_cal_time_get_minute (date),
+                        i_cal_time_is_date (date) ? 0 : i_cal_time_get_second (date));
 
   g_clear_pointer (&tz, g_time_zone_unref);
 
@@ -214,20 +217,6 @@ datetime_is_date (GDateTime *dt)
          g_date_time_get_seconds (dt) == 0;
 }
 
-/**
- * gcal_dup_icaltime:
- * @date: an #icaltimetype
- *
- * Creates an exact copy of @date.
- *
- * Returns: (transfer full): an #icaltimetype
- */
-icaltimetype*
-gcal_dup_icaltime (const icaltimetype *date)
-{
-  return g_memdup (date, sizeof (icaltimetype));
-}
-
 /**
  * gcal_get_weekday:
  * @i: the weekday index
@@ -358,7 +347,7 @@ get_desc_from_component (ECalComponent *component,
   GSList *l;
 
   gchar *desc = NULL;
-  e_cal_component_get_description_list (component, &text_list);
+  text_list = e_cal_component_get_descriptions (component);
 
   for (l = text_list; l != NULL; l = l->next)
     {
@@ -370,18 +359,18 @@ get_desc_from_component (ECalComponent *component,
 
           if (desc != NULL)
             {
-              carrier = g_strconcat (desc, joint_char, text->value, NULL);
+              carrier = g_strconcat (desc, joint_char, e_cal_component_text_get_value (text), NULL);
               g_free (desc);
               desc = carrier;
             }
           else
             {
-              desc = g_strdup (text->value);
+              desc = g_strdup (e_cal_component_text_get_value (text));
             }
         }
     }
 
-  e_cal_component_free_text_list (text_list);
+  g_slist_free_full (text_list, e_cal_component_text_free);
   return desc != NULL ? g_strstrip (desc) : NULL;
 }
 
@@ -404,20 +393,20 @@ get_uuid_from_component (ESource       *source,
   ECalComponentId *id;
 
   id = e_cal_component_get_id (component);
-  if (id->rid != NULL)
+  if (e_cal_component_id_get_rid (id) != NULL)
     {
       uuid = g_strdup_printf ("%s:%s:%s",
                               e_source_get_uid (source),
-                              id->uid,
-                              id->rid);
+                              e_cal_component_id_get_uid (id),
+                              e_cal_component_id_get_rid (id));
     }
   else
     {
       uuid = g_strdup_printf ("%s:%s",
                               e_source_get_uid (source),
-                              id->uid);
+                              e_cal_component_id_get_uid (id));
     }
-  e_cal_component_free_id (id);
+  e_cal_component_id_free (id);
 
   return uuid;
 }
@@ -497,9 +486,10 @@ build_component_from_details (const gchar *summary,
                               GDateTime   *final_date)
 {
   ECalComponent *event;
-  ECalComponentDateTime dt;
-  ECalComponentText summ;
-  icaltimezone *zone;
+  ECalComponentDateTime *dt;
+  ECalComponentText *summ;
+  ICalTimezone *zone;
+  ICalTime *itt;
   gboolean all_day;
 
   event = e_cal_component_new ();
@@ -517,42 +507,38 @@ build_component_from_details (const gchar *summary,
    */
   if (all_day)
     {
-      zone = icaltimezone_get_utc_timezone ();
+      zone = i_cal_timezone_get_utc_timezone ();
     }
   else
     {
-      gchar *system_tz = e_cal_system_timezone_get_location ();
-
-      zone = icaltimezone_get_builtin_timezone (system_tz);
-
-      g_free (system_tz);
+      zone = e_cal_util_get_system_timezone ();
     }
 
   /* Start date */
-  dt.value = datetime_to_icaltime (initial_date);
-  icaltime_set_timezone (dt.value, zone);
-  dt.value->is_date = all_day;
-  dt.tzid = icaltimezone_get_tzid (zone);
-  e_cal_component_set_dtstart (event, &dt);
+  itt = datetime_to_icaltime (initial_date);
+  i_cal_time_set_timezone (itt, zone);
+  i_cal_time_set_is_date (itt, all_day);
+  dt = e_cal_component_datetime_new_take (itt, zone ? g_strdup (i_cal_timezone_get_tzid (zone)) : NULL);
+  e_cal_component_set_dtstart (event, dt);
 
-  g_free (dt.value);
+  e_cal_component_datetime_free (dt);
 
   /* End date */
   if (!final_date)
     final_date = g_date_time_add_days (initial_date, 1);
 
-  dt.value = datetime_to_icaltime (final_date);
-  icaltime_set_timezone (dt.value, zone);
-  dt.value->is_date = all_day;
-  dt.tzid = icaltimezone_get_tzid (zone);
-  e_cal_component_set_dtend (event, &dt);
+  itt = datetime_to_icaltime (final_date);
+  i_cal_time_set_timezone (itt, zone);
+  i_cal_time_set_is_date (itt, all_day);
+  dt = e_cal_component_datetime_new_take (itt, zone ? g_strdup (i_cal_timezone_get_tzid (zone)) : NULL);
+  e_cal_component_set_dtend (event, dt);
 
-  g_free (dt.value);
+  e_cal_component_datetime_free (dt);
 
   /* Summary */
-  summ.altrep = NULL;
-  summ.value = summary;
-  e_cal_component_set_summary (event, &summ);
+  summ = e_cal_component_text_new (summary, NULL);
+  e_cal_component_set_summary (event, summ);
+  e_cal_component_text_free (summ);
 
   e_cal_component_commit_sequence (event);
 
@@ -561,11 +547,11 @@ build_component_from_details (const gchar *summary,
 
 /**
  * icaltime_compare_date:
- * @date1: an #icaltimetype
- * @date2: an #icaltimetype
+ * @date1: an #ICalTime
+ * @date2: an #ICalTime
  *
- * Compare date parts of #icaltimetype objects. Returns negative value,
- * 0 or positive value accordingly if @date1 is before, same day of
+ * Compare date parts of #ICalTime objects. Returns negative value,
+ * 0 or positive value accordingly if @date1 is before, same day or
  * after date2.
  *
  * As a bonus it returns the amount of days passed between two days on the
@@ -574,25 +560,25 @@ build_component_from_details (const gchar *summary,
  * Returns: negative, 0 or positive
  **/
 gint
-icaltime_compare_date (const icaltimetype *date1,
-                       const icaltimetype *date2)
+icaltime_compare_date (const ICalTime *date1,
+                       const ICalTime *date2)
 {
   if (date2 == NULL)
     return 0;
 
-  if (date1->year < date2->year)
+  if (i_cal_time_get_year (date1) < i_cal_time_get_year (date2))
     return -1;
-  else if (date1->year > date2->year)
+  else if (i_cal_time_get_year (date1) > i_cal_time_get_year (date2))
     return 1;
   else
-    return time_day_of_year (date1->day, date1->month - 1, date1->year) -
-           time_day_of_year (date2->day, date2->month - 1, date2->year);
+    return time_day_of_year (i_cal_time_get_day (date1), i_cal_time_get_month (date1) - 1, 
i_cal_time_get_year (date1)) -
+           time_day_of_year (i_cal_time_get_day (date2), i_cal_time_get_month (date2) - 1, 
i_cal_time_get_year (date2));
 }
 
 /**
  * icaltime_compare_with_current:
- * @date1: an #icaltimetype
- * @date2: an #icaltimetype
+ * @date1: an #ICalTime
+ * @date2: an #ICalTime
  * @current_time_t: the current time
  *
  * Compares @date1 and @date2 against the current time. Dates
@@ -602,15 +588,24 @@ icaltime_compare_date (const icaltimetype *date1,
  * equal, positive otherwise
  */
 gint
-icaltime_compare_with_current (const icaltimetype *date1,
-                               const icaltimetype *date2,
-                               time_t             *current_time_t)
+icaltime_compare_with_current (const ICalTime *date1,
+                               const ICalTime *date2,
+                               time_t         *current_time_t)
 {
+  ICalTimezone *zone1, *zone2;
   gint result = 0;
-
   time_t start1, start2, diff1, diff2;
-  start1 = icaltime_as_timet_with_zone (*date1, date1->zone != NULL ? date1->zone : 
e_cal_util_get_system_timezone ());
-  start2 = icaltime_as_timet_with_zone (*date2, date2->zone != NULL ? date2->zone : 
e_cal_util_get_system_timezone ());
+
+  zone1 = i_cal_time_get_timezone (date1);
+  if (!zone1)
+    zone1 = e_cal_util_get_system_timezone ();
+
+  zone2 = i_cal_time_get_timezone (date2);
+  if (!zone2)
+    zone2 = e_cal_util_get_system_timezone ();
+
+  start1 = i_cal_time_as_timet_with_zone (date1, zone1);
+  start2 = i_cal_time_as_timet_with_zone (date2, zone2);
   diff1 = start1 - *current_time_t;
   diff2 = start2 - *current_time_t;
 
@@ -636,7 +631,7 @@ icaltime_compare_with_current (const icaltimetype *date1,
 
 /**
  * get_start_of_week:
- * @date: an #icaltimetype
+ * @date: an #ICalTime
  *
  * Retrieves the start of the week that @date
  * falls in. This function already takes the
@@ -646,32 +641,29 @@ icaltime_compare_with_current (const icaltimetype *date1,
  * the start of the week.
  */
 GDateTime*
-get_start_of_week (icaltimetype *date)
+get_start_of_week (ICalTime *date)
 {
-  icaltimetype *new_date;
+  ICalTime *new_date;
   GDateTime *dt;
 
-  new_date = g_new0 (icaltimetype, 1);
-  *new_date = icaltime_from_day_of_year (icaltime_start_doy_week (*date, get_first_weekday () + 1),
-                                         date->year);
-  new_date->is_date = 0;
-  new_date->hour = 0;
-  new_date->minute = 0;
-  new_date->second = 0;
-
-  dt = g_date_time_new_local (new_date->year,
-                              new_date->month,
-                              new_date->day,
+  new_date = i_cal_time_from_day_of_year (i_cal_time_start_doy_week (date, get_first_weekday () + 1),
+                                          i_cal_time_get_year (date));
+  i_cal_time_set_is_date (new_date, FALSE);
+  i_cal_time_set_time (new_date, 0, 0, 0);
+
+  dt = g_date_time_new_local (i_cal_time_get_year (new_date),
+                              i_cal_time_get_month (new_date),
+                              i_cal_time_get_day (new_date),
                               0, 0, 0);
 
-  g_clear_pointer (&new_date, g_free);
+  g_clear_object (&new_date);
 
   return dt;
 }
 
 /**
  * get_end_of_week:
- * @date: an #icaltimetype
+ * @date: an #ICalTime
  *
  * Retrieves the end of the week that @date
  * falls in. This function already takes the
@@ -681,7 +673,7 @@ get_start_of_week (icaltimetype *date)
  * the end of the week.
  */
 GDateTime*
-get_end_of_week (icaltimetype *date)
+get_end_of_week (ICalTime *date)
 {
   GDateTime *week_start, *week_end;
 
@@ -989,26 +981,28 @@ gint
 get_alarm_trigger_minutes (GcalEvent          *event,
                            ECalComponentAlarm *alarm)
 {
-  ECalComponentAlarmTrigger trigger;
+  ECalComponentAlarmTrigger *trigger;
+  ICalDuration *duration;
   GDateTime *alarm_dt;
   gint diff;
 
-  e_cal_component_alarm_get_trigger (alarm, &trigger);
+  trigger = e_cal_component_alarm_get_trigger (alarm);
 
   /*
    * We only support alarms relative to the start date, and solely
    * ignore whetever different it may be.
    */
-  if (trigger.type != E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START)
+  if (!trigger || e_cal_component_alarm_trigger_get_kind (trigger) != 
E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START)
     return -1;
 
+  duration = e_cal_component_alarm_trigger_get_duration (trigger);
   alarm_dt = g_date_time_add_full (gcal_event_get_date_start (event),
                                    0,
                                    0,
-                                   - (trigger.u.rel_duration.days + trigger.u.rel_duration.weeks * 7),
-                                   - trigger.u.rel_duration.hours,
-                                   - trigger.u.rel_duration.minutes,
-                                   - trigger.u.rel_duration.seconds);
+                                   - (i_cal_duration_get_days (duration) + i_cal_duration_get_weeks 
(duration) * 7),
+                                   - i_cal_duration_get_hours (duration),
+                                   - i_cal_duration_get_minutes (duration),
+                                   - i_cal_duration_get_seconds (duration));
 
   diff = g_date_time_difference (gcal_event_get_date_start (event), alarm_dt) / G_TIME_SPAN_MINUTE;
 
@@ -1128,7 +1122,7 @@ ask_recurrence_modification_type (GtkWidget      *parent,
 
   client = g_object_get_data (G_OBJECT (source), "client");
 
-  if (!e_client_check_capability (E_CLIENT (client), CAL_STATIC_CAPABILITY_NO_THISANDFUTURE))
+  if (!e_client_check_capability (E_CLIENT (client), E_CAL_STATIC_CAPABILITY_NO_THISANDFUTURE))
     gtk_dialog_add_button (GTK_DIALOG (dialog), _("_Subsequent events"), GTK_RESPONSE_OK);
 
   gtk_dialog_add_button (GTK_DIALOG (dialog), _("_All events"), GTK_RESPONSE_YES);
@@ -1226,7 +1220,12 @@ is_workday (guint day)
 
   if (!locale)
     {
-      g_warning ("Locale is NULL, assuming Saturday and Sunday as non workdays");
+      static gboolean know_that = FALSE;
+      if (!know_that)
+        {
+          know_that = TRUE;
+          g_warning ("Locale is NULL, assuming Saturday and Sunday as non workdays");
+        }
       return !(no_work_days & 1 << day);
     }
 
@@ -1295,7 +1294,7 @@ filter_event_list_by_uid_and_modtype (GList                 *widgets,
       component = gcal_event_get_component (event);
       source = gcal_event_get_source (event);
       id = e_cal_component_get_id (component);
-      id_prefix = g_strdup_printf ("%s:%s", e_source_get_uid (source), id->uid);
+      id_prefix = g_strdup_printf ("%s:%s", e_source_get_uid (source), e_cal_component_id_get_uid (id));
 
       for (l = widgets; l != NULL; l = l->next)
         {
@@ -1328,7 +1327,7 @@ filter_event_list_by_uid_and_modtype (GList                 *widgets,
 
         }
 
-      e_cal_component_free_id (id);
+      e_cal_component_id_free (id);
     }
 
   return result;
diff --git a/src/gcal-utils.h b/src/gcal-utils.h
index bda43b95..1ddc8ab8 100644
--- a/src/gcal-utils.h
+++ b/src/gcal-utils.h
@@ -23,9 +23,6 @@
 #include <gtk/gtk.h>
 #include <libecal/libecal.h>
 #include <libgweather/gweather.h>
-#include <libical/icaltime.h>
-
-#define ICAL_TIME_TYPE (icaltime_get_type ())
 
 #define ALIGNED(x)      (round (x) + 0.5)
 #define MINUTES_PER_DAY 1440
@@ -41,18 +38,14 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC (ESource, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (ECalComponent, g_object_unref)
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (GWeatherLocation, gweather_location_unref)
 
-GType                icaltime_get_type                           (void)            G_GNUC_CONST;
-
 gint                 datetime_compare_date                       (GDateTime          *dt1,
                                                                   GDateTime          *dt2);
 
-icaltimetype*        datetime_to_icaltime                        (GDateTime          *dt);
+ICalTime*            datetime_to_icaltime                        (GDateTime          *dt);
 
 gboolean             datetime_is_date                            (GDateTime          *dt);
 
-GDateTime*           icaltime_to_datetime                        (const icaltimetype *date);
-
-icaltimetype*        gcal_dup_icaltime                           (const icaltimetype *date);
+GDateTime*           icaltime_to_datetime                        (const ICalTime     *date);
 
 gchar*               gcal_get_weekday                            (gint                i);
 
@@ -79,16 +72,16 @@ ECalComponent*       build_component_from_details                (const gchar
                                                                   GDateTime          *initial_date,
                                                                   GDateTime          *final_date);
 
-gint                 icaltime_compare_date                       (const icaltimetype *date1,
-                                                                  const icaltimetype *date2);
+gint                 icaltime_compare_date                       (const ICalTime     *date1,
+                                                                  const ICalTime     *date2);
 
-gint                 icaltime_compare_with_current               (const icaltimetype *date1,
-                                                                  const icaltimetype *date2,
+gint                 icaltime_compare_with_current               (const ICalTime     *date1,
+                                                                  const ICalTime     *date2,
                                                                   time_t             *current_time_t);
 
-GDateTime*           get_start_of_week                           (icaltimetype       *date);
+GDateTime*           get_start_of_week                           (ICalTime           *date);
 
-GDateTime*           get_end_of_week                             (icaltimetype       *date);
+GDateTime*           get_end_of_week                             (ICalTime           *date);
 
 gboolean             is_clock_format_24h                         (void);
 
diff --git a/src/gcal-window.c b/src/gcal-window.c
index 46ee5301..7d422bf5 100644
--- a/src/gcal-window.c
+++ b/src/gcal-window.c
@@ -37,7 +37,6 @@
 #include <glib/gi18n.h>
 #include <libgweather/gweather.h>
 #include <libecal/libecal.h>
-#include <libical/icaltime.h>
 
 /**
  * SECTION:gcal-window
@@ -138,7 +137,7 @@ struct _GcalWindow
 
   GcalManager        *manager;
   GcalWindowView      active_view;
-  icaltimetype       *active_date;
+  ICalTime           *active_date;
 
   gboolean            rtl;
 
@@ -255,27 +254,27 @@ update_today_button_sensitive (GcalWindow *window)
   switch (window->active_view)
     {
     case GCAL_WINDOW_VIEW_DAY:
-      sensitive = window->active_date->year != g_date_time_get_year (now) ||
-                  window->active_date->month != g_date_time_get_month (now) ||
-                  window->active_date->day != g_date_time_get_day_of_month (now);
+      sensitive = i_cal_time_get_year (window->active_date) != g_date_time_get_year (now) ||
+                  i_cal_time_get_month (window->active_date) != g_date_time_get_month (now) ||
+                  i_cal_time_get_day (window->active_date) != g_date_time_get_day_of_month (now);
       break;
 
     case GCAL_WINDOW_VIEW_WEEK:
-      sensitive = window->active_date->year != g_date_time_get_year (now) ||
-                  icaltime_week_number (*window->active_date) !=  g_date_time_get_week_of_year (now) - 1;
+      sensitive = i_cal_time_get_year (window->active_date) != g_date_time_get_year (now) ||
+                  i_cal_time_week_number (window->active_date) !=  g_date_time_get_week_of_year (now) - 1;
 
       GCAL_TRACE_MSG ("Week: active date's week is %d, current week is %d",
-                      icaltime_week_number (*window->active_date) + 1,
+                      i_cal_time_week_number (window->active_date) + 1,
                       g_date_time_get_week_of_year (now));
       break;
 
     case GCAL_WINDOW_VIEW_MONTH:
-      sensitive = window->active_date->year != g_date_time_get_year (now) ||
-                  window->active_date->month != g_date_time_get_month (now);
+      sensitive = i_cal_time_get_year (window->active_date) != g_date_time_get_year (now) ||
+                  i_cal_time_get_month (window->active_date) != g_date_time_get_month (now);
       break;
 
     case GCAL_WINDOW_VIEW_YEAR:
-      sensitive = window->active_date->year != g_date_time_get_year (now);
+      sensitive = i_cal_time_get_year (window->active_date) != g_date_time_get_year (now);
       break;
 
     case GCAL_WINDOW_VIEW_LIST:
@@ -291,29 +290,32 @@ update_today_button_sensitive (GcalWindow *window)
 }
 
 static void
-update_active_date (GcalWindow   *window,
-                    icaltimetype *new_date)
+update_active_date (GcalWindow *window,
+                    ICalTime   *new_date)
 {
   GDateTime *date_start, *date_end;
   time_t range_start, range_end;
-  icaltimetype *previous_date;
+  ICalTime *previous_date;
   GDate old_week, new_week;
+  gchar *tmp_str;
 
   GCAL_ENTRY;
 
   previous_date = window->active_date;
   window->active_date = new_date;
 
-  g_debug ("Updating active date to %s", icaltime_as_ical_string (*new_date));
+  tmp_str = i_cal_time_as_ical_string_r (new_date);
+  g_debug ("Updating active date to %s", tmp_str);
+  g_free (tmp_str);
 
   gcal_view_set_date (GCAL_VIEW (window->views[GCAL_WINDOW_VIEW_WEEK]), new_date);
   gcal_view_set_date (GCAL_VIEW (window->views[GCAL_WINDOW_VIEW_MONTH]), new_date);
   gcal_view_set_date (GCAL_VIEW (window->views[GCAL_WINDOW_VIEW_YEAR]), new_date);
 
   /* year_view */
-  if (previous_date->year != new_date->year)
+  if (i_cal_time_get_year (previous_date) != i_cal_time_get_year (new_date))
     {
-      date_start = g_date_time_new_local (new_date->year, 1, 1, 0, 0, 0);
+      date_start = g_date_time_new_local (i_cal_time_get_year (new_date), 1, 1, 0, 0, 0);
       range_start = g_date_time_to_unix (date_start);
 
       date_end = g_date_time_add_years (date_start, 1);
@@ -326,9 +328,9 @@ update_active_date (GcalWindow   *window,
     }
 
   /* month_view */
-  if (previous_date->month != new_date->month || previous_date->year != new_date->year)
+  if (i_cal_time_get_month (previous_date) != i_cal_time_get_month (new_date) || i_cal_time_get_year 
(previous_date) != i_cal_time_get_year (new_date))
     {
-      date_start = g_date_time_new_local (new_date->year, new_date->month, 1, 0, 0, 0);
+      date_start = g_date_time_new_local (i_cal_time_get_year (new_date), i_cal_time_get_month (new_date), 
1, 0, 0, 0);
       range_start = g_date_time_to_unix (date_start);
 
       date_end = g_date_time_add_months (date_start, 1);
@@ -343,13 +345,13 @@ update_active_date (GcalWindow   *window,
   /* week_view */
   g_date_clear (&old_week, 1);
 
-  if (previous_date->day > 0 && previous_date->month > 0 && previous_date->year)
-    g_date_set_dmy (&old_week, previous_date->day, previous_date->month, previous_date->year);
+  if (i_cal_time_get_day (previous_date) > 0 && i_cal_time_get_month (previous_date) > 0 && 
i_cal_time_get_year (previous_date))
+    g_date_set_dmy (&old_week, i_cal_time_get_day (previous_date), i_cal_time_get_month (previous_date), 
i_cal_time_get_year (previous_date));
 
   g_date_clear (&new_week, 1);
-  g_date_set_dmy (&new_week, new_date->day, new_date->month, new_date->year);
+  g_date_set_dmy (&new_week, i_cal_time_get_day (new_date), i_cal_time_get_month (new_date), 
i_cal_time_get_year (new_date));
 
-  if (previous_date->year != new_date->year ||
+  if (i_cal_time_get_year (previous_date) != i_cal_time_get_year (new_date) ||
       !g_date_valid (&old_week) ||
       g_date_get_iso8601_week_of_year (&old_week) != g_date_get_iso8601_week_of_year (&new_week))
     {
@@ -367,7 +369,7 @@ update_active_date (GcalWindow   *window,
 
   update_today_button_sensitive (window);
 
-  g_free (previous_date);
+  g_clear_object (&previous_date);
 
   GCAL_EXIT;
 }
@@ -376,7 +378,7 @@ static void
 date_updated (GcalWindow *window,
               GtkButton  *button)
 {
-  icaltimetype *new_date;
+  ICalTime *new_date;
   gboolean move_back, move_today;
   gint factor;
 
@@ -387,7 +389,7 @@ date_updated (GcalWindow *window,
   move_today = window->today_button == (GtkWidget*) button;
   move_back = window->back_button == (GtkWidget*) button;
 
-  new_date = gcal_dup_icaltime (window->active_date);
+  new_date = i_cal_time_new_clone (window->active_date);
 
   if (move_today)
     {
@@ -401,17 +403,17 @@ date_updated (GcalWindow *window,
       switch (window->active_view)
         {
         case GCAL_WINDOW_VIEW_DAY:
-          new_date->day += 1 * factor * (move_back ? -1 : 1);
+          i_cal_time_set_day (new_date, i_cal_time_get_day (new_date) + 1 * factor * (move_back ? -1 : 1));
           break;
         case GCAL_WINDOW_VIEW_WEEK:
-          new_date->day += 7 * factor * (move_back ? -1 : 1);
+          i_cal_time_set_day (new_date, i_cal_time_get_day (new_date) + 7 * factor * (move_back ? -1 : 1));
           break;
         case GCAL_WINDOW_VIEW_MONTH:
-          new_date->day = 1;
-          new_date->month += 1 * factor * (move_back ? -1 : 1);
+          i_cal_time_set_day (new_date, 1);
+          i_cal_time_set_month (new_date, i_cal_time_get_month (new_date) + 1 * factor * (move_back ? -1 : 
1));
           break;
         case GCAL_WINDOW_VIEW_YEAR:
-          new_date->year += 1 * factor * (move_back ? -1 : 1);
+          i_cal_time_set_year (new_date, i_cal_time_get_year (new_date) + 1 * factor * (move_back ? -1 : 1));
           break;
         case GCAL_WINDOW_VIEW_LIST:
         case GCAL_WINDOW_VIEW_SEARCH:
@@ -419,7 +421,7 @@ date_updated (GcalWindow *window,
           break;
         }
 
-      *new_date = icaltime_normalize (*new_date);
+      i_cal_time_normalize_inplace (new_date);
     }
 
   update_active_date (window, new_date);
@@ -494,7 +496,7 @@ key_pressed (GtkWidget *widget,
 
 static void
 search_event_selected (GcalSearchPopover *search_view,
-                       icaltimetype      *date,
+                       ICalTime          *date,
                        gpointer           user_data)
 {
   g_object_set (user_data, "active-date", date, NULL);
@@ -1214,13 +1216,14 @@ gcal_window_finalize (GObject *object)
 
   g_clear_object (&window->manager);
   g_clear_object (&window->views_switcher);
-
-  g_clear_pointer (&window->active_date, g_free);
-  G_OBJECT_CLASS (gcal_window_parent_class)->finalize (object);
+  g_clear_object (&window->active_date);
 
   gcal_weather_service_stop (window->weather_service);
   g_clear_object (&window->weather_service);
 
+  /* Call the GObjectClass::finalize as the last */
+  G_OBJECT_CLASS (gcal_window_parent_class)->finalize (object);
+
   GCAL_EXIT;
 }
 
@@ -1260,7 +1263,7 @@ gcal_window_set_property (GObject      *object,
       break;
 
     case PROP_ACTIVE_DATE:
-      update_active_date (GCAL_WINDOW (object), g_value_dup_boxed (value));
+      update_active_date (GCAL_WINDOW (object), g_value_dup_object (value));
       break;
 
     case PROP_NEW_EVENT_MODE:
@@ -1330,7 +1333,7 @@ gcal_window_get_property (GObject    *object,
   switch (property_id)
     {
     case PROP_ACTIVE_DATE:
-      g_value_set_boxed (value, self->active_date);
+      g_value_set_object (value, self->active_date);
       break;
 
     case PROP_ACTIVE_VIEW:
@@ -1407,11 +1410,11 @@ gcal_window_class_init (GcalWindowClass *klass)
   widget_class->configure_event = gcal_window_configure_event;
 
 
-  properties[PROP_ACTIVE_DATE] = g_param_spec_boxed ("active-date",
-                                                     "Date",
-                                                     "The active/selected date",
-                                                     ICAL_TIME_TYPE,
-                                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+  properties[PROP_ACTIVE_DATE] = g_param_spec_object ("active-date",
+                                                      "Date",
+                                                      "The active/selected date",
+                                                      I_CAL_TYPE_TIME,
+                                                      G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
 
   properties[PROP_ACTIVE_VIEW] = g_param_spec_enum ("active-view",
                                                     "Active View",
@@ -1540,13 +1543,17 @@ gcal_window_init (GcalWindow *self)
                               self,
                               NULL);
 
-  self->active_date = g_new0 (icaltimetype, 1);
+  self->active_date = i_cal_time_null_time ();
   self->rtl = gtk_widget_get_direction (GTK_WIDGET (self)) == GTK_TEXT_DIR_RTL;
 
   /*
    * FIXME: this is a hack around the issue that happens when trying to bind
-   * there properties using the GtkBuilder .ui file.
+   * these (GObject-type) properties using the GtkBuilder .ui file.
    */
+  g_object_bind_property (self, "active-date", self->search_popover, "active-date", G_BINDING_DEFAULT);
+  g_object_bind_property (self, "active-date", self->month_view, "active-date", G_BINDING_BIDIRECTIONAL);
+  g_object_bind_property (self, "active-date", self->week_view, "active-date", G_BINDING_BIDIRECTIONAL);
+  g_object_bind_property (self, "active-date", self->year_view, "active-date", G_BINDING_BIDIRECTIONAL);
   g_object_bind_property (self, "manager", self->weather_settings, "manager", G_BINDING_DEFAULT);
   g_object_bind_property (self, "manager", self->edit_dialog, "manager", G_BINDING_DEFAULT);
   g_object_bind_property (self, "manager", self->source_dialog, "manager", G_BINDING_DEFAULT);
@@ -1584,7 +1591,7 @@ gcal_window_init (GcalWindow *self)
  */
 GtkWidget*
 gcal_window_new_with_date (GcalApplication *app,
-                           icaltimetype    *date)
+                           ICalTime        *date)
 {
   return g_object_new (GCAL_TYPE_WINDOW,
                        "application", GTK_APPLICATION (app),
diff --git a/src/gcal-window.h b/src/gcal-window.h
index 8b7c55f9..234fca6f 100644
--- a/src/gcal-window.h
+++ b/src/gcal-window.h
@@ -33,7 +33,7 @@ G_BEGIN_DECLS
 G_DECLARE_FINAL_TYPE (GcalWindow, gcal_window, GCAL, WINDOW, GtkApplicationWindow)
 
 GtkWidget*           gcal_window_new_with_date                  (GcalApplication     *app,
-                                                                 icaltimetype        *date);
+                                                                 ICalTime            *date);
 
 void                 gcal_window_set_search_mode                (GcalWindow          *self,
                                                                  gboolean             enabled);
diff --git a/src/views/gcal-month-popover.c b/src/views/gcal-month-popover.c
index c21f17a4..a2262327 100644
--- a/src/views/gcal-month-popover.c
+++ b/src/views/gcal-month-popover.c
@@ -294,11 +294,11 @@ reposition_popover (GcalMonthPopover *self,
 static void
 update_event_list (GcalMonthPopover *self)
 {
-  g_autofree icaltimetype *start = NULL;
-  g_autofree icaltimetype *end = NULL;
   g_autoptr (GDateTime) start_dt = NULL;
   g_autoptr (GDateTime) end_dt = NULL;
   g_autoptr (GList) events = NULL;
+  ICalTime *start = NULL;
+  ICalTime *end = NULL;
   GList *l;
 
   gtk_container_foreach (GTK_CONTAINER (self->listbox), (GtkCallback) gtk_widget_destroy, NULL);
@@ -321,6 +321,9 @@ update_event_list (GcalMonthPopover *self)
 
   events = gcal_manager_get_events (self->manager, start, end);
 
+  g_clear_object (&start);
+  g_clear_object (&end);
+
   for (l = events; l; l = l->next)
     {
       g_autoptr (GDateTime) event_start = NULL;
diff --git a/src/views/gcal-month-view.c b/src/views/gcal-month-view.c
index 9f2c6201..3b0c6e34 100644
--- a/src/views/gcal-month-view.c
+++ b/src/views/gcal-month-view.c
@@ -118,7 +118,7 @@ struct _GcalMonthView
   guint               update_grid_id;
 
   /* property */
-  icaltimetype       *date;
+  ICalTime           *date;
   GcalManager        *manager;
 
   GcalWeatherService *weather_service;
@@ -310,8 +310,8 @@ calculate_event_cells (GcalMonthView *self,
       start_date = gcal_event_get_date_start (event);
       start_date = all_day ? g_date_time_ref (start_date) : g_date_time_to_local (start_date);
 
-      if (g_date_time_get_year (start_date) == self->date->year &&
-          g_date_time_get_month (start_date) == self->date->month)
+      if (g_date_time_get_year (start_date) == i_cal_time_get_year (self->date) &&
+          g_date_time_get_month (start_date) == i_cal_time_get_month (self->date))
         {
           first_cell = g_date_time_get_day_of_month (start_date);
         }
@@ -330,12 +330,12 @@ calculate_event_cells (GcalMonthView *self,
       g_autoptr (GDateTime) end_date = NULL;
       gint last_cell;
 
-      last_cell = icaltime_days_in_month (self->date->month, self->date->year);
+      last_cell = g_date_get_days_in_month (i_cal_time_get_month (self->date), i_cal_time_get_year 
(self->date));
       end_date = gcal_event_get_date_end (event);
       end_date = all_day ? g_date_time_ref (end_date) : g_date_time_to_local (end_date);
 
-      if (g_date_time_get_year (end_date) == self->date->year &&
-          g_date_time_get_month (end_date) == self->date->month)
+      if (g_date_time_get_year (end_date) == i_cal_time_get_year (self->date) &&
+          g_date_time_get_month (end_date) == i_cal_time_get_month (self->date))
         {
           last_cell = g_date_time_get_day_of_month (end_date);
 
@@ -688,8 +688,8 @@ allocate_multiday_events (GcalMonthView *self,
            * some checks and only applies the dates when it's valid.
            */
           dt_start = g_date_time_new (g_date_time_get_timezone (gcal_event_get_date_start (event)),
-                                      self->date->year,
-                                      self->date->month,
+                                      i_cal_time_get_year (self->date),
+                                      i_cal_time_get_month (self->date),
                                       day,
                                       0, 0, 0);
 
@@ -935,8 +935,8 @@ update_month_cells (GcalMonthView *self)
   gboolean show_last_row;
   guint row, col;
 
-  show_last_row = g_date_get_days_in_month (self->date->month, self->date->year) + self->days_delay > 35;
-  dt = g_date_time_new_local (self->date->year, self->date->month, 1, 0, 0, 0);
+  show_last_row = g_date_get_days_in_month (i_cal_time_get_month (self->date), i_cal_time_get_year 
(self->date)) + self->days_delay > 35;
+  dt = g_date_time_new_local (i_cal_time_get_year (self->date), i_cal_time_get_month (self->date), 1, 0, 0, 
0);
 
   for (row = 0; row < 6; row++)
     {
@@ -963,7 +963,7 @@ update_month_cells (GcalMonthView *self)
 
           /* Different month */
           different_month = day < self->days_delay ||
-                            day - self->days_delay >= icaltime_days_in_month (self->date->month, 
self->date->year);
+                            day - self->days_delay >= g_date_get_days_in_month (i_cal_time_get_month 
(self->date), i_cal_time_get_year (self->date));
 
           gcal_month_cell_set_different_month (cell, different_month);
 
@@ -1029,9 +1029,9 @@ update_header_labels (GcalMonthView *self)
 {
   gchar year_str[10] = { 0, };
 
-  g_snprintf (year_str, 10, "%d", self->date->year);
+  g_snprintf (year_str, 10, "%d", i_cal_time_get_year (self->date));
 
-  gtk_label_set_label (GTK_LABEL (self->month_label), gcal_get_month_name (self->date->month - 1));
+  gtk_label_set_label (GTK_LABEL (self->month_label), gcal_get_month_name (i_cal_time_get_month (self->date) 
- 1));
   gtk_label_set_label (GTK_LABEL (self->year_label), year_str);
 }
 
@@ -1068,7 +1068,7 @@ add_new_event_button_cb (GtkWidget *button,
   gcal_month_popover_popdown (self->overflow_popover);
 
   day = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (self->overflow_popover), "selected-day"));
-  start_date = g_date_time_new_local (self->date->year, self->date->month, day, 0, 0, 0);
+  start_date = g_date_time_new_local (i_cal_time_get_year (self->date), i_cal_time_get_month (self->date), 
day, 0, 0, 0);
 
   g_signal_emit_by_name (GCAL_VIEW (user_data), "create-event-detailed", start_date, NULL);
 
@@ -1127,7 +1127,7 @@ on_weather_service_weather_changed_cb (GcalWeatherService *weather_service,
  * GcalView interface
  */
 
-static icaltimetype*
+static ICalTime*
 gcal_month_view_get_date (GcalView *view)
 {
   GcalMonthView *self = GCAL_MONTH_VIEW (view);
@@ -1136,22 +1136,25 @@ gcal_month_view_get_date (GcalView *view)
 }
 
 static void
-gcal_month_view_set_date (GcalView     *view,
-                          icaltimetype *date)
+gcal_month_view_set_date (GcalView *view,
+                          ICalTime *date)
 {
   GcalMonthView *self;
+  gchar *icalstr;
 
   GCAL_ENTRY;
 
   self = GCAL_MONTH_VIEW (view);
 
-  g_clear_pointer (&self->date, g_free);
+  g_clear_object (&self->date);
 
-  self->date = gcal_dup_icaltime (date);
-  self->days_delay = (time_day_of_week (1, self->date->month - 1, self->date->year) - self->first_weekday + 
7) % 7;
-  self->keyboard_cell = self->days_delay + (self->date->day - 1);
+  self->date = i_cal_time_new_clone (date);
+  self->days_delay = (time_day_of_week (1, i_cal_time_get_month (self->date) - 1, i_cal_time_get_year 
(self->date)) - self->first_weekday + 7) % 7;
+  self->keyboard_cell = self->days_delay + (i_cal_time_get_day (self->date) - 1);
 
-  GCAL_TRACE_MSG ("new date: %s", icaltime_as_ical_string (*date));
+  icalstr = i_cal_time_as_ical_string_r (date);
+  GCAL_TRACE_MSG ("new date: %s", icalstr);
+  g_free (icalstr);
 
   update_header_labels (self);
   update_month_cells (self);
@@ -1780,7 +1783,7 @@ gcal_month_view_button_press (GtkWidget      *widget,
   GCAL_ENTRY;
 
   self = GCAL_MONTH_VIEW (widget);
-  days = self->days_delay + icaltime_days_in_month (self->date->month, self->date->year);
+  days = self->days_delay + g_date_get_days_in_month (i_cal_time_get_month (self->date), i_cal_time_get_year 
(self->date));
 
   /* The event may have come from a child widget, so make it relative to the month view */
   if (!gcal_translate_child_window_position (widget, event->window, event->x, event->y, &x, &y))
@@ -1793,7 +1796,7 @@ gcal_month_view_button_press (GtkWidget      *widget,
       g_clear_pointer (&self->start_mark_cell, g_date_time_unref);
 
       self->keyboard_cell = clicked_cell;
-      self->start_mark_cell = g_date_time_new_local (self->date->year, self->date->month,
+      self->start_mark_cell = g_date_time_new_local (i_cal_time_get_year (self->date), i_cal_time_get_month 
(self->date),
                                                      self->keyboard_cell - self->days_delay + 1,
                                                      0, 0, 0);
 
@@ -1815,7 +1818,7 @@ gcal_month_view_motion_notify_event (GtkWidget      *widget,
   GCAL_ENTRY;
 
   self = GCAL_MONTH_VIEW (widget);
-  days = self->days_delay + icaltime_days_in_month (self->date->month, self->date->year);
+  days = self->days_delay + g_date_get_days_in_month (i_cal_time_get_month (self->date), i_cal_time_get_year 
(self->date));
 
   if (!gcal_translate_child_window_position (widget, event->window, event->x, event->y, &x, &y))
     GCAL_RETURN (GDK_EVENT_PROPAGATE);
@@ -1834,8 +1837,8 @@ gcal_month_view_motion_notify_event (GtkWidget      *widget,
       self->keyboard_cell = new_end_cell;
 
       g_clear_pointer (&self->end_mark_cell, g_date_time_unref);
-      self->end_mark_cell = g_date_time_new_local (self->date->year,
-                                                   self->date->month,
+      self->end_mark_cell = g_date_time_new_local (i_cal_time_get_year (self->date),
+                                                   i_cal_time_get_month (self->date),
                                                    new_end_cell - self->days_delay + 1,
                                                    0, 0, 0);
 
@@ -1863,7 +1866,7 @@ gcal_month_view_button_release (GtkWidget      *widget,
   GCAL_ENTRY;
 
   self = GCAL_MONTH_VIEW (widget);
-  days = self->days_delay + icaltime_days_in_month (self->date->month, self->date->year);
+  days = self->days_delay + g_date_get_days_in_month (i_cal_time_get_month (self->date), i_cal_time_get_year 
(self->date));
 
   if (!gcal_translate_child_window_position (widget, event->window, event->x, event->y, &x, &y))
     GCAL_RETURN (GDK_EVENT_PROPAGATE);
@@ -1877,9 +1880,9 @@ gcal_month_view_button_release (GtkWidget      *widget,
       g_clear_pointer (&self->end_mark_cell, g_date_time_unref);
 
       self->keyboard_cell = current_day;
-      self->end_mark_cell = g_date_time_new_local (self->date->year, self->date->month, current_day - 
self->days_delay + 1, 0, 0, 0);
+      self->end_mark_cell = g_date_time_new_local (i_cal_time_get_year (self->date), i_cal_time_get_month 
(self->date), current_day - self->days_delay + 1, 0, 0, 0);
 
-      self->date->day = g_date_time_get_day_of_month (self->end_mark_cell);
+      i_cal_time_set_day (self->date, g_date_time_get_day_of_month (self->end_mark_cell));
 
       /* First, make sure to show the popover */
       valid = emit_create_event (self);
@@ -1935,7 +1938,7 @@ gcal_month_view_key_press (GtkWidget   *widget,
   month_change = 0;
   current_day = self->keyboard_cell - self->days_delay + 1;
   min = self->days_delay;
-  max = self->days_delay + icaltime_days_in_month (self->date->month, self->date->year) - 1;
+  max = self->days_delay + g_date_get_days_in_month (i_cal_time_get_month (self->date), i_cal_time_get_year 
(self->date)) - 1;
   is_ltr = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
 
   /*
@@ -1944,7 +1947,7 @@ gcal_month_view_key_press (GtkWidget   *widget,
    * focused cell.
    */
   if (selection && self->start_mark_cell == NULL)
-      self->start_mark_cell = g_date_time_new_local (self->date->year, self->date->month, current_day, 0, 0, 
0);
+      self->start_mark_cell = g_date_time_new_local (i_cal_time_get_year (self->date), i_cal_time_get_month 
(self->date), current_day, 0, 0, 0);
 
   switch (event->keyval)
     {
@@ -1974,7 +1977,7 @@ gcal_month_view_key_press (GtkWidget   *widget,
        * simulate it by changing the start & end selected cells = keyboard cell.
        */
       if (!selection && !self->start_mark_cell && !self->end_mark_cell)
-        self->start_mark_cell = self->end_mark_cell = g_date_time_new_local (self->date->year, 
self->date->month, current_day, 0, 0, 0);
+        self->start_mark_cell = self->end_mark_cell = g_date_time_new_local (i_cal_time_get_year 
(self->date), i_cal_time_get_month (self->date), current_day, 0, 0, 0);
 
       create_event = TRUE;
       break;
@@ -1994,10 +1997,10 @@ gcal_month_view_key_press (GtkWidget   *widget,
   else
     {
       month_change = self->keyboard_cell + diff > max ? 1 : -1;
-      self->date->month += month_change;
-      *self->date = icaltime_normalize (*self->date);
+      i_cal_time_set_month (self->date, i_cal_time_get_month (self->date) + month_change);
+      i_cal_time_normalize_inplace (self->date);
 
-      self->days_delay = (time_day_of_week (1, self->date->month - 1, self->date->year) - 
self->first_weekday + 7) % 7;
+      self->days_delay = (time_day_of_week (1, i_cal_time_get_month (self->date) - 1, i_cal_time_get_year 
(self->date)) - self->first_weekday + 7) % 7;
 
       /*
        * Set keyboard cell value to the sum or difference of days delay of successive
@@ -2009,7 +2012,7 @@ gcal_month_view_key_press (GtkWidget   *widget,
       if (month_change == 1)
         self->keyboard_cell = self->days_delay + self->keyboard_cell + diff - max - 1;
       else
-        self->keyboard_cell = self->days_delay + icaltime_days_in_month (self->date->month, 
self->date->year) - min + self->keyboard_cell + diff;
+        self->keyboard_cell = self->days_delay + g_date_get_days_in_month (i_cal_time_get_month 
(self->date), i_cal_time_get_year (self->date)) - min + self->keyboard_cell + diff;
     }
 
   /* Focus the selected month cell */
@@ -2019,7 +2022,7 @@ gcal_month_view_key_press (GtkWidget   *widget,
   gtk_widget_grab_focus (self->month_cell[row][col]);
 
   current_day = self->keyboard_cell - self->days_delay + 1;
-  self->date->day = current_day;
+  i_cal_time_set_day (self->date, current_day);
 
   /*
    * We can only emit the :create-event signal ~after~ grabbing the focus, otherwise
@@ -2032,7 +2035,7 @@ gcal_month_view_key_press (GtkWidget   *widget,
 
   if (selection)
     {
-      self->end_mark_cell = g_date_time_new_local (self->date->year, self->date->month, current_day, 0, 0, 
0);
+      self->end_mark_cell = g_date_time_new_local (i_cal_time_get_year (self->date), i_cal_time_get_month 
(self->date), current_day, 0, 0, 0);
     }
   else if (!selection && valid_key)
     {
@@ -2055,8 +2058,8 @@ gcal_month_view_scroll_event (GtkWidget      *widget,
    */
   if (should_change_date_for_scroll (&self->scroll_value, scroll_event))
     {
-      self->date->month += self->scroll_value > 0 ? 1 : -1;
-      *self->date = icaltime_normalize (*self->date);
+      i_cal_time_set_month (self->date, i_cal_time_get_month (self->date) + (self->scroll_value > 0 ? 1 : 
-1));
+      i_cal_time_normalize_inplace (self->date);
       self->scroll_value = 0;
 
       gtk_widget_queue_draw (widget);
@@ -2084,7 +2087,7 @@ gcal_month_view_set_property (GObject       *object,
   switch (property_id)
     {
     case PROP_DATE:
-      gcal_view_set_date (GCAL_VIEW (object), g_value_get_boxed (value));
+      gcal_view_set_date (GCAL_VIEW (object), g_value_get_object (value));
       break;
 
     case PROP_MANAGER:
@@ -2121,7 +2124,7 @@ gcal_month_view_get_property (GObject       *object,
   switch (property_id)
     {
     case PROP_DATE:
-      g_value_set_boxed (value, self->date);
+      g_value_set_object (value, self->date);
       break;
 
     case PROP_MANAGER:
@@ -2143,7 +2146,7 @@ gcal_month_view_finalize (GObject *object)
 {
   GcalMonthView *self = GCAL_MONTH_VIEW (object);
 
-  g_clear_pointer (&self->date, g_free);
+  g_clear_object (&self->date);
   g_clear_pointer (&self->children, g_hash_table_destroy);
   g_clear_pointer (&self->single_cell_children, g_hash_table_destroy);
   g_clear_pointer (&self->overflow_cells, g_hash_table_destroy);
diff --git a/src/views/gcal-view.c b/src/views/gcal-view.c
index 716fdb7b..6470c23c 100644
--- a/src/views/gcal-view.c
+++ b/src/views/gcal-view.c
@@ -37,11 +37,11 @@ gcal_view_default_init (GcalViewInterface *iface)
    * The active date of the view.
    */
   g_object_interface_install_property (iface,
-                                       g_param_spec_boxed ("active-date",
-                                                           "The active date",
-                                                           "The active/selecetd date in the view",
-                                                           ICAL_TIME_TYPE,
-                                                           G_PARAM_READWRITE));
+                                       g_param_spec_object ("active-date",
+                                                            "The active date",
+                                                            "The active/selecetd date in the view",
+                                                            I_CAL_TYPE_TIME,
+                                                            G_PARAM_READWRITE));
 
   /**
    * GcalView::manager:
@@ -114,13 +114,13 @@ gcal_view_default_init (GcalViewInterface *iface)
 /**
  * gcal_view_set_date:
  * @view: a #GcalView
- * @date: an #icaltimetype
+ * @date: an #ICalTime
  *
  * Sets the date of @view.
  */
 void
-gcal_view_set_date (GcalView     *view,
-                    icaltimetype *date)
+gcal_view_set_date (GcalView *view,
+                    ICalTime *date)
 {
   g_return_if_fail (GCAL_IS_VIEW (view));
   g_return_if_fail (GCAL_VIEW_GET_IFACE (view)->set_date);
@@ -231,9 +231,9 @@ gcal_view_set_weather_service_impl_helper (GcalWeatherService  **old_service,
  *
  * Retrieves the date of @view.
  *
- * Returns: (transfer none): an #icaltimetype.
+ * Returns: (transfer none): an #ICalTime.
  */
-icaltimetype*
+ICalTime*
 gcal_view_get_date (GcalView *view)
 {
   g_return_val_if_fail (GCAL_IS_VIEW (view), NULL);
diff --git a/src/views/gcal-view.h b/src/views/gcal-view.h
index 3b10d680..5a9428f1 100644
--- a/src/views/gcal-view.h
+++ b/src/views/gcal-view.h
@@ -36,19 +36,19 @@ struct _GcalViewInterface
 
   /* signals */
   void               (*create_event)                             (GcalView           *view,
-                                                                  icaltimetype       *start_span,
-                                                                  icaltimetype       *end_span,
+                                                                  ICalTime           *start_span,
+                                                                  ICalTime           *end_span,
                                                                   gdouble             x,
                                                                   gdouble             y);
 
   void               (*create_event_detailed)                    (GcalView           *view,
-                                                                  icaltimetype       *start_span,
-                                                                  icaltimetype       *end_span);
+                                                                  ICalTime           *start_span,
+                                                                  ICalTime           *end_span);
 
-  icaltimetype*      (*get_date)                                 (GcalView           *view);
+  ICalTime*          (*get_date)                                 (GcalView           *view);
 
   void               (*set_date)                                 (GcalView           *view,
-                                                                  icaltimetype       *date);
+                                                                  ICalTime           *date);
 
   /* Marks related API */
   void               (*clear_marks)                              (GcalView           *view);
@@ -59,9 +59,9 @@ struct _GcalViewInterface
 };
 
 void                 gcal_view_set_date                          (GcalView           *view,
-                                                                  icaltimetype       *date);
+                                                                  ICalTime           *date);
 
-icaltimetype*        gcal_view_get_date                          (GcalView           *view);
+ICalTime*            gcal_view_get_date                          (GcalView           *view);
 
 GcalManager*         gcal_view_get_manager                       (GcalView           *self);
 
diff --git a/src/views/gcal-week-grid.c b/src/views/gcal-week-grid.c
index 89252cf9..e0479f33 100644
--- a/src/views/gcal-week-grid.c
+++ b/src/views/gcal-week-grid.c
@@ -53,7 +53,7 @@ struct _GcalWeekGrid
   GtkWidget          *hours_sidebar;
   GdkWindow          *event_window;
 
-  icaltimetype       *active_date;
+  ICalTime           *active_date;
 
   GcalRangeTree      *events;
 
@@ -272,7 +272,7 @@ gcal_week_grid_finalize (GObject *object)
   GcalWeekGrid *self = GCAL_WEEK_GRID (object);
 
   g_clear_pointer (&self->events, gcal_range_tree_unref);
-  g_clear_pointer (&self->active_date, g_free);
+  g_clear_object (&self->active_date);
 
   G_OBJECT_CLASS (gcal_week_grid_parent_class)->finalize (object);
 }
@@ -1261,10 +1261,10 @@ gcal_week_grid_clear_marks (GcalWeekGrid *self)
 
 void
 gcal_week_grid_set_date (GcalWeekGrid *self,
-                         icaltimetype *date)
+                         ICalTime     *date)
 {
-  g_clear_pointer (&self->active_date, g_free);
-  self->active_date = gcal_dup_icaltime (date);
+  g_clear_object (&self->active_date);
+  self->active_date = i_cal_time_new_clone (date);
 
   gtk_widget_queue_resize (GTK_WIDGET (self));
   gtk_widget_queue_draw (GTK_WIDGET (self));
diff --git a/src/views/gcal-week-grid.h b/src/views/gcal-week-grid.h
index de0cee72..e75fafd5 100644
--- a/src/views/gcal-week-grid.h
+++ b/src/views/gcal-week-grid.h
@@ -49,7 +49,7 @@ GList*               gcal_week_grid_get_children_by_uuid         (GcalWeekGrid
 void                 gcal_week_grid_clear_marks                  (GcalWeekGrid       *self);
 
 void                 gcal_week_grid_set_date                     (GcalWeekGrid       *self,
-                                                                  icaltimetype       *date);
+                                                                  ICalTime           *date);
 
 G_END_DECLS
 
diff --git a/src/views/gcal-week-header.c b/src/views/gcal-week-header.c
index d9b3084a..6c3e2943 100644
--- a/src/views/gcal-week-header.c
+++ b/src/views/gcal-week-header.c
@@ -88,7 +88,7 @@ struct _GcalWeekHeader
    */
   gboolean            expanded;
 
-  icaltimetype       *active_date;
+  ICalTime           *active_date;
 
   gint                selection_start;
   gint                selection_end;
@@ -824,7 +824,7 @@ add_event_to_grid (GcalWeekHeader *self,
 
 static void
 update_unchanged_events (GcalWeekHeader *self,
-                         icaltimetype   *new_icaldt)
+                         ICalTime       *new_icaldt)
 {
   g_autoptr (GDateTime) new_week_start, new_week_end;
   g_autoptr (GDateTime) utc_week_start, utc_week_end;
@@ -1092,7 +1092,7 @@ gcal_week_header_finalize (GObject *object)
   GcalWeekHeader *self = GCAL_WEEK_HEADER (object);
   gint i;
 
-  g_clear_pointer (&self->active_date, g_free);
+  g_clear_object (&self->active_date);
 
   for (i = 0; i < 7; i++)
     g_list_free (self->events[i]);
@@ -1206,7 +1206,7 @@ gcal_week_header_draw (GtkWidget      *widget,
 
   week_start = get_start_of_week (self->active_date);
   week_end = g_date_time_add_days (week_start, 6);
-  current_cell = icaltime_day_of_week (*(self->active_date)) - 1;
+  current_cell = i_cal_time_day_of_week (self->active_date) - 1;
   current_cell = (7 + current_cell - self->first_weekday) % 7;
   today_column = get_today_column (self);
 
@@ -2011,22 +2011,22 @@ gcal_week_header_clear_marks (GcalWeekHeader *self)
 
 void
 gcal_week_header_set_date (GcalWeekHeader *self,
-                           icaltimetype   *date)
+                           ICalTime       *date)
 {
-  icaltimetype *old_date, *new_date;
+  ICalTime *old_date, *new_date;
 
   old_date = self->active_date;
-  new_date = gcal_dup_icaltime (date);
+  new_date = i_cal_time_new_clone (date);
 
   /*
    * If the active date changed, but we're still in the same week,
    * there's no need to recalculate visible events.
    */
   if (old_date && new_date &&
-      old_date->year == new_date->year &&
-      icaltime_week_number (*old_date) == icaltime_week_number (*new_date))
+      i_cal_time_get_year (old_date) == i_cal_time_get_year (new_date) &&
+      i_cal_time_week_number (old_date) == i_cal_time_week_number (new_date))
     {
-      g_free (new_date);
+      g_clear_object (&new_date);
       return;
     }
 
@@ -2040,7 +2040,7 @@ gcal_week_header_set_date (GcalWeekHeader *self,
 
   gcal_week_header_update_weather_infos (self);
 
-  g_clear_pointer (&old_date, g_free);
+  g_clear_object (&old_date);
 }
 
 /**
diff --git a/src/views/gcal-week-header.h b/src/views/gcal-week-header.h
index 5061738c..ae1366e5 100644
--- a/src/views/gcal-week-header.h
+++ b/src/views/gcal-week-header.h
@@ -50,7 +50,7 @@ GtkSizeGroup*        gcal_week_header_get_sidebar_size_group     (GcalWeekHeader
 void                 gcal_week_header_clear_marks                (GcalWeekHeader     *self);
 
 void                 gcal_week_header_set_date                   (GcalWeekHeader     *self,
-                                                                  icaltimetype       *date);
+                                                                  ICalTime           *date);
 
 void                 gcal_week_header_set_weather_service        (GcalWeekHeader     *self,
                                                                   GcalWeatherService *service);
diff --git a/src/views/gcal-week-view.c b/src/views/gcal-week-view.c
index 0bc06630..134a261e 100644
--- a/src/views/gcal-week-view.c
+++ b/src/views/gcal-week-view.c
@@ -52,7 +52,7 @@ struct _GcalWeekView
   GcalTimeFormat      time_format;
 
   /* property */
-  icaltimetype       *date;
+  ICalTime           *date;
   GcalManager        *manager;         /* owned */
   GcalWeatherService *weather_service; /* owned */
 
@@ -179,7 +179,7 @@ schedule_position_scroll (GcalWeekView *self)
 }
 
 /* GcalView implementation */
-static icaltimetype*
+static ICalTime*
 gcal_week_view_get_date (GcalView *view)
 {
   GcalWeekView *self = GCAL_WEEK_VIEW (view);
@@ -188,15 +188,15 @@ gcal_week_view_get_date (GcalView *view)
 }
 
 static void
-gcal_week_view_set_date (GcalView     *view,
-                         icaltimetype *date)
+gcal_week_view_set_date (GcalView *view,
+                         ICalTime *date)
 {
   GcalWeekView *self = GCAL_WEEK_VIEW (view);
 
   GCAL_ENTRY;
 
-  g_clear_pointer (&self->date, g_free);
-  self->date = gcal_dup_icaltime (date);
+  g_clear_object (&self->date);
+  self->date = i_cal_time_new_clone (date);
 
   /* Propagate the new date */
   gcal_week_grid_set_date (GCAL_WEEK_GRID (self->week_grid), date);
@@ -504,7 +504,7 @@ gcal_week_view_finalize (GObject       *object)
 
   self = GCAL_WEEK_VIEW (object);
 
-  g_clear_pointer (&self->date, g_free);
+  g_clear_object (&self->date);
 
   g_clear_object (&self->manager);
   g_clear_object (&self->weather_service);
@@ -524,7 +524,7 @@ gcal_week_view_set_property (GObject       *object,
   switch (property_id)
     {
     case PROP_DATE:
-      gcal_view_set_date (GCAL_VIEW (object), g_value_get_boxed (value));
+      gcal_view_set_date (GCAL_VIEW (object), g_value_get_object (value));
       break;
 
     case PROP_MANAGER:
@@ -565,7 +565,7 @@ gcal_week_view_get_property (GObject       *object,
   switch (property_id)
     {
     case PROP_DATE:
-      g_value_set_boxed (value, self->date);
+      g_value_set_object (value, self->date);
       break;
 
     case PROP_MANAGER:
diff --git a/src/views/gcal-year-view.c b/src/views/gcal-year-view.c
index 14f5b9de..abf9b397 100644
--- a/src/views/gcal-year-view.c
+++ b/src/views/gcal-year-view.c
@@ -70,8 +70,8 @@ struct _GcalYearView
   GcalWeatherService *weather_service; /* owned, nullable */
 
   /* range shown on the sidebar */
-  icaltimetype       *start_selected_date;
-  icaltimetype       *end_selected_date;
+  ICalTime           *start_selected_date;
+  ICalTime           *end_selected_date;
 
   /* geometry info */
   GridData           *navigator_grid;
@@ -107,7 +107,7 @@ struct _GcalYearView
   gint                k;
 
   /* date property */
-  icaltimetype       *date;
+  ICalTime           *date;
 
   /*
    * Array with the events at every month. Events
@@ -214,52 +214,52 @@ update_selected_dates_from_button_data (GcalYearView *year_view)
       ButtonData selected_data = *(year_view->selected_data);
       order_selected_data (&selected_data);
 
-      year_view->start_selected_date->day = selected_data.start_day;
-      year_view->start_selected_date->month = selected_data.start_month + 1;
-      year_view->start_selected_date->year = year_view->date->year;
-      year_view->end_selected_date->is_date = TRUE;
-
-      year_view->end_selected_date->day = selected_data.end_day;
-      year_view->end_selected_date->month = selected_data.end_month + 1;
-      year_view->end_selected_date->year = year_view->date->year;
-      year_view->end_selected_date->hour = 23;
-      year_view->end_selected_date->minute = 59;
-      year_view->end_selected_date->is_date = TRUE;
-      *(year_view->end_selected_date) = icaltime_normalize (*(year_view->end_selected_date));
+      i_cal_time_set_date (year_view->start_selected_date,
+                           i_cal_time_get_year (year_view->date),
+                           selected_data.start_month + 1,
+                           selected_data.start_day);
+      i_cal_time_set_is_date (year_view->end_selected_date, TRUE);
+
+      i_cal_time_set_date (year_view->end_selected_date,
+                           i_cal_time_get_year (year_view->date),
+                           selected_data.end_month + 1,
+                           selected_data.end_day);
+      i_cal_time_set_time (year_view->end_selected_date, 23, 59, 59);
+      i_cal_time_set_is_date (year_view->end_selected_date, TRUE);
+      i_cal_time_normalize_inplace (year_view->end_selected_date);
     }
   else
     {
-      g_autofree icaltimetype *current_date;
+      ICalTime *current_date;
       g_autoptr (GDateTime) now;
 
       now = g_date_time_new_now_local ();
       current_date = datetime_to_icaltime (now);
 
+      g_clear_object (&year_view->start_selected_date);
       if (year_view->date)
-        *(year_view->start_selected_date) = *year_view->date;
+        year_view->start_selected_date = i_cal_time_new_clone (year_view->date);
       else
-        *(year_view->start_selected_date) = *current_date;
+        year_view->start_selected_date = i_cal_time_new_clone (current_date);
 
-      year_view->start_selected_date->hour = 0;
-      year_view->start_selected_date->minute = 0;
-      year_view->start_selected_date->second = 0;
+      i_cal_time_set_time (year_view->start_selected_date, 0, 0, 0);
 
-      *(year_view->end_selected_date) = *(year_view->start_selected_date);
-      year_view->end_selected_date->hour = 23;
-      year_view->end_selected_date->minute = 59;
-      *(year_view->end_selected_date) = icaltime_normalize (*(year_view->end_selected_date));
+      g_clear_object (&year_view->end_selected_date);
+      year_view->end_selected_date = i_cal_time_new_clone (year_view->start_selected_date);
+      i_cal_time_set_time (year_view->end_selected_date, 23, 59, 59);
+      i_cal_time_normalize_inplace (year_view->end_selected_date);
 
-      year_view->selected_data->start_day = year_view->start_selected_date->day;
-      year_view->selected_data->start_month = year_view->start_selected_date->month - 1;
-      year_view->selected_data->end_day = year_view->end_selected_date->day;
-      year_view->selected_data->end_month = year_view->end_selected_date->month -1;
+      year_view->selected_data->start_day = i_cal_time_get_day (year_view->start_selected_date);
+      year_view->selected_data->start_month = i_cal_time_get_month (year_view->start_selected_date) - 1;
+      year_view->selected_data->end_day = i_cal_time_get_day (year_view->end_selected_date);
+      year_view->selected_data->end_month = i_cal_time_get_month (year_view->end_selected_date) -1;
+
+      g_clear_object (&current_date);
     }
 
-  if (year_view->end_selected_date->year != year_view->start_selected_date->year)
+  if (i_cal_time_get_year (year_view->end_selected_date) != i_cal_time_get_year 
(year_view->start_selected_date))
     {
-      year_view->end_selected_date->day = 31;
-      year_view->end_selected_date->month = 12;
-      year_view->end_selected_date->year = year_view->start_selected_date->year;
+      i_cal_time_set_date (year_view->end_selected_date, 31, 12, i_cal_time_get_year 
(year_view->start_selected_date));
     }
 }
 
@@ -273,8 +273,8 @@ update_no_events_page (GcalYearView *year_view)
   now = g_date_time_new_now_local ();
   start_selected_date = icaltime_to_datetime (year_view->start_selected_date);
 
-  has_range = (year_view->start_selected_date->day != year_view->end_selected_date->day ||
-               year_view->start_selected_date->month != year_view->end_selected_date->month);
+  has_range = (i_cal_time_get_day (year_view->start_selected_date) != i_cal_time_get_day 
(year_view->end_selected_date) ||
+               i_cal_time_get_month (year_view->start_selected_date) != i_cal_time_get_month 
(year_view->end_selected_date));
 
   if (datetime_compare_date (now, start_selected_date) == 0)
     {
@@ -418,7 +418,7 @@ update_sidebar (GcalYearView *year_view)
 
   gtk_container_foreach (GTK_CONTAINER (year_view->events_sidebar), (GtkCallback) gtk_widget_destroy, NULL);
 
-  days_span = icaltime_day_of_year(*(year_view->end_selected_date)) - 
icaltime_day_of_year(*(year_view->start_selected_date)) + 1;
+  days_span = i_cal_time_day_of_year(year_view->end_selected_date) - 
i_cal_time_day_of_year(year_view->start_selected_date) + 1;
   days_widgets_array = g_new0 (GList*, days_span);
 
   events = gcal_manager_get_events (year_view->manager, year_view->start_selected_date, 
year_view->end_selected_date);
@@ -475,7 +475,6 @@ update_sidebar_headers (GtkListBoxRow *row,
   GtkWidget *row_child, *before_child = NULL, *row_header = NULL;
   GcalEvent *row_event, *before_event;
   GDateTime *row_date, *before_date = NULL;
-  icaltimetype date;
   gint row_shift, before_shift =-1;
 
   year_view = GCAL_YEAR_VIEW (user_data);
@@ -503,14 +502,16 @@ update_sidebar_headers (GtkListBoxRow *row,
       g_autoptr (GDateTime) now, dt;
       GtkWidget *label;
       gchar *label_str;
+      ICalTime *date;
 
       row_header = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
       now = g_date_time_new_now_local ();
 
-      date = *(year_view->start_selected_date);
-      icaltime_adjust (&date, row_shift, 0, 0, 0);
+      date = i_cal_time_new_clone (year_view->start_selected_date);
+      i_cal_time_adjust (date, row_shift, 0, 0, 0);
 
-      dt = icaltime_to_datetime (&date);
+      dt = icaltime_to_datetime (date);
+      g_clear_object (&date);
 
       if (datetime_compare_date (dt, now) == 0)
         label_str = g_strdup (_("Today"));
@@ -536,19 +537,19 @@ update_sidebar_headers (GtkListBoxRow *row,
 
 static void
 update_date (GcalYearView *year_view,
-             icaltimetype *new_date)
+             ICalTime *new_date)
 {
   gboolean needs_reset = FALSE;
-  if (year_view->date != NULL && icaltime_compare_date (year_view->date, new_date) && 
year_view->start_selected_date->day != 0)
+  if (year_view->date != NULL && icaltime_compare_date (year_view->date, new_date) && i_cal_time_get_day 
(year_view->start_selected_date) != 0)
     needs_reset = TRUE;
 
-  g_clear_pointer (&year_view->date, g_free);
-  year_view->date = gcal_dup_icaltime (new_date);
+  g_clear_object (&year_view->date);
+  year_view->date = i_cal_time_new_clone (new_date);
 
   year_view->first_week_of_year = get_last_week_of_year_dmy (year_view->first_weekday,
-                                                             1, G_DATE_JANUARY,  year_view->date->year);;
+                                                             1, G_DATE_JANUARY,  i_cal_time_get_year 
(year_view->date));
   year_view->last_week_of_year = get_last_week_of_year_dmy (year_view->first_weekday,
-                                                            31, G_DATE_DECEMBER, year_view->date->year);
+                                                            31, G_DATE_DECEMBER, i_cal_time_get_year 
(year_view->date));
 
   if (needs_reset)
     reset_sidebar (year_view);
@@ -577,7 +578,7 @@ calculate_coord_for_date (GcalYearView *year_view,
 
   /* else */
   sw = 1 - 2 * year_view->k;
-  clicked_cell = day + ((time_day_of_week (1, month, year_view->date->year) - year_view->first_weekday + 7) 
% 7) - 1;
+  clicked_cell = day + ((time_day_of_week (1, month, i_cal_time_get_year (year_view->date)) - 
year_view->first_weekday + 7) % 7) - 1;
 
   cell_x = (clicked_cell % 7 + year_view->k + year_view->show_week_numbers) * 
year_view->navigator_grid->box_side * sw;
   cell_x += (year_view->k * year_view->navigator_grid->box_side * (7 + year_view->show_week_numbers));
@@ -667,9 +668,9 @@ calculate_day_month_for_coord (GcalYearView *year_view,
   column = (x - (year_view->navigator_grid->coordinates[month].x + box_side * year_view->show_week_numbers * 
(1 - year_view->k))) / box_side;
   clicked_cell = row * 7 + column;
   day = 7 * ((clicked_cell + 7 * year_view->k) / 7) + sw * (clicked_cell % 7) + (1 - year_view->k);
-  day -= ((time_day_of_week (1, month, year_view->date->year) - year_view->first_weekday + 7) % 7);
+  day -= ((time_day_of_week (1, month, i_cal_time_get_year (year_view->date)) - year_view->first_weekday + 
7) % 7);
 
-  if (day < 1 || day > time_days_in_month (year_view->date->year, month))
+  if (day < 1 || day > time_days_in_month (i_cal_time_get_year (year_view->date), month))
     return FALSE;
 
   *out_day = day;
@@ -677,13 +678,13 @@ calculate_day_month_for_coord (GcalYearView *year_view,
 }
 static guint
 count_events_at_day (GcalYearView *self,
-                     icaltimetype *today)
+                     ICalTime     *today)
 {
   g_autoptr (GDateTime) today_start, today_end;
   GPtrArray *events;
   guint i, n_events;
 
-  events = self->events[today->month - 1];
+  events = self->events[i_cal_time_get_month (today) - 1];
   n_events = 0;
   today_start = icaltime_to_datetime (today);
   today_end = g_date_time_add_days (today_start, 1);
@@ -738,7 +739,7 @@ draw_month_grid (GcalYearView *year_view,
   gint days_delay, days, shown_rows;
   gchar *str, *nr_day, *nr_week;
   gboolean selected_day;
-  icaltimetype today;
+  ICalTime *today;
 
   now = g_date_time_new_now_local ();
 
@@ -801,18 +802,14 @@ draw_month_grid (GcalYearView *year_view,
   gtk_style_context_get (context, state_flags, "font", &font_desc, NULL);
   pango_layout_set_font_description (layout, font_desc);
 
-  days_delay = (time_day_of_week (1, month_nr, year_view->date->year) - year_view->first_weekday + 7) % 7;
-  days = days_delay + icaltime_days_in_month (month_nr + 1, year_view->date->year);
+  days_delay = (time_day_of_week (1, month_nr, i_cal_time_get_year (year_view->date)) - 
year_view->first_weekday + 7) % 7;
+  days = days_delay + icaltime_days_in_month (month_nr + 1, i_cal_time_get_year (year_view->date));
   shown_rows = ceil (days / 7.0);
 
-  today = icaltime_today ();
-  today.year = year_view->date->year;
-  today.month = month_nr + 1;
-  today.day = 1;
-  today.hour = 0;
-  today.minute = 0;
-  today.second = 0;
-  today.zone = gcal_manager_get_system_timezone (year_view->manager);
+  today = i_cal_time_today ();
+  i_cal_time_set_date (today, i_cal_time_get_year (year_view->date), month_nr + 1, 1);
+  i_cal_time_set_time (today, 0, 0, 0);
+  i_cal_time_set_timezone (today, gcal_manager_get_system_timezone (year_view->manager));
 
   for (i = 0; i < 7 * shown_rows; i++)
     {
@@ -899,7 +896,7 @@ draw_month_grid (GcalYearView *year_view,
             }
         }
 
-      if (year_view->date->year == g_date_time_get_year (now) &&
+      if (i_cal_time_get_year (year_view->date) == g_date_time_get_year (now) &&
           month_nr + 1 == g_date_time_get_month (now) &&
           j == g_date_time_get_day_of_month (now))
         {
@@ -965,9 +962,9 @@ draw_month_grid (GcalYearView *year_view,
         }
 
       /* Update the current day, so we can count the events at this day */
-      today.day = j;
+      i_cal_time_set_day (today, j);
 
-      if (count_events_at_day (year_view, &today) > 0)
+      if (count_events_at_day (year_view, today) > 0)
         {
           gtk_style_context_save (context);
           gtk_style_context_add_class (context, "with-events");
@@ -989,6 +986,7 @@ draw_month_grid (GcalYearView *year_view,
     }
   pango_font_description_free (font_desc);
   gtk_style_context_restore (context);
+  g_clear_object (&today);
 
   /* week numbers */
   gtk_style_context_save (context);
@@ -1073,7 +1071,7 @@ draw_navigator (GcalYearView *year_view,
   gtk_style_context_save (context);
   gtk_style_context_add_class (context, "primary-label");
 
-  header_str = g_strdup_printf ("%d", year_view->date->year);
+  header_str = g_strdup_printf ("%d", i_cal_time_get_year (year_view->date));
   gtk_style_context_get (context, state_flags, "font", &font_desc, NULL);
   gtk_style_context_get_padding (context, state_flags, &padding);
 
@@ -1152,15 +1150,15 @@ navigator_button_release_cb (GcalYearView   *year_view,
     goto fail;
 
   if (is_title)
-    day = g_date_get_days_in_month (month + 1, year_view->date->year);
+    day = g_date_get_days_in_month (month + 1, i_cal_time_get_year (year_view->date));
 
   year_view->button_pressed = FALSE;
   year_view->selected_data->end_day = day;
   year_view->selected_data->end_month = month;
 
   /* update date and notify */
-  year_view->date->day = day;
-  year_view->date->month = month + 1;
+  i_cal_time_set_day (year_view->date, day);
+  i_cal_time_set_month (year_view->date, month + 1);
   g_object_notify (G_OBJECT (year_view), "active-date");
 
   gtk_widget_queue_draw (widget);
@@ -1208,7 +1206,7 @@ navigator_motion_notify_cb (GcalYearView   *year_view,
       if (year_view->button_pressed)
         {
           if (is_title)
-            day = g_date_get_days_in_month (month + 1, year_view->date->year);
+            day = g_date_get_days_in_month (month + 1, i_cal_time_get_year (year_view->date));
 
           year_view->selected_data->end_day = day;
           year_view->selected_data->end_month = month;
@@ -1244,8 +1242,8 @@ navigator_edge_overshot_cb (GcalYearView    *self,
 
   adjustment = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW (self->scrolled_window));
 
-  self->date->year += position_type == GTK_POS_BOTTOM ? 1 : -1;
-  *self->date = icaltime_normalize (*self->date);
+  i_cal_time_set_year (self->date, i_cal_time_get_year (self->date) + (position_type == GTK_POS_BOTTOM ? 1 : 
-1));
+  i_cal_time_normalize_inplace (self->date);
 
   gtk_adjustment_set_value (adjustment, 0.0);
   gtk_widget_queue_draw (self->navigator);
@@ -1274,8 +1272,8 @@ navigator_scroll_event_cb (GcalYearView   *self,
    */
   if (should_change_date_for_scroll (&self->scroll_value, scroll_event))
     {
-      self->date->year += self->scroll_value > 0 ? 1 : -1;
-      *self->date = icaltime_normalize (*self->date);
+      i_cal_time_set_year (self->date, i_cal_time_get_year (self->date) + (self->scroll_value > 0 ? 1 : -1));
+      i_cal_time_normalize_inplace (self->date);
       self->scroll_value = 0;
 
       gtk_widget_queue_draw (self->navigator);
@@ -1292,20 +1290,20 @@ add_event_clicked_cb (GcalYearView *year_view,
 {
   GDateTime *start_date, *end_date = NULL;
 
-  if (year_view->start_selected_date->day == 0)
+  if (i_cal_time_get_day (year_view->start_selected_date) == 0)
     {
       start_date = g_date_time_new_now_local ();
     }
   else
     {
-      icaltimetype *dtstart, *dtend;
+      ICalTime *dtstart, *dtend;
       GDateTime *tmp_date;
 
       dtstart = year_view->start_selected_date;
       dtend = year_view->end_selected_date;
 
-      start_date = g_date_time_new_local (dtstart->year, dtstart->month, dtstart->day, 0, 0, 0);
-      tmp_date = g_date_time_new_local (dtend->year, dtend->month, dtend->day, 0, 0, 0);
+      start_date = g_date_time_new_local (i_cal_time_get_year (dtstart), i_cal_time_get_month (dtstart), 
i_cal_time_get_day (dtstart), 0, 0, 0);
+      tmp_date = g_date_time_new_local (i_cal_time_get_year (dtend), i_cal_time_get_month (dtend), 
i_cal_time_get_day (dtend), 0, 0, 0);
       end_date = g_date_time_add_days (tmp_date, 1);
 
       g_clear_pointer (&tmp_date, g_date_time_unref);
@@ -1489,7 +1487,7 @@ navigator_drag_drop_cb (GcalYearView   *self,
           end_dt = gcal_event_get_date_end (event);
 
           drop_date = g_date_time_add_full (start_dt,
-                                            self->date->year - g_date_time_get_year (start_dt),
+                                            i_cal_time_get_year (self->date) - g_date_time_get_year 
(start_dt),
                                             (month + 1) - g_date_time_get_month (start_dt),
                                             day - g_date_time_get_day_of_month (start_dt),
                                             0, 0, 0);
@@ -1548,7 +1546,7 @@ navigator_drag_leave_cb (GcalYearView   *self,
 }
 
 /* GcalView implementation */
-static icaltimetype*
+static ICalTime*
 gcal_year_view_get_date (GcalView *view)
 {
   GcalYearView *self = GCAL_YEAR_VIEW (view);
@@ -1557,8 +1555,8 @@ gcal_year_view_get_date (GcalView *view)
 }
 
 static void
-gcal_year_view_set_date (GcalView     *view,
-                         icaltimetype *date)
+gcal_year_view_set_date (GcalView *view,
+                         ICalTime *date)
 {
   GCAL_ENTRY;
 
@@ -1603,10 +1601,9 @@ gcal_year_view_finalize (GObject *object)
   g_free (year_view->navigator_grid);
   g_free (year_view->selected_data);
 
-  g_free (year_view->start_selected_date);
-  g_free (year_view->end_selected_date);
-
-  g_clear_pointer (&year_view->date, g_free);
+  g_clear_object (&year_view->start_selected_date);
+  g_clear_object (&year_view->end_selected_date);
+  g_clear_object (&year_view->date);
 
   g_clear_object (&year_view->calendar_settings);
   g_clear_object (&year_view->weather_service);
@@ -1628,7 +1625,7 @@ gcal_year_view_get_property (GObject    *object,
   switch (prop_id)
     {
     case PROP_DATE:
-      g_value_set_boxed (value, self->date);
+      g_value_set_object (value, self->date);
       break;
 
     case PROP_MANAGER:
@@ -1659,7 +1656,7 @@ gcal_year_view_set_property (GObject      *object,
   switch (prop_id)
     {
     case PROP_DATE:
-      gcal_view_set_date (GCAL_VIEW (self), g_value_get_boxed (value));
+      gcal_view_set_date (GCAL_VIEW (self), g_value_get_object (value));
       break;
 
     case PROP_MANAGER:
@@ -1824,10 +1821,10 @@ gcal_year_view_component_added (ECalDataModelSubscriber *subscriber,
   start_month = g_date_time_get_month (event_start) - 1;
   end_month = g_date_time_get_month (event_end) - 1;
 
-  if (g_date_time_get_year (event_start) < self->date->year)
+  if (g_date_time_get_year (event_start) < i_cal_time_get_year (self->date))
     start_month = 0;
 
-  if (g_date_time_get_year (event_end) > self->date->year)
+  if (g_date_time_get_year (event_end) > i_cal_time_get_year (self->date))
     end_month = 11;
 
   /* Add the event to the cache */
@@ -1931,10 +1928,10 @@ gcal_year_view_component_changed (ECalDataModelSubscriber *subscriber,
 
   id = e_cal_component_get_id (comp);
 
-  gcal_year_view_component_removed (subscriber, client, id->uid, id->rid);
+  gcal_year_view_component_removed (subscriber, client, e_cal_component_id_get_uid (id), 
e_cal_component_id_get_rid (id));
   gcal_year_view_component_added (subscriber, client, comp);
 
-  g_clear_pointer (&id, e_cal_component_free_id);
+  g_clear_pointer (&id, e_cal_component_id_free);
 
   GCAL_EXIT;
 }
@@ -1956,6 +1953,8 @@ gcal_year_view_class_init (GcalYearViewClass *klass)
   GObjectClass *object_class = G_OBJECT_CLASS (klass);
   GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
+  g_type_ensure (I_CAL_TYPE_TIME);
+
   object_class->finalize = gcal_year_view_finalize;
   object_class->get_property = gcal_year_view_get_property;
   object_class->set_property = gcal_year_view_set_property;
@@ -2027,10 +2026,10 @@ gcal_year_view_init (GcalYearView *self)
   self->navigator_grid = g_new0 (GridData, 1);
   self->selected_data = g_new0 (ButtonData, 1);
 
-  self->start_selected_date = g_new0 (icaltimetype, 1);
-  self->start_selected_date->zone = e_cal_util_get_system_timezone ();
-  self->end_selected_date = g_new0 (icaltimetype, 1);
-  self->end_selected_date->zone = e_cal_util_get_system_timezone ();
+  self->start_selected_date = i_cal_time_null_time ();
+  i_cal_time_set_timezone (self->start_selected_date, e_cal_util_get_system_timezone ());
+  self->end_selected_date = i_cal_time_null_time ();
+  i_cal_time_set_timezone (self->end_selected_date, e_cal_util_get_system_timezone ());
 
   /* bind GNOME Shell' show week numbers property to GNOME Calendar's one */
   self->calendar_settings = g_settings_new ("org.gnome.desktop.calendar");
@@ -2086,7 +2085,7 @@ update_weather (GcalYearView *self)
       GDate date;
       guint i;
 
-      g_date_set_dmy (&date, self->date->day, self->date->month, self->date->year);
+      g_date_set_dmy (&date, i_cal_time_get_day (self->date), i_cal_time_get_month (self->date), 
i_cal_time_get_year (self->date));
 
       weather_infos = gcal_weather_service_get_weather_infos (self->weather_service);
 
diff --git a/src/views/gcal-year-view.h b/src/views/gcal-year-view.h
index 6e29d9b5..27de9d2c 100644
--- a/src/views/gcal-year-view.h
+++ b/src/views/gcal-year-view.h
@@ -31,8 +31,8 @@ G_BEGIN_DECLS
 
 G_DECLARE_FINAL_TYPE (GcalYearView, gcal_year_view, GCAL, YEAR_VIEW, GtkBox)
 
-void                 gcal_year_view_set_current_date             (GcalYearView       *year_view,
-                                                                  icaltimetype       *current_date);
+void                 gcal_year_view_set_current_date             (GcalYearView *year_view,
+                                                                  ICalTime     *current_date);
 
 G_END_DECLS
 


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