00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <qdatetime.h>
00022 #include <qstring.h>
00023 #include <qptrlist.h>
00024 #include <qfile.h>
00025
00026 #include <kdebug.h>
00027 #include <klocale.h>
00028
00029 extern "C" {
00030 #include <ical.h>
00031 #include <icalss.h>
00032 #include <icalparser.h>
00033 #include <icalrestriction.h>
00034 }
00035
00036 #include "calendar.h"
00037 #include "journal.h"
00038 #include "icalformat.h"
00039 #include "icalformatimpl.h"
00040 #include "compat.h"
00041
00042 #define _ICAL_VERSION "2.0"
00043
00044 using namespace KCal;
00045
00046 const int gSecondsPerMinute = 60;
00047 const int gSecondsPerHour = gSecondsPerMinute * 60;
00048 const int gSecondsPerDay = gSecondsPerHour * 24;
00049 const int gSecondsPerWeek = gSecondsPerDay * 7;
00050
00051 ICalFormatImpl::ICalFormatImpl( ICalFormat *parent ) :
00052 mParent( parent )
00053 {
00054 mCompat = new Compat;
00055 }
00056
00057 ICalFormatImpl::~ICalFormatImpl()
00058 {
00059 delete mCompat;
00060 }
00061
00062 class ToStringVisitor : public Incidence::Visitor
00063 {
00064 public:
00065 ToStringVisitor( ICalFormatImpl *impl ) : mImpl( impl ), mComponent( 0 ) {}
00066
00067 bool visit( Event *e ) { mComponent = mImpl->writeEvent( e ); return true; }
00068 bool visit( Todo *e ) { mComponent = mImpl->writeTodo( e ); return true; }
00069 bool visit( Journal *e ) { mComponent = mImpl->writeJournal( e ); return true; }
00070
00071 icalcomponent *component() { return mComponent; }
00072
00073 private:
00074 ICalFormatImpl *mImpl;
00075 icalcomponent *mComponent;
00076 };
00077
00078 icalcomponent *ICalFormatImpl::writeIncidence(Incidence *incidence)
00079 {
00080 ToStringVisitor v( this );
00081 incidence->accept(v);
00082 return v.component();
00083 }
00084
00085 icalcomponent *ICalFormatImpl::writeTodo(Todo *todo)
00086 {
00087 QString tmpStr;
00088 QStringList tmpStrList;
00089
00090 icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT);
00091
00092 writeIncidence(vtodo,todo);
00093
00094
00095 if (todo->hasDueDate()) {
00096 icaltimetype due;
00097 if (todo->doesFloat()) {
00098 due = writeICalDate(todo->dtDue().date());
00099 } else {
00100 due = writeICalDateTime(todo->dtDue());
00101 }
00102 icalcomponent_add_property(vtodo,icalproperty_new_due(due));
00103 }
00104
00105
00106 if (todo->hasStartDate()) {
00107 icaltimetype start;
00108 if (todo->doesFloat()) {
00109
00110 start = writeICalDate(todo->dtStart().date());
00111 } else {
00112
00113 start = writeICalDateTime(todo->dtStart());
00114 }
00115 icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start));
00116 }
00117
00118
00119 if (todo->isCompleted()) {
00120 if (!todo->hasCompletedDate()) {
00121
00122
00123 todo->setCompleted(QDateTime::currentDateTime());
00124 }
00125 icaltimetype completed = writeICalDateTime(todo->completed());
00126 icalcomponent_add_property(vtodo,icalproperty_new_completed(completed));
00127 }
00128
00129 icalcomponent_add_property(vtodo,
00130 icalproperty_new_percentcomplete(todo->percentComplete()));
00131
00132 return vtodo;
00133 }
00134
00135 icalcomponent *ICalFormatImpl::writeEvent(Event *event)
00136 {
00137 kdDebug(5800) << "Write Event '" << event->summary() << "' (" << event->uid()
00138 << ")" << endl;
00139
00140 QString tmpStr;
00141 QStringList tmpStrList;
00142
00143 icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
00144
00145 writeIncidence(vevent,event);
00146
00147
00148 icaltimetype start;
00149 if (event->doesFloat()) {
00150
00151 start = writeICalDate(event->dtStart().date());
00152 } else {
00153
00154 start = writeICalDateTime(event->dtStart());
00155 }
00156 icalcomponent_add_property(vevent,icalproperty_new_dtstart(start));
00157
00158
00159 icaltimetype end;
00160 if (event->doesFloat()) {
00161
00162
00163 end = writeICalDate( event->dtEnd().date().addDays( 1 ) );
00164 } else {
00165
00166 end = writeICalDateTime(event->dtEnd());
00167 }
00168 icalcomponent_add_property(vevent,icalproperty_new_dtend(end));
00169
00170
00171 #if 0
00172
00173 tmpStrList = anEvent->attachments();
00174 for ( QStringList::Iterator it = tmpStrList.begin();
00175 it != tmpStrList.end();
00176 ++it )
00177 addPropValue(vevent, VCAttachProp, (*it).utf8());
00178
00179
00180 tmpStrList = anEvent->resources();
00181 tmpStr = tmpStrList.join(";");
00182 if (!tmpStr.isEmpty())
00183 addPropValue(vevent, VCResourcesProp, tmpStr.utf8());
00184
00185 #endif
00186
00187
00188
00189
00190
00191
00192 return vevent;
00193 }
00194
00195 icalcomponent *ICalFormatImpl::writeFreeBusy(FreeBusy *freebusy,
00196 Scheduler::Method method)
00197 {
00198 #if QT_VERSION >= 300
00199 kdDebug(5800) << "icalformatimpl: writeFreeBusy: startDate: "
00200 << freebusy->dtStart().toString("ddd MMMM d yyyy: h:m:s ap") << " End Date: "
00201 << freebusy->dtEnd().toString("ddd MMMM d yyyy: h:m:s ap") << endl;
00202 #endif
00203
00204 icalcomponent *vfreebusy = icalcomponent_new(ICAL_VFREEBUSY_COMPONENT);
00205
00206 icalcomponent_add_property(vfreebusy,icalproperty_new_organizer(
00207 ("MAILTO:" + freebusy->organizer()).utf8()));
00208
00209 if (freebusy->attendeeCount() != 0) {
00210 QPtrList<Attendee> al = freebusy->attendees();
00211 QPtrListIterator<Attendee> ai(al);
00212 for (; ai.current(); ++ai) {
00213 icalcomponent_add_property(vfreebusy,writeAttendee(ai.current()));
00214 }
00215 }
00216
00217 icalcomponent_add_property(vfreebusy,icalproperty_new_dtstamp(
00218 writeICalDateTime(QDateTime::currentDateTime())));
00219
00220 icalcomponent_add_property(vfreebusy, icalproperty_new_dtstart(
00221 writeICalDateTime(freebusy->dtStart())));
00222
00223 icalcomponent_add_property(vfreebusy, icalproperty_new_dtend(
00224 writeICalDateTime(freebusy->dtEnd())));
00225
00226 if (method == Scheduler::Request) {
00227 icalcomponent_add_property(vfreebusy,icalproperty_new_uid(
00228 freebusy->uid().utf8()));
00229 }
00230
00231
00232 QValueList<Period> list = freebusy->busyPeriods();
00233 QValueList<Period>::Iterator it;
00234 icalperiodtype period;
00235 for (it = list.begin(); it!= list.end(); ++it) {
00236 period.start = writeICalDateTime((*it).start());
00237 period.end = writeICalDateTime((*it).end());
00238 icalcomponent_add_property(vfreebusy, icalproperty_new_freebusy(period) );
00239 }
00240
00241 return vfreebusy;
00242 }
00243
00244 icalcomponent *ICalFormatImpl::writeJournal(Journal *journal)
00245 {
00246 icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT);
00247
00248 writeIncidence(vjournal,journal);
00249
00250
00251 if (journal->dtStart().isValid()) {
00252 icaltimetype start;
00253 if (journal->doesFloat()) {
00254
00255 start = writeICalDate(journal->dtStart().date());
00256 } else {
00257
00258 start = writeICalDateTime(journal->dtStart());
00259 }
00260 icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start));
00261 }
00262
00263 return vjournal;
00264 }
00265
00266 void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence)
00267 {
00268
00269 icalcomponent_add_property(parent,icalproperty_new_created(
00270 writeICalDateTime(incidence->created())));
00271
00272
00273 icalcomponent_add_property(parent,icalproperty_new_uid(
00274 incidence->uid().utf8()));
00275
00276
00277 icalcomponent_add_property(parent,icalproperty_new_sequence(
00278 incidence->revision()));
00279
00280
00281 icalcomponent_add_property(parent,icalproperty_new_lastmodified(
00282 writeICalDateTime(incidence->lastModified())));
00283
00284 icalcomponent_add_property(parent,icalproperty_new_dtstamp(
00285 writeICalDateTime(QDateTime::currentDateTime())));
00286
00287
00288 icalcomponent_add_property(parent,icalproperty_new_organizer(
00289 ("MAILTO:" + incidence->organizer()).utf8()));
00290
00291
00292 if (incidence->attendeeCount() != 0) {
00293 QPtrList<Attendee> al = incidence->attendees();
00294 QPtrListIterator<Attendee> ai(al);
00295 for (; ai.current(); ++ai) {
00296 icalcomponent_add_property(parent,writeAttendee(ai.current()));
00297 }
00298 }
00299
00300
00301 if (!incidence->description().isEmpty()) {
00302 icalcomponent_add_property(parent,icalproperty_new_description(
00303 incidence->description().utf8()));
00304 }
00305
00306
00307 if (!incidence->summary().isEmpty()) {
00308 icalcomponent_add_property(parent,icalproperty_new_summary(
00309 incidence->summary().utf8()));
00310 }
00311
00312
00313 if (!incidence->location().isEmpty()) {
00314 icalcomponent_add_property(parent,icalproperty_new_location(
00315 incidence->location().utf8()));
00316 }
00317
00318
00319
00320
00321
00322
00323 const char *classStr;
00324 switch (incidence->secrecy()) {
00325 case Incidence::SecrecyPublic:
00326 classStr = "PUBLIC";
00327 break;
00328 case Incidence::SecrecyConfidential:
00329 classStr = "CONFIDENTIAL";
00330 break;
00331 case Incidence::SecrecyPrivate:
00332 default:
00333 classStr = "PRIVATE";
00334 break;
00335 }
00336 icalcomponent_add_property(parent,icalproperty_new_class(classStr));
00337
00338
00339 icalcomponent_add_property(parent,icalproperty_new_priority(
00340 incidence->priority()));
00341
00342
00343 QStringList categories = incidence->categories();
00344 QStringList::Iterator it;
00345 for(it = categories.begin(); it != categories.end(); ++it ) {
00346 icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8()));
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 if (incidence->relatedTo()) {
00377 icalcomponent_add_property(parent,icalproperty_new_relatedto(
00378 incidence->relatedTo()->uid().utf8()));
00379 }
00380
00381
00382 icalproperty *p =
00383 icalproperty_new_x((QString::number(incidence->pilotId())).utf8());
00384 icalproperty_set_x_name(p,"X-PILOTID");
00385 icalcomponent_add_property(parent,p);
00386 p = icalproperty_new_x((QString::number(incidence->syncStatus())).utf8());
00387 icalproperty_set_x_name(p,"X-PILOTSTAT");
00388 icalcomponent_add_property(parent,p);
00389
00390
00391 Recurrence *recur = incidence->recurrence();
00392 if (recur->doesRecur()) {
00393 kdDebug(5800) << "Write recurrence for '" << incidence->summary() << "' (" << incidence->uid()
00394 << ")" << endl;
00395 icalcomponent_add_property(parent,writeRecurrenceRule(recur));
00396 }
00397
00398
00399 DateList dateList = incidence->exDates();
00400 DateList::ConstIterator exIt;
00401 for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) {
00402 icalcomponent_add_property(parent,icalproperty_new_exdate(
00403 writeICalDate(*exIt)));
00404 }
00405
00406
00407 QPtrList<Alarm> alarms = incidence->alarms();
00408 Alarm* alarm;
00409 for (alarm = alarms.first(); alarm; alarm = alarms.next()) {
00410 if (alarm->enabled()) {
00411 kdDebug(5800) << "Write alarm for " << incidence->summary() << endl;
00412 icalcomponent_add_component(parent,writeAlarm(alarm));
00413 }
00414 }
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425 }
00426
00427 icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee)
00428 {
00429 icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8());
00430
00431 if (!attendee->name().isEmpty()) {
00432 icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8()));
00433 }
00434
00435
00436 icalproperty_add_parameter(p,icalparameter_new_rsvp(
00437 attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE ));
00438
00439 icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION;
00440 switch (attendee->status()) {
00441 default:
00442 case Attendee::NeedsAction:
00443 status = ICAL_PARTSTAT_NEEDSACTION;
00444 break;
00445 case Attendee::Accepted:
00446 status = ICAL_PARTSTAT_ACCEPTED;
00447 break;
00448 case Attendee::Declined:
00449 status = ICAL_PARTSTAT_DECLINED;
00450 break;
00451 case Attendee::Tentative:
00452 status = ICAL_PARTSTAT_TENTATIVE;
00453 break;
00454 case Attendee::Delegated:
00455 status = ICAL_PARTSTAT_DELEGATED;
00456 break;
00457 case Attendee::Completed:
00458 status = ICAL_PARTSTAT_COMPLETED;
00459 break;
00460 case Attendee::InProcess:
00461 status = ICAL_PARTSTAT_INPROCESS;
00462 break;
00463 }
00464 icalproperty_add_parameter(p,icalparameter_new_partstat(status));
00465
00466 icalparameter_role role = ICAL_ROLE_REQPARTICIPANT;
00467 switch (attendee->role()) {
00468 case Attendee::Chair:
00469 role = ICAL_ROLE_CHAIR;
00470 break;
00471 default:
00472 case Attendee::ReqParticipant:
00473 role = ICAL_ROLE_REQPARTICIPANT;
00474 break;
00475 case Attendee::OptParticipant:
00476 role = ICAL_ROLE_OPTPARTICIPANT;
00477 break;
00478 case Attendee::NonParticipant:
00479 role = ICAL_ROLE_NONPARTICIPANT;
00480 break;
00481 }
00482 icalproperty_add_parameter(p,icalparameter_new_role(role));
00483
00484 if (!attendee->uid().isEmpty()) {
00485 icalparameter* icalparameter_uid = icalparameter_new_x(attendee->uid().utf8());
00486 icalparameter_set_xname(icalparameter_uid,"X-UID");
00487 icalproperty_add_parameter(p,icalparameter_uid);
00488 }
00489
00490 return p;
00491 }
00492
00493 icalproperty *ICalFormatImpl::writeRecurrenceRule(Recurrence *recur)
00494 {
00495
00496
00497 icalrecurrencetype r;
00498
00499 icalrecurrencetype_clear(&r);
00500
00501 int index = 0;
00502 int index2 = 0;
00503
00504 QPtrList<Recurrence::rMonthPos> tmpPositions;
00505 QPtrList<int> tmpDays;
00506 int *tmpDay;
00507 Recurrence::rMonthPos *tmpPos;
00508 bool datetime = false;
00509 int day;
00510 int i;
00511
00512 switch(recur->doesRecur()) {
00513 case Recurrence::rMinutely:
00514 r.freq = ICAL_MINUTELY_RECURRENCE;
00515 datetime = true;
00516 break;
00517 case Recurrence::rHourly:
00518 r.freq = ICAL_HOURLY_RECURRENCE;
00519 datetime = true;
00520 break;
00521 case Recurrence::rDaily:
00522 r.freq = ICAL_DAILY_RECURRENCE;
00523 break;
00524 case Recurrence::rWeekly:
00525 r.freq = ICAL_WEEKLY_RECURRENCE;
00526 r.week_start = static_cast<icalrecurrencetype_weekday>(recur->weekStart()%7 + 1);
00527 for (i = 0; i < 7; i++) {
00528 if (recur->days().testBit(i)) {
00529 day = (i + 1)%7 + 1;
00530 r.by_day[index++] = icalrecurrencetype_day_day_of_week(day);
00531 }
00532 }
00533
00534 break;
00535 case Recurrence::rMonthlyPos:
00536 r.freq = ICAL_MONTHLY_RECURRENCE;
00537
00538 tmpPositions = recur->monthPositions();
00539 for (tmpPos = tmpPositions.first();
00540 tmpPos;
00541 tmpPos = tmpPositions.next()) {
00542 for (i = 0; i < 7; i++) {
00543 if (tmpPos->rDays.testBit(i)) {
00544 day = (i + 1)%7 + 1;
00545 day += tmpPos->rPos*8;
00546 if (tmpPos->negative) day = -day;
00547 r.by_day[index++] = day;
00548 }
00549 }
00550 }
00551
00552 break;
00553 case Recurrence::rMonthlyDay:
00554 r.freq = ICAL_MONTHLY_RECURRENCE;
00555
00556 tmpDays = recur->monthDays();
00557 for (tmpDay = tmpDays.first();
00558 tmpDay;
00559 tmpDay = tmpDays.next()) {
00560 r.by_month_day[index++] = icalrecurrencetype_day_position(*tmpDay*8);
00561 }
00562
00563 break;
00564 case Recurrence::rYearlyMonth:
00565 case Recurrence::rYearlyPos:
00566 r.freq = ICAL_YEARLY_RECURRENCE;
00567
00568 tmpDays = recur->yearNums();
00569 for (tmpDay = tmpDays.first();
00570 tmpDay;
00571 tmpDay = tmpDays.next()) {
00572 r.by_month[index++] = *tmpDay;
00573 }
00574
00575 if (recur->doesRecur() == Recurrence::rYearlyPos) {
00576 tmpPositions = recur->monthPositions();
00577 for (tmpPos = tmpPositions.first();
00578 tmpPos;
00579 tmpPos = tmpPositions.next()) {
00580 for (i = 0; i < 7; i++) {
00581 if (tmpPos->rDays.testBit(i)) {
00582 day = (i + 1)%7 + 1;
00583 day += tmpPos->rPos*8;
00584 if (tmpPos->negative) day = -day;
00585 r.by_day[index2++] = day;
00586 }
00587 }
00588 }
00589
00590 }
00591 break;
00592 case Recurrence::rYearlyDay:
00593 r.freq = ICAL_YEARLY_RECURRENCE;
00594
00595 tmpDays = recur->yearNums();
00596 for (tmpDay = tmpDays.first();
00597 tmpDay;
00598 tmpDay = tmpDays.next()) {
00599 r.by_year_day[index++] = *tmpDay;
00600 }
00601
00602 break;
00603 default:
00604 r.freq = ICAL_NO_RECURRENCE;
00605 kdDebug(5800) << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl;
00606 break;
00607 }
00608
00609 r.interval = recur->frequency();
00610
00611 if (recur->duration() > 0) {
00612 r.count = recur->duration();
00613 } else if (recur->duration() == -1) {
00614 r.count = 0;
00615 } else {
00616 if (datetime)
00617 r.until = writeICalDateTime(recur->endDateTime());
00618 else
00619 r.until = writeICalDate(recur->endDate());
00620 }
00621
00622
00623 #if 0
00624 const char *str = icalrecurrencetype_as_string(&r);
00625 if (str) {
00626 kdDebug(5800) << " String: " << str << endl;
00627 } else {
00628 kdDebug(5800) << " No String" << endl;
00629 }
00630 #endif
00631
00632 return icalproperty_new_rrule(r);
00633 }
00634
00635 icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm)
00636 {
00637 icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT);
00638
00639 icalproperty_action action;
00640 icalattachtype *attach = 0;
00641
00642 if (!alarm->programFile().isEmpty()) {
00643 action = ICAL_ACTION_PROCEDURE;
00644 attach = icalattachtype_new();
00645 icalattachtype_set_url(attach,QFile::encodeName(alarm->programFile()).data());
00646 icalcomponent_add_property(a,icalproperty_new_attach(attach));
00647 icalattachtype_free(attach);
00648 } else if (!alarm->audioFile().isEmpty()) {
00649 action = ICAL_ACTION_AUDIO;
00650 attach = icalattachtype_new();
00651 icalattachtype_set_url(attach,QFile::encodeName( alarm->audioFile() ).data());
00652 icalcomponent_add_property(a,icalproperty_new_attach(attach));
00653 icalattachtype_free(attach);
00654 } else if (alarm->mailAddresses().count() > 0) {
00655 action = ICAL_ACTION_EMAIL;
00656 QStringList addresses = alarm->mailAddresses();
00657 for (QStringList::Iterator ad = addresses.begin(); ad != addresses.end(); ++ad) {
00658 icalcomponent_add_property(a,icalproperty_new_attendee((*ad).utf8()));
00659 }
00660 icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject().utf8()));
00661 icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
00662 QStringList attachments = alarm->mailAttachments();
00663 if (attachments.count() > 0) {
00664 for (QStringList::Iterator at = attachments.begin(); at != attachments.end(); ++at) {
00665 attach = icalattachtype_new();
00666 icalattachtype_set_url(attach,QFile::encodeName( *at ).data());
00667 icalcomponent_add_property(a,icalproperty_new_attach(attach));
00668 icalattachtype_free(attach);
00669 }
00670 }
00671 } else {
00672 action = ICAL_ACTION_DISPLAY;
00673 icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
00674 }
00675 icalcomponent_add_property(a,icalproperty_new_action(action));
00676
00677 icaltriggertype trigger;
00678 if ( alarm->hasTime() ) {
00679 trigger.time = writeICalDateTime(alarm->time());
00680 trigger.duration = icaldurationtype_null_duration();
00681 } else {
00682 trigger.time = icaltime_null_time();
00683 trigger.duration = icaldurationtype_from_int( alarm->offset().asSeconds() );
00684 }
00685 icalcomponent_add_property(a,icalproperty_new_trigger(trigger));
00686
00687 if (alarm->repeatCount()) {
00688 icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount()));
00689 icalcomponent_add_property(a,icalproperty_new_duration(
00690 icaldurationtype_from_int(alarm->snoozeTime()*60)));
00691 }
00692
00693 return a;
00694 }
00695
00696 Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo)
00697 {
00698 Todo *todo = new Todo;
00699
00700 readIncidence(vtodo,todo);
00701
00702 icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY);
00703
00704
00705 icaltimetype icaltime;
00706
00707 QStringList categories;
00708
00709 while (p) {
00710 icalproperty_kind kind = icalproperty_isa(p);
00711 switch (kind) {
00712
00713 case ICAL_DUE_PROPERTY:
00714 icaltime = icalproperty_get_due(p);
00715 if (icaltime.is_date) {
00716 todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
00717 todo->setFloats(true);
00718
00719 } else {
00720 todo->setDtDue(readICalDateTime(icaltime));
00721 todo->setFloats(false);
00722 }
00723 todo->setHasDueDate(true);
00724 break;
00725
00726 case ICAL_COMPLETED_PROPERTY:
00727 icaltime = icalproperty_get_completed(p);
00728 todo->setCompleted(readICalDateTime(icaltime));
00729 break;
00730
00731 case ICAL_PERCENTCOMPLETE_PROPERTY:
00732 todo->setPercentComplete(icalproperty_get_percentcomplete(p));
00733 break;
00734
00735 case ICAL_RELATEDTO_PROPERTY:
00736 todo->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
00737 mTodosRelate.append(todo);
00738 break;
00739
00740 case ICAL_DTSTART_PROPERTY:
00741
00742 todo->setHasStartDate(true);
00743 break;
00744
00745 default:
00746
00747
00748 break;
00749 }
00750
00751 p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY);
00752 }
00753
00754 return todo;
00755 }
00756
00757 Event *ICalFormatImpl::readEvent(icalcomponent *vevent)
00758 {
00759 Event *event = new Event;
00760 event->setFloats(false);
00761
00762 readIncidence(vevent,event);
00763
00764 icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY);
00765
00766
00767 icaltimetype icaltime;
00768
00769 QStringList categories;
00770
00771 while (p) {
00772 icalproperty_kind kind = icalproperty_isa(p);
00773 switch (kind) {
00774
00775 case ICAL_DTEND_PROPERTY:
00776 icaltime = icalproperty_get_dtend(p);
00777 if (icaltime.is_date) {
00778 event->setFloats( true );
00779
00780 QDate endDate = readICalDate( icaltime ).addDays( -1 );
00781 mCompat->fixFloatingEnd( endDate );
00782 if ( endDate < event->dtStart().date() ) {
00783 endDate = event->dtStart().date();
00784 }
00785 event->setDtEnd( QDateTime( endDate, QTime( 0, 0, 0 ) ) );
00786 } else {
00787 event->setDtEnd(readICalDateTime(icaltime));
00788 }
00789 break;
00790
00791
00792
00793
00794 #if 0
00795 if (!(vo = isAPropertyOf(vevent, VCDTstartProp)))
00796 anEvent->setDtStart(anEvent->dtEnd());
00797 if (!(vo = isAPropertyOf(vevent, VCDTendProp)))
00798 anEvent->setDtEnd(anEvent->dtStart());
00799 #endif
00800
00801
00802 #if 0
00803
00804 if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) {
00805 anEvent->setExDates(s = fakeCString(vObjectUStringZValue(vo)));
00806 deleteStr(s);
00807 }
00808 #endif
00809
00810 #if 0
00811
00812 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
00813 anEvent->setSecrecy(s = fakeCString(vObjectUStringZValue(vo)));
00814 deleteStr(s);
00815 }
00816 else
00817 anEvent->setSecrecy("PUBLIC");
00818
00819
00820 tmpStrList.clear();
00821 initPropIterator(&voi, vevent);
00822 while (moreIteration(&voi)) {
00823 vo = nextVObject(&voi);
00824 if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
00825 tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo)));
00826 deleteStr(s);
00827 }
00828 }
00829 anEvent->setAttachments(tmpStrList);
00830
00831
00832 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
00833 QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
00834 deleteStr(s);
00835 tmpStrList.clear();
00836 index1 = 0;
00837 index2 = 0;
00838 QString resource;
00839 while ((index2 = resources.find(';', index1)) != -1) {
00840 resource = resources.mid(index1, (index2 - index1));
00841 tmpStrList.append(resource);
00842 index1 = index2;
00843 }
00844 anEvent->setResources(tmpStrList);
00845 }
00846 #endif
00847
00848
00849 #if 0
00850
00851 if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) {
00852 anEvent->setTransparency(atoi(s = fakeCString(vObjectUStringZValue(vo))));
00853 deleteStr(s);
00854 }
00855 #endif
00856
00857 case ICAL_RELATEDTO_PROPERTY:
00858 event->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
00859 mEventsRelate.append(event);
00860 break;
00861
00862 case ICAL_X_PROPERTY:
00863 if (strcmp(icalproperty_get_name(p),"X-MICROSOFT-CDO-ALLDAYEVENT") == 0) {
00864 const char *text = icalproperty_get_value_as_string(p);
00865 bool floats = (strcmp(text, "TRUE") == 0);
00866 kdDebug(5800) << "ICALFormat::readEvent(): all day event: " << floats << endl;
00867 event->setFloats(floats);
00868 if (floats) {
00869 QDateTime endDate = event->dtEnd();
00870 event->setDtEnd(endDate.addDays(-1));
00871 }
00872 }
00873 break;
00874
00875
00876 default:
00877
00878
00879 break;
00880 }
00881
00882 p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY);
00883 }
00884
00885
00886
00887 if (event->summary().isEmpty() &&
00888 !(event->description().isEmpty())) {
00889 QString tmpStr = event->description().simplifyWhiteSpace();
00890 event->setDescription("");
00891 event->setSummary(tmpStr);
00892 }
00893
00894 return event;
00895 }
00896
00897 FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy)
00898 {
00899 FreeBusy *freebusy = new FreeBusy;
00900
00901 icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY);
00902
00903 icaltimetype icaltime;
00904 icalperiodtype icalperiod;
00905 QDateTime period_start, period_end;
00906
00907 while (p) {
00908 icalproperty_kind kind = icalproperty_isa(p);
00909 switch (kind) {
00910
00911 case ICAL_UID_PROPERTY:
00912 freebusy->setUid(QString::fromUtf8(icalproperty_get_uid(p)));
00913 break;
00914
00915 case ICAL_ORGANIZER_PROPERTY:
00916 freebusy->setOrganizer(QString::fromUtf8(icalproperty_get_organizer(p)));
00917 break;
00918
00919 case ICAL_ATTENDEE_PROPERTY:
00920 freebusy->addAttendee(readAttendee(p));
00921 break;
00922
00923 case ICAL_DTSTART_PROPERTY:
00924 icaltime = icalproperty_get_dtstart(p);
00925 freebusy->setDtStart(readICalDateTime(icaltime));
00926 break;
00927
00928 case ICAL_DTEND_PROPERTY:
00929 icaltime = icalproperty_get_dtend(p);
00930 freebusy->setDtEnd(readICalDateTime(icaltime));
00931 break;
00932
00933 case ICAL_FREEBUSY_PROPERTY:
00934 icalperiod = icalproperty_get_freebusy(p);
00935 period_start = readICalDateTime(icalperiod.start);
00936 period_end = readICalDateTime(icalperiod.end);
00937 freebusy->addPeriod(period_start, period_end);
00938 break;
00939
00940 default:
00941 kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind
00942 << endl;
00943 break;
00944 }
00945 p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY);
00946 }
00947
00948 return freebusy;
00949 }
00950
00951 Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal)
00952 {
00953 Journal *journal = new Journal;
00954
00955 readIncidence(vjournal,journal);
00956
00957 return journal;
00958 }
00959
00960 Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee)
00961 {
00962 icalparameter *p = 0;
00963
00964 QString email = QString::fromUtf8(icalproperty_get_attendee(attendee));
00965
00966 QString name;
00967 QString uid = QString::null;
00968 p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER);
00969 if (p) {
00970 name = QString::fromUtf8(icalparameter_get_cn(p));
00971 } else {
00972 }
00973
00974 bool rsvp=false;
00975 p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER);
00976 if (p) {
00977 icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p);
00978 if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true;
00979 }
00980
00981 Attendee::PartStat status = Attendee::NeedsAction;
00982 p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER);
00983 if (p) {
00984 icalparameter_partstat partStatParameter = icalparameter_get_partstat(p);
00985 switch(partStatParameter) {
00986 default:
00987 case ICAL_PARTSTAT_NEEDSACTION:
00988 status = Attendee::NeedsAction;
00989 break;
00990 case ICAL_PARTSTAT_ACCEPTED:
00991 status = Attendee::Accepted;
00992 break;
00993 case ICAL_PARTSTAT_DECLINED:
00994 status = Attendee::Declined;
00995 break;
00996 case ICAL_PARTSTAT_TENTATIVE:
00997 status = Attendee::Tentative;
00998 break;
00999 case ICAL_PARTSTAT_DELEGATED:
01000 status = Attendee::Delegated;
01001 break;
01002 case ICAL_PARTSTAT_COMPLETED:
01003 status = Attendee::Completed;
01004 break;
01005 case ICAL_PARTSTAT_INPROCESS:
01006 status = Attendee::InProcess;
01007 break;
01008 }
01009 }
01010
01011 Attendee::Role role = Attendee::ReqParticipant;
01012 p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER);
01013 if (p) {
01014 icalparameter_role roleParameter = icalparameter_get_role(p);
01015 switch(roleParameter) {
01016 case ICAL_ROLE_CHAIR:
01017 role = Attendee::Chair;
01018 break;
01019 default:
01020 case ICAL_ROLE_REQPARTICIPANT:
01021 role = Attendee::ReqParticipant;
01022 break;
01023 case ICAL_ROLE_OPTPARTICIPANT:
01024 role = Attendee::OptParticipant;
01025 break;
01026 case ICAL_ROLE_NONPARTICIPANT:
01027 role = Attendee::NonParticipant;
01028 break;
01029 }
01030 }
01031
01032 p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER);
01033 uid = icalparameter_get_xvalue(p);
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044 return new Attendee( name, email, rsvp, status, role, uid );
01045 }
01046
01047 void ICalFormatImpl::readIncidence(icalcomponent *parent,Incidence *incidence)
01048 {
01049 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
01050
01051 const char *text;
01052 int intvalue;
01053 icaltimetype icaltime;
01054 icaldurationtype icalduration;
01055
01056 QStringList categories;
01057
01058 while (p) {
01059 icalproperty_kind kind = icalproperty_isa(p);
01060 switch (kind) {
01061
01062 case ICAL_CREATED_PROPERTY:
01063 icaltime = icalproperty_get_created(p);
01064 incidence->setCreated(readICalDateTime(icaltime));
01065 break;
01066
01067 case ICAL_UID_PROPERTY:
01068 text = icalproperty_get_uid(p);
01069 incidence->setUid(QString::fromUtf8(text));
01070 break;
01071
01072 case ICAL_SEQUENCE_PROPERTY:
01073 intvalue = icalproperty_get_sequence(p);
01074 incidence->setRevision(intvalue);
01075 break;
01076
01077 case ICAL_LASTMODIFIED_PROPERTY:
01078 icaltime = icalproperty_get_lastmodified(p);
01079 incidence->setLastModified(readICalDateTime(icaltime));
01080 break;
01081
01082 case ICAL_ORGANIZER_PROPERTY:
01083 text = icalproperty_get_organizer(p);
01084 incidence->setOrganizer(QString::fromUtf8(text));
01085 break;
01086
01087 case ICAL_ATTENDEE_PROPERTY:
01088 incidence->addAttendee(readAttendee(p));
01089 break;
01090
01091 case ICAL_DTSTART_PROPERTY:
01092 icaltime = icalproperty_get_dtstart(p);
01093 if (icaltime.is_date) {
01094 incidence->setDtStart(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
01095 incidence->setFloats(true);
01096 } else {
01097 incidence->setDtStart(readICalDateTime(icaltime));
01098 }
01099 break;
01100
01101 case ICAL_DURATION_PROPERTY:
01102 icalduration = icalproperty_get_duration(p);
01103 incidence->setDuration(readICalDuration(icalduration));
01104 break;
01105
01106 case ICAL_DESCRIPTION_PROPERTY:
01107 text = icalproperty_get_description(p);
01108 incidence->setDescription(QString::fromUtf8(text));
01109 break;
01110
01111 case ICAL_SUMMARY_PROPERTY:
01112 text = icalproperty_get_summary(p);
01113 incidence->setSummary(QString::fromUtf8(text));
01114 break;
01115
01116 case ICAL_LOCATION_PROPERTY:
01117 text = icalproperty_get_location(p);
01118 incidence->setLocation(QString::fromUtf8(text));
01119 break;
01120
01121 #if 0
01122
01123 if ((vo = isAPropertyOf(vincidence, VCStatusProp)) != 0) {
01124 incidence->setStatus(s = fakeCString(vObjectUStringZValue(vo)));
01125 deleteStr(s);
01126 }
01127 else
01128 incidence->setStatus("NEEDS ACTION");
01129 #endif
01130
01131 case ICAL_PRIORITY_PROPERTY:
01132 intvalue = icalproperty_get_priority(p);
01133 incidence->setPriority(intvalue);
01134 break;
01135
01136 case ICAL_CATEGORIES_PROPERTY:
01137 text = icalproperty_get_categories(p);
01138 categories.append(QString::fromUtf8(text));
01139 break;
01140
01141 case ICAL_RRULE_PROPERTY:
01142 readRecurrenceRule(p,incidence);
01143 break;
01144
01145 case ICAL_EXDATE_PROPERTY:
01146 icaltime = icalproperty_get_exdate(p);
01147 incidence->addExDate(readICalDate(icaltime));
01148 break;
01149
01150 case ICAL_CLASS_PROPERTY:
01151 text = icalproperty_get_class(p);
01152 if (strcmp(text,"PUBLIC") == 0) {
01153 incidence->setSecrecy(Incidence::SecrecyPublic);
01154 } else if (strcmp(text,"CONFIDENTIAL") == 0) {
01155 incidence->setSecrecy(Incidence::SecrecyConfidential);
01156 } else {
01157 incidence->setSecrecy(Incidence::SecrecyPrivate);
01158 }
01159 break;
01160
01161
01162 case ICAL_X_PROPERTY:
01163 if (strcmp(icalproperty_get_name(p),"X-PILOTID") == 0) {
01164 text = icalproperty_get_value_as_string(p);
01165 incidence->setPilotId(QString::fromUtf8(text).toInt());
01166 } else if (strcmp(icalproperty_get_name(p),"X-PILOTSTAT") == 0) {
01167 text = icalproperty_get_value_as_string(p);
01168 incidence->setSyncStatus(QString::fromUtf8(text).toInt());
01169 }
01170 break;
01171
01172 default:
01173
01174
01175 break;
01176 }
01177
01178 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
01179 }
01180
01181
01182 incidence->recurrence()->setCompatVersion();
01183
01184
01185 incidence->setCategories(categories);
01186
01187
01188 for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT);
01189 alarm;
01190 alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) {
01191 readAlarm(alarm,incidence);
01192 }
01193 }
01194
01195 void ICalFormatImpl::readRecurrenceRule(icalproperty *rrule,Incidence *incidence)
01196 {
01197
01198
01199 Recurrence *recur = incidence->recurrence();
01200 recur->setCompatVersion(mCalendarVersion);
01201 recur->unsetRecurs();
01202
01203 struct icalrecurrencetype r = icalproperty_get_rrule(rrule);
01204
01205 dumpIcalRecurrence(r);
01206
01207 readRecurrence( r, recur );
01208 }
01209
01210 void ICalFormatImpl::readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur )
01211 {
01212 int wkst;
01213 int index = 0;
01214 short day = 0;
01215 QBitArray qba(7);
01216
01217 switch (r.freq) {
01218 case ICAL_MINUTELY_RECURRENCE:
01219 if (!icaltime_is_null_time(r.until)) {
01220 recur->setMinutely(r.interval,readICalDateTime(r.until));
01221 } else {
01222 if (r.count == 0)
01223 recur->setMinutely(r.interval,-1);
01224 else
01225 recur->setMinutely(r.interval,r.count);
01226 }
01227 break;
01228 case ICAL_HOURLY_RECURRENCE:
01229 if (!icaltime_is_null_time(r.until)) {
01230 recur->setHourly(r.interval,readICalDateTime(r.until));
01231 } else {
01232 if (r.count == 0)
01233 recur->setHourly(r.interval,-1);
01234 else
01235 recur->setHourly(r.interval,r.count);
01236 }
01237 break;
01238 case ICAL_DAILY_RECURRENCE:
01239 if (!icaltime_is_null_time(r.until)) {
01240 recur->setDaily(r.interval,readICalDate(r.until));
01241 } else {
01242 if (r.count == 0)
01243 recur->setDaily(r.interval,-1);
01244 else
01245 recur->setDaily(r.interval,r.count);
01246 }
01247 break;
01248 case ICAL_WEEKLY_RECURRENCE:
01249
01250 wkst = (r.week_start + 5)%7 + 1;
01251 if (!icaltime_is_null_time(r.until)) {
01252 recur->setWeekly(r.interval,qba,readICalDate(r.until),wkst);
01253 } else {
01254 if (r.count == 0)
01255 recur->setWeekly(r.interval,qba,-1,wkst);
01256 else
01257 recur->setWeekly(r.interval,qba,r.count,wkst);
01258 }
01259 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01260
01261 qba.setBit((day+5)%7);
01262 }
01263 break;
01264 case ICAL_MONTHLY_RECURRENCE:
01265 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01266 if (!icaltime_is_null_time(r.until)) {
01267 recur->setMonthly(Recurrence::rMonthlyPos,r.interval,
01268 readICalDate(r.until));
01269 } else {
01270 if (r.count == 0)
01271 recur->setMonthly(Recurrence::rMonthlyPos,r.interval,-1);
01272 else
01273 recur->setMonthly(Recurrence::rMonthlyPos,r.interval,r.count);
01274 }
01275 bool useSetPos = false;
01276 short pos = 0;
01277 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01278
01279 pos = icalrecurrencetype_day_position(day);
01280 if (pos) {
01281 day = icalrecurrencetype_day_day_of_week(day);
01282 QBitArray ba(7);
01283 ba.setBit((day+5)%7);
01284 recur->addMonthlyPos(pos,ba);
01285 } else {
01286 qba.setBit((day+5)%7);
01287 useSetPos = true;
01288 }
01289 }
01290 if (useSetPos) {
01291 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01292 recur->addMonthlyPos(r.by_set_pos[0],qba);
01293 }
01294 }
01295 } else if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01296 if (!icaltime_is_null_time(r.until)) {
01297 recur->setMonthly(Recurrence::rMonthlyDay,r.interval,
01298 readICalDate(r.until));
01299 } else {
01300 if (r.count == 0)
01301 recur->setMonthly(Recurrence::rMonthlyDay,r.interval,-1);
01302 else
01303 recur->setMonthly(Recurrence::rMonthlyDay,r.interval,r.count);
01304 }
01305 while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01306
01307 recur->addMonthlyDay(day);
01308 }
01309 }
01310 break;
01311 case ICAL_YEARLY_RECURRENCE:
01312 if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01313 if (!icaltime_is_null_time(r.until)) {
01314 recur->setYearly(Recurrence::rYearlyDay,r.interval,
01315 readICalDate(r.until));
01316 } else {
01317 if (r.count == 0)
01318 recur->setYearly(Recurrence::rYearlyDay,r.interval,-1);
01319 else
01320 recur->setYearly(Recurrence::rYearlyDay,r.interval,r.count);
01321 }
01322 while((day = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01323 recur->addYearlyNum(day);
01324 }
01325 } if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01326 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01327 if (!icaltime_is_null_time(r.until)) {
01328 recur->setYearly(Recurrence::rYearlyPos,r.interval,
01329 readICalDate(r.until));
01330 } else {
01331 if (r.count == 0)
01332 recur->setYearly(Recurrence::rYearlyPos,r.interval,-1);
01333 else
01334 recur->setYearly(Recurrence::rYearlyPos,r.interval,r.count);
01335 }
01336 bool useSetPos = false;
01337 short pos = 0;
01338 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01339
01340 pos = icalrecurrencetype_day_position(day);
01341 if (pos) {
01342 day = icalrecurrencetype_day_day_of_week(day);
01343 QBitArray ba(7);
01344 ba.setBit((day+5)%7);
01345 recur->addYearlyMonthPos(pos,ba);
01346 } else {
01347 qba.setBit((day+5)%7);
01348 useSetPos = true;
01349 }
01350 }
01351 if (useSetPos) {
01352 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01353 recur->addYearlyMonthPos(r.by_set_pos[0],qba);
01354 }
01355 }
01356 } else {
01357 if (!icaltime_is_null_time(r.until)) {
01358 recur->setYearly(Recurrence::rYearlyMonth,r.interval,
01359 readICalDate(r.until));
01360 } else {
01361 if (r.count == 0)
01362 recur->setYearly(Recurrence::rYearlyMonth,r.interval,-1);
01363 else
01364 recur->setYearly(Recurrence::rYearlyMonth,r.interval,r.count);
01365 }
01366 }
01367 index = 0;
01368 while((day = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01369 recur->addYearlyNum(day);
01370 }
01371 }
01372 break;
01373 default:
01374 kdDebug(5800) << "Unknown type of recurrence: " << r.freq << endl;
01375 break;
01376 }
01377 }
01378
01379 void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence)
01380 {
01381
01382
01383 Alarm* ialarm = incidence->newAlarm();
01384 ialarm->setRepeatCount(0);
01385 ialarm->setEnabled(true);
01386
01387 icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY);
01388
01389 icaltriggertype trigger;
01390 icalattachtype *attach;
01391 icaldurationtype duration;
01392
01393 icalproperty_action action = ICAL_ACTION_NONE;
01394
01395 while (p) {
01396 icalproperty_kind kind = icalproperty_isa(p);
01397
01398 switch (kind) {
01399
01400 case ICAL_ACTION_PROPERTY:
01401 action = icalproperty_get_action(p);
01402 break;
01403
01404 case ICAL_TRIGGER_PROPERTY:
01405 trigger = icalproperty_get_trigger(p);
01406 if (icaltime_is_null_time(trigger.time)) {
01407 if (icaldurationtype_is_null_duration(trigger.duration)) {
01408 kdDebug(5800) << "ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl;
01409 } else {
01410 ialarm->setOffset( Duration( icaldurationtype_as_int( trigger.duration ) ) );
01411 }
01412 } else {
01413 ialarm->setTime(readICalDateTime(trigger.time));
01414 }
01415 break;
01416
01417 case ICAL_DURATION_PROPERTY:
01418 duration = icalproperty_get_duration(p);
01419 ialarm->setSnoozeTime(icaldurationtype_as_int(duration)/60);
01420 break;
01421
01422 case ICAL_REPEAT_PROPERTY:
01423 ialarm->setRepeatCount(icalproperty_get_repeat(p));
01424 break;
01425
01426
01427 case ICAL_DESCRIPTION_PROPERTY:
01428 ialarm->setText(QString::fromUtf8(icalproperty_get_description(p)));
01429 break;
01430
01431
01432 case ICAL_SUMMARY_PROPERTY:
01433 ialarm->setMailSubject(QString::fromUtf8(icalproperty_get_summary(p)));
01434 break;
01435
01436
01437 case ICAL_ATTENDEE_PROPERTY:
01438 ialarm->addMailAddress(QString::fromUtf8(icalproperty_get_attendee(p)));
01439 break;
01440
01441 default:
01442 break;
01443 }
01444
01445 p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY);
01446 }
01447
01448
01449 p = icalcomponent_get_first_property(alarm,ICAL_ATTACH_PROPERTY);
01450 while ( p ) {
01451 attach = icalproperty_get_attach(p);
01452 QString url = QFile::decodeName(icalattachtype_get_url(attach));
01453 switch ( action ) {
01454 case ICAL_ACTION_AUDIO:
01455 ialarm->setAudioFile( url );
01456 break;
01457 case ICAL_ACTION_PROCEDURE:
01458 ialarm->setProgramFile( url );
01459 break;
01460 case ICAL_ACTION_EMAIL:
01461 ialarm->addMailAttachment( url );
01462 break;
01463 default:
01464 break;
01465 }
01466
01467 p = icalcomponent_get_next_property(alarm,ICAL_ATTACH_PROPERTY);
01468 }
01469
01470
01471 }
01472
01473 icaltimetype ICalFormatImpl::writeICalDate(const QDate &date)
01474 {
01475 icaltimetype t;
01476
01477 t.year = date.year();
01478 t.month = date.month();
01479 t.day = date.day();
01480
01481 t.hour = 0;
01482 t.minute = 0;
01483 t.second = 0;
01484
01485 t.is_date = 1;
01486
01487 t.is_utc = 0;
01488
01489 t.zone = 0;
01490
01491 return t;
01492 }
01493
01494 icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &datetime)
01495 {
01496 icaltimetype t;
01497
01498 t.year = datetime.date().year();
01499 t.month = datetime.date().month();
01500 t.day = datetime.date().day();
01501
01502 t.hour = datetime.time().hour();
01503 t.minute = datetime.time().minute();
01504 t.second = datetime.time().second();
01505
01506 t.is_date = 0;
01507 t.zone = 0;
01508 t.is_utc = 0;
01509
01510 if ( mParent->utc() ) {
01511 if (mParent->timeZoneId().isEmpty())
01512 t = icaltime_as_utc(t, 0);
01513 else
01514 t = icaltime_as_utc(t,mParent->timeZoneId().local8Bit());
01515 }
01516
01517 return t;
01518 }
01519
01520 QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t)
01521 {
01522
01523
01524
01525
01526
01527
01528
01529
01530
01531 if (t.is_utc) {
01532
01533 if (mParent->timeZoneId().isEmpty())
01534 t = icaltime_as_zone(t, 0);
01535 else
01536 t = icaltime_as_zone(t,mParent->timeZoneId().local8Bit());
01537 }
01538
01539 return QDateTime(QDate(t.year,t.month,t.day),
01540 QTime(t.hour,t.minute,t.second));
01541 }
01542
01543 QDate ICalFormatImpl::readICalDate(icaltimetype t)
01544 {
01545 return QDate(t.year,t.month,t.day);
01546 }
01547
01548 icaldurationtype ICalFormatImpl::writeICalDuration(int seconds)
01549 {
01550 icaldurationtype d;
01551
01552 d.weeks = seconds % gSecondsPerWeek;
01553 seconds -= d.weeks * gSecondsPerWeek;
01554 d.days = seconds % gSecondsPerDay;
01555 seconds -= d.days * gSecondsPerDay;
01556 d.hours = seconds % gSecondsPerHour;
01557 seconds -= d.hours * gSecondsPerHour;
01558 d.minutes = seconds % gSecondsPerMinute;
01559 seconds -= d.minutes * gSecondsPerMinute;
01560 d.seconds = seconds;
01561 d.is_neg = 0;
01562
01563 return d;
01564 }
01565
01566 int ICalFormatImpl::readICalDuration(icaldurationtype d)
01567 {
01568 int result = 0;
01569
01570 result += d.weeks * gSecondsPerWeek;
01571 result += d.days * gSecondsPerDay;
01572 result += d.hours * gSecondsPerHour;
01573 result += d.minutes * gSecondsPerMinute;
01574 result += d.seconds;
01575
01576 if (d.is_neg) result *= -1;
01577
01578 return result;
01579 }
01580
01581 icalcomponent *ICalFormatImpl::createCalendarComponent()
01582 {
01583 icalcomponent *calendar;
01584
01585
01586 calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
01587
01588 icalproperty *p;
01589
01590
01591 p = icalproperty_new_prodid(CalFormat::productId().utf8());
01592 icalcomponent_add_property(calendar,p);
01593
01594
01595
01596
01597 p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION));
01598 icalcomponent_add_property(calendar,p);
01599
01600 return calendar;
01601 }
01602
01603
01604
01605
01606
01607
01608 bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar)
01609 {
01610
01611
01612
01613 if (!calendar) return false;
01614
01615
01616 #if 0
01617 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
01618 char *methodType = 0;
01619 methodType = fakeCString(vObjectUStringZValue(curVO));
01620 if (mEnableDialogs)
01621 KMessageBox::information(mTopWidget,
01622 i18n("This calendar is an iTIP transaction of type \"%1\".")
01623 .arg(methodType),
01624 i18n("%1: iTIP Transaction").arg(CalFormat::application()));
01625 delete methodType;
01626 }
01627 #endif
01628
01629 icalproperty *p;
01630
01631 p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY);
01632 if (!p) {
01633 kdDebug(5800) << "No PRODID property found" << endl;
01634
01635
01636
01637 mLoadedProductId = "";
01638 mCalendarVersion = 0;
01639 } else {
01640 mLoadedProductId = QString::fromUtf8(icalproperty_get_prodid(p));
01641 mCalendarVersion = CalFormat::calendarVersion(mLoadedProductId);
01642 kdDebug(5800) << "VCALENDAR prodid: '" << mLoadedProductId << "'" << endl;
01643
01644 delete mCompat;
01645 mCompat = CompatFactory::createCompat( mLoadedProductId );
01646 }
01647
01648
01649 #if 0
01650 if (!mCalendarVersion
01651 && CalFormat::productId() != mLoadedProductId) {
01652
01653 if (mEnableDialogs)
01654 KMessageBox::information(mTopWidget,
01655 i18n("This vCalendar file was not created by KOrganizer "
01656 "or any other product we support. Loading anyway..."),
01657 i18n("%1: Unknown vCalendar Vendor").arg(CalFormat::application()));
01658 }
01659 #endif
01660
01661 p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY);
01662 if (!p) {
01663 kdDebug(5800) << "No VERSION property found" << endl;
01664 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
01665 return false;
01666 } else {
01667 const char *version = icalproperty_get_version(p);
01668 kdDebug(5800) << "VCALENDAR version: '" << version << "'" << endl;
01669
01670 if (strcmp(version,"1.0") == 0) {
01671 kdDebug(5800) << "Expected iCalendar, got vCalendar" << endl;
01672 mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1,
01673 i18n("Expected iCalendar format")));
01674 return false;
01675 } else if (strcmp(version,"2.0") != 0) {
01676 kdDebug(5800) << "Expected iCalendar, got unknown format" << endl;
01677 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
01678 return false;
01679 }
01680 }
01681
01682
01683
01684 #if 0
01685
01686 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
01687 char *s = fakeCString(vObjectUStringZValue(curVO));
01688 if (strcmp(_VCAL_VERSION, s) != 0)
01689 if (mEnableDialogs)
01690 KMessageBox::sorry(mTopWidget,
01691 i18n("This vCalendar file has version %1.\n"
01692 "We only support %2.")
01693 .arg(s).arg(_VCAL_VERSION),
01694 i18n("%1: Unknown vCalendar Version").arg(CalFormat::application()));
01695 deleteStr(s);
01696 }
01697 #endif
01698
01699
01700 #if 0
01701
01702 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
01703 char *s = fakeCString(vObjectUStringZValue(curVO));
01704 cal->setTimeZone(s);
01705 deleteStr(s);
01706 }
01707 #endif
01708
01709
01710 mEventsRelate.clear();
01711 mTodosRelate.clear();
01712
01713
01714 icalcomponent *c;
01715
01716
01717 c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT);
01718 while (c) {
01719
01720 Todo *todo = readTodo(c);
01721 if (!cal->todo(todo->uid())) cal->addTodo(todo);
01722 c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT);
01723 }
01724
01725
01726 c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT);
01727 while (c) {
01728
01729 Event *event = readEvent(c);
01730 if (!cal->event(event->uid())) cal->addEvent(event);
01731 c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT);
01732 }
01733
01734
01735 c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT);
01736 while (c) {
01737
01738 Journal *journal = readJournal(c);
01739 if (!cal->journal(journal->uid())) cal->addJournal(journal);
01740 c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT);
01741 }
01742
01743 #if 0
01744 initPropIterator(&i, vcal);
01745
01746
01747 while (moreIteration(&i)) {
01748 curVO = nextVObject(&i);
01749
01750
01751
01752
01753 if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
01754
01755 if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) {
01756 char *s;
01757 s = fakeCString(vObjectUStringZValue(curVOProp));
01758
01759 if (atoi(s) == Event::SYNCDEL) {
01760 deleteStr(s);
01761 kdDebug(5800) << "skipping pilot-deleted event" << endl;
01762 goto SKIP;
01763 }
01764 deleteStr(s);
01765 }
01766
01767
01768
01769
01770 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) {
01771 char *s = fakeCString(vObjectUStringZValue(curVOProp));
01772 QString tmpStr(s);
01773 deleteStr(s);
01774
01775 if (cal->event(tmpStr)) {
01776 goto SKIP;
01777 }
01778 if (cal->todo(tmpStr)) {
01779 goto SKIP;
01780 }
01781 }
01782
01783 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) &&
01784 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) {
01785 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl;
01786 goto SKIP;
01787 }
01788
01789 anEvent = VEventToEvent(curVO);
01790
01791
01792 if (anEvent)
01793 cal->addEvent(anEvent);
01794 else {
01795
01796 goto SKIP;
01797 }
01798 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
01799 anEvent = VTodoToEvent(curVO);
01800 cal->addTodo(anEvent);
01801 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
01802 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
01803 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
01804
01805
01806 ;
01807 } else {
01808 kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl;
01809 }
01810 SKIP:
01811 ;
01812 }
01813 #endif
01814
01815
01816 Event *ev;
01817 for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) {
01818 ev->setRelatedTo(cal->event(ev->relatedToUid()));
01819 }
01820 Todo *todo;
01821 for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) {
01822 todo->setRelatedTo(cal->todo(todo->relatedToUid()));
01823 }
01824
01825 return true;
01826 }
01827
01828 QString ICalFormatImpl::extractErrorProperty(icalcomponent *c)
01829 {
01830
01831
01832
01833 QString errorMessage;
01834
01835 icalproperty *error;
01836 error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY);
01837 while(error) {
01838 errorMessage += icalproperty_get_xlicerror(error);
01839 errorMessage += "\n";
01840 error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY);
01841 }
01842
01843
01844
01845 return errorMessage;
01846 }
01847
01848 void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r)
01849 {
01850 int i;
01851
01852 kdDebug(5800) << " Freq: " << r.freq << endl;
01853 kdDebug(5800) << " Until: " << icaltime_as_ctime(r.until) << endl;
01854 kdDebug(5800) << " Count: " << r.count << endl;
01855 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01856 int index = 0;
01857 QString out = " By Day: ";
01858 while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01859 out.append(QString::number(i) + " ");
01860 }
01861 kdDebug(5800) << out << endl;
01862 }
01863 if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01864 int index = 0;
01865 QString out = " By Month Day: ";
01866 while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01867 out.append(QString::number(i) + " ");
01868 }
01869 kdDebug(5800) << out << endl;
01870 }
01871 if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01872 int index = 0;
01873 QString out = " By Year Day: ";
01874 while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01875 out.append(QString::number(i) + " ");
01876 }
01877 kdDebug(5800) << out << endl;
01878 }
01879 if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01880 int index = 0;
01881 QString out = " By Month: ";
01882 while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01883 out.append(QString::number(i) + " ");
01884 }
01885 kdDebug(5800) << out << endl;
01886 }
01887 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01888 int index = 0;
01889 QString out = " By Set Pos: ";
01890 while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01891 kdDebug(5800) << "========= " << i << endl;
01892 out.append(QString::number(i) + " ");
01893 }
01894 kdDebug(5800) << out << endl;
01895 }
01896 }
01897
01898 icalcomponent *ICalFormatImpl::createScheduleComponent(IncidenceBase *incidence,
01899 Scheduler::Method method)
01900 {
01901 icalcomponent *message = createCalendarComponent();
01902
01903 icalproperty_method icalmethod = ICAL_METHOD_NONE;
01904
01905 switch (method) {
01906 case Scheduler::Publish:
01907 icalmethod = ICAL_METHOD_PUBLISH;
01908 break;
01909 case Scheduler::Request:
01910 icalmethod = ICAL_METHOD_REQUEST;
01911 break;
01912 case Scheduler::Refresh:
01913 icalmethod = ICAL_METHOD_REFRESH;
01914 break;
01915 case Scheduler::Cancel:
01916 icalmethod = ICAL_METHOD_CANCEL;
01917 break;
01918 case Scheduler::Add:
01919 icalmethod = ICAL_METHOD_ADD;
01920 break;
01921 case Scheduler::Reply:
01922 icalmethod = ICAL_METHOD_REPLY;
01923 break;
01924 case Scheduler::Counter:
01925 icalmethod = ICAL_METHOD_COUNTER;
01926 break;
01927 case Scheduler::Declinecounter:
01928 icalmethod = ICAL_METHOD_DECLINECOUNTER;
01929 break;
01930 default:
01931 kdDebug(5800) << "ICalFormat::createScheduleMessage(): Unknow method" << endl;
01932 return message;
01933 }
01934
01935 icalcomponent_add_property(message,icalproperty_new_method(icalmethod));
01936
01937
01938 if(incidence->type() == "Todo") {
01939 Todo *todo = static_cast<Todo *>(incidence);
01940 icalcomponent_add_component(message,writeTodo(todo));
01941 }
01942 if(incidence->type() == "Event") {
01943 Event *event = static_cast<Event *>(incidence);
01944 icalcomponent_add_component(message,writeEvent(event));
01945 }
01946 if(incidence->type() == "FreeBusy") {
01947 FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
01948 icalcomponent_add_component(message,writeFreeBusy(freebusy, method));
01949 }
01950
01951 return message;
01952 }