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