Example #1
0
void
dates_new_cb (GtkWidget *source, DatesData *d)
{
    icalcomponent *comp;
    struct icalperiodtype period;

    if (!dates_view_get_selected_period (d->view, &period)) {
	struct icaltimetype date, now;

	/* Create a default time event */
	date = *(dates_view_get_date (d->view));
	now = icaltime_current_time_with_zone (date.zone);
	date.is_date = FALSE;
	now.is_date = FALSE;
	period.duration = icaldurationtype_null_duration ();
	period.duration.minutes = 0;

	/* New events default to starting at 9am */
	period.duration.hours = 9;
	period.start = icaltime_add (
	    date, period.duration);
		
	/* NOTE: 11 is the magic number where we're viewing a 
	 * month or more. See dates_zoom_change.
	 */
	period.duration.hours = (d->zoom >= 11) ? 8 : 2;
	period.end = icaltime_add (period.start, period.duration);
    }
	
    comp = icalcomponent_new_vevent ();
    icalcomponent_set_dtstart (comp, period.start);
    icalcomponent_set_dtend (comp, period.end);
    icalcomponent_set_summary (comp, _("New event"));
    dates_new (d, comp, TRUE);
}
Example #2
0
void
dates_details_time_end_cb (GtkWidget *source, DatesData *d)
{
    ECalComponentDateTime start, end;
    struct icaltimetype oend;
	
    e_cal_component_get_dtend (d->comp, &end);
    oend = *end.value;
    dates_details_time_cb (d, &end);
	
    /* If end <= start, adjust start */
    e_cal_component_get_dtstart (d->comp, &start);
    if (icaltime_compare (*end.value, *start.value) <= 0) {
	struct icaldurationtype duration =
	    icaltime_subtract (*end.value, oend);
	*start.value = icaltime_add (*end.value, duration);
	e_cal_component_set_dtstart (d->comp, &start);

	dates_details_update_time_label (d, d->details_start_label,
					 start.value);
    }
	
    e_cal_component_set_dtend (d->comp, &end);
    dates_details_update_time_label (d, d->details_end_label,
				     end.value);

    e_cal_component_free_datetime (&end);
    e_cal_component_free_datetime (&start);
}
NS_IMETHODIMP
calPeriod::SetIcalString(const nsACString &aIcalString) {
  if (mImmutable) return NS_ERROR_OBJECT_IS_IMMUTABLE;
  struct icalperiodtype ip;
  ip = icalperiodtype_from_string(PromiseFlatCString(aIcalString).get());
  // XXX Shortcut. Assumes nobody tried to overrule our impl. of calIDateTime
  mStart = new calDateTime(&ip.start, nullptr);
  if (icaltime_is_null_time(ip.end)) {
    struct icaltimetype end;
    end = icaltime_add(ip.start, ip.duration);
    mEnd = new calDateTime(&end, nullptr);
  } else {
    mEnd = new calDateTime(&ip.end, nullptr);
  }
  return NS_OK;
}
Example #4
0
NS_IMETHODIMP
calDateTime::AddDuration(calIDuration *aDuration)
{
    NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
    NS_ENSURE_ARG_POINTER(aDuration);

    icaldurationtype idt;
    aDuration->ToIcalDuration(&idt);
    
    icaltimetype itt;
    ToIcalTime(&itt);

    icaltimetype const newitt = icaltime_add(itt, idt);
    FromIcalTime(&newitt, mTimezone);

    return NS_OK;
}
Example #5
0
void
dates_event_moved_cb (DatesView *view, ECalComponent *comp, DatesData *d)
{
    ECalComponentDateTime start, end;
    struct icaldurationtype duration = icaldurationtype_null_duration ();

    if (d->comp) g_object_unref (d->comp);
    d->comp = g_object_ref (comp);

    e_cal_component_get_dtstart (d->comp, &start);
    if (!start.value->is_date) {
	e_cal_component_get_dtend (d->comp, &end);
	duration = icaltime_subtract (*end.value, *start.value);
	*end.value = icaltime_add (*start.value, duration);
	e_cal_component_set_dtstart (d->comp, &start);
	e_cal_component_set_dtend (d->comp, &end);
	e_cal_component_free_datetime (&end);
    }
    e_cal_component_free_datetime (&start);
    dates_commit_event_cb (NULL, d, CALOBJ_MOD_THIS);
}
NS_IMETHODIMP
calDateTime::AddDuration(calIDuration *aDuration)
{
    NS_ENSURE_FALSE(mImmutable, NS_ERROR_OBJECT_IS_IMMUTABLE);
    NS_ENSURE_ARG_POINTER(aDuration);
    ensureTimezone();

    nsresult rv;
    nsCOMPtr<calIDurationLibical> icaldur = do_QueryInterface(aDuration, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    icaldurationtype idt;
    icaldur->ToIcalDuration(&idt);

    icaltimetype itt;
    ToIcalTime(&itt);

    icaltimetype const newitt = icaltime_add(itt, idt);
    FromIcalTime(&newitt, mTimezone);

    return NS_OK;
}
Example #7
0
/**
 * e_cal_util_get_component_occur_times:
 * @comp: an #ECalComponent
 * @start: (out): Location to store the start time
 * @end: (out): Location to store the end time
 * @tz_cb: (closure tz_cb_data) (scope call): The #ECalRecurResolveTimezoneFn to call
 * @tz_cb_data: (closure): User data to be passed to the @tz_cb callback
 * @default_timezone: The default timezone
 * @kind: the type of component, indicated with an icalcomponent_kind
 *
 * Find out when the component starts and stops, being careful about
 * recurrences.
 *
 * Since: 2.32
 **/
void
e_cal_util_get_component_occur_times (ECalComponent *comp,
                                      time_t *start,
                                      time_t *end,
                                      ECalRecurResolveTimezoneFn tz_cb,
                                      gpointer tz_cb_data,
                                      const icaltimezone *default_timezone,
                                      icalcomponent_kind kind)
{
	struct icalrecurrencetype ir;
	ECalComponentDateTime dt_start, dt_end;

	g_return_if_fail (comp != NULL);
	g_return_if_fail (start != NULL);
	g_return_if_fail (end != NULL);

	e_cal_recur_ensure_end_dates (comp, FALSE, tz_cb, tz_cb_data);

	/* Get dtstart of the component and convert it to UTC */
	e_cal_component_get_dtstart (comp, &dt_start);

	if ((*start = componenttime_to_utc_timet (&dt_start, tz_cb, tz_cb_data, default_timezone)) == -1)
		*start = _TIME_MIN;

	e_cal_component_free_datetime (&dt_start);

	/* find out end date of component */
	*end = _TIME_MAX;

	if (kind == ICAL_VTODO_COMPONENT) {
		/* max from COMPLETED and DUE properties */
		struct icaltimetype *tt = NULL;
		time_t completed_time = -1, due_time = -1, max_time;
		ECalComponentDateTime dt_due;

		e_cal_component_get_completed (comp, &tt);
		if (tt) {
			/* COMPLETED must be in UTC. */
			completed_time = icaltime_as_timet_with_zone (
				*tt, icaltimezone_get_utc_timezone ());
			e_cal_component_free_icaltimetype (tt);
		}

		e_cal_component_get_due (comp, &dt_due);
		if (dt_due.value != NULL)
			due_time = componenttime_to_utc_timet (
				&dt_due, tz_cb, tz_cb_data,
				default_timezone);

		e_cal_component_free_datetime (&dt_due);

		max_time = MAX (completed_time, due_time);

		if (max_time != -1)
			*end = max_time;

	} else {
		/* ALARMS, EVENTS: DTEND and reccurences */

		if (e_cal_component_has_recurrences (comp)) {
			GSList *rrules = NULL;
			GSList *exrules = NULL;
			GSList *elem;
			GSList *rdates = NULL;

			/* Do the RRULEs, EXRULEs and RDATEs*/
			e_cal_component_get_rrule_property_list (comp, &rrules);
			e_cal_component_get_exrule_property_list (comp, &exrules);
			e_cal_component_get_rdate_list (comp, &rdates);

			for (elem = rrules; elem; elem = elem->next) {
				time_t rule_end;
				icaltimezone *utc_zone;
				icalproperty *prop = elem->data;
				ir = icalproperty_get_rrule (prop);

				utc_zone = icaltimezone_get_utc_timezone ();
				rule_end = e_cal_recur_obtain_enddate (
					&ir, prop, utc_zone, TRUE);

				if (rule_end == -1) /* repeats forever */
					*end = _TIME_MAX;
				else if (rule_end > *end) /* new maximum */
					*end = rule_end;
			}

			/* Do the EXRULEs. */
			for (elem = exrules; elem; elem = elem->next) {
				icalproperty *prop = elem->data;
				time_t rule_end;
				icaltimezone *utc_zone;
				ir = icalproperty_get_exrule (prop);

				utc_zone = icaltimezone_get_utc_timezone ();
				rule_end = e_cal_recur_obtain_enddate (
					&ir, prop, utc_zone, TRUE);

				if (rule_end == -1) /* repeats forever */
					*end = _TIME_MAX;
				else if (rule_end > *end)
					*end = rule_end;
			}

			/* Do the RDATEs */
			for (elem = rdates; elem; elem = elem->next) {
				ECalComponentPeriod *p = elem->data;
				time_t rdate_end = _TIME_MAX;

				/* FIXME: We currently assume RDATEs are in the same timezone
				 * as DTSTART. We should get the RDATE timezone and convert
				 * to the DTSTART timezone first. */

				/* Check if the end date or duration is set, libical seems to set
				 * second to -1 to denote an unset time */
				if (p->type != E_CAL_COMPONENT_PERIOD_DATETIME || p->u.end.second != -1)
					rdate_end = icaltime_as_timet (icaltime_add (p->start, p->u.duration));
				else
					rdate_end = icaltime_as_timet (p->u.end);

				if (rdate_end == -1) /* repeats forever */
					*end = _TIME_MAX;
				else if (rdate_end > *end)
					*end = rdate_end;
			}

			e_cal_component_free_period_list (rdates);
		}

		/* Get dtend of the component and convert it to UTC */
		e_cal_component_get_dtend (comp, &dt_end);

		if (dt_end.value) {
			time_t dtend_time;

			dtend_time = componenttime_to_utc_timet (
				&dt_end, tz_cb, tz_cb_data, default_timezone);

			if (dtend_time == -1 || (dtend_time > *end))
				*end = dtend_time;
		}

		e_cal_component_free_datetime (&dt_end);
	}
}
Example #8
0
static void
e_cal_util_remove_instances_ex (icalcomponent *icalcomp,
				struct icaltimetype rid,
				ECalObjModType mod,
				gboolean keep_rid,
				gboolean can_add_exrule)
{
	icalproperty *prop;
	struct icaltimetype itt, recur;
	struct icalrecurrencetype rule;
	icalrecur_iterator *iter;
	GSList *remove_props = NULL, *rrules = NULL, *link;

	g_return_if_fail (icalcomp != NULL);
	g_return_if_fail (mod != E_CAL_OBJ_MOD_ALL);

	/* First remove RDATEs and EXDATEs in the indicated range. */
	for (prop = icalcomponent_get_first_property (icalcomp, ICAL_RDATE_PROPERTY);
	     prop;
	     prop = icalcomponent_get_next_property (icalcomp, ICAL_RDATE_PROPERTY)) {
		struct icaldatetimeperiodtype period;

		period = icalproperty_get_rdate (prop);
		if (time_matches_rid (period.time, rid, mod) && (!keep_rid ||
		    icaltime_compare (period.time, rid) != 0))
			remove_props = g_slist_prepend (remove_props, prop);
	}
	for (prop = icalcomponent_get_first_property (icalcomp, ICAL_EXDATE_PROPERTY);
	     prop;
	     prop = icalcomponent_get_next_property (icalcomp, ICAL_EXDATE_PROPERTY)) {
		itt = icalproperty_get_exdate (prop);
		if (time_matches_rid (itt, rid, mod) && (!keep_rid ||
		    icaltime_compare (itt, rid) != 0))
			remove_props = g_slist_prepend (remove_props, prop);
	}

	for (link = remove_props; link; link = g_slist_next (link)) {
		prop = link->data;

		icalcomponent_remove_property (icalcomp, prop);
	}

	g_slist_free (remove_props);
	remove_props = NULL;

	/* If we're only removing one instance, just add an EXDATE. */
	if (mod == E_CAL_OBJ_MOD_THIS) {
		prop = icalproperty_new_exdate (rid);
		icalcomponent_add_property (icalcomp, prop);
		return;
	}

	/* Otherwise, iterate through RRULEs */
	/* FIXME: this may generate duplicate EXRULEs */
	for (prop = icalcomponent_get_first_property (icalcomp, ICAL_RRULE_PROPERTY);
	     prop;
	     prop = icalcomponent_get_next_property (icalcomp, ICAL_RRULE_PROPERTY)) {
		rrules = g_slist_prepend (rrules, prop);
	}

	for (link = rrules; link; link = g_slist_next (link)) {
		prop = link->data;
		rule = icalproperty_get_rrule (prop);

		iter = icalrecur_iterator_new (rule, rid);
		recur = icalrecur_iterator_next (iter);

		if (mod & E_CAL_OBJ_MOD_THIS_AND_FUTURE) {
			/* Truncate the rule at rid. */
			if (!icaltime_is_null_time (recur)) {
				/* Use count if it was used */
				if (rule.count > 0) {
					gint occurrences_count = 0;
					icalrecur_iterator *count_iter;
					struct icaltimetype count_recur;

					count_iter = icalrecur_iterator_new (rule, icalcomponent_get_dtstart (icalcomp));
					while (count_recur = icalrecur_iterator_next (count_iter), !icaltime_is_null_time (count_recur) && occurrences_count < rule.count) {
						if (icaltime_compare (count_recur, rid) >= 0)
							break;

						occurrences_count++;
					}

					icalrecur_iterator_free (count_iter);

					if (keep_rid && icaltime_compare (count_recur, rid) == 0)
						occurrences_count++;

					/* The caller should make sure that the remove will keep at least one instance */
					g_warn_if_fail (occurrences_count > 0);

					rule.count = occurrences_count;
				} else {
					if (keep_rid && icaltime_compare (recur, rid) == 0)
						rule.until = icaltime_add (rid, icalcomponent_get_duration (icalcomp));
					else
						rule.until = rid;
					icaltime_adjust (&rule.until, 0, 0, 0, -1);
				}

				icalproperty_set_rrule (prop, rule);
				icalproperty_remove_parameter_by_name (prop, "X-EVOLUTION-ENDDATE");
			}
		} else {
			/* (If recur == rid, skip to the next occurrence) */
			if (!keep_rid && icaltime_compare (recur, rid) == 0)
				recur = icalrecur_iterator_next (iter);

			/* If there is a recurrence after rid, add
			 * an EXRULE to block instances up to rid.
			 * Otherwise, just remove the RRULE.
			 */
			if (!icaltime_is_null_time (recur)) {
				if (can_add_exrule) {
					rule.count = 0;
					/* iCalendar says we should just use rid
					 * here, but Outlook/Exchange handle
					 * UNTIL incorrectly.
					 */
					if (keep_rid && icaltime_compare (recur, rid) == 0) {
						struct icaldurationtype duration = icalcomponent_get_duration (icalcomp);
						duration.is_neg = !duration.is_neg;
						rule.until = icaltime_add (rid, duration);
					} else
						rule.until = icaltime_add (rid, icalcomponent_get_duration (icalcomp));
					prop = icalproperty_new_exrule (rule);
					icalcomponent_add_property (icalcomp, prop);
				}
			} else {
				remove_props = g_slist_prepend (remove_props, prop);
			}
		}

		icalrecur_iterator_free (iter);
	}

	for (link = remove_props; link; link = g_slist_next (link)) {
		prop = link->data;

		icalcomponent_remove_property (icalcomp, prop);
	}

	g_slist_free (remove_props);
	g_slist_free (rrules);
}
Example #9
0
static int gn_ical2calnote_real(icalcomponent *comp, gn_calnote *calnote, int id)
{
	int retval = GN_ERR_FAILED;
	struct icaltimetype dtstart = {0}, dtend = {0};
	icalcomponent *compresult = NULL;

	if (id < 1)
		id = 1;

	/* iterate through the component */
	iterate_cal(comp, 0, &id, &compresult, ICAL_VEVENT_COMPONENT);

	if (!compresult) {
		dprintf("No component found.\n");
		retval = GN_ERR_EMPTYLOCATION;
	} else {
		const char *str;
		icalcomponent *alarm = {0};
		icalproperty *rrule;
		struct icalrecurrencetype recur;
		retval = GN_ERR_NONE;

		calnote->phone_number[0] = 0;

		/* type */
		str = comp_get_category(compresult);
		calnote->type = str2calnote_type(str);
		switch (calnote->type) {
		case GN_CALNOTE_CALL:
			/* description goes into text */
			/* TODO: UTF8 --> ascii */
			snprintf(calnote->phone_number, GN_CALNOTE_NUMBER_MAX_LENGTH-1, "%s", icalcomponent_get_summary(compresult));
			str = icalcomponent_get_description(compresult);
			break;
		default:
			/* summary goes into text */
			/* TODO: UTF8 --> ascii */
			str = icalcomponent_get_summary(compresult);
			break;
		}
		if (str) {
			snprintf(calnote->text, GN_CALNOTE_MAX_LENGTH - 1, "%s", str);
		}

		/* start time */
		dtstart = icalcomponent_get_dtstart(compresult);
		if (!icaltime_is_null_time(dtstart)) {
			calnote->time.year = dtstart.year;
			calnote->time.month = dtstart.month;
			calnote->time.day = dtstart.day;
			if (!icaltime_is_date(dtstart)) {
				calnote->time.hour = dtstart.hour;
				calnote->time.minute = dtstart.minute;
				calnote->time.second = dtstart.second;
				/* TODO: what about time zones? */
			}
		}

		/* end time */
		memset(&calnote->end_time, 0, sizeof(calnote->end_time));
		dtend = icalcomponent_get_dtend(compresult);
		if (!icaltime_is_null_time(dtend)) {
			calnote->end_time.year = dtend.year;
			calnote->end_time.month = dtend.month;
			calnote->end_time.day = dtend.day;
			if (!icaltime_is_date(dtend)) {
				calnote->end_time.hour = dtend.hour;
				calnote->end_time.minute = dtend.minute;
				calnote->end_time.second = dtend.second;
				/* TODO: what about time zones? */
			}
		}

		/* alarm */
		alarm = icalcomponent_get_first_component(compresult, ICAL_VALARM_COMPONENT);
		if (alarm) {
			icalproperty *trigger = NULL;

			trigger = icalcomponent_get_first_property(alarm, ICAL_TRIGGER_PROPERTY);
			if (trigger) {
				struct icaltriggertype trigger_value;
				struct icaltimetype alarm_start;
				icalproperty *property;

				trigger_value = icalvalue_get_trigger(icalproperty_get_value(trigger));
				if (icaltriggertype_is_null_trigger(trigger_value) ||
						icaltriggertype_is_bad_trigger(trigger_value)) {
					calnote->alarm.enabled = 0;
				} else {
					if (icaltime_is_null_time(trigger_value.time)) {
						memcpy(&alarm_start, &dtstart, sizeof(struct icaltimetype));
					} else {
						memcpy(&alarm_start, &trigger_value.time, sizeof(struct icaltimetype));
					}
					if (!(icaldurationtype_is_bad_duration(trigger_value.duration) ||
							icaldurationtype_is_null_duration(trigger_value.duration))) {
						alarm_start = icaltime_add(alarm_start, trigger_value.duration);
					}
					calnote->alarm.enabled = 1;
					calnote->alarm.timestamp.year = alarm_start.year;
					calnote->alarm.timestamp.month = alarm_start.month;
					calnote->alarm.timestamp.day = alarm_start.day;
					calnote->alarm.timestamp.hour = alarm_start.hour;
					calnote->alarm.timestamp.minute = alarm_start.minute;
					calnote->alarm.timestamp.second = alarm_start.second;
					/* TODO: time zone? */

					property = icalcomponent_get_first_property(alarm, ICAL_ACTION_PROPERTY);
					calnote->alarm.tone = icalproperty_get_action(property) == ICAL_ACTION_AUDIO ? 1 : 0;
				}
			}
		}

		/* recurrence */
		rrule = icalcomponent_get_first_property(compresult, ICAL_RRULE_PROPERTY);
		if (rrule) {
			recur = icalproperty_get_rrule(rrule);
			calnote->occurrences = recur.count;
			switch (recur.freq) {
			case ICAL_SECONDLY_RECURRENCE:
				dprintf("Not supported recurrence type. Approximating recurrence\n");
				calnote->recurrence = recur.interval / 3600;
				if (!calnote->recurrence)
					calnote->recurrence = 1;
				break;
			case ICAL_MINUTELY_RECURRENCE:
				dprintf("Not supported recurrence type. Approximating recurrence\n");
				calnote->recurrence = recur.interval / 60;
				if (!calnote->recurrence)
					calnote->recurrence = 1;
				break;
			case ICAL_HOURLY_RECURRENCE:
				calnote->recurrence = recur.interval;
				break;
			case ICAL_DAILY_RECURRENCE:
				calnote->recurrence = recur.interval * 24;
				break;
			case ICAL_WEEKLY_RECURRENCE:
				calnote->recurrence = recur.interval * 24 * 7;
				break;
			case ICAL_MONTHLY_RECURRENCE:
				calnote->recurrence = GN_CALNOTE_MONTHLY;
				break;
			case ICAL_YEARLY_RECURRENCE:
				calnote->recurrence = GN_CALNOTE_YEARLY;
				break;
			case ICAL_NO_RECURRENCE:
				calnote->recurrence = GN_CALNOTE_NEVER;
				break;
			default:
				dprintf("Not supported recurrence type. Assuming never\n");
				calnote->recurrence = GN_CALNOTE_NEVER;
				break;
			}
		}

		str = icalcomponent_get_location(compresult);
		if (!str)
			str = "";
		snprintf(calnote->mlocation, sizeof(calnote->mlocation), "%s", str);
	}
	if (compresult) {
#ifdef DEBUG
		char *temp;

		temp = icalcomponent_as_ical_string(compresult);
		dprintf("Component found\n%s\n", temp);
		free(temp);
#endif
		icalcomponent_free(compresult);
	}

	return retval;
}
Example #10
0
void parse_iCal(icalcomponent* comp)
{
  icalcomponent * c;
  icalproperty * rrule;
  icalproperty * exdate;

  icalrecur_iterator * data;
  struct icaldurationtype offset;
  struct icaltimetype time_start;
  struct icaltimetype time_end;
  struct icaltimetype time_next;
  struct icaltimetype exdatetime;
  struct icaltimetype now;
  struct icalrecurrencetype recur;
  int i = 0;
  double duration;

  // Get offset:
  time_t t = time(NULL);
  struct tm lt = {0};
  localtime_r(&t, &lt);
  if (debug_flag)
  {
    printf("Offset to GMT is %lds.\n", lt.tm_gmtoff);
  }
  offset.days = 0;
  offset.weeks = 0;
  offset.hours = 0;
  offset.minutes = 0;
  offset.seconds = 0;
  offset.hours = lt.tm_gmtoff / 3600;
  if (lt.tm_gmtoff < 0) {
   offset.is_neg = 1;
  } else {
   offset.is_neg = 0;
  }

  // Get time now:
  now = icaltime_today();

  // Read each event:
  for (c = icalcomponent_get_first_component(comp,ICAL_VEVENT_COMPONENT) ;
       c != 0 ;
       c = icalcomponent_get_next_component(comp,ICAL_VEVENT_COMPONENT)
  )
  {
    // Get details about the event:
    const char * summary = icalcomponent_get_summary(c);
    const char * description = icalcomponent_get_description(c);

    // Help:
    if (debug_flag)
    {
      if (summary != NULL)
      {
        printf("summary: %s\n", summary);
      }
      if (description != NULL)
      {
        printf("description: %s\n", description);
      }
    }

    // Ranging time:
    time_start = icalcomponent_get_dtstart (c);
    time_end = icalcomponent_get_dtend (c);
    duration = difftime(icaltime_as_timet(time_end), icaltime_as_timet(time_start));

    // Rules:
    rrule = icalcomponent_get_first_property(c,ICAL_RRULE_PROPERTY);
    recur = icalproperty_get_rrule(rrule);
    data = icalrecur_iterator_new (recur, time_start);

    // Find next event:
    while (1)
    {
      time_next = icalrecur_iterator_next (data);

      if (icaltime_is_null_time(time_next) == 1) break;
      if (icaltime_compare(time_next, now) >= 0) break;
    }

    // Help:
    if (debug_flag)
    {
      dump_icaltimetype("time start", time_start);
      dump_icaltimetype("time end", time_end);
      dump_icaltimetype("until", recur.until);
      dump_icaltimetype("time next", time_next);
    }

    // One shot event:
    if (
      icaltime_is_null_time(time_next) == 1
      &&
      icaltime_compare(time_start, now) < 0
    )
    {
      if (debug_flag) printf ("event (one shot) is in the past\n");
      continue;
    }

    // Old event: discard recurent events finished before today...
    if (
      icaltime_is_null_time(recur.until) == 0
      &&
      icaltime_compare(recur.until, now) < 0
    )
    {
      if (debug_flag) printf ("event is recurent in the past ...\n");
      continue;
    }

    // Some help:
    if (debug_flag > 2)
    {
      dump_icalrecurrencetype(recur);
    }


    // Set time and hours:
    struct icaltimetype local_time_start = icaltime_add(time_start, offset);
    printf ("%d	%d	", local_time_start.minute, local_time_start.hour);

    // Set option depending of recurence:
    switch (recur.freq)
    {
      // Weekly: OK but need to remove days not needed... ?
      case ICAL_WEEKLY_RECURRENCE:
        printf ("%s", "*	*	");
        for (i = 0; recur.by_day[i] != 32639; i++)
        {
          printf ("%02d", icalrecurrencetype_day_day_of_week(recur.by_day[i]) -1);
          if (recur.by_day[i+1] != 32639)
          {
            printf ("%s", ",");
          }
        }
        printf ("%s", "	");
        break;

      // Happening each month:
      case ICAL_MONTHLY_RECURRENCE:
        // The Xth of the month:
        if (recur.by_month_day[0] != 32639)
        {
          printf ("%02d	*	*	", recur.by_month_day[0]);
        }

        // Day of the week:
        else
        {
            printf ("%d	%d	*	", time_next.day, time_next.month);
        }
        break;


      // Event happening each year ...  OK???
      // OK: one shoot.
      case ICAL_YEARLY_RECURRENCE:
      case ICAL_NO_RECURRENCE:
      default:
        printf ("%02d	%02d	*	", 
          local_time_start.day,
          local_time_start.month
        );
    }



    // How many valid exclude dates:
    exdate = icalcomponent_get_first_property(c, ICAL_EXDATE_PROPERTY);
    unsigned int num_ex = 0;
    if (exdate != NULL)
    {
      for (; exdate != NULL; exdate = icalcomponent_get_next_property(c, ICAL_EXDATE_PROPERTY) )
      {
        exdatetime = icalvalue_get_datetime(icalproperty_get_value(exdate));
        if (icaltime_compare(exdatetime, now) >= 0)
        {
          num_ex++;
        }
      }
    }
    if (num_ex > 0)
    {
      exdate = icalcomponent_get_first_property(c, ICAL_EXDATE_PROPERTY);
      for (; exdate != NULL; exdate = icalcomponent_get_next_property(c, ICAL_EXDATE_PROPERTY) )
      {
        exdatetime = icalvalue_get_datetime(icalproperty_get_value(exdate));
        if (icaltime_compare(exdatetime, now) >= 0)
        {
          struct icaltimetype local_exdatetime = icaltime_add(exdatetime, offset);
          printf ("%s", "[ \"$(date \"+\\\%Y\\\%m\\\%d\")\" = \"");
          printf ("%04d%02d%02d", local_exdatetime.year, local_exdatetime.month, local_exdatetime.day);
          printf ("%s", "\" ] || ");
        }
      }
    }

    // And the action:
    printf ("%s %.0f\n", 
      summary,
      duration
    );

    icalrecur_iterator_free (data);
  }
}