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