icalcomponent *icalbdbset_fetch_match(icalset *set, icalcomponent *comp) { icalbdbset *bset = (icalbdbset *) set; icalcompiter i; struct icalbdbset_id comp_id, match_id; icalerror_check_arg_rz((bset != 0), "bset"); comp_id = icalbdbset_get_id(comp); for (i = icalcomponent_begin_component(bset->cluster, ICAL_ANY_COMPONENT); icalcompiter_deref(&i) != 0; icalcompiter_next(&i)) { icalcomponent *match = icalcompiter_deref(&i); match_id = icalbdbset_get_id(match); if (strcmp(comp_id.uid, match_id.uid) == 0 && (comp_id.recurrence_id == 0 || strcmp(comp_id.recurrence_id, match_id.recurrence_id) == 0)) { /* HACK. What to do with SEQUENCE? */ icalbdbset_id_free(&match_id); icalbdbset_id_free(&comp_id); return match; } icalbdbset_id_free(&match_id); } icalbdbset_id_free(&comp_id); return 0; }
icalerrorenum icaldirset_remove_component(icalset *set, icalcomponent *comp) { icaldirset *dset; icalcomponent *filecomp; icalcompiter i; int found = 0; icalerror_check_arg_re((set != 0), "set", ICAL_BADARG_ERROR); icalerror_check_arg_re((comp != 0), "comp", ICAL_BADARG_ERROR); dset = (icaldirset *) set; icalerror_check_arg_re((dset->cluster != 0), "Cluster pointer", ICAL_USAGE_ERROR); filecomp = icalcluster_get_component(dset->cluster); for (i = icalcomponent_begin_component(filecomp, ICAL_ANY_COMPONENT); icalcompiter_deref(&i) != 0; icalcompiter_next(&i)) { icalcomponent *this = icalcompiter_deref(&i); if (this == comp) { found = 1; break; } } if (found != 1) { icalerror_warn("icaldirset_remove_component: component is not part of current cluster"); icalerror_set_errno(ICAL_USAGE_ERROR); return ICAL_USAGE_ERROR; } (void)icalcluster_remove_component(dset->cluster, comp); /* icalcluster_mark(impl->cluster); */ /* If the removal emptied the fileset, get the next fileset */ if (icalcluster_count_components(dset->cluster, ICAL_ANY_COMPONENT) == 0) { icalerrorenum error = icaldirset_next_cluster(dset); if (dset->cluster != 0 && error == ICAL_NO_ERROR) { (void)icalcluster_get_first_component(dset->cluster); } else { /* HACK. Not strictly correct for impl->cluster==0 */ return error; } } else { /* Do nothing */ } return ICAL_NO_ERROR; }
/* This function is called recursively, since objects may be embedded in a * single VCALENDAR component or each in its own. Returns 0 on an empty set, * 1 -- otherwise. */ static int iterate_cal(icalcomponent *parent, int depth, int *count, icalcomponent **result, icalcomponent_kind kind) { icalcomponent *comp = NULL; icalcompiter compiter; if (!parent) return 0; /* we need to use iterators because we're calling iterate_cal recursively */ compiter = icalcomponent_begin_component(parent, ICAL_ANY_COMPONENT); comp = icalcompiter_deref(&compiter); for (; comp && *count; comp = icalcompiter_next(&compiter)) { if (icalcomponent_isa(comp) == kind) { /* FIXME: should we only consider items with category GNOKII? */ (*count)--; } if (!*count) { *result = comp; dprintf("Found component at depth %d\n", depth); break; } iterate_cal(comp, depth+1, count, result, kind); } return 1; }
/* This removes all components except VTODOs and VTIMEZONEs from the toplevel icalcomponent, and adds the given list of VTODO components. The list is freed afterwards. */ static void prepare_tasks (icalcomponent *icalcomp, GList *vtodos) { icalcomponent *subcomp; GList *elem; icalcompiter iter; iter = icalcomponent_begin_component (icalcomp, ICAL_ANY_COMPONENT); while ((subcomp = icalcompiter_deref (&iter)) != NULL) { icalcomponent_kind child_kind = icalcomponent_isa (subcomp); if (child_kind != ICAL_VTODO_COMPONENT && child_kind != ICAL_VTIMEZONE_COMPONENT) { icalcompiter_next (&iter); icalcomponent_remove_component (icalcomp, subcomp); icalcomponent_free (subcomp); } else { icalcompiter_next (&iter); } } for (elem = vtodos; elem; elem = elem->next) { icalcomponent_add_component (icalcomp, elem->data); } g_list_free (vtodos); }
/* This removes all components except VEVENTs and VTIMEZONEs from the toplevel */ static void prepare_events (icalcomponent *icalcomp, GList **vtodos) { icalcomponent *subcomp; icalcompiter iter; if (vtodos) *vtodos = NULL; iter = icalcomponent_begin_component (icalcomp, ICAL_ANY_COMPONENT); while ((subcomp = icalcompiter_deref (&iter)) != NULL) { icalcomponent_kind child_kind = icalcomponent_isa (subcomp); if (child_kind != ICAL_VEVENT_COMPONENT && child_kind != ICAL_VTIMEZONE_COMPONENT) { icalcompiter_next (&iter); icalcomponent_remove_component (icalcomp, subcomp); if (child_kind == ICAL_VTODO_COMPONENT && vtodos) *vtodos = g_list_prepend (*vtodos, subcomp); else icalcomponent_free (subcomp); } else { icalcompiter_next (&iter); } } }
icalcomponent *icalbdbset_fetch(icalset *set, icalcomponent_kind kind, const char *uid) { icalcompiter i; icalbdbset *bset = (icalbdbset *) set; icalerror_check_arg_rz((bset != 0), "bset"); for (i = icalcomponent_begin_component(bset->cluster, kind); icalcompiter_deref(&i) != 0; icalcompiter_next(&i)) { icalcomponent *this = icalcompiter_deref(&i); icalproperty *p = NULL; const char *this_uid = NULL; if (this != 0) { if (kind == ICAL_VAGENDA_COMPONENT) { p = icalcomponent_get_first_property(this, ICAL_RELCALID_PROPERTY); if (p != NULL) { this_uid = icalproperty_get_relcalid(p); } } else { p = icalcomponent_get_first_property(this, ICAL_UID_PROPERTY); if (p != NULL) { this_uid = icalproperty_get_uid(p); } } if (this_uid == NULL) { icalerror_warn("icalbdbset_fetch found a component with no UID"); continue; } if (strcmp(uid, this_uid) == 0) { return this; } } } return 0; }
icalsetiter icalbdbset_begin_component(icalset *set, icalcomponent_kind kind, icalgauge *gauge, const char *tzid) { icalsetiter itr = icalsetiter_null; icalcomponent *comp = NULL; icalcompiter citr; icalbdbset *bset; struct icaltimetype start, next; icalproperty *dtstart, *rrule, *prop, *due; struct icalrecurrencetype recur; icaltimezone *u_zone; int g = 0; int orig_time_was_utc = 0; icalerror_check_arg_re((set != 0), "set", icalsetiter_null); bset = (icalbdbset *) set; itr.gauge = gauge; itr.tzid = tzid; citr = icalcomponent_begin_component(bset->cluster, kind); comp = icalcompiter_deref(&citr); if (gauge == 0) { itr.iter = citr; return itr; } /* if there is a gauge, the first matched component is returned */ while (comp != 0) { /* check if it is a recurring component and with guage expand, if so * we need to add recurrence-id property to the given component */ rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY); g = icalgauge_get_expand(gauge); if (rrule != 0 && g == 1) { /* it is a recurring event */ u_zone = icaltimezone_get_builtin_timezone(itr.tzid); /* use UTC, if that's all we have. */ if (!u_zone) { u_zone = icaltimezone_get_utc_timezone(); } recur = icalproperty_get_rrule(rrule); start = icaltime_from_timet(time(0), 0); if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) { dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY); if (dtstart) { start = icalproperty_get_dtstart(dtstart); } } else if (icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) { due = icalcomponent_get_first_property(comp, ICAL_DUE_PROPERTY); if (due) { start = icalproperty_get_due(due); } } /* Convert to the user's timezone in order to be able to compare * the results from the rrule iterator. */ if (icaltime_is_utc(start)) { start = icaltime_convert_to_zone(start, u_zone); orig_time_was_utc = 1; } if (itr.last_component == NULL) { itr.ritr = icalrecur_iterator_new(recur, start); next = icalrecur_iterator_next(itr.ritr); itr.last_component = comp; } else { next = icalrecur_iterator_next(itr.ritr); if (icaltime_is_null_time(next)) { itr.last_component = NULL; icalrecur_iterator_free(itr.ritr); itr.ritr = NULL; /* no matched occurrence */ goto getNextComp; } else { itr.last_component = comp; } } /* if it is excluded, do next one */ if (icalproperty_recurrence_is_excluded(comp, &start, &next)) { next = icalrecur_iterator_next(itr.ritr); continue; } /* add recurrence-id value to the property if the property already exist; * add the recurrence id property and the value if the property does not exist */ prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY); if (prop == 0) { icalcomponent_add_property(comp, icalproperty_new_recurrenceid(next)); } else { icalproperty_set_recurrenceid(prop, next); } /* convert the next recurrence time into the user's timezone */ if (orig_time_was_utc) { next = icaltime_convert_to_zone(next, icaltimezone_get_utc_timezone()); } } /* end of a recurring event */ if (gauge == 0 || icalgauge_compare(itr.gauge, comp) == 1) { /* find a matched and return it */ itr.iter = citr; return itr; } /* if it is a recurring but no matched occurrence has been found OR * it is not a recurring and no matched component has been found, * read the next component to find out */ getNextComp: if ((rrule != NULL && itr.last_component == NULL) || (rrule == NULL)) { (void)icalcompiter_next(&citr); comp = icalcompiter_deref(&citr); } } /* while */ /* no matched component has found */ return icalsetiter_null; }
gboolean dates_import_calendar_data_from_file (ECal *cal, gchar *filename, GError **error) { GError *tmp_error = NULL; GIOChannel *channel = NULL; gchar *line; gsize length; gint num_comp_imported = 0; channel = g_io_channel_new_file (filename, "r", &tmp_error); if (tmp_error != NULL) { g_warning ("Error when opening file: %s", tmp_error->message); g_propagate_error (error, tmp_error); return FALSE; } else { GIOStatus status; icalparser *parser = icalparser_new (); /* set the channel as binary mode and let icalparser_add_line * handle encoding */ g_io_channel_set_encoding (channel, NULL, &tmp_error); if (tmp_error != NULL) { g_warning ("Error when set encoding: %s", tmp_error->message); g_propagate_error (error, tmp_error); g_io_channel_unref (channel); return FALSE; } /* Read the from the file line by line and until EOF */ while ((status = g_io_channel_read_line (channel, &line, &length, NULL, &tmp_error)) == G_IO_STATUS_NORMAL) { icalcomponent *icomp = NULL; /* The parser returns an icalcomponent when it has one */ icomp = icalparser_add_line (parser, line); g_free (line); if (icomp) { gchar *uid = NULL; icalcompiter iter; icalcomponent *subcomp; /* The component is a top-level one and e_cal_create_object only * accepts VEVENTs. Iterate through the VEVENTS. */ iter = icalcomponent_begin_component (icomp, ICAL_VEVENT_COMPONENT); while ((subcomp = icalcompiter_deref (&iter)) != NULL) { if (!e_cal_create_object (cal, subcomp, &uid, &tmp_error)) { g_warning ("Creation of imported event failed: %s", tmp_error->message); g_propagate_error (error, tmp_error); if (parser) icalparser_free (parser); if (icomp) icalcomponent_free (icomp); if (channel) g_io_channel_unref (channel); g_free (uid); return FALSE; } num_comp_imported ++; icalcompiter_next (&iter); g_free (uid); } icalcomponent_free (icomp); } } if (parser) icalparser_free (parser); if (tmp_error != NULL) { g_warning ("Error when reading from file: %s", tmp_error->message); g_propagate_error (error, tmp_error); g_io_channel_unref (channel); return FALSE; } } if (channel) g_io_channel_unref (channel); if (num_comp_imported > 0) { return TRUE; } else { *error = g_error_new_literal (g_quark_from_string ("Dates"), 1, _("No calendar events found.")); return FALSE; } }