+2005-07-08 Chenthill Palanisamy <pchenthill@novell.com>
+
+ * backends/groupwise/e-cal-backend-groupwise.c
+ (e_cal_backend_groupwise_remove_object): Use removeItemsRequest
+ for removing all the recurring posted appointments.
+ (get_gw_item_id): Get the item id from the component.
+ (get_deltas): Commented the read cursors request to get the icalids,
+ since we need recurrece keys as we use it as the uid for recurrence items.
+ Get the component from cache using uid and rid.
+ * e-cal.c (e_cal_remove_object): Used CALOBJ_MOD_THIS since we are just removing
+ one component.
+
+2005-07-08 Harish Krishnaswamy <kharish@novell.com>
+
+ * backends/groupwise/e-cal-backend-groupwise-utils.c:
+ (set_rrule_from_comp), (set_properties_from_cal_component),
+ (e_gw_item_to_cal_component), (e_gw_connection_send_appointment):
+ add support for creation of recurrence items by sending the
+ recurrence formula to the server instead of generating the
+ instances at the client end.
+ * backends/groupwise/e-cal-backend-groupwise.c:
+ (e_cal_backend_groupwise_get_static_capabilities):
+ add capability RECURRENCES_NO_MASTER.
+ (e_cal_backend_groupwise_remove_object): add support for
+ removing all instances of a recurrence at one shot.
+ * libecal/e-cal-util.h: Add a static capability
+ RECURRENCES_NO_MASTER. Backends that do not use master objects
+ to represent recurrence information and store them as individual
+ instances.
+ * libecal/e-cal.c: (e_cal_get_recurrences_no_master)
+ (e_cal_generate_instances_for_object): Do not expand instances for objects from
+ backends that do not have master object to represent recurrences.
+ * libecal/e-cal.h:
+ * libedata-cal/e-cal-backend-cache.[ch]
+ (e_cal_backend_cache_get_components_by_uid): Function to
+ fetch all items in the cache that have the same uid. (recurrence
+ items, detached instances etc.)
+
2005-07-08 Sankar P <psankar@novell.com>
* backends/groupwise/e-cal-backend-groupwise.c: (get_deltas)
}
+static void
+set_rrule_from_comp (ECalComponent *comp, EGwItem *item, ECalBackendGroupwise *cbgw)
+{
+
+ EGwItemRecurrenceRule *item_rrule;
+ struct icalrecurrencetype *ical_recur;
+ GSList *rrule_list = NULL, *exdate_list;
+ int i;
+
+ item_rrule = g_new0 (EGwItemRecurrenceRule, 1);
+ e_cal_component_get_rrule_list (comp, &rrule_list);
+ if (rrule_list) {
+ /* assumes only one rrule is present */
+ ical_recur = (struct icalrecurrencetype *) rrule_list->data;
+
+ g_message ("DEBUG: Processing rule\n%s\n", icalrecurrencetype_as_string (ical_recur));
+ /*set the data */
+ switch (ical_recur->freq) {
+ case ICAL_DAILY_RECURRENCE :
+ item_rrule->frequency = E_GW_ITEM_RECURRENCE_FREQUENCY_DAILY;
+ break;
+ case ICAL_WEEKLY_RECURRENCE:
+ item_rrule->frequency = E_GW_ITEM_RECURRENCE_FREQUENCY_WEEKLY;
+ break;
+ case ICAL_MONTHLY_RECURRENCE:
+ item_rrule->frequency = E_GW_ITEM_RECURRENCE_FREQUENCY_MONTHLY;
+ break;
+ case ICAL_YEARLY_RECURRENCE:
+ item_rrule->frequency = E_GW_ITEM_RECURRENCE_FREQUENCY_YEARLY;
+ break;
+ default:
+ break;
+ }
+ if (ical_recur->count != 0)
+ item_rrule->count = ical_recur->count;
+ else
+ item_rrule->until = g_strdup (icaltime_as_ical_string (ical_recur->until));
+
+ item_rrule->interval = ical_recur->interval;
+
+ /*xxx -byday, bymonthday and byyearday not handled FIXME*/
+ for (i = 0; i < ICAL_BY_DAY_SIZE; i++)
+ item_rrule->by_day[i] = ical_recur->by_day[i];
+ for (i = 0; i < ICAL_BY_MONTHDAY_SIZE; i++)
+ item_rrule->by_month_day[i] = ical_recur->by_month_day[i];
+ for (i = 0; i < ICAL_BY_YEARDAY_SIZE; i++)
+ item_rrule->by_year_day[i] = ical_recur->by_year_day[i];
+ for (i = 0; i < ICAL_BY_MONTH_SIZE; i++)
+ item_rrule->by_month[i] = ical_recur->by_month[i];
+
+ e_gw_item_set_rrule (item, item_rrule);
+
+ /* set exceptions */
+ if (e_cal_component_has_exdates (comp)) {
+ GSList *l, *item_exdate_list = NULL;
+ icaltimezone *default_zone, *utc;
+ struct icaltimetype itt_utc;
+
+
+ e_cal_component_get_exdate_list (comp, &exdate_list);
+ default_zone = e_cal_backend_groupwise_get_default_zone (cbgw);
+ utc = icaltimezone_get_utc_timezone ();
+ for (l = exdate_list; l ; l = l->next) {
+ ECalComponentDateTime *dt = (ECalComponentDateTime *) l->data;
+ if (dt->value) {
+ if (!icaltime_get_timezone (*(dt->value)))
+ icaltime_set_timezone (dt->value, default_zone ? default_zone : utc);
+ itt_utc = icaltime_convert_to_zone (*dt->value, utc);
+ item_exdate_list = g_slist_append (item_exdate_list, g_strdup (icaltime_as_ical_string (itt_utc)));
+ }
+ }
+ e_gw_item_set_exdate_list (item, item_exdate_list);
+ e_cal_component_free_exdate_list (exdate_list);
+ }
+ }
+}
+
static EGwItem *
set_properties_from_cal_component (EGwItem *item, ECalComponent *comp, ECalBackendGroupwise *cbgw)
{
/* check if recurrences exist and update the item */
if (e_cal_component_has_recurrences (comp)) {
+ if (e_cal_component_has_rrules (comp))
+ set_rrule_from_comp (comp, item, cbgw);
+ else {
- GSList *recur_dates = NULL;
-
- if (dt.tzid)
- e_cal_recur_generate_instances (comp, -1, -1,get_recur_instance, &recur_dates, resolve_tzid_cb, NULL, (icaltimezone *) default_zone);
- else
- e_cal_recur_generate_instances (comp, -1, -1,get_recur_instance, &recur_dates, resolve_tzid_cb, NULL, utc);
+ GSList *recur_dates = NULL;
+
+ if (dt.tzid)
+ e_cal_recur_generate_instances (comp, -1, -1,get_recur_instance, &recur_dates, resolve_tzid_cb, NULL, (icaltimezone *) default_zone);
+ else
+ e_cal_recur_generate_instances (comp, -1, -1,get_recur_instance, &recur_dates, resolve_tzid_cb, NULL, utc);
- recur_dates = g_slist_delete_link (recur_dates, recur_dates);
-
- e_gw_item_set_recurrence_dates (item, recur_dates);
- }
+ recur_dates = g_slist_delete_link (recur_dates, recur_dates);
+
+ e_gw_item_set_recurrence_dates (item, recur_dates);
+ }
+ }
/* attachments */
if (e_cal_component_has_attachments (comp)) {
e_cal_component_set_attachment_list (comp, comp_attachment_list);
}
+
ECalComponent *
e_gw_item_to_cal_component (EGwItem *item, ECalBackendGroupwise *cbgw)
{
icalcomponent_add_property (e_cal_component_get_icalcomponent (comp), icalprop);
}
- /* UID */
- uid = e_gw_item_get_icalid (item);
- if (uid)
- e_cal_component_set_uid (comp, e_gw_item_get_icalid (item));
- else {
- g_object_unref (comp);
- return NULL;
- }
-
+
if (e_gw_item_get_reply_request (item)) {
char *reply_within;
const char *mess = e_gw_item_get_message (item);
else
return NULL;
+ /* UID */
+ if (e_gw_item_get_recurrence_key (item) != 0) {
+
+ ECalComponentRange *recur_id;
+ char *recur_key = g_strdup_printf ("%d", e_gw_item_get_recurrence_key (item));
+
+ e_cal_component_set_uid (comp, (const char *) recur_key);
+ g_free (recur_key);
+
+ /* set the recurrence id and the X-GW-RECORDID too */
+ recur_id = g_new0 (ECalComponentRange, 1);
+ recur_id->type = E_CAL_COMPONENT_RANGE_SINGLE;
+ recur_id->datetime = dt;
+ e_cal_component_set_recurid (comp, recur_id);
+
+ } else {
+
+ uid = e_gw_item_get_icalid (item);
+ if (uid)
+ e_cal_component_set_uid (comp, e_gw_item_get_icalid (item));
+ else {
+ g_object_unref (comp);
+ return NULL;
+ }
+ }
/* classification */
description = e_gw_item_get_classification (item);
EGwConnectionStatus status;
icalparameter_partstat partstat;
char *item_id;
-
+ gboolean all_instances = FALSE;
+ icalproperty *icalprop;
+ icalcomponent *icalcomp;
+ const char *recurrence_key = NULL;
cnc = e_cal_backend_groupwise_get_connection (cbgw);
g_return_val_if_fail (E_IS_GW_CONNECTION (cnc), E_GW_CONNECTION_STATUS_INVALID_CONNECTION);
/* When the icalcomponent is obtained through the itip message rather
* than from the SOAP protocol, the container id has to be explicitly
* added to the xgwrecordid inorder to obtain the item id. */
-
- switch (e_cal_component_get_vtype (comp)) {
- case E_CAL_COMPONENT_EVENT:
- item_id = g_strconcat (e_cal_component_get_gw_id (comp), GW_EVENT_TYPE_ID, container, NULL);
- break;
- case E_CAL_COMPONENT_TODO:
- item_id = g_strconcat (e_cal_component_get_gw_id (comp), GW_TODO_TYPE_ID, container, NULL);
- break;
- default:
- return E_GW_CONNECTION_STATUS_INVALID_OBJECT;
+
+ /* handle recurrences - All */
+ icalcomp = e_cal_component_get_icalcomponent (comp);
+
+ icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
+ while (icalprop) {
+ const char *x_name;
+
+ x_name = icalproperty_get_x_name (icalprop);
+ if (!strcmp (x_name, "X-GW-RECUR-INSTANCE-MOD-TYPE")) {
+ if (!strcmp (icalproperty_get_x (icalprop), "All"))
+ all_instances = TRUE;
+ if (recurrence_key)
+ break;
+ }
+ if (!strcmp (x_name, "X-GW-RECURRENCE-KEY")) {
+ recurrence_key = icalproperty_get_x (icalprop);
+ }
+ icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
+ }
+
+ if (all_instances) {
+ switch (e_cal_component_get_vtype (comp)) {
+ case E_CAL_COMPONENT_EVENT:
+ item_id = g_strconcat (e_cal_component_get_gw_id (comp), GW_EVENT_TYPE_ID, container, NULL);
+ break;
+ case E_CAL_COMPONENT_TODO:
+ item_id = g_strconcat (e_cal_component_get_gw_id (comp), GW_TODO_TYPE_ID, container, NULL);
+ break;
+ default:
+ return E_GW_CONNECTION_STATUS_INVALID_OBJECT;
+ }
}
+
switch (method) {
case ICAL_METHOD_REQUEST:
/* get attendee here and add the list along. */
case ICAL_PARTSTAT_ACCEPTED:
e_cal_component_get_transparency (comp, &transp);
- if (transp == E_CAL_COMPONENT_TRANSP_OPAQUE)
- status = e_gw_connection_accept_request (cnc, item_id, "Busy");
- else
- status = e_gw_connection_accept_request (cnc, item_id, "Free");
+ if (transp == E_CAL_COMPONENT_TRANSP_OPAQUE) {
+ if (all_instances)
+ status = e_gw_connection_accept_request_by_recurrence_key (cnc, recurrence_key, "Busy", NULL);
+ else
+ status = e_gw_connection_accept_request (cnc, item_id, "Busy");
+ }
+ else {
+ if (all_instances)
+ status = e_gw_connection_accept_request_by_recurrence_key (cnc, recurrence_key, "Free", NULL);
+ else
+ status = e_gw_connection_accept_request (cnc, item_id, "Free");
+ }
break;
case ICAL_PARTSTAT_DECLINED:
- status = e_gw_connection_decline_request (cnc, item_id);
+ if (all_instances)
+ status = e_gw_connection_decline_request_by_recurrence_key (cnc, recurrence_key, NULL);
+ else
+ status = e_gw_connection_decline_request (cnc, item_id);
*remove = TRUE;
break;
case ICAL_PARTSTAT_TENTATIVE:
- status = e_gw_connection_accept_request (cnc, item_id, "Tentative");
+ if (all_instances)
+ status = e_gw_connection_accept_request_by_recurrence_key (cnc, recurrence_key, "Tentative", NULL);
+ else
+ status = e_gw_connection_accept_request (cnc, item_id, "Tentative");
break;
case ICAL_PARTSTAT_COMPLETED:
status = e_gw_connection_complete_request (cnc, item_id);
if (status == E_GW_CONNECTION_STATUS_ITEM_ALREADY_ACCEPTED)
return status;
+ /*FIXME - handling recurrence items */
if (!*remove && status == E_GW_CONNECTION_STATUS_OK) {
EGwItem *item;
item = E_GW_ITEM(item_list->data);
ECalComponent *modified_comp = NULL, *cache_comp = NULL;
char *cache_comp_str = NULL;
-
+ const char *uid, *rid = NULL;
modified_comp = e_gw_item_to_cal_component (item, cbgw);
if (!modified_comp) {
g_message ("Invalid component returned in update");
continue;
}
- cache_comp = e_cal_backend_cache_get_component (cache, e_gw_item_get_icalid (item), NULL);
+ if ((r_key = e_gw_item_get_recurrence_key (item)) != 0)
+ rid = e_cal_component_get_recurid_as_string (modified_comp)
+
+ e_cal_component_get_uid (modified_comp, &uid);
+ cache_comp = e_cal_backend_cache_get_component (cache, uid, rid);
e_cal_component_commit_sequence (modified_comp);
e_cal_component_commit_sequence (cache_comp);
cache_comp_str = NULL;
}
e_cal_backend_cache_put_component (cache, modified_comp);
+
g_object_unref (item);
g_object_unref (modified_comp);
}
g_list_free (item_list);
item_list = NULL;
}
-
+
+ /* TODO currently the read cursors response does not give us the recurrencKey, uncomment
+ this once the response gives the recurrenceKey */
+#if 0
+ /* handle deleted items here by going over the entire cache and
+ * checking for deleted items.*/
position = E_GW_CURSOR_POSITION_END;
cursor = 0;
- status = e_gw_connection_create_cursor (cnc, cbgw->priv->container_id, "iCalId", NULL, &cursor);
+ status = e_gw_connection_create_cursor (cnc, cbgw->priv->container_id, "iCalId recurrenceKey", NULL, &cursor);
if (status != E_GW_CONNECTION_STATUS_OK) {
if (status == E_GW_CONNECTION_STATUS_NO_RESPONSE) {
return TRUE;
}
- /* handle deleted items here by going over the entire cache and
- * checking for deleted items.*/
-
cache_keys = e_cal_backend_cache_get_keys (cache);
done = FALSE;
while (!done) {
g_slist_free (cache_keys);
item_list = NULL;
}
+#endif
g_static_mutex_unlock (&connecting);
CAL_STATIC_CAPABILITY_NO_CONV_TO_ASSIGN_TASK "," \
CAL_STATIC_CAPABILITY_NO_CONV_TO_RECUR "," \
CAL_STATIC_CAPABILITY_REQ_SEND_OPTIONS "," \
+ CAL_STATIC_CAPABILITY_SAVE_SCHEDULES "," \
CAL_STATIC_CAPABILITY_ORGANIZER_MUST_ACCEPT "," \
CAL_STATIC_CAPABILITY_DELEGATE_SUPPORTED "," \
CAL_STATIC_CAPABILITY_DELEGATE_TO_MANY "," \
CAL_STATIC_CAPABILITY_NO_ORGANIZER "," \
+ CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER "," \
CAL_STATIC_CAPABILITY_SAVE_SCHEDULES);
return GNOME_Evolution_Calendar_Success;
return GNOME_Evolution_Calendar_Success;
}
+static const char *
+get_gw_item_id (icalcomponent *icalcomp)
+{
+ icalproperty *icalprop;
+
+ /* search the component for the X-GWRECORDID property */
+ icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
+ while (icalprop) {
+ const char *x_name, *x_val;
+
+ x_name = icalproperty_get_x_name (icalprop);
+ x_val = icalproperty_get_x (icalprop);
+ if (!strcmp (x_name, "X-GWRECORDID")) {
+ return x_val;
+ }
+
+ icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
+ }
+ return NULL;
+}
+
/* Remove_object handler for the file backend */
static ECalBackendSyncStatus
e_cal_backend_groupwise_remove_object (ECalBackendSync *backend, EDataCal *cal,
if (priv->mode == CAL_MODE_REMOTE) {
ECalBackendSyncStatus status;
const char *id_to_remove = NULL;
- icalproperty *icalprop;
icalcomponent *icalcomp;
- status = e_cal_backend_groupwise_get_object (backend, cal, uid, rid, &calobj);
- if (status != GNOME_Evolution_Calendar_Success)
- return status;
-
- *old_object = strdup (calobj);
+ if (mod == CALOBJ_MOD_THIS) {
- icalcomp = icalparser_parse_string (calobj);
- if (!icalcomp) {
- g_free (calobj);
- return GNOME_Evolution_Calendar_InvalidObject;
- }
+ status = e_cal_backend_groupwise_get_object (backend, cal, uid, rid, &calobj);
+ if (status != GNOME_Evolution_Calendar_Success)
+ return status;
- /* search the component for the X-GWRECORDID property */
- icalprop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY);
- while (icalprop) {
- const char *x_name, *x_val;
+ *old_object = strdup (calobj);
- x_name = icalproperty_get_x_name (icalprop);
- x_val = icalproperty_get_x (icalprop);
- if (!strcmp (x_name, "X-GWRECORDID")) {
- id_to_remove = x_val;
- break;
+ icalcomp = icalparser_parse_string (calobj);
+ if (!icalcomp) {
+ g_free (calobj);
+ return GNOME_Evolution_Calendar_InvalidObject;
+ }
+
+ id_to_remove = get_gw_item_id (icalcomp);
+ if (!id_to_remove) {
+ /* use the iCalId to remove the object */
+ id_to_remove = uid;
}
- icalprop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY);
- }
+ /* remove the object */
+ status = e_gw_connection_remove_item (priv->cnc, priv->container_id, id_to_remove);
- if (!id_to_remove) {
- /* use the iCalId to remove the object */
- id_to_remove = uid;
- }
+ if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
+ status = e_gw_connection_remove_item (priv->cnc, priv->container_id, id_to_remove);
+
+ icalcomponent_free (icalcomp);
+ if (status == E_GW_CONNECTION_STATUS_OK) {
+ /* remove the component from the cache */
+ if (!e_cal_backend_cache_remove_component (priv->cache, uid, rid)) {
+ g_free (calobj);
+ return GNOME_Evolution_Calendar_ObjectNotFound;
+ }
+ *object = NULL;
+ g_free (calobj);
+ return GNOME_Evolution_Calendar_Success;
+ } else {
+ g_free (calobj);
+ return GNOME_Evolution_Calendar_OtherError;
+ }
+ } else if (mod == CALOBJ_MOD_ALL) {
+ GSList *l, *comp_list = e_cal_backend_cache_get_components_by_uid (priv->cache, uid);
- /* remove the object */
- status = e_gw_connection_remove_item (priv->cnc, priv->container_id, id_to_remove);
+ if (e_cal_component_has_attendees (E_CAL_COMPONENT (comp_list->data))) {
+ /* get recurrence key and send it to
+ * e_gw_connection_remove_recurrence_item */
+ status = e_gw_connection_decline_request_by_recurrence_key (priv->cnc, uid, NULL);
+ if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
+ status = e_gw_connection_decline_request_by_recurrence_key (priv->cnc, uid, NULL);
+ } else {
+ GList *item_ids;
+ for (l = comp_list; l; l = l->next) {
+ ECalComponent *comp = E_CAL_COMPONENT (l->data);
+
+ id_to_remove = get_gw_item_id (e_cal_component_get_icalcomponent (comp));
+ item_ids = g_list_append (item_ids, (char *) id_to_remove);
+ }
+ status = e_gw_connection_remove_items (priv->cnc, priv->container_id, item_ids);
+
+ if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
+ status = e_gw_connection_remove_items (priv->cnc, priv->container_id, item_ids);
+ }
- if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
- status = e_gw_connection_remove_item (priv->cnc, priv->container_id, id_to_remove);
+ if (status == E_GW_CONNECTION_STATUS_OK) {
- icalcomponent_free (icalcomp);
- if (status == E_GW_CONNECTION_STATUS_OK) {
- /* remove the component from the cache */
- if (!e_cal_backend_cache_remove_component (priv->cache, uid, rid)) {
- g_free (calobj);
- return GNOME_Evolution_Calendar_ObjectNotFound;
+ for (l = comp_list; l; l = l->next) {
+ ECalComponent *comp = E_CAL_COMPONENT (l->data);
+ e_cal_backend_cache_remove_component (priv->cache, uid,
+ e_cal_component_get_recurid_as_string (comp));
+ e_cal_backend_notify_object_removed (E_CAL_BACKEND (cbgw),
+ uid, e_cal_component_get_as_string (comp), NULL);
+ g_object_unref (comp);
+
+ }
+ /* Setting NULL would trigger another signal.
+ * We do not set the *object to NULL */
+ g_slist_free (comp_list);
+ return GNOME_Evolution_Calendar_Success;
+ } else {
+ return GNOME_Evolution_Calendar_OtherError;
}
- *object = NULL;
- g_free (calobj);
- return GNOME_Evolution_Calendar_Success;
- } else {
- g_free (calobj);
- return GNOME_Evolution_Calendar_OtherError;
- }
+ } else
+ return GNOME_Evolution_Calendar_UnsupportedMethod;
} else if (priv->mode == CAL_MODE_LOCAL) {
in_offline (cbgw);
return GNOME_Evolution_Calendar_RepositoryOffline;
- }
-
- /* remove the component from the cache */
- if (!e_cal_backend_cache_remove_component (priv->cache, uid, rid)) {
- g_free (calobj);
- return GNOME_Evolution_Calendar_ObjectNotFound;
- }
-
- g_free (calobj);
- return GNOME_Evolution_Calendar_Success;
+ } else
+ return GNOME_Evolution_Calendar_CalListener_MODE_NOT_SUPPORTED;
+
}
static void
if (e_cal_component_has_attachments (comp))
fetch_attachments (cbgw, comp);
+ modif_comp = comp;
status = e_gw_connection_send_appointment (cbgw, priv->container_id, comp, method, &remove, &modif_comp);
if (status == E_GW_CONNECTION_STATUS_INVALID_CONNECTION)
#define CAL_STATIC_CAPABILITY_NO_CONV_TO_RECUR "no-conv-to-recur"
#define CAL_STATIC_CAPABILITY_NO_GEN_OPTIONS "no-general-options"
#define CAL_STATIC_CAPABILITY_REQ_SEND_OPTIONS "require-send-options"
+#define CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER "recurrences-no-master-object"
#define CAL_STATIC_CAPABILITY_ORGANIZER_MUST_ACCEPT "organizer-must-accept"
#define CAL_STATIC_CAPABILITY_DELEGATE_SUPPORTED "delegate-support"
#define CAL_STATIC_CAPABILITY_NO_ORGANIZER "no-organizer"
}
/**
+ * e_cal_get_recurrences_no_master:
+ * @ecal: A calendar client.
+ *
+ * Checks if the calendar has a master object for recurrences.
+ *
+ * Return value: TRUE if the calendar has a master object for recurrences,
+ * FALSE otherwise.
+ */
+gboolean
+e_cal_get_recurrences_no_master (ECal *ecal)
+{
+ g_return_val_if_fail (ecal != NULL, FALSE);
+ g_return_val_if_fail (E_IS_CAL (ecal), FALSE);
+
+ return check_capability (ecal, CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER);
+}
+
+/**
* e_cal_get_static_capability:
* @ecal: A calendar client.
* @cap: Name of the static capability to check.
return retval;
}
-
/* This is used in the callback which fetches all the timezones needed for an
object. */
typedef struct _ECalGetTimezonesData ECalGetTimezonesData;
comp = e_cal_component_new ();
e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (icalcomp));
+ /*If the backend stores it as individual instances and does not
+ * have a master object - do not expand*/
+ if (e_cal_get_static_capability (ecal, CAL_STATIC_CAPABILITY_RECURRENCES_NO_MASTER)) {
+ time_t start, end;
+ /*return the same instance */
+ result = (* cb) (comp, icaltime_as_timet_with_zone (icalcomponent_get_dtstart (icalcomp), ecal->priv->default_zone),
+ icaltime_as_timet_with_zone (icalcomponent_get_dtend (icalcomp), ecal->priv->default_zone), cb_data);
+ g_object_unref (comp);
+ return;
+ }
+
e_cal_component_get_uid (comp, &uid);
rid = e_cal_component_get_recurid_as_string (comp);
e_return_error_if_fail (ecal && E_IS_CAL (ecal), E_CALENDAR_STATUS_INVALID_ARG);
e_return_error_if_fail (uid, E_CALENDAR_STATUS_INVALID_ARG);
- return e_cal_remove_object_with_mod (ecal, uid, NULL, CALOBJ_MOD_ALL, error);
+ return e_cal_remove_object_with_mod (ecal, uid, NULL, CALOBJ_MOD_THIS, error);
}
/**
gboolean e_cal_set_default_source (ESource *source, ECalSourceType type, GError **error);
gboolean e_cal_get_sources (ESourceList **sources, ECalSourceType type, GError **error);
const char * e_cal_get_local_attachment_store (ECal *ecal);
-
+gboolean e_cal_get_recurrences_no_master (ECal *ecal);
G_END_DECLS
#endif
}
/**
+ * e_cal_backend_cache_get_components_by_uid:
+ * @cache: An #ECalBackendCache object.
+ * @uid: ID of the component to retrieve.
+ *
+ * Retrieves a ical components from the cache.
+ *
+ * Return value: The list of calendar components if found, or NULL otherwise.
+ */
+GSList *
+e_cal_backend_cache_get_components_by_uid (ECalBackendCache *cache, const char *uid)
+{
+ char *comp_str;
+ GSList *l;
+ GSList *list = NULL;
+ icalcomponent *icalcomp;
+ ECalComponent *comp = NULL;
+
+ /* return null if cache is not a valid Backend Cache. */
+ g_return_val_if_fail (E_IS_CAL_BACKEND_CACHE (cache), NULL);
+ l = e_file_cache_get_objects (E_FILE_CACHE (cache));
+ if (!l)
+ return NULL;
+ for ( ; l != NULL; l = g_slist_next (l)) {
+ comp_str = l->data;
+ if (comp_str) {
+ icalcomp = icalparser_parse_string (comp_str);
+ if (icalcomp) {
+ icalcomponent_kind kind;
+
+ kind = icalcomponent_isa (icalcomp);
+ if (kind == ICAL_VEVENT_COMPONENT || kind == ICAL_VTODO_COMPONENT) {
+ comp = e_cal_component_new ();
+ if ((e_cal_component_set_icalcomponent (comp, icalcomp)) &&
+ !strcmp (icalcomponent_get_uid (icalcomp), uid))
+ list = g_slist_append (list, comp);
+ else {
+ g_object_unref (comp);
+ }
+ } else
+ icalcomponent_free (icalcomp);
+ }
+ }
+
+ }
+
+ return list;
+}
+
+/**
* e_cal_backend_cache_get_timezone:
* @cache: An #ECalBackendCache object.
* @tzid: ID of the timezone to retrieve.
const char *uid,
const char *rid);
GList *e_cal_backend_cache_get_components (ECalBackendCache *cache);
+GSList *e_cal_backend_cache_get_components_by_uid (ECalBackendCache *cache, const char *uid);
+
const icaltimezone *e_cal_backend_cache_get_timezone (ECalBackendCache *cache, const char *tzid);