void ical_property_TRIGGER(struct exchange2ical *exchange2ical) { struct icaltriggertype duration; icalproperty *prop; if (!exchange2ical->ReminderDelta) return; if (*exchange2ical->ReminderDelta == 0x5AE980E1) { duration = icaltriggertype_from_int(-15 * 60); prop = icalproperty_new_trigger(duration); icalcomponent_add_property(exchange2ical->valarm, prop); } else { duration = icaltriggertype_from_int(*(exchange2ical->ReminderDelta) * -1 * 60); prop = icalproperty_new_trigger(duration); icalcomponent_add_property(exchange2ical->valarm, prop); } }
/* ICALENDAR Reading functions */ GNOKII_API char *gn_calnote2icalstr(gn_calnote *calnote) { ical_string str; #ifdef HAVE_LIBICAL icalcomponent *pIcal = NULL, *vevent; struct icaltimetype stime = {0}, etime = {0}; char compuid[64]; memset(&str, 0, sizeof (str)); /* In at least some Nokia phones it is possible to skip the year of birth, in this case year == 0xffff, so we set it to the arbitrary value of 1800 */ stime.year = (calnote->time.year == 0xffff ? 1800 : calnote->time.year); stime.month = calnote->time.month; stime.day = calnote->time.day; stime.hour = calnote->time.hour; stime.minute = calnote->time.minute; stime.second = calnote->time.second; stime.is_daylight = 1; snprintf(compuid, sizeof(compuid), "guid.gnokii.org_%d_%d", calnote->location, rand()); vevent = icalcomponent_vanew(ICAL_VEVENT_COMPONENT, icalproperty_new_dtstart(stime), icalproperty_new_uid(compuid), icalproperty_new_categories("GNOKII"), 0); if (!vevent) { dprintf("ERROR in icalcomponent_vanew() creating VEVENT\n"); return NULL; } if (calnote->end_time.year) { etime.year = (calnote->end_time.year == 0xffff ? 1800 : calnote->end_time.year); etime.month = calnote->end_time.month; etime.day = calnote->end_time.day; etime.hour = calnote->end_time.hour; etime.minute = calnote->end_time.minute; etime.second = calnote->end_time.second; etime.is_daylight = 1; icalcomponent_add_property(vevent, icalproperty_new_dtend(etime)); } /* TODO: should the strings be configurable? */ switch(calnote->type) { case GN_CALNOTE_MEMO: icalcomponent_add_property(vevent, icalproperty_new_categories("MISCELLANEOUS")); icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text)); break; case GN_CALNOTE_REMINDER: icalcomponent_add_property(vevent, icalproperty_new_categories("REMINDER")); icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text)); break; case GN_CALNOTE_CALL: icalcomponent_add_property(vevent, icalproperty_new_categories("PHONE CALL")); icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->phone_number)); icalcomponent_add_property(vevent, icalproperty_new_description(calnote->text)); break; case GN_CALNOTE_MEETING: icalcomponent_add_property(vevent, icalproperty_new_categories("MEETING")); icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text)); if (calnote->mlocation[0]) icalcomponent_add_property(vevent, icalproperty_new_location(calnote->mlocation)); break; case GN_CALNOTE_BIRTHDAY: icalcomponent_add_property(vevent, icalproperty_new_categories("ANNIVERSARY")); icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text)); stime.is_date = 1; calnote->recurrence = GN_CALNOTE_YEARLY; break; default: icalcomponent_add_property(vevent, icalproperty_new_categories("UNKNOWN")); icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text)); break; } if (calnote->recurrence) { char rrule[64]; char *freq; int interval = 1; switch (calnote->recurrence) { case GN_CALNOTE_NEVER: goto norecurrence; case GN_CALNOTE_DAILY: freq = "DAILY"; break; case GN_CALNOTE_WEEKLY: freq = "WEEKLY"; break; case GN_CALNOTE_2WEEKLY: freq = "WEEKLY"; interval = 2; break; case GN_CALNOTE_MONTHLY: freq = "MONTHLY"; break; case GN_CALNOTE_YEARLY: freq = "YEARLY"; break; default: freq = "HOURLY"; interval = calnote->recurrence; break; } if (calnote->type == GN_CALNOTE_BIRTHDAY) snprintf(rrule, sizeof(rrule), "FREQ=YEARLY;INTERVAL=1;BYMONTH=%d", stime.month); else if (calnote->occurrences == 0) snprintf(rrule, sizeof(rrule), "FREQ=%s;INTERVAL=%d", freq, interval); else snprintf(rrule, sizeof(rrule), "FREQ=%s;COUNT=%d;INTERVAL=%d", freq, calnote->occurrences, interval); icalcomponent_add_property(vevent, icalproperty_new_rrule(icalrecurrencetype_from_string(rrule))); } norecurrence: if (calnote->alarm.enabled) { icalcomponent *valarm; struct icaltriggertype trig; trig.time.year = (calnote->alarm.timestamp.year == 0xffff ? 1800 : calnote->alarm.timestamp.year); trig.time.month = calnote->alarm.timestamp.month; trig.time.day = calnote->alarm.timestamp.day; trig.time.hour = calnote->alarm.timestamp.hour; trig.time.minute = calnote->alarm.timestamp.minute; trig.time.second = calnote->alarm.timestamp.second; trig.time.is_daylight = 1; valarm = icalcomponent_new_valarm(); icalcomponent_add_property(valarm, icalproperty_new_trigger(trig)); /* FIXME: with ICAL_ACTION_DISPLAY a DESCRIPTION property is mandatory */ icalcomponent_add_property(valarm, icalproperty_new_action(calnote->alarm.tone ? ICAL_ACTION_AUDIO : ICAL_ACTION_DISPLAY)); icalcomponent_add_component(vevent, valarm); } pIcal = icalcomponent_vanew(ICAL_VCALENDAR_COMPONENT, icalproperty_new_version("2.0"), icalproperty_new_prodid(get_prodid()), vevent, 0); if (pIcal) { char *icalstrbuf = NULL; const char *icalstr = icalcomponent_as_ical_string(pIcal); /* conversion to UTF-8 */ if (string_base64(icalstr)) { int icalstrlen = strlen(icalstr); icalstrbuf = malloc(icalstrlen * 2 + 1); utf8_encode(icalstrbuf, icalstrlen * 2, icalstr, icalstrlen); icalstr = icalstrbuf; } ical_append_printf(&str, "%s\n", icalstr); dprintf("%s\n", icalstr); if (icalstrbuf) free(icalstrbuf); icalcomponent_free(pIcal); pIcal = NULL; } else { dprintf("ERROR in icalcomponent_vanew() creating VCALENDAR\n"); } return str.str; #else memset(&str, 0, sizeof (str)); ical_append_printf(&str, "BEGIN:VCALENDAR\r\n"); ical_append_printf(&str, "VERSION:1.0\r\n"); ical_append_printf(&str, "BEGIN:VEVENT\r\n"); ical_append_printf(&str, "CATEGORIES:"); switch (calnote->type) { case GN_CALNOTE_MEMO: ical_append_printf(&str, "MISCELLANEOUS\r\n"); break; case GN_CALNOTE_REMINDER: ical_append_printf(&str, "REMINDER\r\n"); break; case GN_CALNOTE_CALL: ical_append_printf(&str, "PHONE CALL\r\n"); ical_append_printf(&str, "SUMMARY:%s\r\n", calnote->phone_number); ical_append_printf(&str, "DESCRIPTION:%s\r\n", calnote->text); break; case GN_CALNOTE_MEETING: ical_append_printf(&str, "MEETING\r\n"); if (calnote->mlocation[0]) ical_append_printf(&str, "LOCATION:%s\r\n", calnote->mlocation); break; case GN_CALNOTE_BIRTHDAY: ical_append_printf(&str, "SPECIAL OCCASION\r\n"); break; default: ical_append_printf(&str, "UNKNOWN\r\n"); break; } if (calnote->type != GN_CALNOTE_CALL) ical_append_printf(&str, "SUMMARY:%s\r\n", calnote->text); ical_append_printf(&str, "DTSTART:%04d%02d%02dT%02d%02d%02d\r\n", calnote->time.year, calnote->time.month, calnote->time.day, calnote->time.hour, calnote->time.minute, calnote->time.second); if (calnote->end_time.year) { ical_append_printf(&str, "DTEND:%04d%02d%02dT%02d%02d%02d\r\n", calnote->end_time.year, calnote->end_time.month, calnote->end_time.day, calnote->end_time.hour, calnote->end_time.minute, calnote->end_time.second); } if (calnote->alarm.enabled) { ical_append_printf(&str, "%sALARM:%04d%02d%02dT%02d%02d%02d\r\n", (calnote->alarm.tone ? "A" : "D"), calnote->alarm.timestamp.year, calnote->alarm.timestamp.month, calnote->alarm.timestamp.day, calnote->alarm.timestamp.hour, calnote->alarm.timestamp.minute, calnote->alarm.timestamp.second); } switch (calnote->recurrence) { case GN_CALNOTE_NEVER: break; case GN_CALNOTE_DAILY: calnote->occurrences ? ical_append_printf(&str, "RRULE:FREQ=DAILY\r\n") : ical_append_printf(&str, "RRULE:FREQ=DAILY;COUNT=%d\r\n", calnote->occurrences); break; case GN_CALNOTE_WEEKLY: calnote->occurrences ? ical_append_printf(&str, "RRULE:FREQ=WEEKLY\r\n") : ical_append_printf(&str, "RRULE:FREQ=WEEKLY;COUNT=%d\r\n", calnote->occurrences); break; case GN_CALNOTE_2WEEKLY: calnote->occurrences ? ical_append_printf(&str, "RRULE:FREQ=WEEKLY;INTERVAL=2\r\n") : ical_append_printf(&str, "RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=%d\r\n", calnote->occurrences); break; case GN_CALNOTE_MONTHLY: calnote->occurrences ? ical_append_printf(&str, "RRULE:FREQ=MONTHLY\r\n") : ical_append_printf(&str, "RRULE:FREQ=MONTHLY;COUNT=%d\r\n", calnote->occurrences); break; case GN_CALNOTE_YEARLY: calnote->occurrences ? ical_append_printf(&str, "RRULE:FREQ=YEARLY\r\n") : ical_append_printf(&str, "RRULE:FREQ=YEARLY;COUNT=%d\r\n", calnote->occurrences); break; default: calnote->occurrences ? ical_append_printf(&str, "RRULE:FREQ=HOURLY;INTERVAL=%d\r\n", calnote->recurrence) : ical_append_printf(&str, "RRULE:FREQ=HOURLY;INTERVAL=%d;COUNT=%d\r\n", calnote->recurrence, calnote->occurrences); break; } ical_append_printf(&str, "END:VEVENT\r\n"); ical_append_printf(&str, "END:VCALENDAR\r\n"); return str.str; #endif /* HAVE_LIBICAL */ }