Пример #1
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);
}
Пример #2
0
void ical_property_EXDATE(struct exchange2ical *exchange2ical)
{
	uint32_t	i;
	uint32_t	j;
	uint8_t		modified;
	struct icaltimetype	icaltime;
	struct icaltimetype	dttime;

	icalproperty	*prop;
	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;

	/* Sanity check */
	if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0x0)) return;
	if (!pat) return;
	if (!pat->DeletedInstanceCount) return;

	for (i = 0; i < pat->DeletedInstanceCount; i++) {
		modified=0;
		if(pat->ModifiedInstanceDates && pat->ModifiedInstanceCount){
			for(j=0; j < pat->ModifiedInstanceCount; j++){
				if(pat->ModifiedInstanceDates[j]==pat->DeletedInstanceDates[i]){
					modified=1;
					break;
				}
			}
		}
		/* If this is an all-day appointment */
		if (!modified && exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
			struct tm	tm;
			tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]);
			icaltime= get_icaldate_from_tm(&tm);
			prop = icalproperty_new_exdate(icaltime);
			icalcomponent_add_property(exchange2ical->vevent, prop);
		} else if (!modified){
			/* number of minutes between midnight of the specified
			* day and midnight, January 1, 1601 */
			struct tm	tm;
			tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]);
			icaltime= get_icaltimetype_from_tm(&tm);

			if (exchange2ical->TimeZoneDesc) {
				/*Get time from dtstart*/
				if (exchange2ical->apptEndWhole){
					dttime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
					icaltime.hour   = dttime.hour;
					icaltime.minute = dttime.minute;
				}

				prop = icalproperty_new_exdate(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
				icalparameter *tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
				icalproperty_add_parameter(prop, tzid);
			} else {
				/*Get time from dtstart*/
				icaltime.is_utc = 1;
				if (exchange2ical->apptEndWhole){
					dttime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
					icaltime.hour   = dttime.hour;
					icaltime.minute = dttime.minute;
				}
				prop = icalproperty_new_exdate(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
			}
		}		
		
	}
}