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