00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qapplication.h>
00024 #include <qdatetime.h>
00025 #include <qstring.h>
00026 #include <qptrlist.h>
00027 #include <qregexp.h>
00028 #include <qclipboard.h>
00029 #include <qdialog.h>
00030 #include <qfile.h>
00031
00032 #include <kdebug.h>
00033 #include <kmessagebox.h>
00034 #include <kiconloader.h>
00035 #include <klocale.h>
00036
00037 #include "vcc.h"
00038 #include "vobject.h"
00039 extern "C" {
00040 #include "icaltime.h"
00041 #include "icaltimezone.h"
00042 }
00043 #include "vcaldrag.h"
00044 #include "calendar.h"
00045
00046 #include "vcalformat.h"
00047
00048 using namespace KCal;
00049
00050 VCalFormat::VCalFormat()
00051 {
00052 }
00053
00054 VCalFormat::~VCalFormat()
00055 {
00056 }
00057
00058 bool VCalFormat::load(Calendar *calendar, const QString &fileName)
00059 {
00060 mCalendar = calendar;
00061
00062 clearException();
00063
00064 kdDebug(5800) << "VCalFormat::load() " << fileName << endl;
00065
00066 VObject *vcal = 0;
00067
00068
00069
00070 vcal = Parse_MIME_FromFileName(const_cast<char *>(QFile::encodeName(fileName).data()));
00071
00072 if (!vcal) {
00073 setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
00074 return FALSE;
00075 }
00076
00077
00078
00079
00080 populate(vcal);
00081
00082
00083 cleanVObjects(vcal);
00084 cleanStrTbl();
00085
00086 return true;
00087 }
00088
00089
00090 bool VCalFormat::save(Calendar *calendar, const QString &fileName)
00091 {
00092 mCalendar = calendar;
00093
00094 QString tmpStr;
00095 VObject *vcal, *vo;
00096
00097 kdDebug(5800) << "VCalFormat::save(): " << fileName << endl;
00098
00099 vcal = newVObject(VCCalProp);
00100
00101
00102 addPropValue(vcal,VCProdIdProp, productId().latin1());
00103 addPropValue(vcal,VCVersionProp, _VCAL_VERSION);
00104
00105
00106 Todo::List todoList = mCalendar->rawTodos();
00107 Todo::List::ConstIterator it;
00108 for ( it = todoList.begin(); it != todoList.end(); ++it ) {
00109 vo = eventToVTodo( *it );
00110 addVObjectProp( vcal, vo );
00111 }
00112
00113
00114 Event::List events = mCalendar->rawEvents();
00115 Event::List::ConstIterator it2;
00116 for( it2 = events.begin(); it2 != events.end(); ++it2 ) {
00117 vo = eventToVEvent( *it2 );
00118 addVObjectProp( vcal, vo );
00119 }
00120
00121 writeVObjectToFile(QFile::encodeName(fileName).data() ,vcal);
00122 cleanVObjects(vcal);
00123 cleanStrTbl();
00124
00125 if (QFile::exists(fileName)) {
00126 kdDebug(5800) << "No error" << endl;
00127 return true;
00128 } else {
00129 kdDebug(5800) << "Error" << endl;
00130 return false;
00131 }
00132
00133 return false;
00134 }
00135
00136 bool VCalFormat::fromString( Calendar *calendar, const QString &text )
00137 {
00138
00139 mCalendar = calendar;
00140
00141 QCString data = text.utf8();
00142
00143 if ( !data.size() ) return false;
00144
00145 VObject *vcal = Parse_MIME( data.data(), data.size());
00146 if ( !vcal ) return false;
00147
00148 VObjectIterator i;
00149 VObject *curvo;
00150 initPropIterator( &i, vcal );
00151
00152
00153 do {
00154 curvo = nextVObject( &i );
00155 } while ( strcmp( vObjectName( curvo ), VCEventProp ) &&
00156 strcmp( vObjectName( curvo ), VCTodoProp ) );
00157
00158 if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) {
00159 Event *event = VEventToEvent( curvo );
00160 calendar->addEvent( event );
00161 } else {
00162 kdDebug(5800) << "VCalFormat::fromString(): Unknown object type." << endl;
00163 deleteVObject( vcal );
00164 return false;
00165 }
00166
00167 deleteVObject( vcal );
00168
00169 return true;
00170 }
00171
00172 QString VCalFormat::toString( Calendar *calendar )
00173 {
00174
00175 mCalendar = calendar;
00176
00177 VObject *vcal = newVObject(VCCalProp);
00178
00179 addPropValue( vcal, VCProdIdProp, CalFormat::productId().latin1() );
00180 addPropValue( vcal, VCVersionProp, _VCAL_VERSION );
00181
00182
00183 Event::List events = calendar->events();
00184 Event *event = events.first();
00185 if ( !event ) return QString::null;
00186
00187 VObject *vevent = eventToVEvent( event );
00188
00189 addVObjectProp( vcal, vevent );
00190
00191 char *buf = writeMemVObject( 0, 0, vcal );
00192
00193 QString result( buf );
00194
00195 cleanVObject( vcal );
00196
00197 return result;
00198 }
00199
00200 VObject *VCalFormat::eventToVTodo(const Todo *anEvent)
00201 {
00202 VObject *vtodo;
00203 QString tmpStr;
00204
00205 vtodo = newVObject(VCTodoProp);
00206
00207
00208 if (anEvent->hasDueDate()) {
00209 tmpStr = qDateTimeToISO(anEvent->dtDue(),
00210 !anEvent->doesFloat());
00211 addPropValue(vtodo, VCDueProp, tmpStr.local8Bit());
00212 }
00213
00214
00215 if (anEvent->hasStartDate()) {
00216 tmpStr = qDateTimeToISO(anEvent->dtStart(),
00217 !anEvent->doesFloat());
00218 addPropValue(vtodo, VCDTstartProp, tmpStr.local8Bit());
00219 }
00220
00221
00222 tmpStr = qDateTimeToISO(anEvent->created());
00223 addPropValue(vtodo, VCDCreatedProp, tmpStr.local8Bit());
00224
00225
00226 addPropValue(vtodo, VCUniqueStringProp,
00227 anEvent->uid().local8Bit());
00228
00229
00230 tmpStr.sprintf("%i", anEvent->revision());
00231 addPropValue(vtodo, VCSequenceProp, tmpStr.local8Bit());
00232
00233
00234 tmpStr = qDateTimeToISO(anEvent->lastModified());
00235 addPropValue(vtodo, VCLastModifiedProp, tmpStr.local8Bit());
00236
00237
00238
00239 tmpStr = "MAILTO:" + anEvent->organizer().email();
00240 addPropValue(vtodo, ICOrganizerProp, tmpStr.local8Bit());
00241
00242
00243 if ( anEvent->attendeeCount() > 0 ) {
00244 Attendee::List::ConstIterator it;
00245 Attendee *curAttendee;
00246 for ( it = anEvent->attendees().begin(); it != anEvent->attendees().end();
00247 ++it ) {
00248 curAttendee = *it;
00249 if (!curAttendee->email().isEmpty() &&
00250 !curAttendee->name().isEmpty())
00251 tmpStr = "MAILTO:" + curAttendee->name() + " <" +
00252 curAttendee->email() + ">";
00253 else if (curAttendee->name().isEmpty())
00254 tmpStr = "MAILTO: " + curAttendee->email();
00255 else if (curAttendee->email().isEmpty())
00256 tmpStr = "MAILTO: " + curAttendee->name();
00257 else if (curAttendee->name().isEmpty() &&
00258 curAttendee->email().isEmpty())
00259 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl;
00260 VObject *aProp = addPropValue(vtodo, VCAttendeeProp, tmpStr.local8Bit());
00261 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");
00262 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status()));
00263 }
00264 }
00265
00266
00267 if (!anEvent->description().isEmpty()) {
00268 VObject *d = addPropValue(vtodo, VCDescriptionProp,
00269 anEvent->description().local8Bit());
00270 if (anEvent->description().find('\n') != -1)
00271 addPropValue(d, VCEncodingProp, VCQuotedPrintableProp);
00272 }
00273
00274
00275 if (!anEvent->summary().isEmpty())
00276 addPropValue(vtodo, VCSummaryProp, anEvent->summary().local8Bit());
00277
00278
00279 if (!anEvent->location().isEmpty())
00280 addPropValue(vtodo, VCLocationProp, anEvent->location().local8Bit());
00281
00282
00283
00284
00285 addPropValue(vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" :
00286 "NEEDS_ACTION");
00287
00288 if (anEvent->hasCompletedDate()) {
00289 tmpStr = qDateTimeToISO(anEvent->completed());
00290 addPropValue(vtodo, VCCompletedProp, tmpStr.local8Bit());
00291 }
00292
00293
00294 tmpStr.sprintf("%i",anEvent->priority());
00295 addPropValue(vtodo, VCPriorityProp, tmpStr.local8Bit());
00296
00297
00298 if (anEvent->relatedTo()) {
00299 addPropValue(vtodo, VCRelatedToProp,
00300 anEvent->relatedTo()->uid().local8Bit());
00301 }
00302
00303
00304 QStringList tmpStrList = anEvent->categories();
00305 tmpStr = "";
00306 QString catStr;
00307 for ( QStringList::Iterator it = tmpStrList.begin();
00308 it != tmpStrList.end();
00309 ++it ) {
00310 catStr = *it;
00311 if (catStr[0] == ' ')
00312 tmpStr += catStr.mid(1);
00313 else
00314 tmpStr += catStr;
00315
00316
00317
00318 tmpStr += ";";
00319 }
00320 if (!tmpStr.isEmpty()) {
00321 tmpStr.truncate(tmpStr.length()-1);
00322 addPropValue(vtodo, VCCategoriesProp, tmpStr.local8Bit());
00323 }
00324
00325
00326 kdDebug(5800) << "vcalformat::eventToVTodo was called" << endl;
00327 Alarm::List::ConstIterator it;
00328 for ( it = anEvent->alarms().begin(); it != anEvent->alarms().end(); ++it ) {
00329 Alarm *alarm = *it;
00330 if (alarm->enabled()) {
00331 VObject *a = addProp(vtodo, VCDAlarmProp);
00332 tmpStr = qDateTimeToISO(alarm->time());
00333 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
00334 addPropValue(a, VCRepeatCountProp, "1");
00335 addPropValue(a, VCDisplayStringProp, "beep!");
00336 if (alarm->type() == Alarm::Audio) {
00337 a = addProp(vtodo, VCAAlarmProp);
00338 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
00339 addPropValue(a, VCRepeatCountProp, "1");
00340 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile()));
00341 }
00342 else if (alarm->type() == Alarm::Procedure) {
00343 a = addProp(vtodo, VCPAlarmProp);
00344 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
00345 addPropValue(a, VCRepeatCountProp, "1");
00346 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile()));
00347 }
00348 }
00349 }
00350
00351 if (anEvent->pilotId()) {
00352
00353 tmpStr.sprintf("%lu",anEvent->pilotId());
00354 addPropValue(vtodo, KPilotIdProp, tmpStr.local8Bit());
00355 tmpStr.sprintf("%i",anEvent->syncStatus());
00356 addPropValue(vtodo, KPilotStatusProp, tmpStr.local8Bit());
00357 }
00358
00359 return vtodo;
00360 }
00361
00362 VObject* VCalFormat::eventToVEvent(const Event *anEvent)
00363 {
00364 VObject *vevent;
00365 QString tmpStr;
00366
00367 vevent = newVObject(VCEventProp);
00368
00369
00370 tmpStr = qDateTimeToISO(anEvent->dtStart(),
00371 !anEvent->doesFloat());
00372 addPropValue(vevent, VCDTstartProp, tmpStr.local8Bit());
00373
00374
00375
00376 if (anEvent->dtStart() != anEvent->dtEnd()) {
00377 tmpStr = qDateTimeToISO(anEvent->dtEnd(),
00378 !anEvent->doesFloat());
00379 addPropValue(vevent, VCDTendProp, tmpStr.local8Bit());
00380 }
00381
00382
00383 tmpStr = qDateTimeToISO(anEvent->created());
00384 addPropValue(vevent, VCDCreatedProp, tmpStr.local8Bit());
00385
00386
00387 addPropValue(vevent, VCUniqueStringProp,
00388 anEvent->uid().local8Bit());
00389
00390
00391 tmpStr.sprintf("%i", anEvent->revision());
00392 addPropValue(vevent, VCSequenceProp, tmpStr.local8Bit());
00393
00394
00395 tmpStr = qDateTimeToISO(anEvent->lastModified());
00396 addPropValue(vevent, VCLastModifiedProp, tmpStr.local8Bit());
00397
00398
00399
00400 tmpStr = "MAILTO:" + anEvent->organizer().email();
00401 addPropValue(vevent, ICOrganizerProp, tmpStr.local8Bit());
00402
00403
00404 if ( anEvent->attendeeCount() > 0 ) {
00405 Attendee::List::ConstIterator it;
00406 for ( it = anEvent->attendees().begin(); it != anEvent->attendees().end();
00407 ++it ) {
00408 Attendee *curAttendee = *it;
00409 if (!curAttendee->email().isEmpty() &&
00410 !curAttendee->name().isEmpty())
00411 tmpStr = "MAILTO:" + curAttendee->name() + " <" +
00412 curAttendee->email() + ">";
00413 else if (curAttendee->name().isEmpty())
00414 tmpStr = "MAILTO: " + curAttendee->email();
00415 else if (curAttendee->email().isEmpty())
00416 tmpStr = "MAILTO: " + curAttendee->name();
00417 else if (curAttendee->name().isEmpty() &&
00418 curAttendee->email().isEmpty())
00419 kdDebug(5800) << "warning! this Event has an attendee w/o name or email!" << endl;
00420 VObject *aProp = addPropValue(vevent, VCAttendeeProp, tmpStr.local8Bit());
00421 addPropValue(aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE");
00422 addPropValue(aProp, VCStatusProp, writeStatus(curAttendee->status()));
00423 }
00424 }
00425
00426
00427 const Recurrence *recur = anEvent->recurrence();
00428 if ( recur->doesRecur() ) {
00429 bool validRecur = true;
00430 QString tmpStr2;
00431 switch ( recur->recurrenceType() ) {
00432 case Recurrence::rDaily:
00433 tmpStr.sprintf("D%i ",recur->frequency());
00434 break;
00435 case Recurrence::rWeekly:
00436 tmpStr.sprintf("W%i ",recur->frequency());
00437 for (int i = 0; i < 7; i++ ) {
00438 QBitArray days ( recur->days() );
00439 if ( days.testBit(i) )
00440 tmpStr += dayFromNum(i);
00441 }
00442 break;
00443 case Recurrence::rMonthlyPos: {
00444 tmpStr.sprintf("MP%i ", recur->frequency());
00445
00446 QValueList<RecurrenceRule::WDayPos> tmpPositions = recur->monthPositions();
00447 for ( QValueListConstIterator<RecurrenceRule::WDayPos> posit = tmpPositions.begin();
00448 posit != tmpPositions.end(); ++posit ) {
00449 int pos = (*posit).pos();
00450 tmpStr2.sprintf("%i", (pos>0) ? pos : (-pos) );
00451 if ( pos < 0)
00452 tmpStr2 += "- ";
00453 else
00454 tmpStr2 += "+ ";
00455 tmpStr += tmpStr2;
00456 tmpStr += dayFromNum( (*posit).day() - 1 );
00457 }
00458 break; }
00459 case Recurrence::rMonthlyDay: {
00460 tmpStr.sprintf("MD%i ", recur->frequency());
00461
00462 QValueList<int> tmpDays = recur->monthDays();
00463 for ( QValueListIterator<int> tmpDay = tmpDays.begin();
00464 tmpDay != tmpDays.end(); ++tmpDay ) {
00465 tmpStr2.sprintf( "%i ", *tmpDay );
00466 tmpStr += tmpStr2;
00467 }
00468 break; }
00469 case Recurrence::rYearlyMonth: {
00470 tmpStr.sprintf("YM%i ", recur->frequency());
00471
00472
00473 QValueList<int> months = recur->yearMonths();
00474 for ( QValueListIterator<int> mit = months.begin();
00475 mit != months.end(); ++mit ) {
00476 tmpStr2.sprintf( "%i ", *mit );
00477 tmpStr += tmpStr2;
00478 }
00479 break; }
00480 case Recurrence::rYearlyDay: {
00481 tmpStr.sprintf("YD%i ", recur->frequency());
00482
00483 QValueList<int> tmpDays = recur->yearDays();
00484 for ( QValueListIterator<int> tmpDay = tmpDays.begin();
00485 tmpDay != tmpDays.end(); ++tmpDay ) {
00486 tmpStr2.sprintf( "%i ", *tmpDay );
00487 tmpStr += tmpStr2;
00488 }
00489 break; }
00490 default:
00491
00492 kdDebug(5800) << "ERROR, it should never get here in eventToVEvent!" << endl;
00493 validRecur = false;
00494 break;
00495 }
00496
00497 if (recur->duration() > 0) {
00498 tmpStr2.sprintf("#%i",recur->duration());
00499 tmpStr += tmpStr2;
00500 } else if (recur->duration() == -1) {
00501 tmpStr += "#0";
00502 } else {
00503 tmpStr += qDateTimeToISO(recur->endDateTime(), FALSE);
00504 }
00505
00506
00507 if ( validRecur )
00508 addPropValue(vevent,VCRRuleProp, tmpStr.local8Bit());
00509
00510 }
00511
00512
00513 DateList dateList = recur->exDates();
00514 DateList::ConstIterator it;
00515 QString tmpStr2;
00516
00517 for (it = dateList.begin(); it != dateList.end(); ++it) {
00518 tmpStr = qDateToISO(*it) + ";";
00519 tmpStr2 += tmpStr;
00520 }
00521 if (!tmpStr2.isEmpty()) {
00522 tmpStr2.truncate(tmpStr2.length()-1);
00523 addPropValue(vevent, VCExDateProp, tmpStr2.local8Bit());
00524 }
00525
00526
00527 if (!anEvent->description().isEmpty()) {
00528 VObject *d = addPropValue(vevent, VCDescriptionProp,
00529 anEvent->description().local8Bit());
00530 if (anEvent->description().find('\n') != -1)
00531 addPropValue(d, VCEncodingProp, VCQuotedPrintableProp);
00532 }
00533
00534
00535 if (!anEvent->summary().isEmpty())
00536 addPropValue(vevent, VCSummaryProp, anEvent->summary().local8Bit());
00537
00538
00539 if (!anEvent->location().isEmpty())
00540 addPropValue(vevent, VCLocationProp, anEvent->location().local8Bit());
00541
00542
00543
00544
00545
00546
00547 const char *text = 0;
00548 switch (anEvent->secrecy()) {
00549 case Incidence::SecrecyPublic:
00550 text = "PUBLIC";
00551 break;
00552 case Incidence::SecrecyPrivate:
00553 text = "PRIVATE";
00554 break;
00555 case Incidence::SecrecyConfidential:
00556 text = "CONFIDENTIAL";
00557 break;
00558 }
00559 if (text) {
00560 addPropValue(vevent, VCClassProp, text);
00561 }
00562
00563
00564 QStringList tmpStrList = anEvent->categories();
00565 tmpStr = "";
00566 QString catStr;
00567 for ( QStringList::Iterator it = tmpStrList.begin();
00568 it != tmpStrList.end();
00569 ++it ) {
00570 catStr = *it;
00571 if (catStr[0] == ' ')
00572 tmpStr += catStr.mid(1);
00573 else
00574 tmpStr += catStr;
00575
00576
00577
00578 tmpStr += ";";
00579 }
00580 if (!tmpStr.isEmpty()) {
00581 tmpStr.truncate(tmpStr.length()-1);
00582 addPropValue(vevent, VCCategoriesProp, tmpStr.local8Bit());
00583 }
00584
00585
00586
00587 Attachment::List attachments = anEvent->attachments();
00588 Attachment::List::ConstIterator atIt;
00589 for ( atIt = attachments.begin(); atIt != attachments.end(); ++atIt )
00590 addPropValue( vevent, VCAttachProp, (*atIt)->uri().local8Bit() );
00591
00592
00593 tmpStrList = anEvent->resources();
00594 tmpStr = tmpStrList.join(";");
00595 if (!tmpStr.isEmpty())
00596 addPropValue(vevent, VCResourcesProp, tmpStr.local8Bit());
00597
00598
00599 Alarm::List::ConstIterator it2;
00600 for ( it2 = anEvent->alarms().begin(); it2 != anEvent->alarms().end(); ++it2 ) {
00601 Alarm *alarm = *it2;
00602 if (alarm->enabled()) {
00603 VObject *a = addProp(vevent, VCDAlarmProp);
00604 tmpStr = qDateTimeToISO(alarm->time());
00605 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
00606 addPropValue(a, VCRepeatCountProp, "1");
00607 addPropValue(a, VCDisplayStringProp, "beep!");
00608 if (alarm->type() == Alarm::Audio) {
00609 a = addProp(vevent, VCAAlarmProp);
00610 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
00611 addPropValue(a, VCRepeatCountProp, "1");
00612 addPropValue(a, VCAudioContentProp, QFile::encodeName(alarm->audioFile()));
00613 }
00614 if (alarm->type() == Alarm::Procedure) {
00615 a = addProp(vevent, VCPAlarmProp);
00616 addPropValue(a, VCRunTimeProp, tmpStr.local8Bit());
00617 addPropValue(a, VCRepeatCountProp, "1");
00618 addPropValue(a, VCProcedureNameProp, QFile::encodeName(alarm->programFile()));
00619 }
00620 }
00621 }
00622
00623
00624 tmpStr.sprintf("%i",anEvent->priority());
00625 addPropValue(vevent, VCPriorityProp, tmpStr.local8Bit());
00626
00627
00628 tmpStr.sprintf("%i",anEvent->transparency());
00629 addPropValue(vevent, VCTranspProp, tmpStr.local8Bit());
00630
00631
00632 if (anEvent->relatedTo()) {
00633 addPropValue(vevent, VCRelatedToProp,
00634 anEvent->relatedTo()->uid().local8Bit());
00635 }
00636
00637 if (anEvent->pilotId()) {
00638
00639 tmpStr.sprintf("%lu",anEvent->pilotId());
00640 addPropValue(vevent, KPilotIdProp, tmpStr.local8Bit());
00641 tmpStr.sprintf("%i",anEvent->syncStatus());
00642 addPropValue(vevent, KPilotStatusProp, tmpStr.local8Bit());
00643 }
00644
00645 return vevent;
00646 }
00647
00648 Todo *VCalFormat::VTodoToEvent(VObject *vtodo)
00649 {
00650 VObject *vo;
00651 VObjectIterator voi;
00652 char *s;
00653
00654 Todo *anEvent = new Todo;
00655
00656
00657 if ((vo = isAPropertyOf(vtodo, VCDCreatedProp)) != 0) {
00658 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
00659 deleteStr(s);
00660 }
00661
00662
00663 vo = isAPropertyOf(vtodo, VCUniqueStringProp);
00664
00665
00666 if (vo) {
00667 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo)));
00668 deleteStr(s);
00669 }
00670
00671
00672 if ((vo = isAPropertyOf(vtodo, VCLastModifiedProp)) != 0) {
00673 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
00674 deleteStr(s);
00675 }
00676 else
00677 anEvent->setLastModified(QDateTime(QDate::currentDate(),
00678 QTime::currentTime()));
00679
00680
00681
00682 if ((vo = isAPropertyOf(vtodo, ICOrganizerProp)) != 0) {
00683 anEvent->setOrganizer( s = fakeCString(vObjectUStringZValue(vo) ) );
00684 deleteStr(s);
00685 } else {
00686 anEvent->setOrganizer( mCalendar->getOwner() );
00687 }
00688
00689
00690 initPropIterator(&voi, vtodo);
00691 while (moreIteration(&voi)) {
00692 vo = nextVObject(&voi);
00693 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) {
00694 Attendee *a;
00695 VObject *vp;
00696 s = fakeCString(vObjectUStringZValue(vo));
00697 QString tmpStr = QString::fromLocal8Bit(s);
00698 deleteStr(s);
00699 tmpStr = tmpStr.simplifyWhiteSpace();
00700 int emailPos1, emailPos2;
00701 if ((emailPos1 = tmpStr.find('<')) > 0) {
00702
00703 emailPos2 = tmpStr.findRev('>');
00704 a = new Attendee(tmpStr.left(emailPos1 - 1),
00705 tmpStr.mid(emailPos1 + 1,
00706 emailPos2 - (emailPos1 + 1)));
00707 } else if (tmpStr.find('@') > 0) {
00708
00709 a = new Attendee(0, tmpStr);
00710 } else {
00711
00712
00713 QString email = tmpStr.replace( ' ', '.' );
00714 a = new Attendee(tmpStr,email);
00715 }
00716
00717
00718 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0)
00719 a->setRSVP(vObjectStringZValue(vp));
00720
00721 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0)
00722 a->setStatus(readStatus(vObjectStringZValue(vp)));
00723
00724 anEvent->addAttendee(a);
00725 }
00726 }
00727
00728
00729 if ((vo = isAPropertyOf(vtodo, VCDescriptionProp)) != 0) {
00730 s = fakeCString(vObjectUStringZValue(vo));
00731 anEvent->setDescription(QString::fromLocal8Bit(s));
00732 deleteStr(s);
00733 }
00734
00735
00736 if ((vo = isAPropertyOf(vtodo, VCSummaryProp))) {
00737 s = fakeCString(vObjectUStringZValue(vo));
00738 anEvent->setSummary(QString::fromLocal8Bit(s));
00739 deleteStr(s);
00740 }
00741
00742
00743
00744 if ((vo = isAPropertyOf(vtodo, VCLocationProp)) != 0) {
00745 s = fakeCString(vObjectUStringZValue(vo));
00746 anEvent->setLocation( QString::fromLocal8Bit(s) );
00747 deleteStr(s);
00748 }
00749
00750
00751 if ((vo = isAPropertyOf(vtodo, VCStatusProp)) != 0) {
00752 s = fakeCString(vObjectUStringZValue(vo));
00753 if (strcmp(s,"COMPLETED") == 0) {
00754 anEvent->setCompleted(true);
00755 } else {
00756 anEvent->setCompleted(false);
00757 }
00758 deleteStr(s);
00759 }
00760 else
00761 anEvent->setCompleted(false);
00762
00763
00764 if ((vo = isAPropertyOf(vtodo, VCCompletedProp)) != 0) {
00765 anEvent->setCompleted(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
00766 deleteStr(s);
00767 }
00768
00769
00770 if ((vo = isAPropertyOf(vtodo, VCPriorityProp))) {
00771 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo))));
00772 deleteStr(s);
00773 }
00774
00775
00776 if ((vo = isAPropertyOf(vtodo, VCDueProp)) != 0) {
00777 anEvent->setDtDue(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
00778 deleteStr(s);
00779 anEvent->setHasDueDate(true);
00780 } else {
00781 anEvent->setHasDueDate(false);
00782 }
00783
00784
00785 if ((vo = isAPropertyOf(vtodo, VCDTstartProp)) != 0) {
00786 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
00787
00788 deleteStr(s);
00789 anEvent->setHasStartDate(true);
00790 } else {
00791 anEvent->setHasStartDate(false);
00792 }
00793
00794
00795
00796 if ((vo = isAPropertyOf(vtodo, VCDAlarmProp))) {
00797 Alarm* alarm = anEvent->newAlarm();
00798 VObject *a;
00799 if ((a = isAPropertyOf(vo, VCRunTimeProp))) {
00800 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a))));
00801 deleteStr(s);
00802 }
00803 alarm->setEnabled(true);
00804 if ((vo = isAPropertyOf(vtodo, VCPAlarmProp))) {
00805 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) {
00806 s = fakeCString(vObjectUStringZValue(a));
00807 alarm->setProcedureAlarm(QFile::decodeName(s));
00808 deleteStr(s);
00809 }
00810 }
00811 if ((vo = isAPropertyOf(vtodo, VCAAlarmProp))) {
00812 if ((a = isAPropertyOf(vo, VCAudioContentProp))) {
00813 s = fakeCString(vObjectUStringZValue(a));
00814 alarm->setAudioAlarm(QFile::decodeName(s));
00815 deleteStr(s);
00816 }
00817 }
00818 }
00819
00820
00821 if ((vo = isAPropertyOf(vtodo, VCRelatedToProp)) != 0) {
00822 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo)));
00823 deleteStr(s);
00824 mTodosRelate.append(anEvent);
00825 }
00826
00827
00828 if ((vo = isAPropertyOf(vtodo, VCCategoriesProp)) != 0) {
00829 s = fakeCString(vObjectUStringZValue(vo));
00830 QString categories = QString::fromLocal8Bit(s);
00831 deleteStr(s);
00832 QStringList tmpStrList = QStringList::split( ';', categories );
00833 anEvent->setCategories(tmpStrList);
00834 }
00835
00836
00837 if ((vo = isAPropertyOf(vtodo, KPilotIdProp))) {
00838 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo))));
00839 deleteStr(s);
00840 }
00841 else
00842 anEvent->setPilotId(0);
00843
00844 if ((vo = isAPropertyOf(vtodo, KPilotStatusProp))) {
00845 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo))));
00846 deleteStr(s);
00847 }
00848 else
00849 anEvent->setSyncStatus(Event::SYNCMOD);
00850
00851 return anEvent;
00852 }
00853
00854 Event* VCalFormat::VEventToEvent(VObject *vevent)
00855 {
00856 VObject *vo;
00857 VObjectIterator voi;
00858 char *s;
00859
00860 Event *anEvent = new Event;
00861
00862
00863 if ((vo = isAPropertyOf(vevent, VCDCreatedProp)) != 0) {
00864 anEvent->setCreated(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
00865 deleteStr(s);
00866 }
00867
00868
00869 vo = isAPropertyOf(vevent, VCUniqueStringProp);
00870
00871
00872 if (vo) {
00873 anEvent->setUid(s = fakeCString(vObjectUStringZValue(vo)));
00874 deleteStr(s);
00875 }
00876
00877
00878
00879 if ((vo = isAPropertyOf(vevent, VCSequenceProp)) != 0) {
00880 anEvent->setRevision(atoi(s = fakeCString(vObjectUStringZValue(vo))));
00881 deleteStr(s);
00882 }
00883 else
00884 anEvent->setRevision(0);
00885
00886
00887 if ((vo = isAPropertyOf(vevent, VCLastModifiedProp)) != 0) {
00888 anEvent->setLastModified(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
00889 deleteStr(s);
00890 }
00891 else
00892 anEvent->setLastModified(QDateTime(QDate::currentDate(),
00893 QTime::currentTime()));
00894
00895
00896
00897 if ((vo = isAPropertyOf(vevent, ICOrganizerProp)) != 0) {
00898
00899 anEvent->setOrganizer( s = fakeCString(vObjectUStringZValue(vo) ) );
00900 deleteStr(s);
00901 } else {
00902 anEvent->setOrganizer( mCalendar->getOwner() );
00903 }
00904
00905
00906 initPropIterator(&voi, vevent);
00907 while (moreIteration(&voi)) {
00908 vo = nextVObject(&voi);
00909 if (strcmp(vObjectName(vo), VCAttendeeProp) == 0) {
00910 Attendee *a;
00911 VObject *vp;
00912 s = fakeCString(vObjectUStringZValue(vo));
00913 QString tmpStr = QString::fromLocal8Bit(s);
00914 deleteStr(s);
00915 tmpStr = tmpStr.simplifyWhiteSpace();
00916 int emailPos1, emailPos2;
00917 if ((emailPos1 = tmpStr.find('<')) > 0) {
00918
00919 emailPos2 = tmpStr.findRev('>');
00920 a = new Attendee(tmpStr.left(emailPos1 - 1),
00921 tmpStr.mid(emailPos1 + 1,
00922 emailPos2 - (emailPos1 + 1)));
00923 } else if (tmpStr.find('@') > 0) {
00924
00925 a = new Attendee(0, tmpStr);
00926 } else {
00927
00928 QString email = tmpStr.replace( ' ', '.' );
00929 a = new Attendee(tmpStr,email);
00930 }
00931
00932
00933 if ((vp = isAPropertyOf(vo, VCRSVPProp)) != 0)
00934 a->setRSVP(vObjectStringZValue(vp));
00935
00936 if ((vp = isAPropertyOf(vo, VCStatusProp)) != 0)
00937 a->setStatus(readStatus(vObjectStringZValue(vp)));
00938
00939 anEvent->addAttendee(a);
00940 }
00941 }
00942
00943
00944
00945
00946
00947
00948
00949
00950
00951
00952 anEvent->setFloats(FALSE);
00953
00954
00955 if ((vo = isAPropertyOf(vevent, VCDTstartProp)) != 0) {
00956 anEvent->setDtStart(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
00957
00958 deleteStr(s);
00959 if (anEvent->dtStart().time().isNull())
00960 anEvent->setFloats(TRUE);
00961 }
00962
00963
00964 if ((vo = isAPropertyOf(vevent, VCDTendProp)) != 0) {
00965 anEvent->setDtEnd(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(vo))));
00966 deleteStr(s);
00967 if (anEvent->dtEnd().time().isNull())
00968 anEvent->setFloats(TRUE);
00969 }
00970
00971
00972
00973 if (!(vo = isAPropertyOf(vevent, VCDTstartProp)))
00974 anEvent->setDtStart(anEvent->dtEnd());
00975 if (!(vo = isAPropertyOf(vevent, VCDTendProp)))
00976 anEvent->setDtEnd(anEvent->dtStart());
00977
00979
00980
00981 if ((vo = isAPropertyOf(vevent, VCRRuleProp)) != 0) {
00982 QString tmpStr = (s = fakeCString(vObjectUStringZValue(vo)));
00983 deleteStr(s);
00984 tmpStr.simplifyWhiteSpace();
00985 tmpStr = tmpStr.upper();
00986
00987
00988
00989 int typelen = 1;
00990 uint type = Recurrence::rNone;
00991 if ( tmpStr.left(1) == "D") {
00992 type = Recurrence::rDaily;
00993 } else if ( tmpStr.left(1) == "W") {
00994 type = Recurrence::rWeekly;
00995 } else {
00996 typelen = 2;
00997 if ( tmpStr.left(2) == "MP") {
00998 type = Recurrence::rMonthlyPos;
00999 } else if ( tmpStr.left(2) == "MD" ) {
01000 type = Recurrence::rMonthlyDay;
01001 } else if ( tmpStr.left(2) == "YM" ) {
01002 type = Recurrence::rYearlyMonth;
01003 } else if ( tmpStr.left(2) == "YD" ) {
01004 type = Recurrence::rYearlyDay;
01005 }
01006 }
01007
01008 if ( type != Recurrence::rNone ) {
01009
01010
01011
01012 int index = tmpStr.find(' ');
01013 int last = tmpStr.findRev(' ') + 1;
01014 int rFreq = tmpStr.mid(typelen, (index-1)).toInt();
01015 ++index;
01016
01017
01018 switch ( type ) {
01019 case Recurrence::rDaily:
01020 anEvent->recurrence()->setDaily(rFreq);
01021 break;
01022
01023 case Recurrence::rWeekly: {
01024 QBitArray qba(7);
01025 QString dayStr;
01026 if( index == last ) {
01027
01028 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
01029 }
01030 else {
01031
01032 while (index < last) {
01033 dayStr = tmpStr.mid(index, 3);
01034 int dayNum = numFromDay(dayStr);
01035 qba.setBit(dayNum);
01036 index += 3;
01037 }
01038 }
01039 anEvent->recurrence()->setWeekly( rFreq, qba );
01040 break; }
01041
01042 case Recurrence::rMonthlyPos: {
01043 anEvent->recurrence()->setMonthly( rFreq );
01044
01045 QBitArray qba(7);
01046 short tmpPos;
01047 if( index == last ) {
01048
01049 tmpPos = anEvent->dtStart().date().day()/7 + 1;
01050 if( tmpPos == 5 )
01051 tmpPos = -1;
01052 qba.setBit(anEvent->dtStart().date().dayOfWeek() - 1);
01053 anEvent->recurrence()->addMonthlyPos( tmpPos, qba );
01054 }
01055 else {
01056
01057 while (index < last) {
01058 tmpPos = tmpStr.mid(index,1).toShort();
01059 index += 1;
01060 if (tmpStr.mid(index,1) == "-")
01061
01062 tmpPos = 0 - tmpPos;
01063 index += 2;
01064 while (numFromDay(tmpStr.mid(index,3)) >= 0) {
01065 int dayNum = numFromDay(tmpStr.mid(index,3));
01066 qba.setBit(dayNum);
01067 index += 3;
01068 }
01069 anEvent->recurrence()->addMonthlyPos( tmpPos, qba );
01070 qba.detach();
01071 qba.fill(FALSE);
01072 }
01073 }
01074 break;}
01075
01076 case Recurrence::rMonthlyDay:
01077 anEvent->recurrence()->setMonthly( rFreq );
01078 if( index == last ) {
01079
01080 short tmpDay = anEvent->dtStart().date().day();
01081 anEvent->recurrence()->addMonthlyDate( tmpDay );
01082 }
01083 else {
01084
01085 while (index < last) {
01086 int index2 = tmpStr.find(' ', index);
01087 short tmpDay = tmpStr.mid(index, (index2-index)).toShort();
01088 index = index2-1;
01089 if (tmpStr.mid(index, 1) == "-")
01090 tmpDay = 0 - tmpDay;
01091 index += 2;
01092 anEvent->recurrence()->addMonthlyDate( tmpDay );
01093 }
01094 }
01095 break;
01096
01097 case Recurrence::rYearlyMonth:
01098 anEvent->recurrence()->setYearly( rFreq );
01099
01100 if( index == last ) {
01101
01102 short tmpMonth = anEvent->dtStart().date().month();
01103 anEvent->recurrence()->addYearlyMonth( tmpMonth );
01104 }
01105 else {
01106
01107 while (index < last) {
01108 int index2 = tmpStr.find(' ', index);
01109 short tmpMonth = tmpStr.mid(index, (index2-index)).toShort();
01110 index = index2 + 1;
01111 anEvent->recurrence()->addYearlyMonth( tmpMonth );
01112 }
01113 }
01114 break;
01115
01116 case Recurrence::rYearlyDay:
01117 anEvent->recurrence()->setYearly( rFreq );
01118
01119 if( index == last ) {
01120
01121 short tmpDay = anEvent->dtStart().date().dayOfYear();
01122 anEvent->recurrence()->addYearlyDay( tmpDay );
01123 }
01124 else {
01125
01126 while (index < last) {
01127 int index2 = tmpStr.find(' ', index);
01128 short tmpDay = tmpStr.mid(index, (index2-index)).toShort();
01129 index = index2+1;
01130 anEvent->recurrence()->addYearlyDay( tmpDay );
01131 }
01132 }
01133 break;
01134
01135 default: break;
01136 }
01137
01138
01139 index = last;
01140 if ( tmpStr.mid(index,1) == "#") {
01141
01142 index++;
01143 int rDuration = tmpStr.mid(index, tmpStr.length()-index).toInt();
01144 if ( rDuration > 0 )
01145 anEvent->recurrence()->setDuration( rDuration );
01146 } else if ( tmpStr.find('T', index) != -1 ) {
01147 QDate rEndDate = (ISOToQDateTime(tmpStr.mid(index, tmpStr.length()-index))).date();
01148 anEvent->recurrence()->setEndDateTime( rEndDate );
01149 }
01150
01151
01152 } else {
01153 kdDebug(5800) << "we don't understand this type of recurrence!" << endl;
01154 }
01155 }
01156
01157
01158
01159 if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) {
01160 s = fakeCString(vObjectUStringZValue(vo));
01161 QStringList exDates = QStringList::split(",",s);
01162 QStringList::ConstIterator it;
01163 for(it = exDates.begin(); it != exDates.end(); ++it ) {
01164 anEvent->recurrence()->addExDate(ISOToQDate(*it));
01165 }
01166 deleteStr(s);
01167 }
01168
01169
01170 if ((vo = isAPropertyOf(vevent, VCSummaryProp))) {
01171 s = fakeCString(vObjectUStringZValue(vo));
01172 anEvent->setSummary(QString::fromLocal8Bit(s));
01173 deleteStr(s);
01174 }
01175
01176
01177 if ((vo = isAPropertyOf(vevent, VCDescriptionProp)) != 0) {
01178 s = fakeCString(vObjectUStringZValue(vo));
01179 if (!anEvent->description().isEmpty()) {
01180 anEvent->setDescription(anEvent->description() + "\n" +
01181 QString::fromLocal8Bit(s));
01182 } else {
01183 anEvent->setDescription(QString::fromLocal8Bit(s));
01184 }
01185 deleteStr(s);
01186 }
01187
01188
01189 if ((vo = isAPropertyOf(vevent, VCLocationProp)) != 0) {
01190 s = fakeCString(vObjectUStringZValue(vo));
01191 anEvent->setLocation( QString::fromLocal8Bit(s) );
01192 deleteStr(s);
01193 }
01194
01195
01196
01197 if (anEvent->summary().isEmpty() &&
01198 !(anEvent->description().isEmpty())) {
01199 QString tmpStr = anEvent->description().simplifyWhiteSpace();
01200 anEvent->setDescription("");
01201 anEvent->setSummary(tmpStr);
01202 }
01203
01204 #if 0
01205
01206 if ((vo = isAPropertyOf(vevent, VCStatusProp)) != 0) {
01207 QString tmpStr(s = fakeCString(vObjectUStringZValue(vo)));
01208 deleteStr(s);
01209
01210
01211 }
01212 else
01213
01214 #endif
01215
01216
01217 int secrecy = Incidence::SecrecyPublic;
01218 if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
01219 s = fakeCString(vObjectUStringZValue(vo));
01220 if (strcmp(s,"PRIVATE") == 0) {
01221 secrecy = Incidence::SecrecyPrivate;
01222 } else if (strcmp(s,"CONFIDENTIAL") == 0) {
01223 secrecy = Incidence::SecrecyConfidential;
01224 }
01225 deleteStr(s);
01226 }
01227 anEvent->setSecrecy(secrecy);
01228
01229
01230 if ((vo = isAPropertyOf(vevent, VCCategoriesProp)) != 0) {
01231 s = fakeCString(vObjectUStringZValue(vo));
01232 QString categories = QString::fromLocal8Bit(s);
01233 deleteStr(s);
01234 QStringList tmpStrList = QStringList::split( ',', categories );
01235 anEvent->setCategories(tmpStrList);
01236 }
01237
01238
01239 initPropIterator(&voi, vevent);
01240 while (moreIteration(&voi)) {
01241 vo = nextVObject(&voi);
01242 if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
01243 s = fakeCString(vObjectUStringZValue(vo));
01244 anEvent->addAttachment(new Attachment(QString(s)));
01245 deleteStr(s);
01246 }
01247 }
01248
01249
01250 if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
01251 QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
01252 deleteStr(s);
01253 QStringList tmpStrList = QStringList::split( ';', resources );
01254 anEvent->setResources(tmpStrList);
01255 }
01256
01257
01258 if ((vo = isAPropertyOf(vevent, VCDAlarmProp))) {
01259 Alarm* alarm = anEvent->newAlarm();
01260 VObject *a;
01261 if ((a = isAPropertyOf(vo, VCRunTimeProp))) {
01262 alarm->setTime(ISOToQDateTime(s = fakeCString(vObjectUStringZValue(a))));
01263 deleteStr(s);
01264 }
01265 alarm->setEnabled(true);
01266 if ((vo = isAPropertyOf(vevent, VCPAlarmProp))) {
01267 if ((a = isAPropertyOf(vo, VCProcedureNameProp))) {
01268 s = fakeCString(vObjectUStringZValue(a));
01269 alarm->setProcedureAlarm(QFile::decodeName(s));
01270 deleteStr(s);
01271 }
01272 }
01273 if ((vo = isAPropertyOf(vevent, VCAAlarmProp))) {
01274 if ((a = isAPropertyOf(vo, VCAudioContentProp))) {
01275 s = fakeCString(vObjectUStringZValue(a));
01276 alarm->setAudioAlarm(QFile::decodeName(s));
01277 deleteStr(s);
01278 }
01279 }
01280 }
01281
01282
01283 if ((vo = isAPropertyOf(vevent, VCPriorityProp))) {
01284 anEvent->setPriority(atoi(s = fakeCString(vObjectUStringZValue(vo))));
01285 deleteStr(s);
01286 }
01287
01288
01289 if ((vo = isAPropertyOf(vevent, VCTranspProp)) != 0) {
01290 int i = atoi(s = fakeCString(vObjectUStringZValue(vo)));
01291 anEvent->setTransparency( i == 1 ? Event::Transparent : Event::Opaque );
01292 deleteStr(s);
01293 }
01294
01295
01296 if ((vo = isAPropertyOf(vevent, VCRelatedToProp)) != 0) {
01297 anEvent->setRelatedToUid(s = fakeCString(vObjectUStringZValue(vo)));
01298 deleteStr(s);
01299 mEventsRelate.append(anEvent);
01300 }
01301
01302
01303 if ((vo = isAPropertyOf(vevent, KPilotIdProp))) {
01304 anEvent->setPilotId(atoi(s = fakeCString(vObjectUStringZValue(vo))));
01305 deleteStr(s);
01306 }
01307 else
01308 anEvent->setPilotId(0);
01309
01310 if ((vo = isAPropertyOf(vevent, KPilotStatusProp))) {
01311 anEvent->setSyncStatus(atoi(s = fakeCString(vObjectUStringZValue(vo))));
01312 deleteStr(s);
01313 }
01314 else
01315 anEvent->setSyncStatus(Event::SYNCMOD);
01316
01317 return anEvent;
01318 }
01319
01320
01321 QString VCalFormat::qDateToISO(const QDate &qd)
01322 {
01323 QString tmpStr;
01324
01325 Q_ASSERT(qd.isValid());
01326
01327 tmpStr.sprintf("%.2d%.2d%.2d",
01328 qd.year(), qd.month(), qd.day());
01329 return tmpStr;
01330
01331 }
01332
01333
01334
01335 int vcaltime_utc_offset( QDateTime ictt, QString tzid )
01336 {
01337
01338
01339
01340 int daylight;
01341 struct icaltimetype tt = icaltime_from_timet( ictt.toTime_t(), false );
01342
01343
01344 return icaltimezone_get_utc_offset(
01345 icaltimezone_get_builtin_timezone( tzid.latin1() ),
01346 &tt, &daylight );
01347 }
01348
01349 QString VCalFormat::qDateTimeToISO(const QDateTime &qdt, bool zulu)
01350 {
01351 QString tmpStr;
01352
01353 Q_ASSERT(qdt.date().isValid());
01354 Q_ASSERT(qdt.time().isValid());
01355 if (zulu) {
01356 QDateTime tmpDT(qdt);
01357
01358 tmpDT = tmpDT.addSecs(-vcaltime_utc_offset( tmpDT, mCalendar->timeZoneId()));
01359 tmpStr.sprintf( "%.2d%.2d%.2dT%.2d%.2d%.2dZ",
01360 tmpDT.date().year(), tmpDT.date().month(),
01361 tmpDT.date().day(), tmpDT.time().hour(),
01362 tmpDT.time().minute(), tmpDT.time().second());
01363 } else {
01364 tmpStr.sprintf( "%.2d%.2d%.2dT%.2d%.2d%.2d",
01365 qdt.date().year(), qdt.date().month(),
01366 qdt.date().day(), qdt.time().hour(),
01367 qdt.time().minute(), qdt.time().second());
01368 }
01369 return tmpStr;
01370 }
01371
01372 QDateTime VCalFormat::ISOToQDateTime(const QString & dtStr)
01373 {
01374 QDate tmpDate;
01375 QTime tmpTime;
01376 QString tmpStr;
01377 int year, month, day, hour, minute, second;
01378
01379 tmpStr = dtStr;
01380 year = tmpStr.left(4).toInt();
01381 month = tmpStr.mid(4,2).toInt();
01382 day = tmpStr.mid(6,2).toInt();
01383 hour = tmpStr.mid(9,2).toInt();
01384 minute = tmpStr.mid(11,2).toInt();
01385 second = tmpStr.mid(13,2).toInt();
01386 tmpDate.setYMD(year, month, day);
01387 tmpTime.setHMS(hour, minute, second);
01388
01389 Q_ASSERT(tmpDate.isValid());
01390 Q_ASSERT(tmpTime.isValid());
01391 QDateTime tmpDT(tmpDate, tmpTime);
01392
01393 if (dtStr.at(dtStr.length()-1) == 'Z') {
01394 tmpDT = tmpDT.addSecs(vcaltime_utc_offset( tmpDT, mCalendar->timeZoneId()));
01395 }
01396 return tmpDT;
01397 }
01398
01399 QDate VCalFormat::ISOToQDate(const QString &dateStr)
01400 {
01401 int year, month, day;
01402
01403 year = dateStr.left(4).toInt();
01404 month = dateStr.mid(4,2).toInt();
01405 day = dateStr.mid(6,2).toInt();
01406
01407 return(QDate(year, month, day));
01408 }
01409
01410
01411
01412
01413 void VCalFormat::populate(VObject *vcal)
01414 {
01415
01416
01417
01418 VObjectIterator i;
01419 VObject *curVO, *curVOProp;
01420 Event *anEvent;
01421
01422 if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
01423 char *methodType = 0;
01424 methodType = fakeCString(vObjectUStringZValue(curVO));
01425 kdDebug(5800) << "This calendar is an iTIP transaction of type '"
01426 << methodType << "'" << endl;
01427 delete methodType;
01428 }
01429
01430
01431 if ((curVO = isAPropertyOf(vcal, VCProdIdProp)) != 0) {
01432 char *s = fakeCString(vObjectUStringZValue(curVO));
01433 if (strcmp(productId().local8Bit(), s) != 0)
01434 kdDebug(5800) << "This vCalendar file was not created by KOrganizer "
01435 "or any other product we support. Loading anyway..." << endl;
01436 mLoadedProductId = s;
01437 deleteStr(s);
01438 }
01439
01440
01441 if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
01442 char *s = fakeCString(vObjectUStringZValue(curVO));
01443 if (strcmp(_VCAL_VERSION, s) != 0)
01444 kdDebug(5800) << "This vCalendar file has version " << s
01445 << "We only support " << _VCAL_VERSION << endl;
01446 deleteStr(s);
01447 }
01448
01449 #if 0
01450
01451 if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
01452 char *s = fakeCString(vObjectUStringZValue(curVO));
01453 mCalendar->setTimeZone(s);
01454 deleteStr(s);
01455 }
01456 #endif
01457
01458
01459 mEventsRelate.clear();
01460 mTodosRelate.clear();
01461
01462 initPropIterator(&i, vcal);
01463
01464
01465 while (moreIteration(&i)) {
01466 curVO = nextVObject(&i);
01467
01468
01469
01470
01471 if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
01472
01473 if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) {
01474 char *s;
01475 s = fakeCString(vObjectUStringZValue(curVOProp));
01476
01477 if (atoi(s) == Event::SYNCDEL) {
01478 deleteStr(s);
01479 kdDebug(5800) << "skipping pilot-deleted event" << endl;
01480 goto SKIP;
01481 }
01482 deleteStr(s);
01483 }
01484
01485
01486
01487
01488 if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) {
01489 char *s = fakeCString(vObjectUStringZValue(curVOProp));
01490 QString tmpStr(s);
01491 deleteStr(s);
01492
01493 if (mCalendar->incidence(tmpStr)) {
01494 goto SKIP;
01495 }
01496 }
01497
01498 if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) &&
01499 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) {
01500 kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl;
01501 goto SKIP;
01502 }
01503
01504 anEvent = VEventToEvent(curVO);
01505
01506
01507 if (anEvent) {
01508 if ( !anEvent->dtStart().isValid() || !anEvent->dtEnd().isValid() ) {
01509 kdDebug(5800) << "VCalFormat::populate(): Event has invalid dates."
01510 << endl;
01511 } else {
01512 mCalendar->addEvent(anEvent);
01513 }
01514 } else {
01515
01516 goto SKIP;
01517 }
01518 } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
01519 Todo *aTodo = VTodoToEvent(curVO);
01520 mCalendar->addTodo(aTodo);
01521 } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
01522 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
01523 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
01524
01525
01526 ;
01527 } else {
01528 kdDebug(5800) << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"" << endl;
01529 }
01530 SKIP:
01531 ;
01532 }
01533
01534
01535 Event::List::ConstIterator eIt;
01536 for ( eIt = mEventsRelate.begin(); eIt != mEventsRelate.end(); ++eIt ) {
01537 (*eIt)->setRelatedTo( mCalendar->incidence( (*eIt)->relatedToUid() ) );
01538 }
01539 Todo::List::ConstIterator tIt;
01540 for ( tIt = mTodosRelate.begin(); tIt != mTodosRelate.end(); ++tIt ) {
01541 (*tIt)->setRelatedTo( mCalendar->incidence( (*tIt)->relatedToUid() ) );
01542 }
01543 }
01544
01545 const char *VCalFormat::dayFromNum(int day)
01546 {
01547 const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " };
01548
01549 return days[day];
01550 }
01551
01552 int VCalFormat::numFromDay(const QString &day)
01553 {
01554 if (day == "MO ") return 0;
01555 if (day == "TU ") return 1;
01556 if (day == "WE ") return 2;
01557 if (day == "TH ") return 3;
01558 if (day == "FR ") return 4;
01559 if (day == "SA ") return 5;
01560 if (day == "SU ") return 6;
01561
01562 return -1;
01563 }
01564
01565 Attendee::PartStat VCalFormat::readStatus(const char *s) const
01566 {
01567 QString statStr = s;
01568 statStr = statStr.upper();
01569 Attendee::PartStat status;
01570
01571 if (statStr == "X-ACTION")
01572 status = Attendee::NeedsAction;
01573 else if (statStr == "NEEDS ACTION")
01574 status = Attendee::NeedsAction;
01575 else if (statStr== "ACCEPTED")
01576 status = Attendee::Accepted;
01577 else if (statStr== "SENT")
01578 status = Attendee::NeedsAction;
01579 else if (statStr== "TENTATIVE")
01580 status = Attendee::Tentative;
01581 else if (statStr== "CONFIRMED")
01582 status = Attendee::Accepted;
01583 else if (statStr== "DECLINED")
01584 status = Attendee::Declined;
01585 else if (statStr== "COMPLETED")
01586 status = Attendee::Completed;
01587 else if (statStr== "DELEGATED")
01588 status = Attendee::Delegated;
01589 else {
01590 kdDebug(5800) << "error setting attendee mStatus, unknown mStatus!" << endl;
01591 status = Attendee::NeedsAction;
01592 }
01593
01594 return status;
01595 }
01596
01597 QCString VCalFormat::writeStatus(Attendee::PartStat status) const
01598 {
01599 switch(status) {
01600 default:
01601 case Attendee::NeedsAction:
01602 return "NEEDS ACTION";
01603 break;
01604 case Attendee::Accepted:
01605 return "ACCEPTED";
01606 break;
01607 case Attendee::Declined:
01608 return "DECLINED";
01609 break;
01610 case Attendee::Tentative:
01611 return "TENTATIVE";
01612 break;
01613 case Attendee::Delegated:
01614 return "DELEGATED";
01615 break;
01616 case Attendee::Completed:
01617 return "COMPLETED";
01618 break;
01619 case Attendee::InProcess:
01620 return "NEEDS ACTION";
01621 break;
01622 }
01623 }