41 #include "icaltimezones.h"
43 #include "versit/vcc.h"
44 #include "versit/vobject.h"
49 #include <QtCore/QBitArray>
50 #include <QtCore/QFile>
51 #include <QTextDocument>
53 using namespace KCalCore;
61 void removeAllVCal(QVector< QSharedPointer<K> > &c,
const QSharedPointer<K> &x)
69 qCritical() <<
"There number of relatedTos for this incidence is "
70 << cnt <<
" (there must be 1 relatedTo only)";
71 Q_ASSERT_X(
false,
"removeAllVCal",
"Count is not 1.");
75 c.remove(c.indexOf(x));
78 class KCalCore::VCalFormat::Private
84 QSet<QByteArray> mManuallyWrittenExtensionFields;
90 #if defined(KCALCORE_FOR_SYMBIAN)
91 d->mManuallyWrittenExtensionFields << VCRecurrenceIdProp;
92 d->mManuallyWrittenExtensionFields << EPOCAgendaEntryTypeProp;
94 d->mManuallyWrittenExtensionFields << KPilotIdProp;
95 d->mManuallyWrittenExtensionFields << KPilotStatusProp;
105 d->mCalendar = calendar;
113 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data()));
123 QString savedTimeZoneId = d->mCalendar->timeZoneId();
125 d->mCalendar->setTimeZoneId(savedTimeZoneId);
136 d->mCalendar = calendar;
143 vcal = newVObject(VCCalProp);
146 addPropValue(vcal, VCProdIdProp,
productId().toLatin1());
147 addPropValue(vcal, VCVersionProp, _VCAL_VERSION);
150 Todo::List todoList = d->mCalendar->rawTodos();
151 Todo::List::ConstIterator it;
152 for (it = todoList.constBegin(); it != todoList.constEnd(); ++it) {
153 if ((*it)->dtStart().timeZone().name().mid(0, 4) == QLatin1String(
"VCAL")) {
155 if (zone.isValid()) {
157 addPropValue(vcal, VCTimeZoneProp,
parseTZ(timezone).toLocal8Bit());
159 while (!dst.isEmpty()) {
160 addPropValue(vcal, VCDayLightProp, dst.toLocal8Bit());
166 addVObjectProp(vcal, vo);
170 Event::List::ConstIterator it2;
171 for (it2 = events.constBegin(); it2 != events.constEnd(); ++it2) {
172 if ((*it2)->dtStart().timeZone().name().mid(0, 4) == QLatin1String(
"VCAL")) {
174 if (zone.isValid()) {
176 addPropValue(vcal, VCTimeZoneProp,
parseTZ(timezone).toLocal8Bit());
178 while (!dst.isEmpty()) {
179 addPropValue(vcal, VCDayLightProp, dst.toLocal8Bit());
185 addVObjectProp(vcal, vo);
187 writeVObjectToFile(QFile::encodeName(fileName).data(), vcal);
191 if (QFile::exists(fileName)) {
201 bool deleted,
const QString ¬ebook)
203 return fromRawString(calendar,
string.toUtf8(), deleted, notebook);
207 bool deleted,
const QString ¬ebook)
209 d->mCalendar = calendar;
211 if (!
string.size()) {
215 VObject *vcal = Parse_MIME(
string.data(),
string.size());
221 initPropIterator(&i, vcal);
224 QString savedTimeZoneId = d->mCalendar->timeZoneId();
226 d->mCalendar->setTimeZoneId(savedTimeZoneId);
236 const QString ¬ebook,
bool deleted)
239 d->mCalendar = calendar;
244 VObject *vcal = newVObject(VCCalProp);
247 addPropValue(vcal, VCVersionProp, _VCAL_VERSION);
250 Todo::List todoList = deleted ? d->mCalendar->deletedTodos() : d->mCalendar->rawTodos();
251 Todo::List::ConstIterator it;
252 for (it = todoList.constBegin(); it != todoList.constEnd(); ++it) {
253 if (!deleted || !d->mCalendar->todo((*it)->uid(), (*it)->recurrenceId())) {
255 if (notebook.isEmpty() ||
256 (!calendar->notebook(*it).isEmpty() &&
257 notebook.endsWith(calendar->notebook(*it)))) {
258 if ((*it)->dtStart().timeZone().name().mid(0, 4) == QLatin1String(
"VCAL")) {
260 if (zone.isValid()) {
262 addPropValue(vcal, VCTimeZoneProp,
parseTZ(timezone).toUtf8());
264 while (!dst.isEmpty()) {
265 addPropValue(vcal, VCDayLightProp, dst.toUtf8());
271 addVObjectProp(vcal, vo);
277 Event::List events = deleted ? d->mCalendar->deletedEvents() : d->mCalendar->rawEvents();
278 Event::List::ConstIterator it2;
279 for (it2 = events.constBegin(); it2 != events.constEnd(); ++it2) {
280 if (!deleted || !d->mCalendar->event((*it2)->uid(), (*it2)->recurrenceId())) {
282 if (notebook.isEmpty() ||
283 (!calendar->notebook(*it2).isEmpty() &&
284 notebook.endsWith(calendar->notebook(*it2)))) {
285 if ((*it2)->dtStart().timeZone().name().mid(0, 4) == QLatin1String(
"VCAL")) {
287 if (zone.isValid()) {
289 addPropValue(vcal, VCTimeZoneProp,
parseTZ(timezone).toUtf8());
291 while (!dst.isEmpty()) {
292 addPropValue(vcal, VCDayLightProp, dst.toUtf8());
298 addVObjectProp(vcal, vo);
303 char *buf = writeMemVObject(0, 0, vcal);
305 QString result(QString::fromUtf8(buf));
319 vtodo = newVObject(VCTodoProp);
322 if (anEvent->hasDueDate()) {
324 addPropValue(vtodo, VCDueProp, tmpStr.toUtf8());
328 if (anEvent->hasStartDate()) {
330 addPropValue(vtodo, VCDTstartProp, tmpStr.toUtf8());
335 addPropValue(vtodo, VCDCreatedProp, tmpStr.toUtf8());
338 addPropValue(vtodo, VCUniqueStringProp,
339 anEvent->uid().toUtf8());
342 tmpStr.sprintf(
"%i", anEvent->revision());
343 addPropValue(vtodo, VCSequenceProp, tmpStr.toUtf8());
347 addPropValue(vtodo, VCLastModifiedProp, tmpStr.toUtf8());
351 if (!anEvent->organizer()->email().isEmpty()) {
352 tmpStr =
"MAILTO:" + anEvent->organizer()->email();
353 addPropValue(vtodo, ICOrganizerProp, tmpStr.toUtf8());
357 if (anEvent->attendeeCount() > 0) {
358 Attendee::List::ConstIterator it;
360 for (it = anEvent->attendees().constBegin(); it != anEvent->attendees().constEnd();
363 if (!curAttendee->email().isEmpty() && !curAttendee->name().isEmpty()) {
364 tmpStr =
"MAILTO:" + curAttendee->name() +
" <" + curAttendee->email() +
'>';
365 }
else if (curAttendee->name().isEmpty() && curAttendee->email().isEmpty()) {
367 kDebug() <<
"warning! this Event has an attendee w/o name or email!";
368 }
else if (curAttendee->name().isEmpty()) {
369 tmpStr =
"MAILTO: " + curAttendee->email();
371 tmpStr =
"MAILTO: " + curAttendee->name();
373 VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.toUtf8());
374 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ?
"TRUE" :
"FALSE");
375 addPropValue(aProp, VCStatusProp,
writeStatus(curAttendee->status()));
380 const Recurrence *recur = anEvent->recurrence();
382 bool validRecur =
true;
385 case Recurrence::rDaily:
386 tmpStr.sprintf(
"D%i ", recur->
frequency());
388 case Recurrence::rWeekly:
389 tmpStr.sprintf(
"W%i ", recur->
frequency());
390 for (
int i = 0; i < 7; ++i) {
391 QBitArray days(recur->
days());
392 if (days.testBit(i)) {
397 case Recurrence::rMonthlyPos:
399 tmpStr.sprintf(
"MP%i ", recur->
frequency());
401 QList<RecurrenceRule::WDayPos> tmpPositions = recur->
monthPositions();
402 for (QList<RecurrenceRule::WDayPos>::ConstIterator posit = tmpPositions.constBegin();
403 posit != tmpPositions.constEnd(); ++posit) {
404 int pos = (*posit).pos();
405 tmpStr2.sprintf(
"%i", (pos > 0) ? pos : (-pos));
416 case Recurrence::rMonthlyDay:
418 tmpStr.sprintf(
"MD%i ", recur->
frequency());
420 const QList<int> tmpDays = recur->
monthDays();
421 for (QList<int>::ConstIterator tmpDay = tmpDays.constBegin();
422 tmpDay != tmpDays.constEnd(); ++tmpDay) {
423 tmpStr2.sprintf(
"%i ", *tmpDay);
428 case Recurrence::rYearlyMonth:
430 tmpStr.sprintf(
"YM%i ", recur->
frequency());
433 const QList<int> months = recur->
yearMonths();
434 for (QList<int>::ConstIterator mit = months.constBegin();
435 mit != months.constEnd(); ++mit) {
436 tmpStr2.sprintf(
"%i ", *mit);
441 case Recurrence::rYearlyDay:
443 tmpStr.sprintf(
"YD%i ", recur->
frequency());
445 const QList<int> tmpDays = recur->
yearDays();
446 for (QList<int>::ConstIterator tmpDay = tmpDays.begin();
447 tmpDay != tmpDays.end(); ++tmpDay) {
448 tmpStr2.sprintf(
"%i ", *tmpDay);
455 kDebug() <<
"ERROR, it should never get here in eventToVTodo!";
461 tmpStr2.sprintf(
"#%i", recur->
duration());
463 }
else if (recur->
duration() == -1) {
471 addPropValue(vtodo, VCRRuleProp, tmpStr.toUtf8());
477 DateList dateList = recur->exDates();
478 DateList::ConstIterator id;
481 for (
id = dateList.constBegin();
id != dateList.constEnd(); ++id) {
485 if (!tmpStr2.isEmpty()) {
486 tmpStr2.truncate(tmpStr2.length() - 1);
487 addPropValue(vtodo, VCExpDateProp, tmpStr2.toUtf8());
491 DateTimeList::ConstIterator idt;
494 for (idt = dateTimeList.constBegin(); idt != dateTimeList.constEnd(); ++idt) {
498 if (!tmpStr2.isEmpty()) {
499 tmpStr2.truncate(tmpStr2.length() - 1);
500 addPropValue(vtodo, VCExpDateProp, tmpStr2.toUtf8());
504 if (!anEvent->description().isEmpty()) {
505 QByteArray in = anEvent->description().toUtf8();
507 KCodecs::quotedPrintableEncode(in, out,
true);
509 VObject *d = addPropValue(vtodo, VCDescriptionProp, out);
510 addPropValue(d, VCEncodingProp, VCQuotedPrintableProp);
511 addPropValue(d, VCCharSetProp, VCUtf8Prop);
513 addPropValue(vtodo, VCDescriptionProp, in);
518 if (!anEvent->summary().isEmpty()) {
519 QByteArray in = anEvent->summary().toUtf8();
521 KCodecs::quotedPrintableEncode(in, out,
true);
523 VObject *d = addPropValue(vtodo, VCSummaryProp, out);
524 addPropValue(d, VCEncodingProp, VCQuotedPrintableProp);
525 addPropValue(d, VCCharSetProp, VCUtf8Prop);
527 addPropValue(vtodo, VCSummaryProp, in);
532 if (!anEvent->location().isEmpty()) {
533 QByteArray in = anEvent->location().toUtf8();
535 KCodecs::quotedPrintableEncode(in, out,
true);
537 VObject *d = addPropValue(vtodo, VCLocationProp, out);
538 addPropValue(d, VCEncodingProp, VCQuotedPrintableProp);
539 addPropValue(d, VCCharSetProp, VCUtf8Prop);
541 addPropValue(vtodo, VCLocationProp, in);
547 addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ?
"COMPLETED" :
"NEEDS ACTION");
550 if (anEvent->hasCompletedDate()) {
552 addPropValue(vtodo, VCCompletedProp, tmpStr.toUtf8());
556 tmpStr.sprintf(
"%i", anEvent->priority());
557 addPropValue(vtodo, VCPriorityProp, tmpStr.toUtf8());
560 if (!anEvent->relatedTo().isEmpty()) {
561 addPropValue(vtodo, VCRelatedToProp,
562 anEvent->relatedTo().toUtf8());
566 const char *text = 0;
567 switch (anEvent->secrecy()) {
575 text =
"CONFIDENTIAL";
579 addPropValue(vtodo, VCClassProp, text);
583 const QStringList tmpStrList = anEvent->categories();
586 QStringList::const_iterator its;
587 for (its = tmpStrList.constBegin(); its != tmpStrList.constEnd(); ++its) {
589 if (catStr[0] == QLatin1Char(
' ')) {
590 tmpStr += catStr.mid(1);
597 tmpStr += QLatin1Char(
';');
599 if (!tmpStr.isEmpty()) {
600 tmpStr.truncate(tmpStr.length() - 1);
601 addPropValue(vtodo, VCCategoriesProp, tmpStr.toUtf8());
605 Alarm::List::ConstIterator it;
606 for (it = anEvent->alarms().constBegin(); it != anEvent->alarms().constEnd(); ++it) {
608 if (alarm->enabled()) {
611 a = addProp(vtodo, VCDAlarmProp);
613 addPropValue(a, VCRunTimeProp, tmpStr.toUtf8());
614 addPropValue(a, VCRepeatCountProp,
"1");
615 if (alarm->text().isNull()) {
616 addPropValue(a, VCDisplayStringProp,
"beep!");
618 addPropValue(a, VCDisplayStringProp, alarm->text().toLatin1().data());
621 a = addProp(vtodo, VCAAlarmProp);
623 addPropValue(a, VCRunTimeProp, tmpStr.toUtf8());
624 addPropValue(a, VCRepeatCountProp,
"1");
625 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile()));
627 a = addProp(vtodo, VCPAlarmProp);
629 addPropValue(a, VCRunTimeProp, tmpStr.toUtf8());
630 addPropValue(a, VCRepeatCountProp,
"1");
631 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile()));
636 QString pilotId = anEvent->nonKDECustomProperty(KPilotIdProp);
637 if (!pilotId.isEmpty()) {
639 addPropValue(vtodo, KPilotIdProp, pilotId.toUtf8());
640 addPropValue(vtodo, KPilotStatusProp,
641 anEvent->nonKDECustomProperty(KPilotStatusProp).toUtf8());
643 #if defined(KCALCORE_FOR_SYMBIAN)
644 if (anEvent->nonKDECustomProperty(EPOCAgendaEntryTypeProp).isEmpty()) {
647 addPropValue(vtodo, EPOCAgendaEntryTypeProp,
"TODO");
650 writeCustomProperties(vtodo, anEvent);
661 vevent = newVObject(VCEventProp);
665 addPropValue(vevent, VCDTstartProp, tmpStr.toUtf8());
667 #if !defined(KCALCORE_FOR_MEEGO)
670 if (anEvent->dtStart() != anEvent->dtEnd()) {
672 addPropValue(vevent, VCDTendProp, tmpStr.toUtf8());
677 addPropValue(vevent, VCDTendProp, tmpStr.toUtf8());
682 addPropValue(vevent, VCDCreatedProp, tmpStr.toUtf8());
685 addPropValue(vevent, VCUniqueStringProp,
686 anEvent->uid().toUtf8());
689 tmpStr.sprintf(
"%i", anEvent->revision());
690 addPropValue(vevent, VCSequenceProp, tmpStr.toUtf8());
694 addPropValue(vevent, VCLastModifiedProp, tmpStr.toUtf8());
698 if (!anEvent->organizer()->email().isEmpty()) {
699 tmpStr = QLatin1String(
"MAILTO:") + anEvent->organizer()->email();
700 addPropValue(vevent, ICOrganizerProp, tmpStr.toUtf8());
704 if (anEvent->attendeeCount() > 0) {
705 Attendee::List::ConstIterator it;
706 for (it = anEvent->attendees().constBegin(); it != anEvent->attendees().constEnd();
709 if (!curAttendee->email().isEmpty() && !curAttendee->name().isEmpty()) {
710 tmpStr = QLatin1String(
"MAILTO:") + curAttendee->name() + QLatin1String(
" <") + curAttendee->email() + QLatin1Char(
'>');
711 }
else if (curAttendee->name().isEmpty() && curAttendee->email().isEmpty()) {
712 tmpStr = QLatin1String(
"MAILTO: ");
713 kDebug() <<
"warning! this Event has an attendee w/o name or email!";
714 }
else if (curAttendee->name().isEmpty()) {
715 tmpStr = QLatin1String(
"MAILTO: ") + curAttendee->email();
717 tmpStr = QLatin1String(
"MAILTO: ") + curAttendee->name();
719 VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.toUtf8());
720 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ?
"TRUE" :
"FALSE");
721 addPropValue(aProp, VCStatusProp,
writeStatus(curAttendee->status()));
726 const Recurrence *recur = anEvent->recurrence();
728 bool validRecur =
true;
731 case Recurrence::rDaily:
732 tmpStr.sprintf(
"D%i ", recur->
frequency());
734 case Recurrence::rWeekly:
735 tmpStr.sprintf(
"W%i ", recur->
frequency());
736 for (
int i = 0; i < 7; ++i) {
737 QBitArray days(recur->
days());
738 if (days.testBit(i)) {
743 case Recurrence::rMonthlyPos:
745 tmpStr.sprintf(
"MP%i ", recur->
frequency());
747 QList<RecurrenceRule::WDayPos> tmpPositions = recur->
monthPositions();
748 for (QList<RecurrenceRule::WDayPos>::ConstIterator posit = tmpPositions.constBegin();
749 posit != tmpPositions.constEnd(); ++posit) {
750 int pos = (*posit).pos();
751 tmpStr2.sprintf(
"%i", (pos > 0) ? pos : (-pos));
762 case Recurrence::rMonthlyDay:
764 tmpStr.sprintf(
"MD%i ", recur->
frequency());
766 const QList<int> tmpDays = recur->
monthDays();
767 for (QList<int>::ConstIterator tmpDay = tmpDays.constBegin();
768 tmpDay != tmpDays.constEnd(); ++tmpDay) {
769 tmpStr2.sprintf(
"%i ", *tmpDay);
774 case Recurrence::rYearlyMonth:
776 tmpStr.sprintf(
"YM%i ", recur->
frequency());
779 const QList<int> months = recur->
yearMonths();
780 for (QList<int>::ConstIterator mit = months.constBegin();
781 mit != months.constEnd(); ++mit) {
782 tmpStr2.sprintf(
"%i ", *mit);
787 case Recurrence::rYearlyDay:
789 tmpStr.sprintf(
"YD%i ", recur->
frequency());
791 const QList<int> tmpDays = recur->
yearDays();
792 for (QList<int>::ConstIterator tmpDay = tmpDays.begin();
793 tmpDay != tmpDays.end(); ++tmpDay) {
794 tmpStr2.sprintf(
"%i ", *tmpDay);
801 kDebug() <<
"ERROR, it should never get here in eventToVEvent!";
807 tmpStr2.sprintf(
"#%i", recur->
duration());
809 }
else if (recur->
duration() == -1) {
812 #if !defined(KCALCORE_FOR_MEEGO)
822 addPropValue(vevent, VCRRuleProp, tmpStr.toUtf8());
828 DateList dateList = recur->exDates();
829 DateList::ConstIterator it;
832 for (it = dateList.constBegin(); it != dateList.constEnd(); ++it) {
836 if (!tmpStr2.isEmpty()) {
837 tmpStr2.truncate(tmpStr2.length() - 1);
838 addPropValue(vevent, VCExpDateProp, tmpStr2.toUtf8());
842 DateTimeList::ConstIterator idt;
845 for (idt = dateTimeList.constBegin(); idt != dateTimeList.constEnd(); ++idt) {
849 if (!tmpStr2.isEmpty()) {
850 tmpStr2.truncate(tmpStr2.length() - 1);
851 addPropValue(vevent, VCExpDateProp, tmpStr2.toUtf8());
855 if (!anEvent->description().isEmpty()) {
856 QByteArray in = anEvent->description().toUtf8();
858 KCodecs::quotedPrintableEncode(in, out,
true);
860 VObject *d = addPropValue(vevent, VCDescriptionProp, out);
861 addPropValue(d, VCEncodingProp, VCQuotedPrintableProp);
862 addPropValue(d, VCCharSetProp, VCUtf8Prop);
864 addPropValue(vevent, VCDescriptionProp, in);
869 if (!anEvent->summary().isEmpty()) {
870 QByteArray in = anEvent->summary().toUtf8();
872 KCodecs::quotedPrintableEncode(in, out,
true);
874 VObject *d = addPropValue(vevent, VCSummaryProp, out);
875 addPropValue(d, VCEncodingProp, VCQuotedPrintableProp);
876 addPropValue(d, VCCharSetProp, VCUtf8Prop);
878 addPropValue(vevent, VCSummaryProp, in);
883 if (!anEvent->location().isEmpty()) {
884 QByteArray in = anEvent->location().toUtf8();
886 KCodecs::quotedPrintableEncode(in, out,
true);
888 VObject *d = addPropValue(vevent, VCLocationProp, out);
889 addPropValue(d, VCEncodingProp, VCQuotedPrintableProp);
890 addPropValue(d, VCCharSetProp, VCUtf8Prop);
892 addPropValue(vevent, VCLocationProp, in);
901 const char *text = 0;
902 switch (anEvent->secrecy()) {
910 text =
"CONFIDENTIAL";
914 addPropValue(vevent, VCClassProp, text);
918 QStringList tmpStrList = anEvent->categories();
921 for (QStringList::const_iterator it = tmpStrList.constBegin(); it != tmpStrList.constEnd();
924 if (catStr[0] ==
' ') {
925 tmpStr += catStr.mid(1);
934 if (!tmpStr.isEmpty()) {
935 tmpStr.truncate(tmpStr.length() - 1);
936 addPropValue(vevent, VCCategoriesProp, tmpStr.toUtf8());
942 Attachment::List::ConstIterator atIt;
943 for (atIt = attachments.constBegin(); atIt != attachments.constEnd(); ++atIt) {
944 addPropValue(vevent, VCAttachProp, (*atIt)->uri().toUtf8());
948 tmpStrList = anEvent->resources();
949 tmpStr = tmpStrList.join(
";");
950 if (!tmpStr.isEmpty()) {
951 addPropValue(vevent, VCResourcesProp, tmpStr.toUtf8());
955 Alarm::List::ConstIterator it2;
956 for (it2 = anEvent->alarms().constBegin(); it2 != anEvent->alarms().constEnd(); ++it2) {
958 if (alarm->enabled()) {
961 a = addProp(vevent, VCDAlarmProp);
963 addPropValue(a, VCRunTimeProp, tmpStr.toUtf8());
964 addPropValue(a, VCRepeatCountProp,
"1");
965 if (alarm->text().isNull()) {
966 addPropValue(a, VCDisplayStringProp,
"beep!");
968 addPropValue(a, VCDisplayStringProp, alarm->text().toLatin1().data());
971 a = addProp(vevent, VCAAlarmProp);
973 addPropValue(a, VCRunTimeProp, tmpStr.toUtf8());
974 addPropValue(a, VCRepeatCountProp,
"1");
975 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile()));
978 a = addProp(vevent, VCPAlarmProp);
980 addPropValue(a, VCRunTimeProp, tmpStr.toUtf8());
981 addPropValue(a, VCRepeatCountProp,
"1");
982 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile()));
988 tmpStr.sprintf(
"%i", anEvent->priority());
989 addPropValue(vevent, VCPriorityProp, tmpStr.toUtf8());
992 tmpStr.sprintf(
"%i", anEvent->transparency());
993 addPropValue(vevent, VCTranspProp, tmpStr.toUtf8());
996 if (!anEvent->relatedTo().isEmpty()) {
997 addPropValue(vevent, VCRelatedToProp, anEvent->relatedTo().toUtf8());
1000 QString pilotId = anEvent->nonKDECustomProperty(KPilotIdProp);
1001 if (!pilotId.isEmpty()) {
1003 addPropValue(vevent, KPilotIdProp, pilotId.toUtf8());
1004 addPropValue(vevent, KPilotStatusProp,
1005 anEvent->nonKDECustomProperty(KPilotStatusProp).toUtf8());
1008 #if defined(KCALCORE_FOR_SYMBIAN)
1009 if (anEvent->nonKDECustomProperty(EPOCAgendaEntryTypeProp).isEmpty()) {
1012 if (anEvent->allDay()) {
1013 addPropValue(vevent, EPOCAgendaEntryTypeProp,
"EVENT");
1015 addPropValue(vevent, EPOCAgendaEntryTypeProp,
"APPOINTMENT");
1019 if (anEvent->hasRecurrenceId()) {
1021 addPropValue(vevent, VCRecurrenceIdProp, tmpStr.toUtf8());
1023 writeCustomProperties(vevent, anEvent);
1032 VObjectIterator voi;
1038 if ((vo = isAPropertyOf(vtodo, VCDCreatedProp)) != 0) {
1039 anEvent->setCreated(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1044 vo = isAPropertyOf(vtodo, VCUniqueStringProp);
1048 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo)));
1053 if ((vo = isAPropertyOf(vtodo, VCLastModifiedProp)) != 0) {
1054 anEvent->setLastModified(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1057 anEvent->setLastModified(KDateTime::currentUtcDateTime());
1062 if ((vo = isAPropertyOf(vtodo, ICOrganizerProp)) != 0) {
1063 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo)));
1066 if (d->mCalendar->owner()->name() != QLatin1String(
"Unknown Name")) {
1067 anEvent->setOrganizer(d->mCalendar->owner());
1072 initPropIterator(&voi, vtodo);
1073 while (moreIteration(&voi)) {
1074 vo = nextVObject(&voi);
1075 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) {
1078 s = fakeCString(vObjectUStringZValue(vo));
1079 QString tmpStr = QString::fromUtf8(s);
1081 tmpStr = tmpStr.simplified();
1082 int emailPos1, emailPos2;
1083 if ((emailPos1 = tmpStr.indexOf(QLatin1Char(
'<'))) > 0) {
1085 emailPos2 = tmpStr.lastIndexOf(QLatin1Char(
'>'));
1087 tmpStr.mid(emailPos1 + 1,
1088 emailPos2 - (emailPos1 + 1))));
1089 }
else if (tmpStr.indexOf(QLatin1Char(
'@')) > 0) {
1095 QString email = tmpStr.replace(
' ',
'.');
1100 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) {
1101 a->setRSVP(vObjectStringZValue(vp));
1104 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) {
1105 a->setStatus(
readStatus(vObjectStringZValue(vp)));
1108 anEvent->addAttendee(a);
1113 if ((vo = isAPropertyOf(vtodo, VCDescriptionProp)) != 0) {
1114 s = fakeCString(vObjectUStringZValue(vo));
1115 anEvent->setDescription(QString::fromUtf8(s), Qt::mightBeRichText(s));
1120 if ((vo = isAPropertyOf(vtodo, VCSummaryProp))) {
1121 s = fakeCString(vObjectUStringZValue(vo));
1122 anEvent->setSummary(QString::fromUtf8(s), Qt::mightBeRichText(s));
1127 if ((vo = isAPropertyOf(vtodo, VCLocationProp)) != 0) {
1128 s = fakeCString(vObjectUStringZValue(vo));
1129 anEvent->setLocation(QString::fromUtf8(s), Qt::mightBeRichText(s));
1135 if ((vo = isAPropertyOf(vtodo, VCStatusProp)) != 0) {
1136 s = fakeCString(vObjectUStringZValue(vo));
1137 if (s && strcmp(s,
"COMPLETED") == 0) {
1138 anEvent->setCompleted(
true);
1140 anEvent->setCompleted(
false);
1144 anEvent->setCompleted(
false);
1148 if ((vo = isAPropertyOf(vtodo, VCCompletedProp)) != 0) {
1149 anEvent->setCompleted(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1154 if ((vo = isAPropertyOf(vtodo, VCPriorityProp))) {
1155 s = fakeCString(vObjectUStringZValue(vo));
1157 anEvent->setPriority(atoi(s));
1162 anEvent->setAllDay(
false);
1165 if ((vo = isAPropertyOf(vtodo, VCDueProp)) != 0) {
1166 anEvent->setDtDue(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1168 if (anEvent->dtDue().time().hour() == 0 &&
1169 anEvent->dtDue().time().minute() == 0 &&
1170 anEvent->dtDue().time().second() == 0) {
1171 #if defined(KCALCORE_FOR_MEEGO)
1172 QDate dueDate = anEvent->dtDue().date();
1173 anEvent->setDtDue(KDateTime(dueDate, KDateTime::ClockTime));
1175 anEvent->setAllDay(
true);
1178 anEvent->setDtDue(KDateTime());
1182 if ((vo = isAPropertyOf(vtodo, VCDTstartProp)) != 0) {
1183 anEvent->setDtStart(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1185 if (anEvent->dtStart().time().hour() == 0 &&
1186 anEvent->dtStart().time().minute() == 0 &&
1187 anEvent->dtStart().time().second() == 0) {
1188 #if defined(KCALCORE_FOR_MEEGO)
1189 QDate startDate = anEvent->dtStart().date();
1190 anEvent->setDtStart(KDateTime(startDate, KDateTime::ClockTime));
1192 anEvent->setAllDay(
true);
1195 anEvent->setDtStart(KDateTime());
1199 if ((vo = isAPropertyOf(vtodo, VCRRuleProp)) != 0) {
1200 QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo)));
1202 tmpStr = tmpStr.simplified();
1203 tmpStr = tmpStr.toUpper();
1206 uint type = Recurrence::rNone;
1207 if (tmpStr.left(1) ==
"D") {
1208 type = Recurrence::rDaily;
1209 }
else if (tmpStr.left(1) ==
"W") {
1210 type = Recurrence::rWeekly;
1213 if (tmpStr.left(2) ==
"MP") {
1214 type = Recurrence::rMonthlyPos;
1215 }
else if (tmpStr.left(2) ==
"MD") {
1216 type = Recurrence::rMonthlyDay;
1217 }
else if (tmpStr.left(2) ==
"YM") {
1218 type = Recurrence::rYearlyMonth;
1219 }
else if (tmpStr.left(2) ==
"YD") {
1220 type = Recurrence::rYearlyDay;
1224 if (type != Recurrence::rNone) {
1227 int index = tmpStr.indexOf(
' ');
1228 int last = tmpStr.lastIndexOf(
' ') + 1;
1229 int rFreq = tmpStr.mid(typelen, (index - 1)).toInt();
1234 case Recurrence::rDaily:
1235 anEvent->recurrence()->setDaily(rFreq);
1238 case Recurrence::rWeekly:
1242 if (index == last) {
1244 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1247 while (index < last) {
1248 dayStr = tmpStr.mid(index, 3);
1256 anEvent->recurrence()->setWeekly(rFreq, qba);
1260 case Recurrence::rMonthlyPos:
1262 anEvent->recurrence()->setMonthly(rFreq);
1266 if (index == last) {
1268 tmpPos = anEvent->dtStart().date().day() / 7 + 1;
1272 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1273 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1276 while (index < last) {
1277 tmpPos = tmpStr.mid(index, 1).toShort();
1279 if (tmpStr.mid(index, 1) ==
"-") {
1281 tmpPos = 0 - tmpPos;
1284 while (
numFromDay(tmpStr.mid(index, 3)) >= 0) {
1285 int dayNum =
numFromDay(tmpStr.mid(index, 3));
1289 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1297 case Recurrence::rMonthlyDay:
1298 anEvent->recurrence()->setMonthly(rFreq);
1299 if (index == last) {
1301 short tmpDay = anEvent->dtStart().date().day();
1302 anEvent->recurrence()->addMonthlyDate(tmpDay);
1305 while (index < last) {
1306 int index2 = tmpStr.indexOf(
' ', index);
1307 if ((tmpStr.mid((index2 - 1), 1) ==
"-") ||
1308 (tmpStr.mid((index2 - 1), 1) ==
"+")) {
1309 index2 = index2 - 1;
1311 short tmpDay = tmpStr.mid(index, (index2 - index)).toShort();
1313 if (tmpStr.mid(index, 1) ==
"-") {
1314 tmpDay = 0 - tmpDay;
1317 anEvent->recurrence()->addMonthlyDate(tmpDay);
1322 case Recurrence::rYearlyMonth:
1323 anEvent->recurrence()->setYearly(rFreq);
1325 if (index == last) {
1327 short tmpMonth = anEvent->dtStart().date().month();
1328 anEvent->recurrence()->addYearlyMonth(tmpMonth);
1331 while (index < last) {
1332 int index2 = tmpStr.indexOf(
' ', index);
1333 short tmpMonth = tmpStr.mid(index, (index2 - index)).toShort();
1335 anEvent->recurrence()->addYearlyMonth(tmpMonth);
1340 case Recurrence::rYearlyDay:
1341 anEvent->recurrence()->setYearly(rFreq);
1343 if (index == last) {
1345 short tmpDay = anEvent->dtStart().date().dayOfYear();
1346 anEvent->recurrence()->addYearlyDay(tmpDay);
1349 while (index < last) {
1350 int index2 = tmpStr.indexOf(
' ', index);
1351 short tmpDay = tmpStr.mid(index, (index2 - index)).toShort();
1353 anEvent->recurrence()->addYearlyDay(tmpDay);
1364 if (tmpStr.mid(index, 1) ==
"#") {
1367 int rDuration = tmpStr.mid(index, tmpStr.length() - index).toInt();
1368 if (rDuration > 0) {
1369 anEvent->recurrence()->setDuration(rDuration);
1371 }
else if (tmpStr.indexOf(
'T', index) != -1) {
1372 KDateTime rEndDate =
ISOToKDateTime(tmpStr.mid(index, tmpStr.length() - index));
1373 anEvent->recurrence()->setEndDateTime(rEndDate);
1376 kDebug() <<
"we don't understand this type of recurrence!";
1381 if ((vo = isAPropertyOf(vtodo, VCExpDateProp)) != 0) {
1382 s = fakeCString(vObjectUStringZValue(vo));
1383 QStringList exDates = QString::fromUtf8(s).split(
',');
1384 QStringList::ConstIterator it;
1385 for (it = exDates.constBegin(); it != exDates.constEnd(); ++it) {
1387 if (exDate.time().hour() == 0 &&
1388 exDate.time().minute() == 0 &&
1389 exDate.time().second() == 0) {
1390 anEvent->recurrence()->addExDate(
ISOToQDate(*it));
1392 anEvent->recurrence()->addExDateTime(exDate);
1399 if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) {
1403 a = isAPropertyOf(vo, VCRunTimeProp);
1404 b = isAPropertyOf(vo, VCDisplayStringProp);
1407 alarm = anEvent->newAlarm();
1409 alarm->setTime(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(a))));
1412 alarm->setEnabled(
true);
1414 s = fakeCString(vObjectUStringZValue(b));
1415 alarm->setDisplayAlarm(QString(s));
1418 alarm->setDisplayAlarm(QString());
1423 if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) {
1427 a = isAPropertyOf(vo, VCRunTimeProp);
1428 b = isAPropertyOf(vo, VCAudioContentProp);
1431 alarm = anEvent->newAlarm();
1433 alarm->setTime(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(a))));
1436 alarm->setEnabled(
true);
1438 s = fakeCString(vObjectUStringZValue(b));
1439 alarm->setAudioAlarm(QFile::decodeName(s));
1442 alarm->setAudioAlarm(QString());
1447 if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) {
1451 a = isAPropertyOf(vo, VCRunTimeProp);
1452 b = isAPropertyOf(vo, VCProcedureNameProp);
1455 alarm = anEvent->newAlarm();
1457 alarm->setTime(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(a))));
1460 alarm->setEnabled(
true);
1463 s = fakeCString(vObjectUStringZValue(b));
1464 alarm->setProcedureAlarm(QFile::decodeName(s));
1467 alarm->setProcedureAlarm(QString());
1473 if ((vo = isAPropertyOf(vtodo, VCRelatedToProp)) != 0) {
1474 anEvent->setRelatedTo(s = fakeCString(vObjectUStringZValue(vo)));
1476 d->mTodosRelate.append(anEvent);
1481 if ((vo = isAPropertyOf(vtodo, VCClassProp)) != 0) {
1482 s = fakeCString(vObjectUStringZValue(vo));
1483 if (s && strcmp(s,
"PRIVATE") == 0) {
1485 }
else if (s && strcmp(s,
"CONFIDENTIAL") == 0) {
1490 anEvent->setSecrecy(secrecy);
1493 if ((vo = isAPropertyOf(vtodo, VCCategoriesProp)) != 0) {
1494 s = fakeCString(vObjectUStringZValue(vo));
1495 QString categories = QString::fromUtf8(s);
1497 QStringList tmpStrList = categories.split(
';');
1498 anEvent->setCategories(tmpStrList);
1502 if ((vo = isAPropertyOf(vtodo, KPilotIdProp))) {
1503 anEvent->setNonKDECustomProperty(
1504 KPilotIdProp, QString::fromUtf8(s = fakeCString(vObjectUStringZValue(vo))));
1506 if ((vo = isAPropertyOf(vtodo, KPilotStatusProp))) {
1507 anEvent->setNonKDECustomProperty(
1508 KPilotStatusProp, QString::fromUtf8(s = fakeCString(vObjectUStringZValue(vo))));
1511 anEvent->setNonKDECustomProperty(KPilotStatusProp, QString::number(
int(SYNCMOD)));
1521 VObjectIterator voi;
1527 if ((vo = isAPropertyOf(vevent, VCDCreatedProp)) != 0) {
1528 anEvent->setCreated(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1533 vo = isAPropertyOf(vevent, VCUniqueStringProp);
1537 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo)));
1541 #if defined(KCALCORE_FOR_SYMBIAN)
1543 vo = isAPropertyOf(vevent, VCRecurrenceIdProp);
1545 anEvent->setRecurrenceId(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1552 anEvent->setRevision(0);
1553 if ((vo = isAPropertyOf(vevent, VCSequenceProp)) != 0) {
1554 s = fakeCString(vObjectUStringZValue(vo));
1556 anEvent->setRevision(atoi(s));
1562 if ((vo = isAPropertyOf(vevent, VCLastModifiedProp)) != 0) {
1563 anEvent->setLastModified(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1566 anEvent->setLastModified(KDateTime::currentUtcDateTime());
1571 if ((vo = isAPropertyOf(vevent, ICOrganizerProp)) != 0) {
1573 anEvent->setOrganizer(s = fakeCString(vObjectUStringZValue(vo)));
1576 if (d->mCalendar->owner()->name() !=
"Unknown Name") {
1577 anEvent->setOrganizer(d->mCalendar->owner());
1582 initPropIterator(&voi, vevent);
1583 while (moreIteration(&voi)) {
1584 vo = nextVObject(&voi);
1585 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) {
1588 s = fakeCString(vObjectUStringZValue(vo));
1589 QString tmpStr = QString::fromUtf8(s);
1591 tmpStr = tmpStr.simplified();
1592 int emailPos1, emailPos2;
1593 if ((emailPos1 = tmpStr.indexOf(
'<')) > 0) {
1595 emailPos2 = tmpStr.lastIndexOf(
'>');
1597 tmpStr.mid(emailPos1 + 1,
1598 emailPos2 - (emailPos1 + 1))));
1599 }
else if (tmpStr.indexOf(
'@') > 0) {
1604 QString email = tmpStr.replace(
' ',
'.');
1609 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0) {
1610 a->setRSVP(vObjectStringZValue(vp));
1613 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0) {
1614 a->setStatus(
readStatus(vObjectStringZValue(vp)));
1617 anEvent->addAttendee(a);
1630 anEvent->setAllDay(
false);
1633 if ((vo = isAPropertyOf(vevent, VCDTstartProp)) != 0) {
1634 anEvent->setDtStart(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1637 if (anEvent->dtStart().time().hour() == 0 &&
1638 anEvent->dtStart().time().minute() == 0 &&
1639 anEvent->dtStart().time().second() == 0) {
1640 #if defined(KCALCORE_FOR_MEEGO)
1641 QDate startDate = anEvent->dtStart().date();
1642 anEvent->setDtStart(KDateTime(startDate, KDateTime::ClockTime));
1644 anEvent->setAllDay(
true);
1649 if ((vo = isAPropertyOf(vevent, VCDTendProp)) != 0) {
1650 anEvent->setDtEnd(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(vo))));
1653 if (anEvent->dtEnd().time().hour() == 0 &&
1654 anEvent->dtEnd().time().minute() == 0 &&
1655 anEvent->dtEnd().time().second() == 0) {
1656 #if defined(KCALCORE_FOR_MEEGO)
1657 QDate endDate = anEvent->dtEnd().date();
1658 anEvent->setDtEnd(KDateTime(endDate, KDateTime::ClockTime));
1660 anEvent->setAllDay(
true);
1663 #if defined(KCALCORE_FOR_MEEGO)
1664 if (anEvent->allDay()) {
1665 if (anEvent->dtEnd() == anEvent->dtStart()) {
1666 anEvent->setDtEnd(anEvent->dtEnd().addDays(1));
1673 if (!isAPropertyOf(vevent, VCDTstartProp)) {
1674 anEvent->setDtStart(anEvent->dtEnd());
1676 if (! isAPropertyOf(vevent, VCDTendProp)) {
1677 anEvent->setDtEnd(anEvent->dtStart());
1683 if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) {
1684 QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo)));
1686 tmpStr = tmpStr.simplified();
1687 tmpStr = tmpStr.toUpper();
1690 uint type = Recurrence::rNone;
1691 if (tmpStr.left(1) ==
"D") {
1692 type = Recurrence::rDaily;
1693 }
else if (tmpStr.left(1) ==
"W") {
1694 type = Recurrence::rWeekly;
1697 if (tmpStr.left(2) ==
"MP") {
1698 type = Recurrence::rMonthlyPos;
1699 }
else if (tmpStr.left(2) ==
"MD") {
1700 type = Recurrence::rMonthlyDay;
1701 }
else if (tmpStr.left(2) ==
"YM") {
1702 type = Recurrence::rYearlyMonth;
1703 }
else if (tmpStr.left(2) ==
"YD") {
1704 type = Recurrence::rYearlyDay;
1708 if (type != Recurrence::rNone) {
1711 int index = tmpStr.indexOf(
' ');
1712 int last = tmpStr.lastIndexOf(
' ') + 1;
1713 int rFreq = tmpStr.mid(typelen, (index - 1)).toInt();
1718 case Recurrence::rDaily:
1719 anEvent->recurrence()->setDaily(rFreq);
1722 case Recurrence::rWeekly:
1726 if (index == last) {
1728 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1731 while (index < last) {
1732 dayStr = tmpStr.mid(index, 3);
1740 anEvent->recurrence()->setWeekly(rFreq, qba);
1744 case Recurrence::rMonthlyPos:
1746 anEvent->recurrence()->setMonthly(rFreq);
1750 if (index == last) {
1752 tmpPos = anEvent->dtStart().date().day() / 7 + 1;
1756 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
1757 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1760 while (index < last) {
1761 tmpPos = tmpStr.mid(index, 1).toShort();
1763 if (tmpStr.mid(index, 1) ==
"-") {
1765 tmpPos = 0 - tmpPos;
1768 while (
numFromDay(tmpStr.mid(index, 3)) >= 0) {
1769 int dayNum =
numFromDay(tmpStr.mid(index, 3));
1773 anEvent->recurrence()->addMonthlyPos(tmpPos, qba);
1781 case Recurrence::rMonthlyDay:
1782 anEvent->recurrence()->setMonthly(rFreq);
1783 if (index == last) {
1785 short tmpDay = anEvent->dtStart().date().day();
1786 anEvent->recurrence()->addMonthlyDate(tmpDay);
1789 while (index < last) {
1790 int index2 = tmpStr.indexOf(
' ', index);
1791 if ((tmpStr.mid((index2 - 1), 1) ==
"-") ||
1792 (tmpStr.mid((index2 - 1), 1) ==
"+")) {
1793 index2 = index2 - 1;
1795 short tmpDay = tmpStr.mid(index, (index2 - index)).toShort();
1797 if (tmpStr.mid(index, 1) ==
"-") {
1798 tmpDay = 0 - tmpDay;
1801 anEvent->recurrence()->addMonthlyDate(tmpDay);
1806 case Recurrence::rYearlyMonth:
1807 anEvent->recurrence()->setYearly(rFreq);
1809 if (index == last) {
1811 short tmpMonth = anEvent->dtStart().date().month();
1812 anEvent->recurrence()->addYearlyMonth(tmpMonth);
1815 while (index < last) {
1816 int index2 = tmpStr.indexOf(
' ', index);
1817 short tmpMonth = tmpStr.mid(index, (index2 - index)).toShort();
1819 anEvent->recurrence()->addYearlyMonth(tmpMonth);
1824 case Recurrence::rYearlyDay:
1825 anEvent->recurrence()->setYearly(rFreq);
1827 if (index == last) {
1829 short tmpDay = anEvent->dtStart().date().dayOfYear();
1830 anEvent->recurrence()->addYearlyDay(tmpDay);
1833 while (index < last) {
1834 int index2 = tmpStr.indexOf(
' ', index);
1835 short tmpDay = tmpStr.mid(index, (index2 - index)).toShort();
1837 anEvent->recurrence()->addYearlyDay(tmpDay);
1848 if (tmpStr.mid(index, 1) ==
"#") {
1851 int rDuration = tmpStr.mid(index, tmpStr.length() - index).toInt();
1852 if (rDuration > 0) {
1853 anEvent->recurrence()->setDuration(rDuration);
1855 }
else if (tmpStr.indexOf(
'T', index) != -1) {
1856 KDateTime rEndDate =
ISOToKDateTime(tmpStr.mid(index, tmpStr.length() - index));
1857 anEvent->recurrence()->setEndDateTime(rEndDate);
1862 kDebug() <<
"we don't understand this type of recurrence!";
1867 if ((vo = isAPropertyOf(vevent, VCExpDateProp)) != 0) {
1868 s = fakeCString(vObjectUStringZValue(vo));
1869 QStringList exDates = QString::fromUtf8(s).split(
',');
1870 QStringList::ConstIterator it;
1871 for (it = exDates.constBegin(); it != exDates.constEnd(); ++it) {
1873 if (exDate.time().hour() == 0 &&
1874 exDate.time().minute() == 0 &&
1875 exDate.time().second() == 0) {
1876 anEvent->recurrence()->addExDate(
ISOToQDate(*it));
1878 anEvent->recurrence()->addExDateTime(exDate);
1885 if ((vo = isAPropertyOf(vevent, VCSummaryProp))) {
1886 s = fakeCString(vObjectUStringZValue(vo));
1887 anEvent->setSummary(QString::fromUtf8(s), Qt::mightBeRichText(s));
1892 if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) {
1893 s = fakeCString(vObjectUStringZValue(vo));
1894 bool isRich = Qt::mightBeRichText(s);
1895 if (!anEvent->description().isEmpty()) {
1896 anEvent->setDescription(
1897 anEvent->description() +
'\n' + QString::fromUtf8(s), isRich);
1899 anEvent->setDescription(QString::fromUtf8(s), isRich);
1905 if ((vo = isAPropertyOf(vevent, VCLocationProp)) != 0) {
1906 s = fakeCString(vObjectUStringZValue(vo));
1907 anEvent->setLocation(QString::fromUtf8(s), Qt::mightBeRichText(s));
1913 if (anEvent->summary().isEmpty() && !(anEvent->description().isEmpty())) {
1914 QString tmpStr = anEvent->description().simplified();
1915 anEvent->setDescription(
"");
1916 anEvent->setSummary(tmpStr);
1921 if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) {
1922 QString tmpStr(s = fakeCString(vObjectUStringZValue(vo)));
1933 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
1934 s = fakeCString(vObjectUStringZValue(vo));
1935 if (s && strcmp(s,
"PRIVATE") == 0) {
1937 }
else if (s && strcmp(s,
"CONFIDENTIAL") == 0) {
1942 anEvent->setSecrecy(secrecy);
1945 if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) {
1946 s = fakeCString(vObjectUStringZValue(vo));
1947 QString categories = QString::fromUtf8(s);
1949 QStringList tmpStrList = categories.split(
',');
1950 anEvent->setCategories(tmpStrList);
1954 initPropIterator(&voi, vevent);
1955 while (moreIteration(&voi)) {
1956 vo = nextVObject(&voi);
1957 if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
1958 s = fakeCString(vObjectUStringZValue(vo));
1965 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
1966 QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
1968 QStringList tmpStrList = resources.split(
';');
1969 anEvent->setResources(tmpStrList);
1973 if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) {
1977 a = isAPropertyOf(vo, VCRunTimeProp);
1978 b = isAPropertyOf(vo, VCDisplayStringProp);
1981 alarm = anEvent->newAlarm();
1983 alarm->setTime(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(a))));
1986 alarm->setEnabled(
true);
1989 s = fakeCString(vObjectUStringZValue(b));
1990 alarm->setDisplayAlarm(QString(s));
1993 alarm->setDisplayAlarm(QString());
1998 if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) {
2002 a = isAPropertyOf(vo, VCRunTimeProp);
2003 b = isAPropertyOf(vo, VCAudioContentProp);
2006 alarm = anEvent->newAlarm();
2008 alarm->setTime(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(a))));
2011 alarm->setEnabled(
true);
2014 s = fakeCString(vObjectUStringZValue(b));
2015 alarm->setAudioAlarm(QFile::decodeName(s));
2018 alarm->setAudioAlarm(QString());
2023 if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) {
2027 a = isAPropertyOf(vo, VCRunTimeProp);
2028 b = isAPropertyOf(vo, VCProcedureNameProp);
2031 alarm = anEvent->newAlarm();
2033 alarm->setTime(
ISOToKDateTime(s = fakeCString(vObjectUStringZValue(a))));
2036 alarm->setEnabled(
true);
2039 s = fakeCString(vObjectUStringZValue(b));
2040 alarm->setProcedureAlarm(QFile::decodeName(s));
2043 alarm->setProcedureAlarm(QString());
2049 if ((vo = isAPropertyOf(vevent, VCPriorityProp))) {
2050 s = fakeCString(vObjectUStringZValue(vo));
2052 anEvent->setPriority(atoi(s));
2058 if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) {
2059 s = fakeCString(vObjectUStringZValue(vo));
2068 if ((vo = isAPropertyOf(vevent, VCRelatedToProp)) != 0) {
2069 anEvent->setRelatedTo(s = fakeCString(vObjectUStringZValue(vo)));
2071 d->mEventsRelate.append(anEvent);
2075 if ((vo = isAPropertyOf(vevent, KPilotIdProp))) {
2076 anEvent->setNonKDECustomProperty(
2077 KPilotIdProp, QString::fromUtf8(s = fakeCString(vObjectUStringZValue(vo))));
2079 if ((vo = isAPropertyOf(vevent, KPilotStatusProp))) {
2080 anEvent->setNonKDECustomProperty(
2081 KPilotStatusProp, QString::fromUtf8(s = fakeCString(vObjectUStringZValue(vo))));
2084 anEvent->setNonKDECustomProperty(KPilotStatusProp, QString::number(
int(SYNCMOD)));
2089 readCustomProperties(vevent, anEvent);
2097 QString pZone = timezone.mid(timezone.indexOf(
"TZID:VCAL") + 9);
2098 return pZone.mid(0, pZone.indexOf(QChar(QLatin1Char(
'\n'))));
2103 if (!timezone.contains(
"BEGIN:DAYLIGHT")) {
2107 timezone = timezone.mid(timezone.indexOf(
"BEGIN:DAYLIGHT"));
2108 timezone = timezone.mid(timezone.indexOf(
"TZNAME:") + 7);
2109 QString sStart = timezone.mid(0, (timezone.indexOf(
"COMMENT:")));
2111 timezone = timezone.mid(timezone.indexOf(
"TZOFFSETTO:") + 11);
2112 QString sOffset = timezone.mid(0, (timezone.indexOf(
"DTSTART:")));
2114 sOffset.insert(3, QString(
":"));
2115 timezone = timezone.mid(timezone.indexOf(
"TZNAME:") + 7);
2116 QString sEnd = timezone.mid(0, (timezone.indexOf(
"COMMENT:")));
2119 return "TRUE;" + sOffset +
';' + sStart +
';' + sEnd +
";;";
2126 if (!qd.isValid()) {
2130 tmpStr.sprintf(
"%.2d%.2d%.2d", qd.year(), qd.month(), qd.day());
2139 if (!dt.isValid()) {
2145 tmpDT = dt.toUtc().dateTime();
2147 #if !defined(KCALCORE_FOR_MEEGO)
2148 tmpDT = dt.toTimeSpec(d->mCalendar->timeSpec()).dateTime();
2150 tmpDT = dt.dateTime();
2153 tmpStr.sprintf(
"%.2d%.2d%.2dT%.2d%.2d%.2d",
2154 tmpDT.date().year(), tmpDT.date().month(),
2155 tmpDT.date().day(), tmpDT.time().hour(),
2156 tmpDT.time().minute(), tmpDT.time().second());
2157 if (zulu || dt.isUtc()) {
2168 int year, month, day, hour, minute, second;
2171 year = tmpStr.left(4).toInt();
2172 month = tmpStr.mid(4, 2).toInt();
2173 day = tmpStr.mid(6, 2).toInt();
2174 hour = tmpStr.mid(9, 2).toInt();
2175 minute = tmpStr.mid(11, 2).toInt();
2176 second = tmpStr.mid(13, 2).toInt();
2177 tmpDate.setYMD(year, month, day);
2178 tmpTime.setHMS(hour, minute, second);
2180 if (tmpDate.isValid() && tmpTime.isValid()) {
2182 if (dtStr.at(dtStr.length() - 1) ==
'Z') {
2183 return KDateTime(tmpDate, tmpTime, KDateTime::UTC);
2185 return KDateTime(tmpDate, tmpTime, d->mCalendar->timeSpec());
2194 int year, month, day;
2196 year = dateStr.left(4).toInt();
2197 month = dateStr.mid(4, 2).toInt();
2198 day = dateStr.mid(6, 2).toInt();
2200 return QDate(year, month, day);
2213 QString str = s.trimmed();
2218 if (str.size() <= ofs) {
2221 if (str[ofs] ==
'-') {
2224 }
else if (str[ofs] ==
'+') {
2227 if (str.size() <= ofs) {
2234 if (str.size() < (ofs + 2)) {
2238 v = str.mid(ofs, 2).toInt(&ok) * 60;
2244 if (str.size() > ofs) {
2245 if (str[ofs] ==
':') {
2248 if (str.size() > ofs) {
2249 if (str.size() < (ofs + 2)) {
2252 v += str.mid(ofs, 2).toInt(&ok);
2258 result = v * mod * 60;
2272 VObject *curVO, *curVOProp;
2274 bool hasTimeZone =
false;
2275 KDateTime::Spec previousSpec;
2277 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
2278 char *methodType = 0;
2279 methodType = fakeCString(vObjectUStringZValue(curVO));
2281 deleteStr(methodType);
2285 if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) {
2286 char *s = fakeCString(vObjectUStringZValue(curVO));
2287 if (!s || strcmp(
productId().toUtf8(), s) != 0) {
2288 kDebug() <<
"This vCalendar file was not created by KOrganizer or"
2289 <<
"any other product we support. Loading anyway...";
2296 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
2297 char *s = fakeCString(vObjectUStringZValue(curVO));
2298 if (!s || strcmp(_VCAL_VERSION, s) != 0) {
2299 kDebug() <<
"This vCalendar file has version" << s
2300 <<
"We only support" << _VCAL_VERSION;
2306 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
2307 char *s = fakeCString(vObjectUStringZValue(curVO));
2309 QString name = QLatin1String(
"VCAL") + ts;
2325 KDateTime dt = KDateTime(QDateTime(QDate(1900, 1, 1), QTime(0, 0, 0)));
2326 tz = QString(
"STD;%1;false;%2").arg(QString::number(utcOffset)).arg(dt.toString());
2330 initPropIterator(&i, vcal);
2331 while (moreIteration(&i)) {
2332 curVO = nextVObject(&i);
2333 if (strcmp(vObjectName(curVO), VCDayLightProp) == 0) {
2334 char *s = fakeCString(vObjectUStringZValue(curVO));
2335 QString dst = QLatin1String(s);
2336 QStringList argl = dst.split(QLatin1Char(
','));
2340 if (argl.size() < 4) {
2345 if (argl[0] != QLatin1String(
"TRUE")) {
2353 QString strEndDate = argl[3];
2356 QString strStartDate = argl[2];
2359 QString strRealEndDate = strEndDate;
2360 QString strRealStartDate = strStartDate;
2361 KDateTime realEndDate = endDate;
2362 KDateTime realStartDate = startDate;
2364 if (endDate < startDate) {
2365 strRealEndDate = strStartDate;
2366 strRealStartDate = strEndDate;
2367 realEndDate = startDate;
2368 realStartDate = endDate;
2370 tz = QString::fromLatin1(
"%1;%2;false;%3").
2371 arg(strRealEndDate).
2372 arg(QString::number(utcOffset)).
2373 arg(realEndDate.toString());
2376 tz = QString::fromLatin1(
"%1;%2;true;%3").
2377 arg(strRealStartDate).
2378 arg(QString::number(utcOffsetDst)).
2379 arg(realStartDate.toString());
2382 kDebug() <<
"unable to parse dst" << argl[1];
2389 if (!zone.isValid()) {
2390 kDebug() <<
"zone is not valid, parsing error" << tzList;
2392 previousSpec = d->mCalendar->timeSpec();
2393 d->mCalendar->setTimeZoneId(name);
2397 kDebug() <<
"unable to parse tzoffset" << ts;
2402 d->mEventsRelate.clear();
2403 d->mTodosRelate.clear();
2405 initPropIterator(&i, vcal);
2408 while (moreIteration(&i)) {
2409 curVO = nextVObject(&i);
2414 if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
2416 if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) {
2418 s = fakeCString(vObjectUStringZValue(curVOProp));
2421 if (atoi(s) == SYNCDEL) {
2423 kDebug() <<
"skipping pilot-deleted event";
2430 if (!isAPropertyOf(curVO, VCDTstartProp) &&
2431 !isAPropertyOf(curVO, VCDTendProp)) {
2432 kDebug() <<
"found a VEvent with no DTSTART and no DTEND! Skipping...";
2438 if (hasTimeZone && !anEvent->allDay() && anEvent->dtStart().isUtc()) {
2443 int utcOffSet = anEvent->dtStart().utcOffset();
2444 KDateTime dtStart(anEvent->dtStart().dateTime().addSecs(utcOffSet),
2445 d->mCalendar->timeSpec());
2446 KDateTime dtEnd(anEvent->dtEnd().dateTime().addSecs(utcOffSet),
2447 d->mCalendar->timeSpec());
2448 anEvent->setDtStart(dtStart);
2449 anEvent->setDtEnd(dtEnd);
2451 Event::Ptr old = !anEvent->hasRecurrenceId() ?
2452 d->mCalendar->event(anEvent->uid()) :
2453 d->mCalendar->event(anEvent->uid(), anEvent->recurrenceId());
2457 d->mCalendar->deleteEvent(old);
2458 removeAllVCal(d->mEventsRelate, old);
2459 }
else if (anEvent->revision() > old->revision()) {
2460 d->mCalendar->deleteEvent(old);
2461 removeAllVCal(d->mEventsRelate, old);
2462 d->mCalendar->addEvent(anEvent);
2464 }
else if (deleted) {
2465 old = !anEvent->hasRecurrenceId() ?
2466 d->mCalendar->deletedEvent(anEvent->uid()) :
2467 d->mCalendar->deletedEvent(anEvent->uid(), anEvent->recurrenceId());
2469 d->mCalendar->addEvent(anEvent);
2470 d->mCalendar->deleteEvent(anEvent);
2473 d->mCalendar->addEvent(anEvent);
2476 }
else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
2479 if (hasTimeZone && !aTodo->allDay() && aTodo->dtStart().isUtc()) {
2484 int utcOffSet = aTodo->dtStart().utcOffset();
2485 KDateTime dtStart(aTodo->dtStart().dateTime().addSecs(utcOffSet),
2486 d->mCalendar->timeSpec());
2487 aTodo->setDtStart(dtStart);
2488 if (aTodo->hasDueDate()) {
2489 KDateTime dtDue(aTodo->dtDue().dateTime().addSecs(utcOffSet),
2490 d->mCalendar->timeSpec());
2491 aTodo->setDtDue(dtDue);
2494 Todo::Ptr old = !aTodo->hasRecurrenceId() ?
2495 d->mCalendar->todo(aTodo->uid()) :
2496 d->mCalendar->todo(aTodo->uid(), aTodo->recurrenceId());
2499 d->mCalendar->deleteTodo(old);
2500 removeAllVCal(d->mTodosRelate, old);
2501 }
else if (aTodo->revision() > old->revision()) {
2502 d->mCalendar->deleteTodo(old);
2503 removeAllVCal(d->mTodosRelate, old);
2504 d->mCalendar->addTodo(aTodo);
2506 }
else if (deleted) {
2507 old = d->mCalendar->deletedTodo(aTodo->uid(), aTodo->recurrenceId());
2509 d->mCalendar->addTodo(aTodo);
2510 d->mCalendar->deleteTodo(aTodo);
2513 d->mCalendar->addTodo(aTodo);
2516 }
else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
2517 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
2518 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
2522 }
else if (strcmp(vObjectName(curVO), VCDayLightProp) == 0) {
2526 kDebug() <<
"Ignoring unknown vObject \"" << vObjectName(curVO) <<
"\"";
2533 Event::List::ConstIterator eIt;
2534 for (eIt = d->mEventsRelate.constBegin(); eIt != d->mEventsRelate.constEnd(); ++eIt) {
2535 (*eIt)->setRelatedTo((*eIt)->relatedTo());
2537 Todo::List::ConstIterator tIt;
2538 for (tIt = d->mTodosRelate.constBegin(); tIt != d->mTodosRelate.constEnd(); ++tIt) {
2539 (*tIt)->setRelatedTo((*tIt)->relatedTo());
2544 d->mCalendar->setTimeSpec(previousSpec);
2551 const char *days[7] = {
"MO ",
"TU ",
"WE ",
"TH ",
"FR ",
"SA ",
"SU " };
2558 if (day == QLatin1String(
"MO ")) {
2561 if (day == QLatin1String(
"TU ")) {
2564 if (day == QLatin1String(
"WE ")) {
2567 if (day == QLatin1String(
"TH ")) {
2570 if (day == QLatin1String(
"FR ")) {
2573 if (day == QLatin1String(
"SA ")) {
2576 if (day == QLatin1String(
"SU ")) {
2585 QString statStr = s;
2586 statStr = statStr.toUpper();
2589 if (statStr == QLatin1String(
"X-ACTION")) {
2591 }
else if (statStr == QLatin1String(
"NEEDS ACTION")) {
2593 }
else if (statStr == QLatin1String(
"ACCEPTED")) {
2595 }
else if (statStr == QLatin1String(
"SENT")) {
2597 }
else if (statStr == QLatin1String(
"TENTATIVE")) {
2599 }
else if (statStr == QLatin1String(
"CONFIRMED")) {
2601 }
else if (statStr == QLatin1String(
"DECLINED")) {
2603 }
else if (statStr == QLatin1String(
"COMPLETED")) {
2605 }
else if (statStr == QLatin1String(
"DELEGATED")) {
2608 kDebug() <<
"error setting attendee mStatus, unknown mStatus!";
2620 return "NEEDS ACTION";
2638 return "NEEDS ACTION";
2643 void VCalFormat::readCustomProperties(VObject *o,
const Incidence::Ptr &i)
2645 VObjectIterator iter;
2647 const char *curname;
2650 initPropIterator(&iter, o);
2651 while (moreIteration(&iter)) {
2652 cur = nextVObject(&iter);
2653 curname = vObjectName(cur);
2655 if ((curname[0] ==
'X' && curname[1] ==
'-') &&
2656 strcmp(curname, ICOrganizerProp) != 0) {
2659 i->setNonKDECustomProperty(
2660 curname, QString::fromUtf8(s = fakeCString(vObjectUStringZValue(cur))));
2666 void VCalFormat::writeCustomProperties(VObject *o,
const Incidence::Ptr &i)
2668 const QMap<QByteArray, QString> custom = i->customProperties();
2669 for (QMap<QByteArray, QString>::ConstIterator c = custom.begin();
2670 c != custom.end(); ++c) {
2671 if (d->mManuallyWrittenExtensionFields.contains(c.key()) ||
2672 c.key().startsWith(
"X-KDE-VOLATILE")) {
2676 addPropValue(o, c.key(), c.value().toUtf8());
Exception base class, currently used as a fancy kind of error code and not as an C++ exception...
QSharedPointer< Attachment > Ptr
A shared pointer to an Attachment object.
QSharedPointer< Alarm > Ptr
A shared pointer to an Alarm object.
Secret to the owner and some others.
QSharedPointer< Event > Ptr
A shared pointer to an Event object.
A class which reads and parses iCalendar VTIMEZONE components, and accesses libical time zone data...
QList< int > yearDays() const
Returns the day numbers within a yearly recurrence.
QVector< Ptr > List
List of attachments.
QSharedPointer< Incidence > Ptr
A shared pointer to an Incidence.
int frequency() const
Returns frequency of recurrence, in terms of the recurrence time period type.
QVector< Ptr > List
List of events.
Event appears in free/busy time.
Event or to-do delegated.
Event does not appear in free/busy time.
This class represents a recurrence rule for a calendar incidence.
This file is part of the API for handling calendar data and defines the Todo class.
Unknown calendar format detected.
A QList which can be sorted.
This file is part of the API for handling calendar data and defines the Calendar class.
PartStat
The different types of participant status.
QList< int > monthDays() const
Returns list of day numbers of a month.
ICalTimeZone parse(icalcomponent *vtimezone)
Creates an ICalTimeZone instance containing the detailed information parsed from an iCalendar VTIMEZO...
This file is part of the API for handling calendar data and defines the Exception class...
QByteArray vtimezone() const
Returns the VTIMEZONE string which represents this time zone.
int duration() const
Returns -1 if the event recurs infinitely, 0 if the end date is set, otherwise the total number of re...
QList< int > yearMonths() const
Returns the months within a yearly recurrence.
To-do in process of being completed.
QSharedPointer< Calendar > Ptr
A shared pointer to a Calendar.
QVector< Ptr > List
List of to-dos.
Event, to-do or journal needs action (default)
QSharedPointer< Attendee > Ptr
A shared pointer to an Attendee object.
This file is part of the API for handling calendar data and defines the Event class.
Provides a To-do in the sense of RFC2445.
This class provides an Event in the sense of RFC2445.
Represents information related to an attachment for a Calendar Incidence.
Secrecy
The different types of incidence access classifications.
The ICalTimeZones class represents a time zone database which consists of a collection of individual ...
Event or to-do tentatively accepted.
The ICalTimeZone class represents an iCalendar VTIMEZONE component.
ushort recurrenceType() const
Returns the event's recurrence status.
Represents information related to an attendee of an Calendar Incidence, typically a meeting or task (...
QSharedPointer< Todo > Ptr
A shared pointer to a Todo object.
QBitArray days() const
Returns week day mask (bit 0 = Monday).
KDateTime endDateTime() const
Returns the date/time of the last recurrence.
Event, to-do or journal accepted.
bool recurs() const
Returns whether the event recurs at all.
Event, to-do or journal declined.
ICalTimeZone zone(const QString &name) const
Returns the time zone with the given name.
QList< RecurrenceRule::WDayPos > monthPositions() const
Returns list of day positions in months.