[evolution-data-server/wip/mcrha/libical-glib] Changes around e-cal-recur.c/.h



commit c0106d47b590a984cd8168dd956f65ba920ec318
Author: Milan Crha <mcrha redhat com>
Date:   Thu Feb 7 11:54:35 2019 +0100

    Changes around e-cal-recur.c/.h

 .../libecal/e-cal-component-alarm-trigger.c        |   3 +-
 src/calendar/libecal/e-cal-enums.h                 |  19 +
 src/calendar/libecal/e-cal-recur.c                 | 762 +++++++++++----------
 src/calendar/libecal/e-cal-recur.h                 | 126 ++--
 src/calendar/libecal/e-cal-util.c                  |   8 +-
 5 files changed, 493 insertions(+), 425 deletions(-)
---
diff --git a/src/calendar/libecal/e-cal-component-alarm-trigger.c 
b/src/calendar/libecal/e-cal-component-alarm-trigger.c
index 0864e2594..3ff4d3c3b 100644
--- a/src/calendar/libecal/e-cal-component-alarm-trigger.c
+++ b/src/calendar/libecal/e-cal-component-alarm-trigger.c
@@ -305,7 +305,7 @@ e_cal_component_alarm_trigger_fill_property (const ECalComponentAlarmTrigger *tr
                                             ICalProperty *property)
 {
        ICalParameter *param;
-       ICalParameterValue value_type;
+       ICalParameterValue value_type = I_CAL_VALUE_DATETIME;
        ICalParameterRelated related;
        ICalTriggerType *trgtype;
 
@@ -333,6 +333,7 @@ e_cal_component_alarm_trigger_fill_property (const ECalComponentAlarmTrigger *tr
                i_cal_trigger_type_set_time (trgtype, trigger->abs_time);
                value_type = I_CAL_VALUE_DATETIME;
                break;
+
        case E_CAL_COMPONENT_ALARM_TRIGGER_NONE:
                g_object_unref (trgtype);
                return;
diff --git a/src/calendar/libecal/e-cal-enums.h b/src/calendar/libecal/e-cal-enums.h
index afa350142..d1ea0226d 100644
--- a/src/calendar/libecal/e-cal-enums.h
+++ b/src/calendar/libecal/e-cal-enums.h
@@ -183,6 +183,25 @@ typedef enum {
        E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE
 } ECalComponentAlarmTriggerKind;
 
+/**
+ * ECalRecurDescribeRecurrenceFlags:
+ * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_NONE: no extra flags, either returns %NULL or the recurrence 
description,
+ *    something like "Every 2 weeks..."
+ * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED: either returns %NULL or the recurrence description 
prefixed
+ *    with text like "The meeting recurs", forming something like "The meeting recurs every 2 weeks..."
+ * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK: returns %NULL only if the component doesn't recur,
+ *    otherwise returns either the recurrence description or at least text like "The meeting recurs"
+ *
+ * Influences behaviour of e_cal_recur_describe_recurrence().
+ *
+ * Since: 3.30
+ **/
+typedef enum {
+       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_NONE       = 0,
+       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED   = (1 << 0),
+       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK   = (1 << 1)
+} ECalRecurDescribeRecurrenceFlags;
+
 G_END_DECLS
 
 #endif /* E_CAL_ENUMS_H */
diff --git a/src/calendar/libecal/e-cal-recur.c b/src/calendar/libecal/e-cal-recur.c
index dc8112807..77c0ec9f1 100644
--- a/src/calendar/libecal/e-cal-recur.c
+++ b/src/calendar/libecal/e-cal-recur.c
@@ -178,6 +178,7 @@ ensure_timezone (icalcomponent *comp,
                 ECalRecurResolveTimezoneCb get_tz_callback,
                 gpointer get_tz_callback_user_data,
                 icaltimezone *default_timezone,
+                GHashTable **pcached_zones,
                 GCancellable *cancellable,
                 GError **error)
 {
@@ -217,9 +218,24 @@ ensure_timezone (icalcomponent *comp,
        if (!tzid || !*tzid)
                return TRUE;
 
-       if (get_tz_callback)
-               tt->zone = get_tz_callback (tzid, get_tz_callback_user_data, cancellable, &local_error);
-       else
+       if (get_tz_callback) {
+               ICalTimezone *zone = NULL;
+
+               if (*pcached_zones)
+                       zone = g_hash_table_lookup (*pcached_zones, tzid);
+
+               if (!zone) {
+                       zone = get_tz_callback (tzid, get_tz_callback_user_data, cancellable, &local_error);
+                       if (zone) {
+                               if (!*pcached_zones)
+                                       *pcached_zones = g_hash_table_new_full (g_str_hash, g_str_equal, 
g_free, g_object_unref);
+
+                               g_hash_table_insert (*pcached_zones, g_strdup (tzid), zone);
+                       }
+               }
+
+               tt->zone = zone ? i_cal_object_get_native (I_CAL_OBJECT (zone)) : NULL;
+       } else
                tt->zone = NULL;
 
        if (!tt->zone)
@@ -296,14 +312,14 @@ intersects_interval (const struct icaltimetype *tt,
 
 /**
  * e_cal_recur_generate_instances_sync:
- * @comp: an icalcomponent
+ * @icalcomp: an #ICalComponent
  * @interval_start: an interval start, for which generate instances
  * @interval_end: an interval end, for which generate instances
  * @callback: (scope call): a callback to be called for each instance
  * @callback_user_data: (closure callback): user data for @callback
  * @get_tz_callback: (scope call): a callback to call when resolving timezone
  * @get_tz_callback_user_data: (closure get_tz_callback): user data for @get_tz_callback
- * @default_timezone: a default icaltimezone
+ * @default_timezone: a default #ICalTimezone
  * @cancellable: a #GCancellable; can be %NULL
  * @error: (out): a #GError to set an error, if any
  *
@@ -317,7 +333,7 @@ intersects_interval (const struct icaltimetype *tt,
  * The start and end times are required valid times, start before end time.
  *
  * The @get_tz_callback is used to resolve references to timezones. It is passed
- * a TZID and should return the icaltimezone * corresponding to that TZID. We need to
+ * a TZID and should return the ICalTimezone * corresponding to that TZID. We need to
  * do this as we access timezones in different ways on the client & server.
  *
  * The default_timezone argument is used for DTSTART or DTEND properties that
@@ -328,35 +344,54 @@ intersects_interval (const struct icaltimetype *tt,
  * Since: 3.20
  **/
 gboolean
-e_cal_recur_generate_instances_sync (icalcomponent *comp,
-                                    struct icaltimetype interval_start,
-                                    struct icaltimetype interval_end,
+e_cal_recur_generate_instances_sync (ICalComponent *icalcomp,
+                                    ICalTimetype *interval_start,
+                                    ICalTimetype *interval_end,
                                     ECalRecurInstanceCb callback,
                                     gpointer callback_user_data,
                                     ECalRecurResolveTimezoneCb get_tz_callback,
                                     gpointer get_tz_callback_user_data,
-                                    icaltimezone *default_timezone,
+                                    ICalTimezone *default_timezone,
                                     GCancellable *cancellable,
                                     GError **error)
 {
-       struct icaltimetype dtstart, dtend, next;
-       gint64 duration_days, duration_seconds;
+       struct icaltimetype dtstart, dtend, next, interval_start_tt, interval_end_tt, *native_tt;
+       icalcomponent *comp;
        icalproperty *prop;
-       GHashTable *times;
+       icaltimezone *default_zone;
+       gint64 duration_days, duration_seconds;
+       GHashTable *times, *cached_zones = NULL;
        gboolean success = TRUE;
 
-       g_return_val_if_fail (comp != NULL, FALSE);
+       g_return_val_if_fail (icalcomp != NULL, FALSE);
        g_return_val_if_fail (callback != NULL, FALSE);
-       g_return_val_if_fail (icaltime_compare (interval_start, interval_end) < 0, FALSE);
+       g_return_val_if_fail (interval_start != NULL, FALSE);
+       g_return_val_if_fail (interval_end != NULL, FALSE);
+       g_return_val_if_fail (i_cal_time_compare (interval_start, interval_end) < 0, FALSE);
 
        if (g_cancellable_set_error_if_cancelled (cancellable, error))
                return FALSE;
 
+       /* Keep the public API using libical-glib, but internally use libical,
+          for its memory management simplicity. */
+       comp = i_cal_object_get_native (I_CAL_OBJECT (icalcomp));
+       g_return_val_if_fail (comp != NULL, FALSE);
+
+       native_tt = i_cal_object_get_native (I_CAL_OBJECT (interval_start));
+       g_return_val_if_fail (native_tt != NULL, FALSE);
+       interval_start_tt = *native_tt;
+
+       native_tt = i_cal_object_get_native (I_CAL_OBJECT (interval_end));
+       g_return_val_if_fail (native_tt != NULL, FALSE);
+       interval_end_tt = *native_tt;
+
+       default_zone = default_timezone ? i_cal_object_get_native (I_CAL_OBJECT (default_timezone)) : NULL;
+
        times = g_hash_table_new_full (e_instance_time_hash, e_instance_time_equal, g_free, NULL);
 
        dtstart = icalcomponent_get_dtstart (comp);
        success = ensure_timezone (comp, &dtstart, ICAL_DTSTART_PROPERTY, NULL,
-               get_tz_callback, get_tz_callback_user_data, default_timezone, cancellable, error);
+               get_tz_callback, get_tz_callback_user_data, default_zone, &cached_zones, cancellable, error);
 
        duration_seconds = 0;
        dtend = icalcomponent_get_dtend (comp);
@@ -398,7 +433,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
 
        if (success && !icaltime_is_null_time (dtend)) {
                success = ensure_timezone (comp, &dtend, ICAL_DTEND_PROPERTY, NULL,
-                       get_tz_callback, get_tz_callback_user_data, default_timezone, cancellable, error);
+                       get_tz_callback, get_tz_callback_user_data, default_zone, &cached_zones, cancellable, 
error);
                duration_seconds = (gint64) icaltime_as_timet_with_zone (dtend, dtend.zone) -
                        (gint64) icaltime_as_timet_with_zone (dtstart, dtstart.zone);
                if (duration_seconds < 0)
@@ -408,7 +443,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
        duration_days = duration_seconds / (24 * 60 * 60);
        duration_seconds = duration_seconds % (24 * 60 * 60);
 
-       if (success && intersects_interval (&dtstart, NULL, duration_days, duration_seconds, &interval_start, 
&interval_end)) {
+       if (success && intersects_interval (&dtstart, NULL, duration_days, duration_seconds, 
&interval_start_tt, &interval_end_tt)) {
                g_hash_table_insert (times, e_instance_time_new (&dtstart, NULL), NULL);
        }
 
@@ -423,7 +458,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                        if (!icaltime_is_null_time (rrule.until)) {
                                success = ensure_timezone (comp, &rrule.until, 0, prop,
                                        get_tz_callback, get_tz_callback_user_data, (icaltimezone *) 
dtstart.zone,
-                                       cancellable, error);
+                                       &cached_zones, cancellable, error);
                                if (!success)
                                        break;
                        }
@@ -445,14 +480,14 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                                struct icaltimetype prev = icaltime_null_time ();
 
                                for (next = icalrecur_iterator_next (riter);
-                                    !icaltime_is_null_time (next) && icaltime_compare (next, interval_end) 
<= 0;
+                                    !icaltime_is_null_time (next) && icaltime_compare (next, 
interval_end_tt) <= 0;
                                     next = icalrecur_iterator_next (riter)) {
                                        if (!icaltime_is_null_time (prev) &&
                                            icaltime_compare (next, prev) == 0)
                                                break;
                                        prev = next;
 
-                                       if (intersects_interval (&next, NULL, duration_days, 
duration_seconds, &interval_start, &interval_end)) {
+                                       if (intersects_interval (&next, NULL, duration_days, 
duration_seconds, &interval_start_tt, &interval_end_tt)) {
                                                g_hash_table_insert (times, e_instance_time_new (&next, 
NULL), NULL);
                                        }
                                }
@@ -511,11 +546,11 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                        if (!icaltime_is_null_time (tt)) {
                                success = ensure_timezone (comp, &tt, 0, prop,
                                        get_tz_callback, get_tz_callback_user_data, (icaltimezone *) 
dtstart.zone,
-                                       cancellable, error);
+                                       &cached_zones, cancellable, error);
                                if (!success)
                                        break;
 
-                               if (intersects_interval (&tt, &duration, duration_days, duration_seconds, 
&interval_start, &interval_end)) {
+                               if (intersects_interval (&tt, &duration, duration_days, duration_seconds, 
&interval_start_tt, &interval_end_tt)) {
                                        g_hash_table_insert (times, e_instance_time_new (&tt, &duration), 
NULL);
                                }
                        }
@@ -530,7 +565,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                        if (!icaltime_is_null_time (exrule.until)) {
                                success = ensure_timezone (comp, &exrule.until, 0, prop,
                                        get_tz_callback, get_tz_callback_user_data, (icaltimezone *) 
dtstart.zone,
-                                       cancellable, error);
+                                       &cached_zones, cancellable, error);
                                if (!success)
                                        break;
                        }
@@ -552,14 +587,14 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                                struct icaltimetype prev = icaltime_null_time ();
 
                                for (next = icalrecur_iterator_next (riter);
-                                    !icaltime_is_null_time (next) && icaltime_compare (next, interval_end) 
<= 0;
+                                    !icaltime_is_null_time (next) && icaltime_compare (next, 
interval_end_tt) <= 0;
                                     next = icalrecur_iterator_next (riter)) {
                                        if (!icaltime_is_null_time (prev) &&
                                            icaltime_compare (next, prev) == 0)
                                                break;
                                        prev = next;
 
-                                       if (intersects_interval (&next, NULL, duration_days, 
duration_seconds, &interval_start, &interval_end)) {
+                                       if (intersects_interval (&next, NULL, duration_days, 
duration_seconds, &interval_start_tt, &interval_end_tt)) {
                                                EInstanceTime it;
 
                                                it.tt = next;
@@ -583,14 +618,14 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
 
                        success = ensure_timezone (comp, &exdate, 0, prop,
                                get_tz_callback, get_tz_callback_user_data, (icaltimezone *) dtstart.zone,
-                               cancellable, error);
+                               &cached_zones, cancellable, error);
                        if (!success)
                                break;
 
                        if (!exdate.zone && !icaltime_is_utc (exdate))
                                exdate.zone = dtstart.zone;
 
-                       if (intersects_interval (&exdate, NULL, duration_days, duration_seconds, 
&interval_start, &interval_end)) {
+                       if (intersects_interval (&exdate, NULL, duration_days, duration_seconds, 
&interval_start_tt, &interval_end_tt)) {
                                EInstanceTime it;
 
                                it.tt = exdate;
@@ -624,6 +659,7 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                for (ii = 0; ii < times_array->len; ii++) {
                        EInstanceTime *it = g_ptr_array_index (times_array, ii);
                        struct icaltimetype ttend;
+                       ICalTimetype *gttstart, *gttend;
                        gint dur_days = duration_days, dur_seconds = duration_seconds;
 
                        if (!it)
@@ -646,7 +682,14 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
                                break;
                        }
 
-                       success = callback (comp, it->tt, ttend, callback_user_data, cancellable, error);
+                       gttstart = i_cal_object_construct (I_CAL_TYPE_TIMETYPE, &(it->tt), NULL, FALSE, NULL);
+                       gttend = i_cal_object_construct (I_CAL_TYPE_TIMETYPE, &ttend, NULL, FALSE, NULL);
+
+                       success = callback (icalcomp, gttstart, gttend, callback_user_data, cancellable, 
error);
+
+                       g_clear_object (&gttstart);
+                       g_clear_object (&gttend);
+
                        if (!success)
                                break;
                }
@@ -656,6 +699,9 @@ e_cal_recur_generate_instances_sync (icalcomponent *comp,
 
        g_hash_table_destroy (times);
 
+       if (cached_zones)
+               g_hash_table_destroy (cached_zones);
+
        return success;
 }
 
@@ -849,9 +895,6 @@ struct _CalObjRecurrenceDate {
        ECalComponentPeriod *period;
 };
 
-/* The paramter we use to store the enddate in RRULE and EXRULE properties. */
-#define EVOLUTION_END_DATE_PARAMETER   "X-EVOLUTION-ENDDATE"
-
 typedef gboolean (*CalObjFindStartFn) (CalObjTime *event_start,
                                       CalObjTime *event_end,
                                       RecurData  *recur_data,
@@ -895,13 +938,13 @@ static void e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                                                  icalproperty  *prop,
                                                  time_t         start,
                                                  time_t         end,
-                                                 ECalRecurInstanceFn cb,
+                                                 ECalRecurInstanceCb cb,
                                                  gpointer       cb_data,
-                                                 ECalRecurResolveTimezoneFn  tz_cb,
+                                                 ECalRecurResolveTimezoneCb  tz_cb,
                                                  gpointer       tz_cb_data,
                                                  icaltimezone  *default_timezone);
 
-static ECalRecurrence * e_cal_recur_from_icalproperty (icalproperty *prop,
+static ECalRecurrence * e_cal_recur_from_icalproperty (ICalProperty *prop,
                                                    gboolean exception,
                                                    icaltimezone *zone,
                                                    gboolean convert_end_date);
@@ -931,7 +974,7 @@ static gboolean generate_instances_for_chunk        (ECalComponent          *comp,
                                                 gint                    duration_days,
                                                 gint                    duration_seconds,
                                                 gboolean                convert_end_date,
-                                                ECalRecurInstanceFn     cb,
+                                                ECalRecurInstanceCb     cb,
                                                 gpointer                cb_data);
 
 static GArray * cal_obj_expand_recurrence      (CalObjTime       *event_start,
@@ -1107,18 +1150,22 @@ static void cal_object_time_from_time           (CalObjTime *cotime,
 static gint cal_obj_date_only_compare_func     (gconstpointer arg1,
                                                 gconstpointer arg2);
 static gboolean e_cal_recur_ensure_rule_end_date       (ECalComponent  *comp,
-                                                icalproperty   *prop,
+                                                ICalProperty   *prop,
                                                 gboolean        exception,
                                                 gboolean        refresh,
-                                                ECalRecurResolveTimezoneFn tz_cb,
-                                                gpointer        tz_cb_data);
-static gboolean e_cal_recur_ensure_rule_end_date_cb    (ECalComponent  *comp,
-                                                        time_t          instance_start,
-                                                        time_t          instance_end,
-                                                        gpointer        data);
-static time_t e_cal_recur_get_rule_end_date    (icalproperty   *prop,
-                                                icaltimezone   *default_timezone);
-static void e_cal_recur_set_rule_end_date              (icalproperty   *prop,
+                                                ECalRecurResolveTimezoneCb tz_cb,
+                                                gpointer        tz_cb_data,
+                                                GCancellable *cancellable,
+                                                GError **error);
+static gboolean e_cal_recur_ensure_rule_end_date_cb    (ICalComponent  *comp,
+                                                        ICalTimetype *instance_start,
+                                                        ICalTimetype *instance_end,
+                                                        gpointer user_data,
+                                                        GCancellable *cancellable,
+                                                        GError **error);
+static time_t e_cal_recur_get_rule_end_date    (ICalProperty   *prop,
+                                                ICalTimezone   *default_timezone);
+static void e_cal_recur_set_rule_end_date      (ICalProperty   *prop,
                                                 time_t          end_date);
 
 #ifdef CAL_OBJ_DEBUG
@@ -1223,115 +1270,29 @@ static ECalRecurVTable cal_obj_secondly_vtable = {
        cal_obj_bysecond_filter
 };
 
-struct BackwardCompatibilityData
-{
-       ECalComponent *comp;
-       ECalRecurInstanceFn cb;
-       gpointer cb_data;
-       ECalRecurResolveTimezoneFn tz_cb;
-       gpointer tz_cb_data;
-};
-
-static icaltimezone *
-backward_compatibility_resolve_timezone_cb (const gchar *tzid,
-                                           gpointer user_data,
-                                           GCancellable *cancellable,
-                                           GError **error)
-{
-       struct BackwardCompatibilityData *bcd = user_data;
-
-       if (bcd && bcd->tz_cb)
-               return bcd->tz_cb (tzid, bcd->tz_cb_data);
-
-       return NULL;
-}
-
 static gboolean
-backward_compatibility_instance_cb (icalcomponent *comp,
-                                   struct icaltimetype instance_start,
-                                   struct icaltimetype instance_end,
-                                   gpointer user_data,
-                                   GCancellable *cancellable,
-                                   GError **error)
+call_instance_callback (ECalRecurInstanceCb cb,
+                       ECalComponent *comp,
+                       time_t dtstart_time,
+                       time_t dtend_time,
+                       gpointer cb_data)
 {
-       struct BackwardCompatibilityData *bcd = user_data;
+       ICalTimetype *start, *end;
+       ICalTimezone *utc_zone;
+       gboolean res;
 
-       if (bcd && bcd->cb) {
-               time_t istart, iend;
+       g_return_val_if_fail (cb != NULL, FALSE);
 
-               if (instance_start.zone)
-                       istart = icaltime_as_timet_with_zone (instance_start, instance_start.zone);
-               else
-                       istart = icaltime_as_timet (instance_start);
+       utc_zone = i_cal_timezone_get_utc_timezone ();
+       start = i_cal_time_from_timet_with_zone (dtstart_time, FALSE, utc_zone);
+       end = i_cal_time_from_timet_with_zone (dtend_time, FALSE, utc_zone);
 
-               if (instance_end.zone)
-                       iend = icaltime_as_timet_with_zone (instance_end, instance_end.zone);
-               else
-                       iend = icaltime_as_timet (instance_end);
+       res = cb (e_cal_component_get_icalcomponent (comp), start, end, cb_data, NULL, NULL);
 
-               return bcd->cb (bcd->comp, istart, iend, bcd->cb_data);
-       }
+       g_clear_object (&start);
+       g_clear_object (&end);
 
-       return FALSE;
-}
-
-/**
- * e_cal_recur_generate_instances:
- * @comp: A calendar component object
- * @start: Range start time
- * @end: Range end time
- * @cb: (closure cb_data) (scope call): Callback function
- * @cb_data: (closure): Closure data for the callback function
- * @tz_cb: (closure tz_cb_data) (scope call): Callback for retrieving timezones
- * @tz_cb_data: (closure): Closure data for the timezone callback
- * @default_timezone: Default timezone to use when a timezone cannot be
- * found
- *
- * Calls the given callback function for each occurrence of the event that
- * intersects the range between the given @start and @end times (the end time is
- * not included). Note that the occurrences may start before the given start
- * time.
- *
- * If the callback routine returns FALSE the occurrence generation stops.
- *
- * Both start and end can be -1, in which case we start at the events first
- * instance and continue until it ends, or forever if it has no enddate.
- *
- * The tz_cb is used to resolve references to timezones. It is passed a TZID
- * and should return the icaltimezone* corresponding to that TZID. We need to
- * do this as we access timezones in different ways on the client & server.
- *
- * The default_timezone argument is used for DTSTART or DTEND properties that
- * are DATE values or do not have a TZID (i.e. floating times).
- *
- * Note: This will be replaced by e_cal_recur_generate_instances_sync().
- */
-void
-e_cal_recur_generate_instances (ECalComponent *comp,
-                                time_t start,
-                                time_t end,
-                                ECalRecurInstanceFn cb,
-                                gpointer cb_data,
-                                ECalRecurResolveTimezoneFn tz_cb,
-                                gpointer tz_cb_data,
-                                icaltimezone *default_timezone)
-{
-       struct icaltimetype istart, iend;
-       struct BackwardCompatibilityData bcd;
-
-       bcd.comp = comp;
-       bcd.cb = cb;
-       bcd.cb_data = cb_data;
-       bcd.tz_cb = tz_cb;
-       bcd.tz_cb_data = tz_cb_data;
-
-       istart = icaltime_from_timet_with_zone (start, FALSE, icaltimezone_get_utc_timezone ());
-       iend = icaltime_from_timet_with_zone (end, FALSE, icaltimezone_get_utc_timezone ());
-
-       e_cal_recur_generate_instances_sync (e_cal_component_get_icalcomponent (comp), istart, iend,
-               backward_compatibility_instance_cb, &bcd,
-               backward_compatibility_resolve_timezone_cb, &bcd,
-               default_timezone, NULL, NULL);
+       return res;
 }
 
 /*
@@ -1353,21 +1314,23 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                                         icalproperty *prop,
                                         time_t start,
                                         time_t end,
-                                        ECalRecurInstanceFn cb,
+                                        ECalRecurInstanceCb cb,
                                         gpointer cb_data,
-                                        ECalRecurResolveTimezoneFn tz_cb,
+                                        ECalRecurResolveTimezoneCb tz_cb,
                                         gpointer tz_cb_data,
                                         icaltimezone *default_timezone)
 {
-       ECalComponentDateTime dtstart, dtend;
+       ECalComponentDateTime *dtstart, *dtend;
        time_t dtstart_time, dtend_time;
-       GSList *rrules = NULL, *rdates = NULL, elem;
+       GSList *rrules = NULL, *rdates = NULL;
        GSList *exrules = NULL, *exdates = NULL;
        CalObjTime interval_start, interval_end, event_start, event_end;
        CalObjTime chunk_start, chunk_end;
        gint days, seconds, year;
        gboolean single_rule, convert_end_date = FALSE;
        icaltimezone *start_zone = NULL, *end_zone = NULL;
+       ICalTimezone *gstart_zone = NULL, *gend_zone = NULL;
+       struct icaltimetype *dtstarttt, *dtendtt;
 
        g_return_if_fail (comp != NULL);
        g_return_if_fail (cb != NULL);
@@ -1379,10 +1342,15 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
         * cal_component_get_dtend () will convert a DURATION property to a
         * DTEND so we don't need to worry about that. */
 
-       e_cal_component_get_dtstart (comp, &dtstart);
-       e_cal_component_get_dtend (comp, &dtend);
+       dtstart = e_cal_component_get_dtstart (comp);
+       dtend = e_cal_component_get_dtend (comp);
+
+       dtstarttt = (dtstart && e_cal_component_datetime_get_value (dtstart)) ?
+               i_cal_object_get_native (I_CAL_OBJECT (e_cal_component_datetime_get_value (dtstart))) : NULL;
+       dtendtt = (dtend && e_cal_component_datetime_get_value (dtend)) ?
+               i_cal_object_get_native (I_CAL_OBJECT (e_cal_component_datetime_get_value (dtend))) : NULL;
 
-       if (!dtstart.value) {
+       if (!dtstart || !dtstarttt) {
                g_message (
                        "e_cal_recur_generate_instances_of_rule(): bogus "
                        "component, does not have DTSTART.  Skipping...");
@@ -1392,8 +1360,10 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
        /* For DATE-TIME values with a TZID, we use the supplied callback to
         * resolve the TZID. For DATE values and DATE-TIME values without a
         * TZID (i.e. floating times) we use the default timezone. */
-       if (dtstart.tzid && !dtstart.value->is_date) {
-               start_zone = (*tz_cb) (dtstart.tzid, tz_cb_data);
+       if (e_cal_component_datetime_get_tzid (dtstart) && !dtstarttt->is_date) {
+               gstart_zone = (*tz_cb) (e_cal_component_datetime_get_tzid (dtstart), tz_cb_data, NULL, NULL);
+               if (gstart_zone)
+                       start_zone = i_cal_object_get_native (I_CAL_OBJECT (gstart_zone));
                if (!start_zone)
                        start_zone = default_timezone;
        } else {
@@ -1404,37 +1374,41 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                convert_end_date = TRUE;
        }
 
-       dtstart_time = icaltime_as_timet_with_zone (
-               *dtstart.value,
-               start_zone);
+       dtstart_time = icaltime_as_timet_with_zone (*dtstarttt, start_zone);
        if (start == -1)
                start = dtstart_time;
 
-       if (dtend.value) {
+       if (dtendtt) {
                /* If both DTSTART and DTEND are DATE values, and they are the
                 * same day, we add 1 day to DTEND. This means that most
                 * events created with the old Evolution behavior will still
                 * work OK. I'm not sure what Outlook does in this case. */
-               if (dtstart.value->is_date && dtend.value->is_date) {
-                       if (icaltime_compare_date_only (*dtstart.value,
-                                                       *dtend.value) == 0) {
-                               icaltime_adjust (dtend.value, 1, 0, 0, 0);
+               if (dtstarttt->is_date && dtendtt->is_date) {
+                       if (icaltime_compare_date_only (*dtstarttt, *dtendtt) == 0) {
+                               icaltime_adjust (dtendtt, 1, 0, 0, 0);
                        }
                }
        } else {
                /* If there is no DTEND, then if DTSTART is a DATE-TIME value
                 * we use the same time (so we have a single point in time).
                 * If DTSTART is a DATE value we add 1 day. */
-               dtend.value = g_new (struct icaltimetype, 1);
-               *dtend.value = *dtstart.value;
+               e_cal_component_datetime_free (dtend);
 
-               if (dtstart.value->is_date) {
-                       icaltime_adjust (dtend.value, 1, 0, 0, 0);
+               dtend = e_cal_component_datetime_copy (dtstart);
+               dtendtt = (dtend && e_cal_component_datetime_get_value (dtend)) ?
+                       i_cal_object_get_native (I_CAL_OBJECT (e_cal_component_datetime_get_value (dtend))) : 
NULL;
+
+               g_warn_if_fail (dtendtt != NULL);
+
+               if (dtstarttt->is_date) {
+                       icaltime_adjust (dtendtt, 1, 0, 0, 0);
                }
        }
 
-       if (dtend.tzid && !dtend.value->is_date) {
-               end_zone = (*tz_cb) (dtend.tzid, tz_cb_data);
+       if (e_cal_component_datetime_get_tzid (dtend) && dtendtt && !dtendtt->is_date) {
+               gend_zone = (*tz_cb) (e_cal_component_datetime_get_tzid (dtend), tz_cb_data, NULL, NULL);
+               if (gend_zone)
+                       end_zone = i_cal_object_get_native (I_CAL_OBJECT (gend_zone));
                if (!end_zone)
                        end_zone = default_timezone;
        } else {
@@ -1446,14 +1420,14 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
 #if 0
        /* If DTEND is a DATE value, we add 1 day to it so that it includes
         * the entire day. */
-       if (dtend.value->is_date) {
-               dtend.value->hour = 0;
-               dtend.value->minute = 0;
-               dtend.value->second = 0;
-               icaltime_adjust (dtend.value, 1, 0, 0, 0);
+       if (dtendtt->is_date) {
+               dtendtt->hour = 0;
+               dtendtt->minute = 0;
+               dtendtt->second = 0;
+               icaltime_adjust (dtendtt, 1, 0, 0, 0);
        }
 #endif
-       dtend_time = icaltime_as_timet_with_zone (*dtend.value, end_zone);
+       dtend_time = icaltime_as_timet_with_zone (*dtendtt, end_zone);
 
        /* If there is no recurrence, just call the callback if the event
         * intersects the given interval. */
@@ -1463,10 +1437,10 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                        icaltimetype start_t = icaltime_from_timet_with_zone (start, FALSE, default_timezone);
                        icaltimetype end_t = icaltime_from_timet_with_zone (end, FALSE, default_timezone);
 
-                       if ((icaltime_compare_date_only (*dtstart.value, start_t) >= 0) && 
((icaltime_compare_date_only (*dtstart.value, end_t) < 0)))
-                               (* cb) (comp, dtstart_time, dtend_time, cb_data);
+                       if ((icaltime_compare_date_only (*dtstarttt, start_t) >= 0) && 
((icaltime_compare_date_only (*dtstarttt, end_t) < 0)))
+                               call_instance_callback (cb, comp, dtstart_time, dtend_time, cb_data);
                } else if  ((end == -1 || dtstart_time < end) && dtend_time > start) {
-                       (* cb) (comp, dtstart_time, dtend_time, cb_data);
+                       call_instance_callback (cb, comp, dtstart_time, dtend_time, cb_data);
                }
 
                goto out;
@@ -1477,21 +1451,19 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
        if (prop) {
                single_rule = TRUE;
 
-               elem.data = prop;
-               elem.next = NULL;
-               rrules = &elem;
+               rrules = g_slist_prepend (NULL, i_cal_object_construct (I_CAL_TYPE_PROPERTY, prop, NULL, 
FALSE, NULL));
        } else if (e_cal_component_is_instance (comp)) {
                single_rule = FALSE;
        } else {
                single_rule = FALSE;
 
                /* Make sure all the enddates for the rules are set. */
-               e_cal_recur_ensure_end_dates (comp, FALSE, tz_cb, tz_cb_data);
+               e_cal_recur_ensure_end_dates (comp, FALSE, tz_cb, tz_cb_data, NULL, NULL);
 
-               e_cal_component_get_rrule_property_list (comp, &rrules);
-               e_cal_component_get_rdate_list (comp, &rdates);
-               e_cal_component_get_exrule_property_list (comp, &exrules);
-               e_cal_component_get_exdate_list (comp, &exdates);
+               rrules = e_cal_component_get_rrule_properties (comp);
+               rdates = e_cal_component_get_rdates (comp);
+               exrules = e_cal_component_get_exrule_properties (comp);
+               exdates = e_cal_component_get_exdates (comp);
        }
 
        /* Convert the interval start & end to CalObjTime. Note that if end
@@ -1570,14 +1542,16 @@ e_cal_recur_generate_instances_of_rule (ECalComponent *comp,
                        break;
        }
 
-       if (!prop) {
-               e_cal_component_free_period_list (rdates);
-               e_cal_component_free_exdate_list (exdates);
-       }
+       g_slist_free_full (rdates, e_cal_component_period_free);
+       g_slist_free_full (exdates, e_cal_component_datetime_free);
+       g_slist_free_full (rrules, g_object_unref);
+       g_slist_free_full (exrules, g_object_unref);
 
  out:
-       e_cal_component_free_datetime (&dtstart);
-       e_cal_component_free_datetime (&dtend);
+       e_cal_component_datetime_free (dtstart);
+       e_cal_component_datetime_free (dtend);
+       g_clear_object (&gstart_zone);
+       g_clear_object (&gend_zone);
 }
 
 /* Builds a list of GINT_TO_POINTER() elements out of a short array from a
@@ -1600,12 +1574,12 @@ array_to_list (gshort *array,
 /**
  * e_cal_recur_get_enddate:
  * @ir: RRULE or EXRULE recurrence 
- * @prop: An RRULE or EXRULE #icalproperty. 
+ * @prop: An RRULE or EXRULE #ICalProperty.
  * @zone: The DTSTART timezone, used for converting the UNTIL property if it
- * is given as a DATE value.
+ *    is given as a DATE value.
  * @convert_end_date: TRUE if the saved end date needs to be converted to the
- * given @zone timezone. This is needed if the DTSTART is a DATE or floating
- * time.
+ *    given @zone timezone. This is needed if the DTSTART is a DATE or floating
+ *    time.
  * 
  * Finds out end time of (reccurent) event.
  *
@@ -1614,54 +1588,54 @@ array_to_list (gshort *array,
  * Since: 2.32
  */
 time_t
-e_cal_recur_obtain_enddate (struct icalrecurrencetype *ir,
-                            icalproperty *prop,
-          icaltimezone *zone,
-                            gboolean convert_end_date)
+e_cal_recur_obtain_enddate (ICalRecurrenceType *ir,
+                           ICalProperty *prop,
+                           ICalTimezone *zone,
+                           gboolean convert_end_date)
 {
        time_t enddate = -1;
 
        g_return_val_if_fail (prop != NULL, 0);
        g_return_val_if_fail (ir != NULL, 0);
 
-       if (ir->count != 0) {
+       if (i_cal_recurrence_type_get_count (ir) != 0) {
                /* If COUNT is set, we use the pre-calculated enddate.
                Note that this can be 0 if the RULE doesn't actually
                generate COUNT instances. */
                enddate = e_cal_recur_get_rule_end_date (prop, convert_end_date ? zone : NULL);
        } else {
-               if (icaltime_is_null_time (ir->until)) {
+               ICalTimetype *until;
+
+               until = i_cal_recurrence_type_get_until (ir);
+
+               if (!until || i_cal_time_is_null_time (until)) {
                        /* If neither COUNT or UNTIL is set, the event
                        recurs forever. */
-               } else if (ir->until.is_date) {
+               } else if (i_cal_timetype_get_is_date (until)) {
                        /* If UNTIL is a DATE, we stop at the end of
                        the day, in local time (with the DTSTART timezone).
                        Note that UNTIL is inclusive so we stop before
                        midnight. */
-                       ir->until.hour = 23;
-                       ir->until.minute = 59;
-                       ir->until.second = 59;
-                       ir->until.is_date = FALSE;
-
-                       enddate = icaltime_as_timet_with_zone (ir->until, zone);
-#if 0
-       g_print ("  until: %li - %s", r->enddate, ctime (&r->enddate));
-#endif
+                       i_cal_timetype_set_hour (until, 23);
+                       i_cal_timetype_set_minute (until, 59);
+                       i_cal_timetype_set_second (until, 59);
+                       i_cal_timetype_set_is_date (until, FALSE);
 
+                       enddate = i_cal_time_as_timet_with_zone (until, zone);
                } else {
-               /* If UNTIL is a DATE-TIME, it must be in UTC. */
-               icaltimezone *utc_zone;
-               utc_zone = icaltimezone_get_utc_timezone ();
-               enddate = icaltime_as_timet_with_zone (ir->until, utc_zone);
+                       /* If UNTIL is a DATE-TIME, it must be in UTC. */
+                       enddate = i_cal_time_as_timet_with_zone (until, i_cal_timezone_get_utc_timezone ());
                }
+
+               g_clear_object (&until);
        }
 
        return enddate;
 }
 
-/**
+/*
  * e_cal_recur_from_icalproperty:
- * @prop: An RRULE or EXRULE #icalproperty.
+ * @prop: An RRULE or EXRULE #ICalProperty.
  * @exception: TRUE if this is an EXRULE rather than an RRULE.
  * @zone: The DTSTART timezone, used for converting the UNTIL property if it
  * is given as a DATE value.
@@ -1669,30 +1643,39 @@ e_cal_recur_obtain_enddate (struct icalrecurrencetype *ir,
  * given @zone timezone. This is needed if the DTSTART is a DATE or floating
  * time.
  *
- * Converts an #icalproperty to a #ECalRecurrence.  This should be
+ * Converts an #ICalProperty to a #ECalRecurrence.  This should be
  * freed using the e_cal_recur_free() function.
  *
  * Returns: #ECalRecurrence structure.
- **/
+ */
 static ECalRecurrence *
-e_cal_recur_from_icalproperty (icalproperty *prop,
+e_cal_recur_from_icalproperty (ICalProperty *gprop,
                                gboolean exception,
                                icaltimezone *zone,
                                gboolean convert_end_date)
 {
        struct icalrecurrencetype ir;
+       ICalRecurrenceType *gir;
+       ICalTimezone *gzone;
+       icalproperty *prop;
        ECalRecurrence *r;
        gint max_elements, i;
        GList *elem;
 
+       g_return_val_if_fail (gprop != NULL, NULL);
+
+       prop = i_cal_object_get_native (I_CAL_OBJECT (gprop));
        g_return_val_if_fail (prop != NULL, NULL);
 
        r = g_new (ECalRecurrence, 1);
 
-       if (exception)
+       if (exception) {
                ir = icalproperty_get_exrule (prop);
-       else
+               gir = i_cal_property_get_exrule (gprop);
+       } else {
                ir = icalproperty_get_rrule (prop);
+               gir = i_cal_property_get_rrule (gprop);
+       }
 
        r->freq = ir.freq;
 
@@ -1705,7 +1688,11 @@ e_cal_recur_from_icalproperty (icalproperty *prop,
                r->interval = ir.interval;
        }
 
-  r->enddate = e_cal_recur_obtain_enddate (&ir, prop, zone, convert_end_date);
+       gzone = zone ? i_cal_object_construct (I_CAL_TYPE_TIMEZONE, zone, NULL, FALSE, NULL) : NULL;
+
+       r->enddate = e_cal_recur_obtain_enddate (gir, gprop, gzone, convert_end_date);
+
+       g_clear_object (&gzone);
 
        r->week_start_day = e_cal_recur_ical_weekday_to_weekday (ir.week_start);
 
@@ -1750,6 +1737,8 @@ e_cal_recur_from_icalproperty (icalproperty *prop,
 
        r->bysetpos = array_to_list (ir.by_set_pos, G_N_ELEMENTS (ir.by_set_pos));
 
+       g_clear_object (&gir);
+
        return r;
 }
 
@@ -1832,7 +1821,7 @@ static gboolean
 generate_instances_for_chunk (ECalComponent *comp,
                               time_t comp_dtstart,
                               icaltimezone *zone,
-                              GSList *rrules,
+                              GSList *rrules, /* ICalProperty * */
                               GSList *rdates,
                               GSList *exrules,
                               GSList *exdates,
@@ -1844,7 +1833,7 @@ generate_instances_for_chunk (ECalComponent *comp,
                               gint duration_days,
                               gint duration_seconds,
                               gboolean convert_end_date,
-                              ECalRecurInstanceFn cb,
+                              ECalRecurInstanceCb cb,
                               gpointer cb_data)
 {
        GArray *occs, *ex_occs, *tmp_occs, *rdate_periods;
@@ -1888,7 +1877,7 @@ generate_instances_for_chunk (ECalComponent *comp,
 
        /* Expand each of the recurrence rules. */
        for (elem = rrules; elem; elem = elem->next) {
-               icalproperty *prop;
+               ICalProperty *prop;
                ECalRecurrence *r;
 
                prop = elem->data;
@@ -1917,13 +1906,20 @@ generate_instances_for_chunk (ECalComponent *comp,
         * period in the rdate_periods array. Otherwise we can just treat them
         * as normal occurrences. */
        for (elem = rdates; elem; elem = elem->next) {
-               ECalComponentPeriod *p;
+               ECalComponentPeriod *period = elem->data;
                CalObjRecurrenceDate rdate;
-               struct icaltimetype tt;
+               ICalTimetype *gtt;
+               struct icaltimetype tt, *pstart;
+
+               gtt = e_cal_component_period_get_start (period);
+               if (!gtt)
+                       continue;
 
-               p = elem->data;
+               pstart = i_cal_object_get_native (I_CAL_OBJECT (gtt));
+               if (!pstart)
+                       continue;
 
-               tt = icaltime_convert_to_zone (p->start, zone);
+               tt = icaltime_convert_to_zone (*pstart, zone);
                cotime.year = tt.year;
                cotime.month = tt.month - 1;
                cotime.day = tt.day;
@@ -1943,12 +1939,13 @@ generate_instances_for_chunk (ECalComponent *comp,
                 * to store it so we can get it later. (libical seems to set
                 * second to -1 to denote an unset time. See icalvalue.c)
                 * FIXME. */
-               if (p->type != E_CAL_COMPONENT_PERIOD_DATETIME
-                   || p->u.end.second != -1) {
+               if (e_cal_component_period_get_kind (period) != E_CAL_COMPONENT_PERIOD_DATETIME ||
+                   !e_cal_component_period_get_end (period) ||
+                   i_cal_timetype_get_second (e_cal_component_period_get_end (period)) != -1) {
                        cotime.flags = TRUE;
 
                        rdate.start = cotime;
-                       rdate.period = p;
+                       rdate.period = period;
                        g_array_append_val (rdate_periods, rdate);
                }
 
@@ -1957,7 +1954,7 @@ generate_instances_for_chunk (ECalComponent *comp,
 
        /* Expand each of the exception rules. */
        for (elem = exrules; elem; elem = elem->next) {
-               icalproperty *prop;
+               ICalProperty *prop;
                ECalRecurrence *r;
 
                prop = elem->data;
@@ -1979,10 +1976,18 @@ generate_instances_for_chunk (ECalComponent *comp,
        /* Add on specific exception dates. */
        for (elem = exdates; elem; elem = elem->next) {
                ECalComponentDateTime *cdt;
-               struct icaltimetype tt;
+               struct icaltimetype tt, *value;
 
                cdt = elem->data;
-               tt = icaltime_convert_to_zone (*cdt->value, zone);
+
+               if (!e_cal_component_datetime_get_value (cdt))
+                       continue;
+
+               value = i_cal_object_get_native (I_CAL_OBJECT (e_cal_component_datetime_get_value (cdt)));
+               if (!value)
+                       continue;
+
+               tt = icaltime_convert_to_zone (*value, zone);
 
                cotime.year = tt.year;
                cotime.month = tt.month - 1;
@@ -1991,7 +1996,7 @@ generate_instances_for_chunk (ECalComponent *comp,
                /* If the EXDATE has a DATE value, set the time to the start
                 * of the day and set flags to TRUE so we know to skip all
                 * occurrences on that date. */
-               if (cdt->value->is_date) {
+               if (value->is_date) {
                        cotime.hour = 0;
                        cotime.minute = 0;
                        cotime.second = 0;
@@ -2098,7 +2103,7 @@ generate_instances_for_chunk (ECalComponent *comp,
                        continue;
                }
 
-               cb_status = (*cb) (comp, start_time, end_time, cb_data);
+               cb_status = call_instance_callback (cb, comp, start_time, end_time, cb_data);
                if (!cb_status)
                        break;
        }
@@ -2122,7 +2127,7 @@ cal_object_get_rdate_end (CalObjTime *occ,
                           icaltimezone *zone)
 {
        CalObjRecurrenceDate *rdate = NULL;
-       ECalComponentPeriod *p;
+       ECalComponentPeriod *period;
        gint lower, upper, middle, cmp = 0;
 
        lower = 0;
@@ -2152,25 +2157,36 @@ cal_object_get_rdate_end (CalObjTime *occ,
                return FALSE;
        }
 
-       p = rdate->period;
-       if (p->type == E_CAL_COMPONENT_PERIOD_DATETIME) {
-               struct icaltimetype tt =
-                       icaltime_convert_to_zone (p->u.end, zone);
-               occ->year = tt.year;
-               occ->month = tt.month - 1;
-               occ->day = tt.day;
-               occ->hour = tt.hour;
-               occ->minute = tt.minute;
-               occ->second = tt.second;
-               occ->flags = FALSE;
+       period = rdate->period;
+       if (e_cal_component_period_get_kind (period) == E_CAL_COMPONENT_PERIOD_DATETIME) {
+               ICalTimetype *end;
+               struct icaltimetype *endtt, tt;
+
+               end = e_cal_component_period_get_end (period);
+               endtt = end ? i_cal_object_get_native (I_CAL_OBJECT (end)) : NULL;
+               g_warn_if_fail (endtt != NULL);
+               if (endtt) {
+                       tt = icaltime_convert_to_zone (*endtt, zone);
+                       occ->year = tt.year;
+                       occ->month = tt.month - 1;
+                       occ->day = tt.day;
+                       occ->hour = tt.hour;
+                       occ->minute = tt.minute;
+                       occ->second = tt.second;
+                       occ->flags = FALSE;
+               }
        } else {
+               ICalDurationType *duration;
+
+               duration = e_cal_component_period_get_duration (period);
+
                cal_obj_time_add_days (
                        occ,
-                       p->u.duration.weeks * 7 +
-                       p->u.duration.days);
-               cal_obj_time_add_hours (occ, p->u.duration.hours);
-               cal_obj_time_add_minutes (occ, p->u.duration.minutes);
-               cal_obj_time_add_seconds (occ, p->u.duration.seconds);
+                       i_cal_duration_type_get_weeks (duration) * 7 +
+                       i_cal_duration_type_get_days (duration));
+               cal_obj_time_add_hours (occ, i_cal_duration_type_get_hours (duration));
+               cal_obj_time_add_minutes (occ, i_cal_duration_type_get_minutes (duration));
+               cal_obj_time_add_seconds (occ, i_cal_duration_type_get_seconds (duration));
        }
 
        return TRUE;
@@ -4523,16 +4539,17 @@ cal_obj_time_to_string (CalObjTime *cotime)
  * e_cal_recur_ensure_end_dates:
  * @comp: an #ECalComponent
  * @refresh: %TRUE to recalculate all end dates
- * @tz_cb: (closure tz_cb_data) (scope call): function to call to resolve
- * timezones
- * @tz_cb_data: (closure): data to pass to @tz_cb
+ * @tz_cb: (scope call): function to call to resolve timezones
+ * @tz_cb_data: (closure tz_cb_data): user data to pass to @tz_cb
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
  *
  * This recalculates the end dates for recurrence & exception rules which use
  * the COUNT property. If @refresh is %TRUE it will recalculate all enddates
  * for rules which use COUNT. If @refresh is %FALSE, it will only calculate
  * the enddate if it hasn't already been set. It returns %TRUE if the component
  * was changed, i.e. if the component should be saved at some point.
- * We store the enddate in the "X-EVOLUTION-ENDDATE" parameter of the RRULE
+ * We store the enddate in the %E_CAL_EVOLUTION_ENDDATE_PARAMETER parameter of the RRULE
  * or EXRULE.
  *
  * Returns: %TRUE if the component was changed, %FALSE otherwise
@@ -4541,29 +4558,32 @@ cal_obj_time_to_string (CalObjTime *cotime)
  **/
 gboolean
 e_cal_recur_ensure_end_dates (ECalComponent *comp,
-                              gboolean refresh,
-                              ECalRecurResolveTimezoneFn tz_cb,
-                              gpointer tz_cb_data)
+                             gboolean refresh,
+                             ECalRecurResolveTimezoneCb tz_cb,
+                             gpointer tz_cb_data,
+                             GCancellable *cancellable,
+                             GError **error)
 {
        GSList *rrules, *exrules, *elem;
        gboolean changed = FALSE;
 
        /* Do the RRULEs. */
-       e_cal_component_get_rrule_property_list (comp, &rrules);
-       for (elem = rrules; elem; elem = elem->next) {
+       rrules = e_cal_component_get_rrule_properties (comp);
+       for (elem = rrules; elem && !g_cancellable_is_cancelled (cancellable); elem = elem->next) {
                changed |= e_cal_recur_ensure_rule_end_date (comp, elem->data,
-                                                          FALSE, refresh,
-                                                          tz_cb, tz_cb_data);
+                       FALSE, refresh, tz_cb, tz_cb_data, cancellable, error);
        }
 
        /* Do the EXRULEs. */
-       e_cal_component_get_exrule_property_list (comp, &exrules);
-       for (elem = exrules; elem; elem = elem->next) {
+       exrules = e_cal_component_get_exrule_properties (comp);
+       for (elem = exrules; elem && !g_cancellable_is_cancelled (cancellable); elem = elem->next) {
                changed |= e_cal_recur_ensure_rule_end_date (comp, elem->data,
-                                                          TRUE, refresh,
-                                                          tz_cb, tz_cb_data);
+                       TRUE, refresh, tz_cb, tz_cb_data, cancellable, error);
        }
 
+       g_slist_free_full (rrules, g_object_unref);
+       g_slist_free_full (exrules, g_object_unref);
+
        return changed;
 }
 
@@ -4576,32 +4596,41 @@ struct _ECalRecurEnsureEndDateData {
 
 static gboolean
 e_cal_recur_ensure_rule_end_date (ECalComponent *comp,
-                                  icalproperty *prop,
+                                  ICalProperty *prop,
                                   gboolean exception,
                                   gboolean refresh,
-                                  ECalRecurResolveTimezoneFn tz_cb,
-                                  gpointer tz_cb_data)
+                                  ECalRecurResolveTimezoneCb tz_cb,
+                                  gpointer tz_cb_data,
+                                 GCancellable *cancellable,
+                                 GError **error)
 {
-       struct icalrecurrencetype rule;
+       ICalRecurrenceType *rule;
        ECalRecurEnsureEndDateData cb_data;
 
+       if (!prop)
+               return FALSE;
+
        if (exception)
-               rule = icalproperty_get_exrule (prop);
+               rule = i_cal_property_get_exrule (prop);
        else
-               rule = icalproperty_get_rrule (prop);
+               rule = i_cal_property_get_rrule (prop);
 
        /* If the rule doesn't use COUNT just return. */
-       if (rule.count == 0)
+       if (!rule || !i_cal_recurrence_type_get_count (rule)) {
+               g_clear_object (&rule);
                return FALSE;
+       }
 
        /* If refresh is FALSE, we check if the enddate is already set, and
         * if it is we just return. */
        if (!refresh) {
-               if (e_cal_recur_get_rule_end_date (prop, NULL) != -1)
+               if (e_cal_recur_get_rule_end_date (prop, NULL) != -1) {
+                       g_clear_object (&rule);
                        return FALSE;
+               }
        } else {
                /* Remove the property parameter, thus it'll not influence the regeneration */
-               icalproperty_remove_parameter_by_name (prop, EVOLUTION_END_DATE_PARAMETER);
+               i_cal_property_remove_parameter_by_name (prop, E_CAL_EVOLUTION_ENDDATE_PARAMETER);
        }
 
        /* Calculate the end date. Note that we initialize end_date to 0, so
@@ -4609,36 +4638,37 @@ e_cal_recur_ensure_rule_end_date (ECalComponent *comp,
         * Also note that we use the UTC timezone as the default timezone.
         * In get_end_date () if the DTSTART is a DATE or floating time, we will
         * convert the ENDDATE to the current timezone. */
-       cb_data.count = rule.count;
+       cb_data.count = i_cal_recurrence_type_get_count (rule);
        cb_data.instances = 0;
        cb_data.end_date = 0;
        e_cal_recur_generate_instances_of_rule (
-               comp, prop, -1, -1,
+               comp, i_cal_object_get_native (I_CAL_OBJECT (prop)), -1, -1,
                e_cal_recur_ensure_rule_end_date_cb,
                &cb_data, tz_cb, tz_cb_data,
                icaltimezone_get_utc_timezone ());
 
-       /* Store the end date in the "X-EVOLUTION-ENDDATE" parameter of the
-        * rule. */
+       /* Store the end date in the E_CAL_EVOLUTION_ENDDATE_PARAMETER parameter of the rule. */
        e_cal_recur_set_rule_end_date (prop, cb_data.end_date);
 
+       g_clear_object (&rule);
+
        return TRUE;
 }
 
 static gboolean
-e_cal_recur_ensure_rule_end_date_cb (ECalComponent *comp,
-                                     time_t instance_start,
-                                     time_t instance_end,
-                                     gpointer data)
+e_cal_recur_ensure_rule_end_date_cb (ICalComponent *comp,
+                                    ICalTimetype *instance_start,
+                                    ICalTimetype *instance_end,
+                                    gpointer user_data,
+                                    GCancellable *cancellable,
+                                    GError **error)
 {
-       ECalRecurEnsureEndDateData *cb_data;
-
-       cb_data = (ECalRecurEnsureEndDateData *) data;
+       ECalRecurEnsureEndDateData *cb_data = user_data;
 
        cb_data->instances++;
 
        if (cb_data->instances == cb_data->count) {
-               cb_data->end_date = instance_start;
+               cb_data->end_date = i_cal_time_as_timet (instance_start);
                return FALSE;
        }
 
@@ -4650,77 +4680,79 @@ e_cal_recur_ensure_rule_end_date_cb (ECalComponent *comp,
  * value, since the RRULE end date will change depending on the timezone that
  * it is evaluated in. */
 static time_t
-e_cal_recur_get_rule_end_date (icalproperty *prop,
-                               icaltimezone *default_timezone)
+e_cal_recur_get_rule_end_date (ICalProperty *prop,
+                               ICalTimezone *default_timezone)
 {
-       icalparameter *param;
+       ICalParameter *param;
        const gchar *xname, *xvalue;
-       icalvalue *value;
-       struct icaltimetype icaltime;
-       icaltimezone *zone;
-
-       param = icalproperty_get_first_parameter (prop, ICAL_X_PARAMETER);
-       while (param) {
-               xname = icalparameter_get_xname (param);
-               if (xname && !strcmp (xname, EVOLUTION_END_DATE_PARAMETER)) {
-                       xvalue = icalparameter_get_x (param);
-                       value = icalvalue_new_from_string (
-                               ICAL_DATETIME_VALUE,
-                               xvalue);
+
+       for (param = i_cal_property_get_first_parameter (prop, I_CAL_X_PARAMETER);
+            param;
+            g_object_unref (param), param = i_cal_property_get_next_parameter (prop, I_CAL_X_PARAMETER)) {
+               xname = i_cal_parameter_get_xname (param);
+               if (xname && !strcmp (xname, E_CAL_EVOLUTION_ENDDATE_PARAMETER)) {
+                       icalvalue *value;
+
+                       xvalue = i_cal_parameter_get_x (param);
+                       value = icalvalue_new_from_string (ICAL_DATETIME_VALUE, xvalue);
                        if (value) {
+                               struct icaltimetype icaltime;
+                               icaltimezone *zone;
+
                                icaltime = icalvalue_get_datetime (value);
                                icalvalue_free (value);
 
-                               zone = default_timezone ? default_timezone :
-                                       icaltimezone_get_utc_timezone ();
-                               return icaltime_as_timet_with_zone (
-                                       icaltime,
-                                       zone);
+                               zone = default_timezone ? i_cal_object_get_native (I_CAL_OBJECT 
(default_timezone)) : NULL;
+                               if (!zone)
+                                       zone = icaltimezone_get_utc_timezone ();
+
+                               g_object_unref (param);
+
+                               return icaltime_as_timet_with_zone (icaltime, zone);
                        }
                }
-
-               param = icalproperty_get_next_parameter (
-                       prop,
-                       ICAL_X_PARAMETER);
        }
 
        return -1;
 }
 
 static void
-e_cal_recur_set_rule_end_date (icalproperty *prop,
+e_cal_recur_set_rule_end_date (ICalProperty *prop,
                                time_t end_date)
 {
-       icalparameter *param;
-       icalvalue *value;
-       icaltimezone *utc_zone;
-       struct icaltimetype icaltime;
+       ICalParameter *param;
+       ICalValue *value;
+       ICalTimezone *utc_zone;
+       ICalTimetype *icaltime;
        const gchar *xname;
        gchar *end_date_string;
 
        /* We save the value as a UTC DATE-TIME. */
-       utc_zone = icaltimezone_get_utc_timezone ();
-       icaltime = icaltime_from_timet_with_zone (end_date, FALSE, utc_zone);
-       value = icalvalue_new_datetime (icaltime);
-       end_date_string = icalvalue_as_ical_string_r (value);
-       icalvalue_free (value);
+       utc_zone = i_cal_timezone_get_utc_timezone ();
+       icaltime = i_cal_time_from_timet_with_zone (end_date, FALSE, utc_zone);
+       value = i_cal_value_new_datetime (icaltime);
+       end_date_string = i_cal_value_as_ical_string_r (value);
+       g_object_unref (value);
+       g_object_unref (icaltime);
 
        /* If we already have an X-EVOLUTION-ENDDATE parameter, set the value
         * to the new date-time. */
-       param = icalproperty_get_first_parameter (prop, ICAL_X_PARAMETER);
-       while (param) {
-               xname = icalparameter_get_xname (param);
-               if (xname && !strcmp (xname, EVOLUTION_END_DATE_PARAMETER)) {
-                       icalparameter_set_x (param, end_date_string);
+       for (param = i_cal_property_get_first_parameter (prop, I_CAL_X_PARAMETER);
+            param;
+            g_object_unref (param), param = i_cal_property_get_next_parameter (prop, I_CAL_X_PARAMETER)) {
+               xname = i_cal_parameter_get_xname (param);
+               if (xname && !strcmp (xname, E_CAL_EVOLUTION_ENDDATE_PARAMETER)) {
+                       i_cal_parameter_set_x (param, end_date_string);
+                       g_free (end_date_string);
+                       g_object_unref (param);
                        return;
                }
-               param = icalproperty_get_next_parameter (prop, ICAL_X_PARAMETER);
        }
 
        /* Create a new X-EVOLUTION-ENDDATE and add it to the property. */
-       param = icalparameter_new_x (end_date_string);
-       icalparameter_set_xname (param, EVOLUTION_END_DATE_PARAMETER);
-       icalproperty_add_parameter (prop, param);
+       param = i_cal_parameter_new_x (end_date_string);
+       i_cal_parameter_set_xname (param, E_CAL_EVOLUTION_ENDDATE_PARAMETER);
+       i_cal_property_take_parameter (prop, param);
 
        g_free (end_date_string);
 }
@@ -4792,13 +4824,13 @@ cal_comp_util_recurrence_count_by_xxx (gshort *field,
 
 /**
  * e_cal_recur_describe_recurrence:
- * @icalcomp: an icalcomponent
+ * @icalcomp: an #ICalComponent
  * @week_start_day: a day when the week starts
  * @flags: bit-or of #ECalRecurDescribeRecurrenceFlags
  *
  * Describes some simple types of recurrences in a human-readable and localized way.
- * The @flags influence the output output format and what to do when the @icalcomp
- * contain more complicated recurrence, some which the function cannot describe.
+ * The @flags influence the output format and what to do when the @icalcomp
+ * contains more complicated recurrence, some which the function cannot describe.
  *
  * The @week_start_day is used for weekly recurrences, to start the list of selected
  * days at that day.
@@ -4813,11 +4845,12 @@ cal_comp_util_recurrence_count_by_xxx (gshort *field,
  * Since: 3.30
  **/
 gchar *
-e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
+e_cal_recur_describe_recurrence (ICalComponent *icalcomp,
                                 GDateWeekday week_start_day,
                                 guint32 flags)
 {
        gchar *prefix = NULL, *mid = NULL, *suffix = NULL, *result = NULL;
+       icalcomponent *comp;
        icalproperty *prop;
        struct icalrecurrencetype rrule;
        gint n_by_second, n_by_minute, n_by_hour;
@@ -4827,14 +4860,17 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
 
        g_return_val_if_fail (icalcomp != NULL, NULL);
 
+       comp = i_cal_object_get_native (I_CAL_OBJECT (icalcomp));
+       g_return_val_if_fail (comp != NULL, NULL);
+
        prefixed = (flags & E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED) != 0;
        fallback = (flags & E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK) != 0;
 
-       prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
+       prop = icalcomponent_get_first_property (comp, ICAL_RRULE_PROPERTY);
        if (!prop)
                return NULL;
 
-       switch (icalcomponent_isa (icalcomp)) {
+       switch (icalcomponent_isa (comp)) {
        case ICAL_VEVENT_COMPONENT:
        case ICAL_VTODO_COMPONENT:
        case ICAL_VJOURNAL_COMPONENT:
@@ -4843,9 +4879,9 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                return NULL;
        }
 
-       if (icalcomponent_count_properties (icalcomp, ICAL_RRULE_PROPERTY) != 1 ||
-           icalcomponent_count_properties (icalcomp, ICAL_RDATE_PROPERTY) != 0 ||
-           icalcomponent_count_properties (icalcomp, ICAL_EXRULE_PROPERTY) != 0)
+       if (icalcomponent_count_properties (comp, ICAL_RRULE_PROPERTY) != 1 ||
+           icalcomponent_count_properties (comp, ICAL_RDATE_PROPERTY) != 0 ||
+           icalcomponent_count_properties (comp, ICAL_EXRULE_PROPERTY) != 0)
                goto custom;
 
        rrule = icalproperty_get_rrule (prop);
@@ -4988,7 +5024,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                if (ii == 0) {
                        struct icaltimetype dtstart;
 
-                       dtstart = icalcomponent_get_dtstart (icalcomp);
+                       dtstart = icalcomponent_get_dtstart (comp);
 
                        ii = icaltime_day_of_week (dtstart);
                        if (ii >= 1)
@@ -5134,7 +5170,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                        if (nth == -1) {
                                struct icaltimetype dtstart;
 
-                               dtstart = icalcomponent_get_dtstart (icalcomp);
+                               dtstart = icalcomponent_get_dtstart (comp);
 
                                month_index = dtstart.day;
                                month_num = MONTH_NUM_LAST;
@@ -5614,6 +5650,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                                        rrule.count), rrule.count);
                } else if (rrule.until.year) {
                        struct tm tm;
+                       ICalTimetype *tt;
                        gchar dt_str[256];
 
                        dt_str[0] = 0;
@@ -5622,7 +5659,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                                icaltimezone *from_zone, *to_zone;
                                struct icaltimetype dtstart;
 
-                               dtstart = icalcomponent_get_dtstart (icalcomp);
+                               dtstart = icalcomponent_get_dtstart (comp);
 
                                from_zone = icaltimezone_get_utc_timezone ();
                                to_zone = (icaltimezone *) dtstart.zone;
@@ -5636,7 +5673,10 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                                rrule.until.is_date = TRUE;
                        }
 
-                       tm = icaltimetype_to_tm (&rrule.until);
+                       tt = i_cal_object_construct (I_CAL_TYPE_TIMETYPE, &rrule.until, NULL, FALSE, NULL);
+                       tm = icaltimetype_to_tm (tt);
+                       g_clear_object (&tt);
+
                        e_time_format_date_and_time (&tm, FALSE, FALSE, FALSE, dt_str, 255);
 
                        if (*dt_str) {
@@ -5673,7 +5713,7 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                gint n_exdates;
                gchar *tmp;
 
-               n_exdates = icalcomponent_count_properties (icalcomp, ICAL_EXDATE_PROPERTY);
+               n_exdates = icalcomponent_count_properties (comp, ICAL_EXDATE_PROPERTY);
                if (n_exdates > 0) {
                        gchar *exdates_str;
 
@@ -5698,16 +5738,16 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                if (prefixed) {
                        const gchar *comp_prefix;
 
-                       if (icalcomponent_isa (icalcomp) == ICAL_VEVENT_COMPONENT) {
-                               if (icalcomponent_count_properties (icalcomp, ICAL_ORGANIZER_PROPERTY) > 0 &&
-                                   icalcomponent_count_properties (icalcomp, ICAL_ATTENDEE_PROPERTY) > 0) {
+                       if (icalcomponent_isa (comp) == ICAL_VEVENT_COMPONENT) {
+                               if (icalcomponent_count_properties (comp, ICAL_ORGANIZER_PROPERTY) > 0 &&
+                                   icalcomponent_count_properties (comp, ICAL_ATTENDEE_PROPERTY) > 0) {
                                        comp_prefix = C_("recur-description", "The meeting recurs");
                                } else {
                                        comp_prefix = C_("recur-description", "The appointment recurs");
                                }
-                       } else if (icalcomponent_isa (icalcomp) == ICAL_VTODO_COMPONENT) {
+                       } else if (icalcomponent_isa (comp) == ICAL_VTODO_COMPONENT) {
                                comp_prefix = C_("recur-description", "The task recurs");
-                       } else /* if (icalcomponent_isa (icalcomp) == ICAL_VJOURNAL_COMPONENT) */ {
+                       } else /* if (icalcomponent_isa (comp) == ICAL_VJOURNAL_COMPONENT) */ {
                                comp_prefix = C_("recur-description", "The memo recurs");
                        }
 
@@ -5721,16 +5761,16 @@ e_cal_recur_describe_recurrence (icalcomponent *icalcomp,
                        result = tmp;
                }
        } else if (fallback) {
-               if (icalcomponent_isa (icalcomp) == ICAL_VEVENT_COMPONENT) {
-                       if (icalcomponent_count_properties (icalcomp, ICAL_ORGANIZER_PROPERTY) > 0 &&
-                           icalcomponent_count_properties (icalcomp, ICAL_ATTENDEE_PROPERTY) > 0) {
+               if (icalcomponent_isa (comp) == ICAL_VEVENT_COMPONENT) {
+                       if (icalcomponent_count_properties (comp, ICAL_ORGANIZER_PROPERTY) > 0 &&
+                           icalcomponent_count_properties (comp, ICAL_ATTENDEE_PROPERTY) > 0) {
                                result = g_strdup (C_("recur-description", "The meeting recurs"));
                        } else {
                                result = g_strdup (C_("recur-description", "The appointment recurs"));
                        }
-               } else if (icalcomponent_isa (icalcomp) == ICAL_VTODO_COMPONENT) {
+               } else if (icalcomponent_isa (comp) == ICAL_VTODO_COMPONENT) {
                        result = g_strdup (C_("recur-description", "The task recurs"));
-               } else if (icalcomponent_isa (icalcomp) == ICAL_VJOURNAL_COMPONENT) {
+               } else if (icalcomponent_isa (comp) == ICAL_VJOURNAL_COMPONENT) {
                        result = g_strdup (C_("recur-description", "The memo recurs"));
                }
        }
diff --git a/src/calendar/libecal/e-cal-recur.h b/src/calendar/libecal/e-cal-recur.h
index 1cbeef787..286aeb0c8 100644
--- a/src/calendar/libecal/e-cal-recur.h
+++ b/src/calendar/libecal/e-cal-recur.h
@@ -30,86 +30,92 @@
 #include <gio/gio.h>
 
 #include <libical-glib/libical-glib.h>
+
 #include <libecal/e-cal-component.h>
+#include <libecal/e-cal-enums.h>
 
 G_BEGIN_DECLS
 
-typedef icaltimezone * (* ECalRecurResolveTimezoneCb)  (const gchar *tzid,
+/**
+ * E_CAL_EVOLUTION_ENDDATE_PARAMETER:
+ *
+ * The X parameter name being used to store the enddate in RRULE and EXRULE properties.
+ *
+ * Since: 3.36
+ **/
+#define E_CAL_EVOLUTION_ENDDATE_PARAMETER      "X-EVOLUTION-ENDDATE"
+
+/**
+ * ECalRecurResolveTimezoneCb:
+ * @tzid: timezone ID to resolve
+ * @user_data: user data used for this callback
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Resolve timezone by its ID provided as @tzid. Free the returned object,
+ * if not %NULL, with g_object_unref(), when no longer needed.
+ *
+ * Returns: (transfer full) (nullable): a new #ICalTimezone object for @tzid,
+ *    or %NULL, on error or if not found.
+ *
+ * Since: 3.36
+ **/
+typedef ICalTimezone * (* ECalRecurResolveTimezoneCb)  (const gchar *tzid,
                                                         gpointer user_data,
                                                         GCancellable *cancellable,
                                                         GError **error);
 
-typedef gboolean (* ECalRecurInstanceCb)               (icalcomponent *comp,
-                                                        struct icaltimetype instance_start,
-                                                        struct icaltimetype instance_end,
+/**
+ * ECalRecurInstanceCb:
+ * @comp: an #ICalComponent
+ * @instance_start: start time of an instance
+ * @instance_end: end time of an instance
+ * @user_data: user data used for this callback in e_cal_recur_generate_instances_sync()
+ * @cancellable: optional #GCancellable object, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Callback used by e_cal_recur_generate_instances_sync(), called
+ * for each instance of a (recurring) component within given time range.
+ *
+ * Returns: %TRUE, to continue recurrence generation, %FALSE to stop
+ *
+ * Since: 3.36
+ **/
+typedef gboolean (* ECalRecurInstanceCb)               (ICalComponent *comp,
+                                                        ICalTimetype *instance_start,
+                                                        ICalTimetype *instance_end,
                                                         gpointer user_data,
                                                         GCancellable *cancellable,
                                                         GError **error);
 
-gboolean       e_cal_recur_generate_instances_sync     (icalcomponent *comp,
-                                                        struct icaltimetype interval_start,
-                                                        struct icaltimetype interval_end,
+gboolean       e_cal_recur_generate_instances_sync     (ICalComponent *icalcomp,
+                                                        ICalTimetype *interval_start,
+                                                        ICalTimetype *interval_end,
                                                         ECalRecurInstanceCb callback,
                                                         gpointer callback_user_data,
                                                         ECalRecurResolveTimezoneCb get_tz_callback,
                                                         gpointer get_tz_callback_user_data,
-                                                        icaltimezone *default_timezone,
+                                                        ICalTimezone *default_timezone,
                                                         GCancellable *cancellable,
                                                         GError **error);
 
-typedef gboolean (* ECalRecurInstanceFn) (ECalComponent *comp,
-                                        time_t        instance_start,
-                                        time_t        instance_end,
-                                        gpointer      user_data);
-
-typedef icaltimezone * (* ECalRecurResolveTimezoneFn)  (const gchar   *tzid,
-                                                        gpointer      data);
-
-void   e_cal_recur_generate_instances  (ECalComponent          *comp,
-                                        time_t                  start,
-                                        time_t                  end,
-                                        ECalRecurInstanceFn     cb,
-                                        gpointer                cb_data,
-                                        ECalRecurResolveTimezoneFn tz_cb,
-                                        gpointer                  tz_cb_data,
-                                        icaltimezone           *default_timezone);
-
-time_t
-e_cal_recur_obtain_enddate (struct icalrecurrencetype *ir,
-                            icalproperty *prop,
-                            icaltimezone *zone,
-                            gboolean convert_end_date);
-
-gboolean
-e_cal_recur_ensure_end_dates (ECalComponent    *comp,
-                           gboolean             refresh,
-                           ECalRecurResolveTimezoneFn  tz_cb,
-                           gpointer             tz_cb_data);
-
-const gchar *          e_cal_recur_get_localized_nth           (gint nth);
+time_t         e_cal_recur_obtain_enddate              (ICalRecurrenceType *ir,
+                                                        ICalProperty *prop,
+                                                        ICalTimezone *zone,
+                                                        gboolean convert_end_date);
 
-/**
- * ECalRecurDescribeRecurrenceFlags:
- * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_NONE: no extra flags, either returns %NULL or the recurrence 
description,
- *    something like "Every 2 weeks..."
- * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED: either returns %NULL or the recurrence description 
prefixed
- *    with text like "The meeting recurs", forming something like "The meeting recurs every 2 weeks..."
- * @E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK: returns %NULL only if the component doesn't recur,
- *    otherwise returns either the recurrence description or at least text like "The meeting recurs"
- *
- * Influences behaviour of e_cal_recur_describe_recurrence().
- *
- * Since: 3.30
- **/
-typedef enum {
-       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_NONE       = 0,
-       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_PREFIXED   = (1 << 0),
-       E_CAL_RECUR_DESCRIBE_RECURRENCE_FLAG_FALLBACK   = (1 << 1)
-} ECalRecurDescribeRecurrenceFlags;
-
-gchar *                        e_cal_recur_describe_recurrence         (icalcomponent *icalcomp,
-                                                                GDateWeekday week_start_day,
-                                                                guint32 flags);
+gboolean       e_cal_recur_ensure_end_dates            (ECalComponent *comp,
+                                                        gboolean refresh,
+                                                        ECalRecurResolveTimezoneCb tz_cb,
+                                                        gpointer tz_cb_data,
+                                                        GCancellable *cancellable,
+                                                        GError **error);
+
+const gchar *  e_cal_recur_get_localized_nth           (gint nth);
+
+gchar *                e_cal_recur_describe_recurrence         (ICalComponent *icalcomp,
+                                                        GDateWeekday week_start_day,
+                                                        guint32 flags); /* bit-or of 
ECalRecurDescribeRecurrenceFlags */
 
 G_END_DECLS
 
diff --git a/src/calendar/libecal/e-cal-util.c b/src/calendar/libecal/e-cal-util.c
index 038c958f1..9466b0580 100644
--- a/src/calendar/libecal/e-cal-util.c
+++ b/src/calendar/libecal/e-cal-util.c
@@ -26,9 +26,11 @@
 
 #include <libedataserver/libedataserver.h>
 
-#include "e-cal-util.h"
 #include "e-cal-client.h"
 #include "e-cal-system-timezone.h"
+#include "e-cal-recur.h"
+
+#include "e-cal-util.h"
 
 #define _TIME_MIN      ((time_t) 0)            /* Min valid time_t     */
 #define _TIME_MAX      ((time_t) INT_MAX)
@@ -1345,7 +1347,7 @@ e_cal_util_remove_instances_ex (ICalComponent *icalcomp,
                                }
 
                                i_cal_property_set_rrule (prop, rule);
-                               i_cal_property_remove_parameter_by_name (prop, "X-EVOLUTION-ENDDATE");
+                               i_cal_property_remove_parameter_by_name (prop, 
E_CAL_EVOLUTION_ENDDATE_PARAMETER);
                        }
                } else {
                        /* (If recur == rid, skip to the next occurrence) */
@@ -1558,7 +1560,7 @@ e_cal_util_split_at_instance (ICalComponent *icalcomp,
                        } else {
                                i_cal_recurrence_type_set_count (rule, rule_count - occurrences_count);
                                i_cal_property_set_rrule (prop, rule);
-                               i_cal_property_remove_parameter_by_name (prop, "X-EVOLUTION-ENDDATE");
+                               i_cal_property_remove_parameter_by_name (prop, 
E_CAL_EVOLUTION_ENDDATE_PARAMETER);
                        }
 
                        g_clear_object (&iter);


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