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