/* cal-backend-wcap-events.c * * Copyright (C) 2002-2004 Sun Microsystems, Inc * * AUTHORS * Jack Jia * Harry Lu * Alfred Peng * Jedy Wang * Rodrigo Moya * JP Rosevear * */ #ifdef HAVE_CONFIG_H #include #endif #include #include #include "cal-backend-wcap-events.h" static CalBackendWCAPClass *parent_class = NULL; #define d(x) G_DEFINE_TYPE (CalBackendWCAPEvents, cal_backend_wcap_events, CAL_BACKEND_WCAP_TYPE) static ECalComponent * find_master_event (CalBackendWCAP *wcap, ECalComponent *comp) { const char *unmangled_uid; ECalComponent *master_comp = NULL; GList *ilist; sunone_util_unmangle_uid (comp); e_cal_component_get_uid (comp, &unmangled_uid); if ((ilist = g_hash_table_lookup (cal_backend_wcap_get_instances (wcap), unmangled_uid))) { master_comp = ilist->data; } sunone_util_mangle_uid (comp); return master_comp; } static ECalComponent * find_old_event (CalBackendWCAP *wcap, ECalComponent *comp) { const char *uid; ECalComponent *tmp_comp; e_cal_component_get_uid (comp, &uid); if ((tmp_comp = g_hash_table_lookup (cal_backend_wcap_get_objects (wcap), uid))) { return tmp_comp; } else { return NULL; } } static void process_modified_recurrence (CalBackendWCAP *wcap, ECalComponent *comp, CalObjModType mod) { ECalComponentDateTime dtstart, dtend; ECalComponentDateTime old_dtstart, old_dtend; ECalComponentDateTime master_dtstart, master_dtend; struct icaldurationtype dur; ECalComponent *old_comp; ECalComponent *master_comp; ECalComponentRange recur_id; gboolean allday = FALSE; /* all modified recurrences should exist? */ old_comp = find_old_event (wcap, comp); if (!old_comp) return; /* all modified recurrences should have master? */ master_comp = find_master_event (wcap, old_comp); if (!master_comp) return; if (CALOBJ_MOD_ALL != mod) return; e_cal_component_get_recurid (master_comp, &recur_id); if(!recur_id.datetime.value) return; e_cal_component_set_recurid (comp, &recur_id); e_cal_component_free_range (&recur_id); e_cal_component_get_dtstart (comp, &dtstart); e_cal_component_get_dtend (comp, &dtend); e_cal_component_get_dtstart (old_comp, &old_dtstart); e_cal_component_get_dtend (old_comp, &old_dtend); e_cal_component_get_dtstart (master_comp, &master_dtstart); e_cal_component_get_dtend (master_comp, &master_dtend); if (dtstart.value && dtstart.value->is_date) { if (dtend.value && dtend.value->is_date) allday = TRUE; if (!dtend.value) { allday = TRUE; } } if (!old_dtend.value->is_date) old_dtend.value->day = old_dtend.value->day + 1; old_dtstart.value->is_date = TRUE; old_dtend.value->is_date = TRUE; if (!master_dtend.value->is_date) master_dtend.value->day = master_dtend.value->day + 1; master_dtstart.value->is_date = TRUE; master_dtend.value->is_date = TRUE; /* same time zone as the master */ if (master_dtstart.tzid) { g_free ((char *)dtstart.tzid); dtstart.tzid = g_strdup (master_dtstart.tzid); } dur = icaltime_subtract (*master_dtstart.value, *old_dtstart.value); dtstart.value->is_date = FALSE; *dtstart.value = icaltime_add (*dtstart.value, dur); dtstart.value->is_utc = FALSE; if (master_dtend.tzid) { g_free ((char *)dtend.tzid); dtend.tzid = g_strdup (master_dtend.tzid); } dur = icaltime_subtract (*master_dtend.value, *old_dtend.value); dtend.value->is_date = FALSE; *dtend.value = icaltime_add (*dtend.value, dur); dtend.value->is_utc = FALSE; if (allday) { dtstart.value->is_date = TRUE; dtend.value->is_date = TRUE; } e_cal_component_set_dtstart (comp, &dtstart); e_cal_component_set_dtend (comp, &dtend); e_cal_component_free_datetime (&master_dtstart); e_cal_component_free_datetime (&master_dtend); e_cal_component_free_datetime (&old_dtstart); e_cal_component_free_datetime (&old_dtend); e_cal_component_free_datetime (&dtstart); e_cal_component_free_datetime (&dtend); } static void process_events_component_to_server (CalBackendWCAP *wcap, ECalComponent *comp, gboolean *relativeAlarm, gboolean *allday) { ECalComponentDateTime dt,dtstart,dtend; ECalComponentOrganizer organizer; icalcomponent *icalcomp; icalproperty *prop; icaltimezone *zone = NULL, *old_zone = NULL; char *location = NULL; if (allday) *allday = FALSE; /* Check for all day event and get starting timezone (if there is one) */ e_cal_component_get_dtstart (comp, &dtstart); e_cal_component_get_dtend (comp, &dtend); if (allday && dtstart.value && dtstart.value->is_date) { if (dtend.value && dtend.value->is_date) *allday = TRUE; if (!dtend.value) *allday = TRUE; if (*allday) { icaltimezone_convert_time (dtstart.value, cal_backend_wcap_get_default_zone (wcap), cal_backend_wcap_get_server_default_zone (wcap)); g_free ((char *)dtstart.tzid); dtstart.tzid = g_strdup (icaltimezone_get_tzid (cal_backend_wcap_get_server_default_zone (wcap))); dtstart.value->hour = 0; dtstart.value->minute = 0; dtstart.value->second = 0; dtstart.value->is_date = TRUE; dtstart.value->is_utc = FALSE; e_cal_component_set_dtstart (comp, &dtstart); icaltimezone_convert_time (dtend.value, cal_backend_wcap_get_default_zone (wcap), cal_backend_wcap_get_server_default_zone (wcap)); g_free ((char *)dtend.tzid); dtend.tzid = g_strdup (icaltimezone_get_tzid (cal_backend_wcap_get_server_default_zone (wcap))); dtend.value->hour = 0; dtend.value->minute = 0; dtend.value->second = 0; dtend.value->is_date = TRUE; dtend.value->is_utc = FALSE; e_cal_component_set_dtend (comp, &dtend); zone = cal_backend_wcap_get_server_default_zone (wcap); } } /* Ok, Sunone can't handle other timezones, so, we make a * guess as to the timezone intended, if we fail, we convert * it to the default server side timezone for this calendar */ if (dtstart.value && dtstart.tzid && allday && !(*allday)) { zone = cal_backend_wcap_get_timezone_from_tzid (wcap, dtstart.tzid, TRUE); if (!zone) { zone = icaltimezone_get_builtin_timezone_from_tzid (dtstart.tzid); if (zone) { icaltimezone *local_zone; location = icaltimezone_get_location (zone); local_zone = cal_backend_wcap_get_timezone_from_tzid (wcap, location, TRUE); if (!local_zone) local_zone = cal_backend_wcap_get_server_default_zone (wcap); icaltimezone_convert_time (dtstart.value, zone, local_zone); g_free ((char *)dtstart.tzid); dtstart.tzid = g_strdup (icaltimezone_get_tzid (local_zone)); e_cal_component_set_dtstart (comp, &dtstart); zone = local_zone; } } } e_cal_component_free_datetime (&dtstart); e_cal_component_free_datetime (&dtend); if (zone) location = icaltimezone_get_tzid (zone); /* Convert other Date-Time values to the same zone as the start time */ if (zone) { e_cal_component_get_dtend (comp, &dt); if (dt.value && dt.tzid) { old_zone = e_cal_backend_internal_get_timezone (E_CAL_BACKEND (wcap), dt.tzid); icaltimezone_convert_time (dt.value, old_zone, zone); g_free ((char *)dt.tzid); dt.tzid = g_strdup (icaltimezone_get_tzid (zone)); e_cal_component_set_dtend (comp, &dt); } e_cal_component_free_datetime (&dt); } if (zone) { e_cal_component_get_due (comp, &dt); if (dt.value && dt.tzid) { old_zone = e_cal_backend_internal_get_timezone (E_CAL_BACKEND (wcap), dt.tzid); icaltimezone_convert_time (dt.value, old_zone, zone); g_free ((char *)dt.tzid); dt.tzid = g_strdup (icaltimezone_get_tzid (zone)); e_cal_component_set_due (comp, &dt); } e_cal_component_free_datetime (&dt); } /* Fix exdates to be UTC and date/times */ if (e_cal_component_has_exdates (comp)) { GSList *exdate_list, *l; e_cal_component_get_exdate_list (comp, &exdate_list); for (l = exdate_list; l != NULL; l = l->next) { ECalComponentDateTime *ex; icaltimezone *from_zone, *to_zone; e_cal_component_get_dtstart (comp, &dt); ex = l->data; /* make exdates use the same timezone as dtstart */ if (dt.tzid) { g_free ((char *)ex->tzid); ex->tzid = g_strdup (dt.tzid); } if (allday && *allday) { ex->value->is_date = TRUE; if (dt.tzid == NULL) from_zone = icaltimezone_get_utc_timezone (); else from_zone = e_cal_backend_internal_get_timezone (E_CAL_BACKEND (wcap), dt.tzid); to_zone = icaltimezone_get_utc_timezone (); icaltimezone_convert_time (ex->value, from_zone, to_zone); ex->value->is_utc = TRUE; e_cal_component_free_datetime (&dt); continue; } ex->value->hour = dt.value->hour; ex->value->minute = dt.value->minute; ex->value->second = dt.value->second; ex->value->is_date = FALSE; if (dt.tzid == NULL) from_zone = icaltimezone_get_utc_timezone (); else from_zone = e_cal_backend_internal_get_timezone (E_CAL_BACKEND (wcap), dt.tzid); to_zone = icaltimezone_get_utc_timezone (); icaltimezone_convert_time (ex->value, from_zone, to_zone); ex->value->is_utc = TRUE; e_cal_component_free_datetime (&dt); } e_cal_component_set_exdate_list (comp, exdate_list); e_cal_component_free_recur_list (exdate_list); } /* Alarms */ if (e_cal_component_has_alarms (comp)) { GList *auids, *l; icaltimezone *utc_zone = icaltimezone_get_utc_timezone (); e_cal_component_get_dtstart (comp, &dtstart); e_cal_component_get_dtend (comp, &dtend); if (dtstart.value) { dtstart.value->is_date = 0; icaltimezone_convert_time (dtstart.value, zone ? zone : cal_backend_wcap_get_default_zone (wcap), utc_zone); if (dtend.value) { dtend.value->is_date = 0; icaltimezone_convert_time (dtend.value, zone ? zone : cal_backend_wcap_get_default_zone (wcap), utc_zone); } auids = e_cal_component_get_alarm_uids (comp); for (l = auids; l != NULL; l = l->next) { const char *auid = l->data; ECalComponentAlarm *alarm; ECalComponentAlarmTrigger trigger; ECalComponentAlarmAction action; struct icaltimetype t; int is_neg; alarm = e_cal_component_get_alarm (comp, auid); e_cal_component_alarm_get_trigger (alarm, &trigger); e_cal_component_alarm_get_action (alarm, &action); if (trigger.type == E_CAL_COMPONENT_ALARM_TRIGGER_NONE || trigger.type == E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE) { e_cal_component_alarm_free (alarm); continue; } switch (trigger.type) { case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_START: if (!IS_WCAP_2_0(wcap)) { e_cal_component_alarm_free (alarm); if (relativeAlarm) *relativeAlarm = TRUE; continue; } t = *dtstart.value; break; case E_CAL_COMPONENT_ALARM_TRIGGER_RELATIVE_END: if (dtend.value) t = *dtend.value; else t = *dtstart.value; break; default : t = *dtstart.value; break; } trigger.type = E_CAL_COMPONENT_ALARM_TRIGGER_ABSOLUTE; is_neg = trigger.u.rel_duration.is_neg; t = icaltime_add(t, trigger.u.rel_duration); trigger.u.abs_time = t; trigger.u.abs_time.is_utc = 1; e_cal_component_alarm_set_trigger (alarm, trigger); e_cal_component_alarm_free (alarm); } cal_obj_uid_list_free (auids); } e_cal_component_free_datetime (&dtstart); e_cal_component_free_datetime (&dtend); } /*if a meeting, set email address to calid*/ e_cal_component_get_organizer (comp, &organizer); if (organizer.value) { if (!strncasecmp ("mailto:", organizer.value, 7)) { const char *temp = organizer.value + 7; if (!strcasecmp (temp, cal_backend_wcap_get_account_email (wcap))) { organizer.value = cal_backend_wcap_get_calid (wcap); e_cal_component_set_organizer (comp, &organizer); } } } /*if there is no attendee, clear organizer*/ if(!e_cal_component_has_attendees (comp)) { e_cal_component_set_organizer (comp, NULL); } e_cal_component_abort_sequence (comp); /* Set x properties */ icalcomp = e_cal_component_get_icalcomponent (comp); prop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY); while (prop) { const char *x_name, *x_val; x_name = icalproperty_get_x_name (prop); x_val = icalproperty_get_x (prop); if (!strcmp (x_name, "X-NSCP-DTSTART-TZID") && location) { icalproperty_set_x (prop, location); location = NULL; } prop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY); } if (location) { prop = icalproperty_new_x (location); icalproperty_set_x_name (prop, "X-NSCP-DTSTART-TZID"); icalcomponent_add_property (icalcomp, prop); } e_cal_component_abort_sequence (comp); } ECalBackendSyncStatus cal_backend_wcap_events_update_objects (ECalBackendSync *backend, EDataCal *cal, const char *calobj, CalObjModType mod, char **old_object, char **new_object) { ECalBackendSyncStatus result = GNOME_Evolution_Calendar_Success; CalBackendWCAP *wcap = CAL_BACKEND_WCAP (backend); ECalComponent *comp; icalcomponent *toplevel_comp, *subcomp; icalcomponent_kind kind; gboolean hasImport = FALSE; gboolean relativeAlarm = FALSE; g_return_val_if_fail (IS_CAL_BACKEND_WCAP (wcap), GNOME_Evolution_Calendar_OtherError); if (!cal_backend_wcap_is_online (wcap)) return GNOME_Evolution_Calendar_RepositoryOffline; if (!cal_backend_wcap_get_connection (wcap)) return cal_backend_wcap_get_open_error (wcap); toplevel_comp = icalparser_parse_string (calobj); if (!toplevel_comp) return GNOME_Evolution_Calendar_InvalidObject; kind = icalcomponent_isa (toplevel_comp); if (kind == ICAL_VEVENT_COMPONENT) { icalcomponent *icalcomp; icalproperty *prop; /* Create a temporary toplevel component and put the VEVENT in it, to simplify the code below. */ icalcomp = toplevel_comp; prop = icalcomponent_get_first_property (icalcomp, ICAL_X_PROPERTY); while (prop) { const char *x_name; x_name = icalproperty_get_x_name (prop); if (!strcmp (x_name, "X-NSCP-GSE-COMPONENT-STATE")) { icalcomponent_remove_property (icalcomp, prop); break; } prop = icalcomponent_get_next_property (icalcomp, ICAL_X_PROPERTY); } toplevel_comp = e_cal_util_new_top_level (); icalcomponent_add_component (toplevel_comp, icalcomp); } else if (kind != ICAL_VCALENDAR_COMPONENT) { /* We don't support this type of component */ icalcomponent_free (toplevel_comp); return GNOME_Evolution_Calendar_InvalidObject; } subcomp = icalcomponent_get_first_component (toplevel_comp, ICAL_ANY_COMPONENT); comp = e_cal_component_new (); while (subcomp) { /* We ignore anything except VEVENT and VJOURNAL components. */ icalcomponent_kind child_kind = icalcomponent_isa (subcomp); if (child_kind == ICAL_VEVENT_COMPONENT) { icalcomponent *return_icalcomp, *return_subcomp; const char *uid; gboolean allday, expand; guint error_code; SunOneMethod method; e_cal_component_set_icalcomponent (comp, subcomp); /* recurrences need special process */ process_modified_recurrence (wcap, comp, mod); /* Fix up the component for the server */ process_events_component_to_server (wcap, comp, &relativeAlarm, &allday); if (cal_backend_wcap_need_import (wcap, comp)) { result = cal_backend_wcap_handle_import (wcap, comp, mod, toplevel_comp, subcomp, child_kind); subcomp = icalcomponent_get_next_component (toplevel_comp, ICAL_ANY_COMPONENT); hasImport = TRUE; continue; } if (mod == CALOBJ_MOD_ALL) expand = TRUE; else expand = FALSE; e_cal_component_get_uid (comp, &uid); /* Unmangle the uid so its the right uid */ if (e_cal_component_is_instance (comp)) sunone_util_unmangle_uid (comp); /* Get the uid for verification */ e_cal_component_get_uid (comp, &uid); /* Guess the method */ method = cal_backend_wcap_guess_method (wcap, cal, comp); error_code = sunone_connection_storeevents (cal_backend_wcap_get_connection (wcap), cal_backend_wcap_get_calid (wcap), subcomp, method, cal_backend_wcap_to_sunone_mod (mod, comp), expand, allday, &return_icalcomp, cal_backend_wcap_get_account_email (wcap)); cal_backend_wcap_verify_exists_uid (wcap, uid); e_cal_component_set_icalcomponent (comp, NULL); if (!SUNONE_ERROR_IS_SUCCESSFUL (error_code)) { result = cal_backend_wcap_result_from_error (error_code); subcomp = icalcomponent_get_next_component (toplevel_comp, ICAL_ANY_COMPONENT); continue; } return_subcomp = icalcomponent_get_first_component (return_icalcomp, child_kind); while (return_subcomp) { cal_backend_wcap_add_component (wcap, return_subcomp, TRUE, old_object, new_object); return_subcomp = icalcomponent_get_next_component (return_icalcomp, child_kind); } icalcomponent_free (return_icalcomp); } subcomp = icalcomponent_get_next_component (toplevel_comp, ICAL_ANY_COMPONENT); } g_object_unref (G_OBJECT (comp)); icalcomponent_free (toplevel_comp); if (hasImport || relativeAlarm) cal_backend_wcap_poll_cb (wcap); else cal_backend_wcap_write_cache (wcap); return result; } static ECalBackendSyncStatus cal_backend_wcap_events_create_object (ECalBackendSync *backend, EDataCal *cal, char **calobj, char **uid) { ECalBackendSyncStatus result = GNOME_Evolution_Calendar_Success; CalObjModType mod = CALOBJ_MOD_ALL; g_return_val_if_fail (calobj != NULL, GNOME_Evolution_Calendar_InvalidObject); d(printf("cal_backend_wcap_events_create_object(%p, %s)\n", backend, *calobj)); result = cal_backend_wcap_events_update_objects (backend, cal, *calobj, mod, NULL, NULL); /* *calobj = NULL; */ return result; } static ECalBackendSyncStatus cal_backend_wcap_events_modify_object (ECalBackendSync *backend, EDataCal *cal, const char *calobj, CalObjModType mod, char **old_object, char **new_object) { ECalBackendSyncStatus result = GNOME_Evolution_Calendar_Success; g_return_val_if_fail (calobj != NULL, GNOME_Evolution_Calendar_InvalidObject); d(printf("cal_backend_wcap_events_modify_object(%p, %s)\n", backend, calobj)); result = cal_backend_wcap_events_update_objects (backend, cal, calobj, mod, old_object, new_object); return result; } static ECalBackendSyncStatus cal_backend_wcap_events_remove_object (ECalBackendSync *backend, EDataCal *cal, const char *uid, const char *rid, CalObjModType mod, char **old_object, char **object) { CalBackendWCAP *wcap = CAL_BACKEND_WCAP (backend); ECalComponent *comp; icalcomponent *icalcomp; ECalBackendSyncStatus status; const char *unmangled_uid; guint error_code; char *calobj; d(printf("cal_backend_wcap_evnets_remove_object(%p, %s, %s)\n", backend, uid, rid)); if (!cal_backend_wcap_is_online (wcap)) return GNOME_Evolution_Calendar_RepositoryOffline; if (!cal_backend_wcap_get_connection (wcap)) return cal_backend_wcap_get_open_error (wcap); status = E_CAL_BACKEND_SYNC_CLASS (parent_class)->get_object_sync (backend, cal, uid, rid, &calobj); if (status != GNOME_Evolution_Calendar_Success) return status; icalcomp = icalcomponent_new_from_string (calobj); if (!icalcomp) { g_free (calobj); return GNOME_Evolution_Calendar_InvalidObject; } comp = e_cal_component_new (); e_cal_component_set_icalcomponent (comp, icalcomp); sunone_util_unmangle_uid (comp); e_cal_component_get_uid (comp, &unmangled_uid); rid = cal_backend_wcap_get_rid_string (comp); error_code = sunone_connection_deleteevents_by_id (cal_backend_wcap_get_connection (wcap), cal_backend_wcap_get_calid (wcap), unmangled_uid, rid, cal_backend_wcap_to_sunone_mod (mod, comp)); g_object_unref (G_OBJECT (comp)); if (!SUNONE_ERROR_IS_SUCCESSFUL (error_code)) { g_free (calobj); return cal_backend_wcap_result_from_error (error_code); } cal_backend_wcap_remove_component (wcap, uid, mod, old_object); g_free (calobj); cal_backend_wcap_write_cache (wcap); return GNOME_Evolution_Calendar_Success; } static void get_fb_info (SunOneConnection *so_cnc, const char *user, const char *calid, time_t start, time_t end, GList **freebusy) { icalcomponent *icalcomp, *fb; icaltimezone *utc_zone; guint error_code; const char *user_calid; if (!so_cnc) return; utc_zone = icaltimezone_get_utc_timezone (); if (strchr (user, '@')) { /*if user is account's email, change it to calid*/ CalBackendWCAP *wcap = NULL; char *key = g_strconcat (calid, ":calendar", NULL); const char *user_mail; if (!strncasecmp (user, "mailto:", 7)) user_mail = user + 7; else user_mail = user; wcap = sunone_connection_get_wcap (so_cnc, key); g_free (key); if(wcap && !strcasecmp (cal_backend_wcap_get_account_email (wcap), user_mail)) user_calid = cal_backend_wcap_get_calid (wcap); else user_calid = user_mail; } else user_calid = user; error_code = sunone_connection_get_freebusy (so_cnc, user_calid, icaltime_from_timet_with_zone (start, FALSE, utc_zone), icaltime_from_timet_with_zone (end, FALSE, utc_zone), &icalcomp); if (!SUNONE_ERROR_IS_SUCCESSFUL (error_code)) return; fb = icalcomponent_get_first_component (icalcomp, ICAL_VFREEBUSY_COMPONENT); if (fb) { icalproperty *prop; prop = icalproperty_new_organizer (user); if (prop != NULL) icalcomponent_add_property (fb, prop); *freebusy = g_list_append (*freebusy, g_strdup (icalcomponent_as_ical_string (fb))); } icalcomponent_free (icalcomp); } static ECalBackendSyncStatus cal_backend_wcap_events_get_freebusy (ECalBackendSync *backend, EDataCal *cal, GList *users, time_t start, time_t end, GList **freebusy) { GList *l; CalBackendWCAP *wcap = CAL_BACKEND_WCAP (backend); g_return_val_if_fail (freebusy != NULL, GNOME_Evolution_Calendar_InvalidObject); g_return_val_if_fail (IS_CAL_BACKEND_WCAP (wcap), GNOME_Evolution_Calendar_OtherError); d(printf("cal_backend_wcap_get_freebusy(%p)\n", backend)); if (!cal_backend_wcap_is_online (wcap)) return GNOME_Evolution_Calendar_RepositoryOffline; if (!cal_backend_wcap_get_connection (wcap)) return cal_backend_wcap_get_open_error (wcap); if (!users) { get_fb_info (cal_backend_wcap_get_connection (wcap), cal_backend_wcap_get_calid (wcap), cal_backend_wcap_get_calid (wcap), start, end, freebusy); } else { for (l = users; l != NULL; l = l->next) get_fb_info (cal_backend_wcap_get_connection (wcap), l->data, cal_backend_wcap_get_calid (wcap), start, end, freebusy); } return GNOME_Evolution_Calendar_Success; } static ECalBackendSyncStatus cal_backend_wcap_events_receive_objects (ECalBackendSync *backend, EDataCal *cal, const char *calobj) { ECalBackendSyncStatus result = GNOME_Evolution_Calendar_Success; CalBackendWCAP *wcap = CAL_BACKEND_WCAP (backend); icalcomponent *toplevel_comp; icalcomponent_kind kind; guint error_code; g_return_val_if_fail (calobj != NULL, GNOME_Evolution_Calendar_InvalidObject); d(printf("cal_backend_wcap_receive_objects(%p, %p, %s)\n", backend, cal, calobj)); g_return_val_if_fail (IS_CAL_BACKEND_WCAP (wcap), GNOME_Evolution_Calendar_OtherError); if (!cal_backend_wcap_is_online (wcap)) return GNOME_Evolution_Calendar_RepositoryOffline; if (!cal_backend_wcap_get_connection (wcap)) return cal_backend_wcap_get_open_error (wcap); toplevel_comp = icalparser_parse_string (calobj); if (!toplevel_comp) return GNOME_Evolution_Calendar_InvalidObject; kind = icalcomponent_isa (toplevel_comp); if (kind == ICAL_VEVENT_COMPONENT) { icalcomponent *icalcomp; /* Create a temporary toplevel component and put the VEVENT in it, to simplify the code below. */ icalcomp = toplevel_comp; toplevel_comp = e_cal_util_new_top_level (); icalcomponent_add_component (toplevel_comp, icalcomp); } else if (kind != ICAL_VCALENDAR_COMPONENT){ /* We don't support this type of component */ icalcomponent_free (toplevel_comp); return GNOME_Evolution_Calendar_InvalidObject; } error_code = sunone_connection_import (cal_backend_wcap_get_connection (wcap), cal_backend_wcap_get_calid (wcap), toplevel_comp); if (!SUNONE_ERROR_IS_SUCCESSFUL (error_code)) result = cal_backend_wcap_result_from_error (error_code); cal_backend_wcap_poll_cb (wcap); icalcomponent_free (toplevel_comp); return result; } static void e_cal_backend_wcap_events_dispose(GObject *object) { if (G_OBJECT_CLASS (parent_class)->dispose) (*G_OBJECT_CLASS (parent_class)->dispose) (object); } static void e_cal_backend_wcap_events_finalize(GObject *object) { if (G_OBJECT_CLASS (parent_class)->finalize) (*G_OBJECT_CLASS (parent_class)->finalize) (object); } static void cal_backend_wcap_events_class_init (CalBackendWCAPEventsClass *klass) { GObjectClass *object_class; ECalBackendClass *backend_class; ECalBackendSyncClass *sync_class; object_class = G_OBJECT_CLASS (klass); backend_class = E_CAL_BACKEND_CLASS (klass); sync_class = E_CAL_BACKEND_SYNC_CLASS (klass); parent_class = g_type_class_peek_parent (klass); sync_class->create_object_sync = cal_backend_wcap_events_create_object; sync_class->modify_object_sync = cal_backend_wcap_events_modify_object; sync_class->remove_object_sync = cal_backend_wcap_events_remove_object; sync_class->get_freebusy_sync = cal_backend_wcap_events_get_freebusy; sync_class->receive_objects_sync = cal_backend_wcap_events_receive_objects; object_class->dispose = e_cal_backend_wcap_events_dispose; object_class->finalize = e_cal_backend_wcap_events_finalize; } static void cal_backend_wcap_events_init (CalBackendWCAPEvents *klass) { }