Re: [Evolution-hackers] calendar status
- From: Dan Winship <danw ximian com>
- To: Rodrigo Moya <rodrigo ximian com>
- Cc: Evolution Hackers <evolution-hackers ximian com>
- Subject: Re: [Evolution-hackers] calendar status
- Date: Wed, 15 Oct 2003 09:15:50 -0400
> * recurrences: I've got lot of code done for this, but not finished yet,
> since I have left it apart for a few days to fix all the new-ui-branch
> problems. But I think once everything starts working correctly, I should
> be done with the recurrence stuff in 2/3 days more.
Doh. I hope we're not duplicating each other's work. I've also been
doing recurrence stuff for Connector. Here's some of what I've written
(I was planning to move these functions to cal-util.)
struct instance_data {
time_t start;
gboolean found;
}
static void
check_instance (icalcomponent *comp, struct icaltime_span span, void *data)
{
struct instance_data instance = data;
if (span.start == instance->start)
instance->found = TRUE;
}
/**
* cal_util_construct_instance:
* @comp: a recurring #icalcomponent
* @rid: the RECURRENCE-ID to construct a component for
*
* This checks that @rid indicates a valid recurrence of @comp, and
* if so, generates a copy of @comp containing a RECURRENCE-ID of @rid.
*
* Return value: the instance, or %NULL
**/
icalcomponent *
cal_util_construct_instance (icalcomponent *comp,
struct icaltimetype rid)
{
struct instance_data instance;
struct icaltimetype start, end;
/* Make sure this is really recurring */
if (!icalcomponent_get_first_property (comp, ICAL_RRULE_PROPERTY) &&
!icalcomponent_get_first_property (comp, ICAL_RDATE_PROPERTY))
return NULL;
/* Make sure the specified instance really exists */
/* FIXME: does the libical recurrence code work correctly now? */
start = icaltime_convert_to_zone (rid, icaltimezone_get_utc_timezone ());
end = start;
icaltime_adjust (&end, 0, 0, 0, 1);
instance.start = icaltime_as_timet (start);
instance.found = FALSE;
icalcomponent_foreach_recurrence (comp, start, end,
check_instance, &instance);
if (!instance.found)
return NULL;
/* Make the instance */
comp = icalcomponent_clone (comp);
icalcomponent_set_recurrenceid (comp, rid);
return comp;
}
static inline gboolean
time_matches_rid (struct icaltimetype itt, struct icaltimetype rid,
CalObjModType mod)
{
int compare;
compare = icaltime_compare (itt, rid);
if (compare == 0)
return TRUE;
else if (compare < 0 && (mod & CALOBJ_MOD_THISANDPRIOR))
return TRUE;
else if (compare > 0 && (mod & CALOBJ_MOD_THISANDFUTURE))
return TRUE;
else
return FALSE;
}
/**
* cal_util_remove_instances:
* @comp: a (recurring) #icalcomponent
* @rid: the base RECURRENCE-ID to remove
* @mod: how to interpret @rid
*
* Removes one or more instances from @comp according to @rid and @mod.
*
* FIXME: should probably have a return value indicating whether or not
* @comp still has any instances
**/
void
cal_util_remove_instances (icalcomponent *comp,
struct icaltimetype rid,
CalObjModType mod)
{
icalproperty *prop;
struct icaltimetype itt, recur;
struct icalrecurrencetype rule;
icalrecur_iterator *iter;
struct instance_data instance;
g_return_if_fail (mod != CALOBJ_MOD_ALL);
/* First remove RDATEs and EXDATEs in the indicated range. */
for (prop = icalcomponent_get_first_property (comp, ICAL_RDATE_PROPERTY);
prop;
prop = icalcomponent_get_next_property (comp, ICAL_RDATE_PROPERTY)) {
itt = icalproperty_get_rdate (prop);
if (time_matches_rid (itt, rid, mod))
icalcomponent_remove_property (comp, prop);
}
for (prop = icalcomponent_get_first_property (comp, ICAL_EXDATE_PROPERTY);
prop;
prop = icalcomponent_get_next_property (comp, ICAL_EXDATE_PROPERTY)) {
itt = icalproperty_get_exdate (prop);
if (time_matches_rid (itt, rid, mod))
icalcomponent_remove_property (comp, prop);
}
/* If we're only removing one instance, just add an EXDATE. */
if (mod == CALOBJ_MOD_THIS) {
prop = icalproperty_new_exdate (rid);
icalcomponent_add_property (comp, prop);
return;
}
/* Otherwise, iterate through RRULEs */
/* FIXME: this may generate duplicate EXRULEs */
for (prop = icalcomponent_get_first_property (comp, ICAL_RRULE_PROPERTY);
prop;
prop = icalcomponent_get_next_property (comp, ICAL_RRULE_PROPERTY)) {
rule = icalproperty_get_rrule (prop);
iter = icalrecur_iterator_new (rule, rid);
recur = icalrecur_iterator_next (iter);
if (mod & CALOBJ_MOD_THISANDFUTURE) {
/* If there is a recurrence on or after rid,
* use the UNTIL parameter to truncate the rule
* at rid.
*/
if (!icaltime_is_null_time (recur)) {
rule.count = 0;
rule.until = rid;
icaltime_adjust (&rule.until, 0, 0, 0, -1);
icalproperty_set_rrule (prop, rule);
}
} else {
/* (If recur == rid, skip to the next occurrence) */
if (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)) {
rule.count = 0;
/* iCalendar says we should just use rid
* here, but Outlook/Exchange handle
* UNTIL incorrectly.
*/
rule.until = icaltime_add (rid, icalcomponent_get_duration (comp));
prop = icalproperty_new_exrule (rule);
icalcomponent_add_property (prop);
} else
icalcomponent_remove_property (prop);
}
icalrecur_iterator_free (iter);
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]