Page MenuHomePhorge

kcalconversion.cpp
No OneTemporary

Authored By
Unknown
Size
29 KB
Referenced Files
None
Subscribers
None

kcalconversion.cpp

/*
* Copyright (C) 2011 Christian Mollekopf <mollekopf@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "kcalconversion.h"
#include <kcalcore/recurrence.h>
#include <QtCore/QBitArray>
#include <QtCore/QVector>
#include <QtCore/QDebug>
#include <QUrl>
#include <QDate>
#include <vector>
#include "kolabformat/errorhandler.h"
#include "commonconversion.h"
namespace Kolab {
namespace Conversion {
//The uid of a contact which refers to the uuid of a contact in the addressbook
#define CUSTOM_KOLAB_CONTACT_UUID "X_KOLAB_CONTACT_UUID"
#define CUSTOM_KOLAB_CONTACT_CUTYPE "X_KOLAB_CONTACT_CUTYPE"
#define CUSTOM_KOLAB_URL "X-KOLAB-URL"
KCalCore::Duration toDuration(const Kolab::Duration &d)
{
int value = 0;
if (d.hours() || d.minutes() || d.seconds()) {
value = ((((d.weeks() * 7 + d.days()) * 24 + d.hours()) * 60 + d.minutes()) * 60 + d.seconds());
if (d.isNegative()) {
value = -value;
}
return KCalCore::Duration(value);
}
value = d.weeks() * 7 + d.days();
if (d.isNegative()) {
value = -value;
}
return KCalCore::Duration(value, KCalCore::Duration::Days);
}
Kolab::Duration fromDuration(const KCalCore::Duration &d)
{
int value = d.value();
bool isNegative = false;
if (value < 0) {
isNegative = true;
value = -value;
}
//We don't know how the seconds/days were distributed before, so no point in distributing them (probably)
if (d.isDaily()) {
int days = value;
return Kolab::Duration(days, 0, 0, 0, isNegative);
}
int seconds = value;
// int minutes = seconds / 60;
// seconds = seconds % 60;
// int hours = minutes / 60;
// minutes = minutes % 60;
return Kolab::Duration(0, 0, 0, seconds, isNegative);
}
KCalCore::Incidence::Secrecy toSecrecy(Kolab::Classification c)
{
switch(c) {
case Kolab::ClassPublic:
return KCalCore::Incidence::SecrecyPublic;
case Kolab::ClassPrivate:
return KCalCore::Incidence::SecrecyPrivate;
case Kolab::ClassConfidential:
return KCalCore::Incidence::SecrecyConfidential;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return KCalCore::Incidence::SecrecyPublic;
}
Kolab::Classification fromSecrecy(KCalCore::Incidence::Secrecy c)
{
switch(c) {
case KCalCore::Incidence::SecrecyPublic:
return Kolab::ClassPublic;
case KCalCore::Incidence::SecrecyPrivate:
return Kolab::ClassPrivate;
case KCalCore::Incidence::SecrecyConfidential:
return Kolab::ClassConfidential;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return Kolab::ClassPublic;
}
int toPriority(int priority)
{
//Same mapping
return priority;
}
int fromPriority(int priority)
{
//Same mapping
return priority;
}
KCalCore::Incidence::Status toStatus(Kolab::Status s)
{
switch (s) {
case StatusUndefined:
return KCalCore::Incidence::StatusNone;
case StatusNeedsAction:
return KCalCore::Incidence::StatusNeedsAction;
case StatusCompleted:
return KCalCore::Incidence::StatusCompleted;
case StatusInProcess:
return KCalCore::Incidence::StatusInProcess;
case StatusCancelled:
return KCalCore::Incidence::StatusCanceled;
case StatusTentative:
return KCalCore::Incidence::StatusTentative;
case StatusConfirmed:
return KCalCore::Incidence::StatusConfirmed;
case StatusDraft:
return KCalCore::Incidence::StatusDraft;
case StatusFinal:
return KCalCore::Incidence::StatusFinal;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return KCalCore::Incidence::StatusNone;
}
Kolab::Status fromStatus(KCalCore::Incidence::Status s)
{
switch (s) {
case KCalCore::Incidence::StatusNone:
return StatusUndefined;
case KCalCore::Incidence::StatusNeedsAction:
return StatusNeedsAction;
case KCalCore::Incidence::StatusCompleted:
return StatusCompleted;
case KCalCore::Incidence::StatusInProcess:
return StatusInProcess;
case KCalCore::Incidence::StatusCanceled:
return StatusCancelled;
case KCalCore::Incidence::StatusTentative:
return StatusTentative;
case KCalCore::Incidence::StatusConfirmed:
return StatusConfirmed;
case KCalCore::Incidence::StatusDraft:
return StatusDraft;
case KCalCore::Incidence::StatusFinal:
return StatusFinal;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return StatusUndefined;
}
KCalCore::Attendee::PartStat toPartStat(Kolab::PartStatus p)
{
switch (p) {
case PartNeedsAction:
return KCalCore::Attendee::NeedsAction;
case PartAccepted:
return KCalCore::Attendee::Accepted;
case PartDeclined:
return KCalCore::Attendee::Declined;
case PartTentative:
return KCalCore::Attendee::Tentative;
case PartDelegated:
return KCalCore::Attendee::Delegated;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return KCalCore::Attendee::NeedsAction;
}
Kolab::PartStatus fromPartStat(KCalCore::Attendee::PartStat p)
{
switch (p) {
case KCalCore::Attendee::NeedsAction:
return PartNeedsAction;
case KCalCore::Attendee::Accepted:
return PartAccepted;
case KCalCore::Attendee::Declined:
return PartDeclined;
case KCalCore::Attendee::Tentative:
return PartTentative;
case KCalCore::Attendee::Delegated:
return PartDelegated;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return PartNeedsAction;
}
KCalCore::Attendee::Role toRole(Kolab::Role r)
{
switch (r) {
case Required:
return KCalCore::Attendee::ReqParticipant;
case Chair:
return KCalCore::Attendee::Chair;
case Optional:
return KCalCore::Attendee::OptParticipant;
case NonParticipant:
return KCalCore::Attendee::NonParticipant;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return KCalCore::Attendee::ReqParticipant;
}
Kolab::Role fromRole(KCalCore::Attendee::Role r)
{
switch (r) {
case KCalCore::Attendee::ReqParticipant:
return Required;
case KCalCore::Attendee::Chair:
return Chair;
case KCalCore::Attendee::OptParticipant:
return Optional;
case KCalCore::Attendee::NonParticipant:
return NonParticipant;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return Required;
}
template <typename T>
QString getCustomProperty(const QString &id, const T &e)
{
std::vector<CustomProperty> &props = e.customProperties();
foreach (const CustomProperty &p, props) {
if (fromStdString(p.identifier) == id) {
return fromStdString(p.value);
}
}
}
template <typename T>
void setIncidence(KCalCore::Incidence &i, const T &e)
{
if (!e.uid().empty()) {
i.setUid(fromStdString(e.uid()));
}
i.setCreated(toDate(e.created()));
i.setLastModified(toDate(e.lastModified()));
i.setRevision(e.sequence());
i.setSecrecy(toSecrecy(e.classification()));
i.setCategories(toStringList(e.categories()));
if (e.start().isValid()) {
i.setDtStart(toDate(e.start()));
}
i.setSummary(fromStdString(e.summary())); //TODO detect richtext
i.setDescription(fromStdString(e.description())); //TODO detect richtext
i.setStatus(toStatus(e.status()));
foreach (const Kolab::Attendee a, e.attendees()) {
/*
* KCalCore always sets a UID if empty, but that's just a pointer, and not the uid of a real contact.
* Since that means the semantics of the two are different, we have to store the kolab uid as a custom property.
*/
KCalCore::Attendee::Ptr attendee = KCalCore::Attendee::Ptr(new KCalCore::Attendee(fromStdString(a.contact().name()),
fromStdString(a.contact().email()),
a.rsvp(),
toPartStat(a.partStat()),
toRole(a.role()) ));
if (!a.contact().uid().empty()) { //TODO Identify contact from addressbook based on uid
attendee->customProperties().setNonKDECustomProperty(CUSTOM_KOLAB_CONTACT_UUID, fromStdString(a.contact().uid()));
}
if (!a.delegatedTo().empty()) {
if (a.delegatedTo().size() > 1) {
WARNING("multiple delegatees are not supported");
}
attendee->setDelegate(toMailto(a.delegatedTo().front().email(), a.delegatedTo().front().name()).toString());
}
if (!a.delegatedFrom().empty()) {
if (a.delegatedFrom().size() > 1) {
WARNING("multiple delegators are not supported");
}
attendee->setDelegator(toMailto(a.delegatedFrom().front().email(), a.delegatedFrom().front().name()).toString());
}
if (a.cutype() != CutypeIndividual) {
attendee->customProperties().setNonKDECustomProperty(CUSTOM_KOLAB_CONTACT_CUTYPE, QString::number(a.cutype()));
}
i.addAttendee(attendee);
}
foreach (const Kolab::Attachment a, e.attachments()) {
KCalCore::Attachment::Ptr ptr;
if (!a.uri().empty()) {
qDebug() << "with uri";
ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(fromStdString(a.uri()), fromStdString(a.mimetype())));
} else {
qDebug() << "with data " << a.data();
ptr = KCalCore::Attachment::Ptr(new KCalCore::Attachment(QByteArray::fromRawData(a.data().c_str(), a.data().size()).toBase64(), fromStdString(a.mimetype())));
}
if (!a.label().empty()) {
ptr->setLabel(fromStdString(a.label()));
}
i.addAttachment(ptr);
}
QMap<QByteArray, QString> props;
foreach (const Kolab::CustomProperty &prop, e.customProperties()) {
QString key;
if (prop.identifier.compare(0, 5, "X-KDE")) {
key.append(QString::fromLatin1("X-KOLAB-"));
}
key.append(fromStdString(prop.identifier));
props.insert(key.toLatin1(), fromStdString(prop.value));
// i.setCustomProperty("KOLAB", fromStdString(prop.identifier).toLatin1(), fromStdString(prop.value));
}
i.setCustomProperties(props);
}
template <typename T, typename I>
void getIncidence(T &i, const I &e)
{
i.setUid(toStdString(e.uid()));
i.setCreated(fromDate(e.created()));
i.setLastModified(fromDate(e.lastModified()));
i.setSequence(e.revision());
i.setClassification(fromSecrecy(e.secrecy()));
i.setCategories(fromStringList(e.categories()));
i.setStart(fromDate(e.dtStart()));
i.setSummary(toStdString(e.summary()));
i.setDescription(toStdString(e.description()));
i.setStatus(fromStatus(e.status()));
std::vector<Kolab::Attendee> attendees;
foreach (const KCalCore::Attendee::Ptr ptr, e.attendees()) {
const QString &uid = ptr->customProperties().nonKDECustomProperty(CUSTOM_KOLAB_CONTACT_UUID);
Kolab::Attendee a(Kolab::ContactReference(toStdString(ptr->email()), toStdString(ptr->name()), toStdString(uid)));
a.setRSVP(ptr->RSVP());
a.setPartStat(fromPartStat(ptr->status()));
a.setRole(fromRole(ptr->role()));
if (!ptr->delegate().isEmpty()) {
std::string name;
const std::string &email = fromMailto(QUrl(ptr->delegate()), name);
a.setDelegatedTo(std::vector<Kolab::ContactReference>() << Kolab::ContactReference(email, name));
}
if (!ptr->delegator().isEmpty()) {
std::string name;
const std::string &email = fromMailto(QUrl(ptr->delegator()), name);
a.setDelegatedFrom(std::vector<Kolab::ContactReference>() << Kolab::ContactReference(email, name));
}
const QString &cutype = ptr->customProperties().nonKDECustomProperty(CUSTOM_KOLAB_CONTACT_CUTYPE);
if (!cutype.isEmpty()) {
a.setCutype(static_cast<Kolab::Cutype>(cutype.toInt()));
}
attendees.push_back(a);
}
i.setAttendees(attendees);
std::vector<Kolab::Attachment> attachments;
foreach (const KCalCore::Attachment::Ptr &ptr, e.attachments()) {
Kolab::Attachment a;
if (ptr->isUri()) {
a.setUri(toStdString(ptr->uri()), toStdString(ptr->mimeType()));
} else {
a.setData(std::string(ptr->decodedData().data(), ptr->decodedData().size()), toStdString(ptr->mimeType()));
}
a.setLabel(toStdString(ptr->label()));
attachments.push_back(a);
}
i.setAttachments(attachments);
std::vector<Kolab::CustomProperty> customProperties;
const QMap<QByteArray, QString> &props = e.customProperties();
for (QMap<QByteArray, QString>::const_iterator it = props.begin(); it != props.end(); it++) {
QString key(it.key());
if (key == QLatin1String(CUSTOM_KOLAB_URL)) {
continue;
}
customProperties.push_back(Kolab::CustomProperty(toStdString(key.remove("X-KOLAB-")), toStdString(it.value())));
}
i.setCustomProperties(customProperties);
}
int toWeekDay(Kolab::Weekday wday)
{
switch (wday) {
case Kolab::Monday:
return 1;
case Kolab::Tuesday:
return 2;
case Kolab::Wednesday:
return 3;
case Kolab::Thursday:
return 4;
case Kolab::Friday:
return 5;
case Kolab::Saturday:
return 6;
case Kolab::Sunday:
return 7;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return 1;
}
Kolab::Weekday fromWeekDay(int wday)
{
switch (wday) {
case 1:
return Kolab::Monday;
case 2:
return Kolab::Tuesday;
case 3:
return Kolab::Wednesday;
case 4:
return Kolab::Thursday;
case 5:
return Kolab::Friday;
case 6:
return Kolab::Saturday;
case 7:
return Kolab::Sunday;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return Kolab::Monday;
}
KCalCore::RecurrenceRule::PeriodType toRecurrenceType(Kolab::RecurrenceRule::Frequency freq)
{
switch(freq) {
case Kolab::RecurrenceRule::FreqNone:
Warning() << "no recurrence?";
break;
case Kolab::RecurrenceRule::Yearly:
return KCalCore::RecurrenceRule::rYearly;
case Kolab::RecurrenceRule::Monthly:
return KCalCore::RecurrenceRule::rMonthly;
case Kolab::RecurrenceRule::Weekly:
return KCalCore::RecurrenceRule::rWeekly;
case Kolab::RecurrenceRule::Daily:
return KCalCore::RecurrenceRule::rDaily;
case Kolab::RecurrenceRule::Hourly:
return KCalCore::RecurrenceRule::rHourly;
case Kolab::RecurrenceRule::Minutely:
return KCalCore::RecurrenceRule::rMinutely;
case Kolab::RecurrenceRule::Secondly:
return KCalCore::RecurrenceRule::rSecondly;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return KCalCore::RecurrenceRule::rNone;
}
Kolab::RecurrenceRule::Frequency fromRecurrenceType(KCalCore::RecurrenceRule::PeriodType freq)
{
switch(freq) {
case KCalCore::RecurrenceRule::rNone:
Warning() << "no recurrence?";
break;
case KCalCore::RecurrenceRule::rYearly:
return Kolab::RecurrenceRule::Yearly;
case KCalCore::RecurrenceRule::rMonthly:
return Kolab::RecurrenceRule::Monthly;
case KCalCore::RecurrenceRule::rWeekly:
return Kolab::RecurrenceRule::Weekly;
case KCalCore::RecurrenceRule::rDaily:
return Kolab::RecurrenceRule::Daily;
case KCalCore::RecurrenceRule::rHourly:
return Kolab::RecurrenceRule::Hourly;
case KCalCore::RecurrenceRule::rMinutely:
return Kolab::RecurrenceRule::Minutely;
case KCalCore::RecurrenceRule::rSecondly:
return Kolab::RecurrenceRule::Secondly;
default:
Error() << "unhandled";
Q_ASSERT(0);
}
return Kolab::RecurrenceRule::FreqNone;
}
KCalCore::RecurrenceRule::WDayPos toWeekDayPos(const Kolab::DayPos &dp)
{
return KCalCore::RecurrenceRule::WDayPos(dp.occurence(), toWeekDay(dp.weekday()));
}
Kolab::DayPos fromWeekDayPos(const KCalCore::RecurrenceRule::WDayPos &dp)
{
return Kolab::DayPos(dp.pos(), fromWeekDay(dp.day()));
}
template <typename T>
void setRecurrence(KCalCore::Incidence &e, const T &event)
{
const Kolab::RecurrenceRule &rrule = event.recurrenceRule();
if (rrule.isValid()) {
KCalCore::Recurrence *rec = e.recurrence();
KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(true);
Q_ASSERT(defaultRR);
defaultRR->setWeekStart(toWeekDay(rrule.weekStart()));
defaultRR->setRecurrenceType(toRecurrenceType(rrule.frequency()));
defaultRR->setFrequency(rrule.interval());
if (rrule.end().isValid()) {
rec->setEndDateTime(toDate(rrule.end())); //TODO date/datetime setEndDate(). With date-only the start date has to be taken into account.
} else {
rec->setDuration(rrule.count());
}
if (!rrule.bysecond().empty()) {
defaultRR->setBySeconds(QVector<int>::fromStdVector(rrule.bysecond()).toList());
}
if (!rrule.byminute().empty()) {
defaultRR->setByMinutes(QVector<int>::fromStdVector(rrule.byminute()).toList());
}
if (!rrule.byhour().empty()) {
defaultRR->setByHours(QVector<int>::fromStdVector(rrule.byhour()).toList());
}
if (!rrule.byday().empty()) {
QList<KCalCore::RecurrenceRule::WDayPos> daypos;
foreach(const Kolab::DayPos &dp, rrule.byday()) {
daypos.append(toWeekDayPos(dp));
}
defaultRR->setByDays(daypos);
}
if (!rrule.bymonthday().empty()) {
defaultRR->setByMonthDays(QVector<int>::fromStdVector(rrule.bymonthday()).toList());
}
if (!rrule.byyearday().empty()) {
defaultRR->setByYearDays(QVector<int>::fromStdVector(rrule.byyearday()).toList());
}
if (!rrule.byweekno().empty()) {
defaultRR->setByWeekNumbers(QVector<int>::fromStdVector(rrule.byweekno()).toList());
}
if (!rrule.bymonth().empty()) {
defaultRR->setByMonths(QVector<int>::fromStdVector(rrule.bymonth()).toList());
}
}
foreach (const Kolab::cDateTime &dt, event.recurrenceDates()) {
const KDateTime &date = toDate(dt);
if (date.isDateOnly()) {
e.recurrence()->addRDate(date.date());
} else {
e.recurrence()->addRDateTime(date);
}
}
foreach (const Kolab::cDateTime &dt, event.exceptionDates()) {
const KDateTime &date = toDate(dt);
if (date.isDateOnly()) {
e.recurrence()->addExDate(date.date());
} else {
e.recurrence()->addExDateTime(date);
}
}
}
template <typename T, typename I>
void getRecurrence(T &i, const I &e)
{
if (!e.recurs()) {
return;
}
KCalCore::Recurrence *rec = e.recurrence();
KCalCore::RecurrenceRule *defaultRR = rec->defaultRRule(false);
if (!defaultRR) {
Warning() << "no recurrence";
return;
}
Q_ASSERT(defaultRR);
Kolab::RecurrenceRule rrule;
rrule.setWeekStart(fromWeekDay(defaultRR->weekStart()));
rrule.setFrequency(fromRecurrenceType(defaultRR->recurrenceType()));
rrule.setInterval(defaultRR->frequency());
if (defaultRR->duration() != 0) { //Inidcates if end date is set or not
if (defaultRR->duration() > 0) {
rrule.setCount(defaultRR->duration());
}
} else {
rrule.setEnd(fromDate(defaultRR->endDt()));
}
rrule.setBysecond(defaultRR->bySeconds().toVector().toStdVector());
rrule.setByminute(defaultRR->byMinutes().toVector().toStdVector());
rrule.setByhour(defaultRR->byHours().toVector().toStdVector());
std::vector<Kolab::DayPos> daypos;
foreach (const KCalCore::RecurrenceRule::WDayPos &dp, defaultRR->byDays()) {
daypos.push_back(fromWeekDayPos(dp));
}
rrule.setByday(daypos);
rrule.setBymonthday(defaultRR->byMonthDays().toVector().toStdVector());
rrule.setByyearday(defaultRR->byYearDays().toVector().toStdVector());
rrule.setByweekno(defaultRR->byWeekNumbers().toVector().toStdVector());
rrule.setBymonth(defaultRR->byMonths().toVector().toStdVector());
i.setRecurrenceRule(rrule);
std::vector<Kolab::cDateTime> rdates;
foreach (const KDateTime &dt, rec->rDateTimes()) {
rdates.push_back(fromDate(dt));
}
foreach (const QDate &dt, rec->rDates()) {
rdates.push_back(fromDate(KDateTime(dt)));
}
i.setRecurrenceDates(rdates);
std::vector<Kolab::cDateTime> exdates;
foreach (const KDateTime &dt, rec->exDateTimes()) {
exdates.push_back(fromDate(dt));
}
foreach (const QDate &dt, rec->exDates()) {
exdates.push_back(fromDate(KDateTime(dt)));
}
i.setExceptionDates(exdates);
if (!rec->exRules().empty()) {
Warning() << "exrules are not supported";
}
}
template <typename T>
void setTodoEvent(KCalCore::Incidence &i, const T &e)
{
i.setPriority(toPriority(e.priority()));
if (!e.location().empty()) {
i.setLocation(fromStdString(e.location())); //TODO detect richtext
}
if (e.organizer().isValid()) {
i.setOrganizer(KCalCore::Person::Ptr(new KCalCore::Person(fromStdString(e.organizer().name()), fromStdString(e.organizer().email())))); //TODO handle uid too
}
if (!e.url().empty()) {
i.setNonKDECustomProperty(CUSTOM_KOLAB_URL, fromStdString(e.url()));
}
if (e.recurrenceID().isValid()) {
i.setRecurrenceId(toDate(e.recurrenceID())); //TODO THISANDFUTURE
}
setRecurrence(i, e);
foreach (const Kolab::Alarm a, e.alarms()) {
KCalCore::Alarm::Ptr alarm = KCalCore::Alarm::Ptr(new KCalCore::Alarm(&i));
switch (a.type()) {
case Kolab::Alarm::EMailAlarm: {
KCalCore::Person::List receipents;
foreach (Kolab::ContactReference c ,a.attendees()) {
KCalCore::Person::Ptr person = KCalCore::Person::Ptr(new KCalCore::Person(fromStdString(c.name()), fromStdString(c.email())));
receipents.append(person);
}
alarm->setEmailAlarm(fromStdString(a.summary()), fromStdString(a.description()), receipents);
}
break;
case Kolab::Alarm::DisplayAlarm:
alarm->setDisplayAlarm(fromStdString(a.text()));
break;
case Kolab::Alarm::AudioAlarm:
alarm->setAudioAlarm(fromStdString(a.audioFile().uri()));
break;
default:
Error() << "invalid alarm";
}
if (a.start().isValid()) {
alarm->setTime(toDate(a.start()));
} else if (a.relativeStart().isValid()) {
if (a.relativeTo() == Kolab::End) {
alarm->setEndOffset(toDuration(a.relativeStart()));
} else {
alarm->setStartOffset(toDuration(a.relativeStart()));
}
}
alarm->setSnoozeTime(toDuration(a.duration()));
alarm->setRepeatCount(a.numrepeat());
alarm->setEnabled(true);
i.addAlarm(alarm);
}
}
template <typename T, typename I>
void getTodoEvent(T &i, const I &e)
{
i.setPriority(fromPriority(e.priority()));
i.setLocation(toStdString(e.location()));
if (e.organizer() && !e.organizer()->email().isEmpty()) {
i.setOrganizer(Kolab::ContactReference(Kolab::ContactReference::EmailReference, toStdString(e.organizer()->email()), toStdString(e.organizer()->name()))); //TODO handle uid too
}
i.setUrl(toStdString(e.nonKDECustomProperty(CUSTOM_KOLAB_URL)));
i.setRecurrenceID(fromDate(e.recurrenceId()), false); //TODO THISANDFUTURE
getRecurrence(i, e);
std::vector <Kolab::Alarm> alarms;
foreach (const KCalCore::Alarm::Ptr &a, e.alarms()) {
Kolab::Alarm alarm;
//TODO KCalCore disables alarms using KCalCore::Alarm::enabled() (X-KDE-KCALCORE-ENABLED) We should either delete the alarm, or store the attribute .
//Ideally we would store the alarm somewhere and temporarily delete it, so we can restore it when parsing. For now we just remove disabled alarms.
if (!a->enabled()) {
Warning() << "skipping disabled alarm";
continue;
}
switch (a->type()) {
case KCalCore::Alarm::Display:
alarm = Kolab::Alarm(toStdString(a->text()));
break;
case KCalCore::Alarm::Email: {
std::vector<Kolab::ContactReference> receipents;
foreach(const KCalCore::Person::Ptr &p, a->mailAddresses()) {
receipents.push_back(Kolab::ContactReference(toStdString(p->email()), toStdString(p->name())));
}
alarm = Kolab::Alarm(toStdString(a->mailSubject()), toStdString(a->mailText()), receipents);
}
break;
case KCalCore::Alarm::Audio: {
Kolab::Attachment audioFile;
audioFile.setUri(toStdString(a->audioFile()), std::string());
alarm = Kolab::Alarm(audioFile);
}
break;
default:
Error() << "unhandled alarm";
}
if (a->hasTime()) {
alarm.setStart(fromDate(a->time()));
} else if (a->hasStartOffset()) {
alarm.setRelativeStart(fromDuration(a->startOffset()), Start);
} else if (a->hasEndOffset()) {
alarm.setRelativeStart(fromDuration(a->endOffset()), End);
} else {
Error() << "alarm trigger is missing";
continue;
}
alarm.setDuration(fromDuration(a->snoozeTime()), a->repeatCount());
alarms.push_back(alarm);
}
i.setAlarms(alarms);
}
KCalCore::Event::Ptr toKCalCore(const Kolab::Event &event)
{
KCalCore::Event::Ptr e(new KCalCore::Event);
setIncidence(*e, event);
setTodoEvent(*e, event);
if (event.end().isValid()) {
e->setDtEnd(toDate(event.end()));
}
if (event.duration().isValid()) {
e->setDuration(toDuration(event.duration()));
}
if (event.transparency()) {
e->setTransparency(KCalCore::Event::Transparent);
} else {
e->setTransparency(KCalCore::Event::Opaque);
}
return e;
}
Event fromKCalCore(const KCalCore::Event &event)
{
Event e;
getIncidence(e, event);
getTodoEvent(e, event);
if (event.hasEndDate()) {
e.setEnd(fromDate(event.dtEnd()));
} else if (event.hasDuration()) {
e.setDuration(fromDuration(event.duration()));
}
if (event.transparency() == KCalCore::Event::Transparent) {
e.setTransparency(true);
} else {
e.setTransparency(false);
}
return e;
}
KCalCore::Todo::Ptr toKCalCore ( const Todo &todo )
{
KCalCore::Todo::Ptr e(new KCalCore::Todo);
setIncidence(*e, todo);
setTodoEvent(*e, todo);
if (todo.due().isValid()) {
e->setDtDue(toDate(todo.due()));
}
if (!todo.relatedTo().empty()) {
e->setRelatedTo(Conversion::fromStdString(todo.relatedTo().front()), KCalCore::Incidence::RelTypeParent);
if (todo.relatedTo().size() > 1) {
Error() << "only one relation support but got multiple";
}
}
e->setPercentComplete(todo.percentComplete());
return e;
}
Todo fromKCalCore ( const KCalCore::Todo &todo )
{
Todo t;
getIncidence(t, todo);
getTodoEvent(t, todo);
t.setDue(fromDate(todo.dtDue(true)));
t.setPercentComplete(todo.percentComplete());
const QString relatedTo = todo.relatedTo(KCalCore::Incidence::RelTypeParent);
if (!relatedTo.isEmpty()) {
std::vector<std::string> relateds;
relateds.push_back(Conversion::toStdString(relatedTo));
t.setRelatedTo(relateds);
}
return t;
}
KCalCore::Journal::Ptr toKCalCore ( const Journal &journal )
{
KCalCore::Journal::Ptr e(new KCalCore::Journal);
setIncidence(*e, journal);
//TODO contacts
return e;
}
Journal fromKCalCore ( const KCalCore::Journal &journal )
{
Journal j;
getIncidence(j, journal);
//TODO contacts
return j;
}
}
}

File Metadata

Mime Type
text/x-c++
Expires
Sat, Apr 4, 3:03 AM (2 d, 19 h ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
18755295
Default Alt Text
kcalconversion.cpp (29 KB)

Event Timeline