00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <qdatetime.h>
00024 #include <qstring.h>
00025 #include <qptrlist.h>
00026 #include <qfile.h>
00027 #include <cstdlib>
00028
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 #include <kmdcodec.h>
00032
00033 extern "C" {
00034 #include <ical.h>
00035 #include <icalparser.h>
00036 #include <icalrestriction.h>
00037 }
00038
00039 #include "calendar.h"
00040 #include "journal.h"
00041 #include "icalformat.h"
00042 #include "icalformatimpl.h"
00043 #include "compat.h"
00044
00045 #define _ICAL_VERSION "2.0"
00046
00047 using namespace KCal;
00048
00049
00050 static QDateTime ICalDate2QDate(const icaltimetype& t)
00051 {
00052
00053
00054 const int year = (t.year>=1754) ? t.year : 1754;
00055 return QDateTime(QDate(year,t.month,t.day), QTime(t.hour,t.minute,t.second));
00056 }
00057
00058 static void _dumpIcaltime( const icaltimetype& t)
00059 {
00060 kdDebug(5800) << "--- Y: " << t.year << " M: " << t.month << " D: " << t.day
00061 << endl;
00062 kdDebug(5800) << "--- H: " << t.hour << " M: " << t.minute << " S: " << t.second
00063 << endl;
00064 kdDebug(5800) << "--- isUtc: " << icaltime_is_utc( t )<< endl;
00065 kdDebug(5800) << "--- zoneId: " << icaltimezone_get_tzid( const_cast<icaltimezone*>( t.zone ) )<< endl;
00066 }
00067
00068 const int gSecondsPerMinute = 60;
00069 const int gSecondsPerHour = gSecondsPerMinute * 60;
00070 const int gSecondsPerDay = gSecondsPerHour * 24;
00071 const int gSecondsPerWeek = gSecondsPerDay * 7;
00072
00073 ICalFormatImpl::ICalFormatImpl( ICalFormat *parent ) :
00074 mParent( parent ), mCompat( new Compat )
00075 {
00076 }
00077
00078 ICalFormatImpl::~ICalFormatImpl()
00079 {
00080 delete mCompat;
00081 }
00082
00083 class ICalFormatImpl::ToComponentVisitor : public IncidenceBase::Visitor
00084 {
00085 public:
00086 ToComponentVisitor( ICalFormatImpl *impl, Scheduler::Method m ) : mImpl( impl ), mComponent( 0 ), mMethod( m ) {}
00087
00088 bool visit( Event *e ) { mComponent = mImpl->writeEvent( e ); return true; }
00089 bool visit( Todo *e ) { mComponent = mImpl->writeTodo( e ); return true; }
00090 bool visit( Journal *e ) { mComponent = mImpl->writeJournal( e ); return true; }
00091 bool visit( FreeBusy *fb ) { mComponent = mImpl->writeFreeBusy( fb, mMethod ); return true; }
00092
00093 icalcomponent *component() { return mComponent; }
00094
00095 private:
00096 ICalFormatImpl *mImpl;
00097 icalcomponent *mComponent;
00098 Scheduler::Method mMethod;
00099 };
00100
00101 icalcomponent *ICalFormatImpl::writeIncidence( IncidenceBase *incidence, Scheduler::Method method )
00102 {
00103 ToComponentVisitor v( this, method );
00104 if ( incidence->accept(v) )
00105 return v.component();
00106 else return 0;
00107 }
00108
00109 icalcomponent *ICalFormatImpl::writeTodo(Todo *todo)
00110 {
00111 QString tmpStr;
00112 QStringList tmpStrList;
00113
00114 icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT);
00115
00116 writeIncidence(vtodo,todo);
00117
00118
00119 if (todo->hasDueDate()) {
00120 icaltimetype due;
00121 if (todo->doesFloat()) {
00122 due = writeICalDate(todo->dtDue(true).date());
00123 } else {
00124 due = writeICalDateTime(todo->dtDue(true));
00125 }
00126 icalcomponent_add_property(vtodo,icalproperty_new_due(due));
00127 }
00128
00129
00130 if ( todo->hasStartDate() || todo->doesRecur() ) {
00131 icaltimetype start;
00132 if (todo->doesFloat()) {
00133
00134 start = writeICalDate(todo->dtStart(true).date());
00135 } else {
00136
00137 start = writeICalDateTime(todo->dtStart(true));
00138 }
00139 icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start));
00140 }
00141
00142
00143 if (todo->isCompleted()) {
00144 if (!todo->hasCompletedDate()) {
00145
00146
00147 todo->setCompleted(QDateTime::currentDateTime());
00148 }
00149 icaltimetype completed = writeICalDateTime(todo->completed());
00150 icalcomponent_add_property(vtodo,icalproperty_new_completed(completed));
00151 }
00152
00153 icalcomponent_add_property(vtodo,
00154 icalproperty_new_percentcomplete(todo->percentComplete()));
00155
00156 if( todo->doesRecur() ) {
00157 icalcomponent_add_property(vtodo,
00158 icalproperty_new_recurrenceid( writeICalDateTime( todo->dtDue())));
00159 }
00160
00161 return vtodo;
00162 }
00163
00164 icalcomponent *ICalFormatImpl::writeEvent(Event *event)
00165 {
00166 #if 0
00167 kdDebug(5800) << "Write Event '" << event->summary() << "' (" << event->uid()
00168 << ")" << endl;
00169 #endif
00170
00171 QString tmpStr;
00172 QStringList tmpStrList;
00173
00174 icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
00175
00176 writeIncidence(vevent,event);
00177
00178
00179 icaltimetype start;
00180 if (event->doesFloat()) {
00181
00182 start = writeICalDate(event->dtStart().date());
00183 } else {
00184
00185 start = writeICalDateTime(event->dtStart());
00186 }
00187 icalcomponent_add_property(vevent,icalproperty_new_dtstart(start));
00188
00189 if (event->hasEndDate()) {
00190
00191
00192 icaltimetype end;
00193 if (event->doesFloat()) {
00194
00195
00196 end = writeICalDate( event->dtEnd().date().addDays( 1 ) );
00197 icalcomponent_add_property(vevent,icalproperty_new_dtend(end));
00198 } else {
00199
00200 if (event->dtEnd() != event->dtStart()) {
00201 end = writeICalDateTime(event->dtEnd());
00202 icalcomponent_add_property(vevent,icalproperty_new_dtend(end));
00203 }
00204 }
00205 }
00206
00207
00208 #if 0
00209
00210 tmpStrList = anEvent->resources();
00211 tmpStr = tmpStrList.join(";");
00212 if (!tmpStr.isEmpty())
00213 addPropValue(vevent, VCResourcesProp, tmpStr.utf8());
00214
00215 #endif
00216
00217
00218 switch( event->transparency() ) {
00219 case Event::Transparent:
00220 icalcomponent_add_property(
00221 vevent,
00222 icalproperty_new_transp( ICAL_TRANSP_TRANSPARENT ) );
00223 break;
00224 case Event::Opaque:
00225 icalcomponent_add_property(
00226 vevent,
00227 icalproperty_new_transp( ICAL_TRANSP_OPAQUE ) );
00228 break;
00229 }
00230
00231 return vevent;
00232 }
00233
00234 icalcomponent *ICalFormatImpl::writeFreeBusy(FreeBusy *freebusy,
00235 Scheduler::Method method)
00236 {
00237 #if QT_VERSION >= 300
00238 kdDebug(5800) << "icalformatimpl: writeFreeBusy: startDate: "
00239 << freebusy->dtStart().toString("ddd MMMM d yyyy: h:m:s ap") << " End Date: "
00240 << freebusy->dtEnd().toString("ddd MMMM d yyyy: h:m:s ap") << endl;
00241 #endif
00242
00243 icalcomponent *vfreebusy = icalcomponent_new(ICAL_VFREEBUSY_COMPONENT);
00244
00245 writeIncidenceBase(vfreebusy,freebusy);
00246
00247 icalcomponent_add_property(vfreebusy, icalproperty_new_dtstart(
00248 writeICalDateTime(freebusy->dtStart())));
00249
00250 icalcomponent_add_property(vfreebusy, icalproperty_new_dtend(
00251 writeICalDateTime(freebusy->dtEnd())));
00252
00253 if (method == Scheduler::Request) {
00254 icalcomponent_add_property(vfreebusy,icalproperty_new_uid(
00255 freebusy->uid().utf8()));
00256 }
00257
00258
00259 QValueList<Period> list = freebusy->busyPeriods();
00260 QValueList<Period>::Iterator it;
00261 icalperiodtype period = icalperiodtype_null_period();
00262 for (it = list.begin(); it!= list.end(); ++it) {
00263 period.start = writeICalDateTime((*it).start());
00264 if ( (*it).hasDuration() ) {
00265 period.duration = writeICalDuration( (*it).duration().asSeconds() );
00266 } else {
00267 period.end = writeICalDateTime((*it).end());
00268 }
00269 icalcomponent_add_property(vfreebusy, icalproperty_new_freebusy(period) );
00270 }
00271
00272 return vfreebusy;
00273 }
00274
00275 icalcomponent *ICalFormatImpl::writeJournal(Journal *journal)
00276 {
00277 icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT);
00278
00279 writeIncidence(vjournal,journal);
00280
00281
00282 if (journal->dtStart().isValid()) {
00283 icaltimetype start;
00284 if (journal->doesFloat()) {
00285
00286 start = writeICalDate(journal->dtStart().date());
00287 } else {
00288
00289 start = writeICalDateTime(journal->dtStart());
00290 }
00291 icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start));
00292 }
00293
00294 return vjournal;
00295 }
00296
00297 void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence)
00298 {
00299
00300
00301 if (incidence->pilotId()) {
00302
00303
00304
00305
00306
00307 icalproperty *p = 0;
00308 p = icalproperty_new_x(QString::number(incidence->syncStatus()).utf8());
00309 icalproperty_set_x_name(p,"X-PILOTSTAT");
00310 icalcomponent_add_property(parent,p);
00311
00312 p = icalproperty_new_x(QString::number(incidence->pilotId()).utf8());
00313 icalproperty_set_x_name(p,"X-PILOTID");
00314 icalcomponent_add_property(parent,p);
00315 }
00316
00317 if ( incidence->schedulingID() != incidence->uid() )
00318
00319
00320 incidence->setCustomProperty( "LIBKCAL", "ID", incidence->uid() );
00321 else
00322 incidence->removeCustomProperty( "LIBKCAL", "ID" );
00323
00324 writeIncidenceBase(parent,incidence);
00325
00326
00327 icalcomponent_add_property(parent,icalproperty_new_created(
00328 writeICalDateTime(incidence->created())));
00329
00330
00331
00332
00333 if ( !incidence->schedulingID().isEmpty() ) {
00334 icalcomponent_add_property(parent,icalproperty_new_uid(
00335 incidence->schedulingID().utf8()));
00336 }
00337
00338
00339 if ( incidence->revision() > 0 ) {
00340 icalcomponent_add_property(parent,icalproperty_new_sequence(
00341 incidence->revision()));
00342 }
00343
00344
00345 if ( incidence->lastModified().isValid() ) {
00346 icalcomponent_add_property(parent,icalproperty_new_lastmodified(
00347 writeICalDateTime(incidence->lastModified())));
00348 }
00349
00350
00351 if (!incidence->description().isEmpty()) {
00352 icalcomponent_add_property(parent,icalproperty_new_description(
00353 incidence->description().utf8()));
00354 }
00355
00356
00357 if (!incidence->summary().isEmpty()) {
00358 icalcomponent_add_property(parent,icalproperty_new_summary(
00359 incidence->summary().utf8()));
00360 }
00361
00362
00363 if (!incidence->location().isEmpty()) {
00364 icalcomponent_add_property(parent,icalproperty_new_location(
00365 incidence->location().utf8()));
00366 }
00367
00368
00369 icalproperty_status status = ICAL_STATUS_NONE;
00370 switch (incidence->status()) {
00371 case Incidence::StatusTentative: status = ICAL_STATUS_TENTATIVE; break;
00372 case Incidence::StatusConfirmed: status = ICAL_STATUS_CONFIRMED; break;
00373 case Incidence::StatusCompleted: status = ICAL_STATUS_COMPLETED; break;
00374 case Incidence::StatusNeedsAction: status = ICAL_STATUS_NEEDSACTION; break;
00375 case Incidence::StatusCanceled: status = ICAL_STATUS_CANCELLED; break;
00376 case Incidence::StatusInProcess: status = ICAL_STATUS_INPROCESS; break;
00377 case Incidence::StatusDraft: status = ICAL_STATUS_DRAFT; break;
00378 case Incidence::StatusFinal: status = ICAL_STATUS_FINAL; break;
00379 case Incidence::StatusX: {
00380 icalproperty* p = icalproperty_new_status(ICAL_STATUS_X);
00381 icalvalue_set_x(icalproperty_get_value(p), incidence->statusStr().utf8());
00382 icalcomponent_add_property(parent, p);
00383 break;
00384 }
00385 case Incidence::StatusNone:
00386 default:
00387 break;
00388 }
00389 if (status != ICAL_STATUS_NONE)
00390 icalcomponent_add_property(parent, icalproperty_new_status(status));
00391
00392
00393 icalproperty_class secClass;
00394 switch (incidence->secrecy()) {
00395 case Incidence::SecrecyPublic:
00396 secClass = ICAL_CLASS_PUBLIC;
00397 break;
00398 case Incidence::SecrecyConfidential:
00399 secClass = ICAL_CLASS_CONFIDENTIAL;
00400 break;
00401 case Incidence::SecrecyPrivate:
00402 default:
00403 secClass = ICAL_CLASS_PRIVATE;
00404 break;
00405 }
00406 if ( secClass != ICAL_CLASS_PUBLIC ) {
00407 icalcomponent_add_property(parent,icalproperty_new_class(secClass));
00408 }
00409
00410
00411 if ( incidence->priority() > 0 ) {
00412 icalcomponent_add_property(parent,icalproperty_new_priority(
00413 incidence->priority()));
00414 }
00415
00416
00417 QStringList categories = incidence->categories();
00418 QStringList::Iterator it;
00419 for(it = categories.begin(); it != categories.end(); ++it ) {
00420 icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8()));
00421 }
00422
00423
00424 if ( !incidence->relatedToUid().isEmpty() ) {
00425 icalcomponent_add_property(parent,icalproperty_new_relatedto(
00426 incidence->relatedToUid().utf8()));
00427 }
00428
00429
00430
00431
00432 RecurrenceRule::List rrules( incidence->recurrence()->rRules() );
00433 RecurrenceRule::List::ConstIterator rit;
00434 for ( rit = rrules.begin(); rit != rrules.end(); ++rit ) {
00435 icalcomponent_add_property( parent, icalproperty_new_rrule(
00436 writeRecurrenceRule( (*rit) ) ) );
00437 }
00438
00439 RecurrenceRule::List exrules( incidence->recurrence()->exRules() );
00440 RecurrenceRule::List::ConstIterator exit;
00441 for ( exit = exrules.begin(); exit != exrules.end(); ++exit ) {
00442 icalcomponent_add_property( parent, icalproperty_new_rrule(
00443 writeRecurrenceRule( (*exit) ) ) );
00444 }
00445
00446 DateList dateList = incidence->recurrence()->exDates();
00447 DateList::ConstIterator exIt;
00448 for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) {
00449 icalcomponent_add_property(parent,icalproperty_new_exdate(
00450 writeICalDate(*exIt)));
00451 }
00452 DateTimeList dateTimeList = incidence->recurrence()->exDateTimes();
00453 DateTimeList::ConstIterator extIt;
00454 for(extIt = dateTimeList.begin(); extIt != dateTimeList.end(); ++extIt) {
00455 icalcomponent_add_property(parent,icalproperty_new_exdate(
00456 writeICalDateTime(*extIt)));
00457 }
00458
00459
00460 dateList = incidence->recurrence()->rDates();
00461 DateList::ConstIterator rdIt;
00462 for( rdIt = dateList.begin(); rdIt != dateList.end(); ++rdIt) {
00463 icalcomponent_add_property( parent, icalproperty_new_rdate(
00464 writeICalDatePeriod(*rdIt) ) );
00465 }
00466 dateTimeList = incidence->recurrence()->rDateTimes();
00467 DateTimeList::ConstIterator rdtIt;
00468 for( rdtIt = dateTimeList.begin(); rdtIt != dateTimeList.end(); ++rdtIt) {
00469 icalcomponent_add_property( parent, icalproperty_new_rdate(
00470 writeICalDateTimePeriod(*rdtIt) ) );
00471 }
00472
00473
00474 Attachment::List attachments = incidence->attachments();
00475 Attachment::List::ConstIterator atIt;
00476 for ( atIt = attachments.begin(); atIt != attachments.end(); ++atIt ) {
00477 icalcomponent_add_property( parent, writeAttachment( *atIt ) );
00478 }
00479
00480
00481 Alarm::List::ConstIterator alarmIt;
00482 for ( alarmIt = incidence->alarms().begin();
00483 alarmIt != incidence->alarms().end(); ++alarmIt ) {
00484 if ( (*alarmIt)->enabled() ) {
00485
00486 icalcomponent_add_component( parent, writeAlarm( *alarmIt ) );
00487 }
00488 }
00489
00490
00491 if (incidence->hasDuration()) {
00492 icaldurationtype duration;
00493 duration = writeICalDuration( incidence->duration() );
00494 icalcomponent_add_property(parent,icalproperty_new_duration(duration));
00495 }
00496 }
00497
00498 void ICalFormatImpl::writeIncidenceBase( icalcomponent *parent,
00499 IncidenceBase * incidenceBase )
00500 {
00501 icalcomponent_add_property( parent, icalproperty_new_dtstamp(
00502 writeICalDateTime( QDateTime::currentDateTime() ) ) );
00503
00504
00505 if ( !incidenceBase->organizer().isEmpty() ) {
00506 icalcomponent_add_property( parent, writeOrganizer( incidenceBase->organizer() ) );
00507 }
00508
00509
00510 if ( incidenceBase->attendeeCount() > 0 ) {
00511 Attendee::List::ConstIterator it;
00512 for( it = incidenceBase->attendees().begin();
00513 it != incidenceBase->attendees().end(); ++it ) {
00514 icalcomponent_add_property( parent, writeAttendee( *it ) );
00515 }
00516 }
00517
00518
00519 QStringList comments = incidenceBase->comments();
00520 for (QStringList::Iterator it=comments.begin(); it!=comments.end(); ++it) {
00521 icalcomponent_add_property(parent, icalproperty_new_comment((*it).utf8()));
00522 }
00523
00524
00525 writeCustomProperties( parent, incidenceBase );
00526 }
00527
00528 void ICalFormatImpl::writeCustomProperties(icalcomponent *parent,CustomProperties *properties)
00529 {
00530 QMap<QCString, QString> custom = properties->customProperties();
00531 for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
00532 icalproperty *p = icalproperty_new_x(c.data().utf8());
00533 icalproperty_set_x_name(p,c.key());
00534 icalcomponent_add_property(parent,p);
00535 }
00536 }
00537
00538 icalproperty *ICalFormatImpl::writeOrganizer( const Person &organizer )
00539 {
00540 icalproperty *p = icalproperty_new_organizer("MAILTO:" + organizer.email().utf8());
00541
00542 if (!organizer.name().isEmpty()) {
00543 icalproperty_add_parameter( p, icalparameter_new_cn(organizer.name().utf8()) );
00544 }
00545
00546
00547 return p;
00548 }
00549
00550
00551 icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee)
00552 {
00553 icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8());
00554
00555 if (!attendee->name().isEmpty()) {
00556 icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8()));
00557 }
00558
00559
00560 icalproperty_add_parameter(p,icalparameter_new_rsvp(
00561 attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE ));
00562
00563 icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION;
00564 switch (attendee->status()) {
00565 default:
00566 case Attendee::NeedsAction:
00567 status = ICAL_PARTSTAT_NEEDSACTION;
00568 break;
00569 case Attendee::Accepted:
00570 status = ICAL_PARTSTAT_ACCEPTED;
00571 break;
00572 case Attendee::Declined:
00573 status = ICAL_PARTSTAT_DECLINED;
00574 break;
00575 case Attendee::Tentative:
00576 status = ICAL_PARTSTAT_TENTATIVE;
00577 break;
00578 case Attendee::Delegated:
00579 status = ICAL_PARTSTAT_DELEGATED;
00580 break;
00581 case Attendee::Completed:
00582 status = ICAL_PARTSTAT_COMPLETED;
00583 break;
00584 case Attendee::InProcess:
00585 status = ICAL_PARTSTAT_INPROCESS;
00586 break;
00587 }
00588 icalproperty_add_parameter(p,icalparameter_new_partstat(status));
00589
00590 icalparameter_role role = ICAL_ROLE_REQPARTICIPANT;
00591 switch (attendee->role()) {
00592 case Attendee::Chair:
00593 role = ICAL_ROLE_CHAIR;
00594 break;
00595 default:
00596 case Attendee::ReqParticipant:
00597 role = ICAL_ROLE_REQPARTICIPANT;
00598 break;
00599 case Attendee::OptParticipant:
00600 role = ICAL_ROLE_OPTPARTICIPANT;
00601 break;
00602 case Attendee::NonParticipant:
00603 role = ICAL_ROLE_NONPARTICIPANT;
00604 break;
00605 }
00606 icalproperty_add_parameter(p,icalparameter_new_role(role));
00607
00608 if (!attendee->uid().isEmpty()) {
00609 icalparameter* icalparameter_uid = icalparameter_new_x(attendee->uid().utf8());
00610 icalparameter_set_xname(icalparameter_uid,"X-UID");
00611 icalproperty_add_parameter(p,icalparameter_uid);
00612 }
00613
00614 if ( !attendee->delegate().isEmpty() ) {
00615 icalparameter* icalparameter_delegate = icalparameter_new_delegatedto( attendee->delegate().utf8() );
00616 icalproperty_add_parameter( p, icalparameter_delegate );
00617 }
00618
00619 if ( !attendee->delegator().isEmpty() ) {
00620 icalparameter* icalparameter_delegator = icalparameter_new_delegatedfrom( attendee->delegator().utf8() );
00621 icalproperty_add_parameter( p, icalparameter_delegator );
00622 }
00623
00624 return p;
00625 }
00626
00627 icalproperty *ICalFormatImpl::writeAttachment(Attachment *att)
00628 {
00629 icalattach *attach;
00630 if (att->isUri())
00631 attach = icalattach_new_from_url( att->uri().utf8().data());
00632 else
00633 attach = icalattach_new_from_data ( (unsigned char *)att->data(), 0, 0);
00634 icalproperty *p = icalproperty_new_attach(attach);
00635
00636 if ( !att->mimeType().isEmpty() ) {
00637 icalproperty_add_parameter( p,
00638 icalparameter_new_fmttype( att->mimeType().utf8().data() ) );
00639 }
00640
00641 if ( att->isBinary() ) {
00642 icalproperty_add_parameter( p,
00643 icalparameter_new_value( ICAL_VALUE_BINARY ) );
00644 icalproperty_add_parameter( p,
00645 icalparameter_new_encoding( ICAL_ENCODING_BASE64 ) );
00646 }
00647
00648 if ( att->showInline() ) {
00649 icalparameter* icalparameter_inline = icalparameter_new_x( "inline" );
00650 icalparameter_set_xname( icalparameter_inline, "X-CONTENT-DISPOSITION" );
00651 icalproperty_add_parameter( p, icalparameter_inline );
00652 }
00653
00654 if ( !att->label().isEmpty() ) {
00655 icalparameter* icalparameter_label = icalparameter_new_x( att->label().utf8() );
00656 icalparameter_set_xname( icalparameter_label, "X-LABEL" );
00657 icalproperty_add_parameter( p, icalparameter_label );
00658 }
00659
00660 return p;
00661 }
00662
00663 icalrecurrencetype ICalFormatImpl::writeRecurrenceRule( RecurrenceRule *recur )
00664 {
00665
00666
00667 icalrecurrencetype r;
00668 icalrecurrencetype_clear(&r);
00669
00670 switch( recur->recurrenceType() ) {
00671 case RecurrenceRule::rSecondly:
00672 r.freq = ICAL_SECONDLY_RECURRENCE;
00673 break;
00674 case RecurrenceRule::rMinutely:
00675 r.freq = ICAL_MINUTELY_RECURRENCE;
00676 break;
00677 case RecurrenceRule::rHourly:
00678 r.freq = ICAL_HOURLY_RECURRENCE;
00679 break;
00680 case RecurrenceRule::rDaily:
00681 r.freq = ICAL_DAILY_RECURRENCE;
00682 break;
00683 case RecurrenceRule::rWeekly:
00684 r.freq = ICAL_WEEKLY_RECURRENCE;
00685 break;
00686 case RecurrenceRule::rMonthly:
00687 r.freq = ICAL_MONTHLY_RECURRENCE;
00688 break;
00689 case RecurrenceRule::rYearly:
00690 r.freq = ICAL_YEARLY_RECURRENCE;
00691 break;
00692 default:
00693 r.freq = ICAL_NO_RECURRENCE;
00694 kdDebug(5800) << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl;
00695 break;
00696 }
00697
00698 int index = 0;
00699 QValueList<int> bys;
00700 QValueList<int>::ConstIterator it;
00701
00702
00703 bys = recur->bySeconds();
00704 index = 0;
00705 for ( it = bys.begin(); it != bys.end(); ++it ) {
00706 r.by_second[index++] = *it;
00707 }
00708
00709 bys = recur->byMinutes();
00710 index = 0;
00711 for ( it = bys.begin(); it != bys.end(); ++it ) {
00712 r.by_minute[index++] = *it;
00713 }
00714
00715 bys = recur->byHours();
00716 index = 0;
00717 for ( it = bys.begin(); it != bys.end(); ++it ) {
00718 r.by_hour[index++] = *it;
00719 }
00720
00721 bys = recur->byMonthDays();
00722 index = 0;
00723 for ( it = bys.begin(); it != bys.end(); ++it ) {
00724 r.by_month_day[index++] = icalrecurrencetype_day_position( (*it) * 8 );
00725 }
00726
00727 bys = recur->byYearDays();
00728 index = 0;
00729 for ( it = bys.begin(); it != bys.end(); ++it ) {
00730 r.by_year_day[index++] = *it;
00731 }
00732
00733 bys = recur->byWeekNumbers();
00734 index = 0;
00735 for ( it = bys.begin(); it != bys.end(); ++it ) {
00736 r.by_week_no[index++] = *it;
00737 }
00738
00739 bys = recur->byMonths();
00740 index = 0;
00741 for ( it = bys.begin(); it != bys.end(); ++it ) {
00742 r.by_month[index++] = *it;
00743 }
00744
00745 bys = recur->bySetPos();
00746 index = 0;
00747 for ( it = bys.begin(); it != bys.end(); ++it ) {
00748 r.by_set_pos[index++] = *it;
00749 }
00750
00751
00752 QValueList<RecurrenceRule::WDayPos> byd = recur->byDays();
00753 int day;
00754 index = 0;
00755 for ( QValueList<RecurrenceRule::WDayPos>::ConstIterator dit = byd.begin();
00756 dit != byd.end(); ++dit ) {
00757 day = (*dit).day() % 7 + 1;
00758 if ( (*dit).pos() < 0 ) {
00759 day += (-(*dit).pos())*8;
00760 day = -day;
00761 } else {
00762 day += (*dit).pos()*8;
00763 }
00764 r.by_day[index++] = day;
00765 }
00766
00767 r.week_start = static_cast<icalrecurrencetype_weekday>(
00768 recur->weekStart()%7 + 1);
00769
00770 if ( recur->frequency() > 1 ) {
00771
00772 r.interval = recur->frequency();
00773 }
00774
00775 if ( recur->duration() > 0 ) {
00776 r.count = recur->duration();
00777 } else if ( recur->duration() == -1 ) {
00778 r.count = 0;
00779 } else {
00780 if ( recur->doesFloat() )
00781 r.until = writeICalDate(recur->endDt().date());
00782 else
00783 r.until = writeICalDateTime(recur->endDt());
00784 }
00785
00786
00787 #if 0
00788 const char *str = icalrecurrencetype_as_string(&r);
00789 if (str) {
00790 kdDebug(5800) << " String: " << str << endl;
00791 } else {
00792 kdDebug(5800) << " No String" << endl;
00793 }
00794 #endif
00795
00796 return r;
00797 }
00798
00799
00800 icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm)
00801 {
00802
00803 icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT);
00804
00805 icalproperty_action action;
00806 icalattach *attach = 0;
00807
00808 switch (alarm->type()) {
00809 case Alarm::Procedure:
00810 action = ICAL_ACTION_PROCEDURE;
00811 attach = icalattach_new_from_url(QFile::encodeName(alarm->programFile()).data());
00812 icalcomponent_add_property(a,icalproperty_new_attach(attach));
00813 if (!alarm->programArguments().isEmpty()) {
00814 icalcomponent_add_property(a,icalproperty_new_description(alarm->programArguments().utf8()));
00815 }
00816 break;
00817 case Alarm::Audio:
00818 action = ICAL_ACTION_AUDIO;
00819
00820 if (!alarm->audioFile().isEmpty()) {
00821 attach = icalattach_new_from_url(QFile::encodeName( alarm->audioFile() ).data());
00822 icalcomponent_add_property(a,icalproperty_new_attach(attach));
00823 }
00824 break;
00825 case Alarm::Email: {
00826 action = ICAL_ACTION_EMAIL;
00827 QValueList<Person> addresses = alarm->mailAddresses();
00828 for (QValueList<Person>::Iterator ad = addresses.begin(); ad != addresses.end(); ++ad) {
00829 icalproperty *p = icalproperty_new_attendee("MAILTO:" + (*ad).email().utf8());
00830 if (!(*ad).name().isEmpty()) {
00831 icalproperty_add_parameter(p,icalparameter_new_cn((*ad).name().utf8()));
00832 }
00833 icalcomponent_add_property(a,p);
00834 }
00835 icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject().utf8()));
00836 icalcomponent_add_property(a,icalproperty_new_description(alarm->mailText().utf8()));
00837 QStringList attachments = alarm->mailAttachments();
00838 if (attachments.count() > 0) {
00839 for (QStringList::Iterator at = attachments.begin(); at != attachments.end(); ++at) {
00840 attach = icalattach_new_from_url(QFile::encodeName( *at ).data());
00841 icalcomponent_add_property(a,icalproperty_new_attach(attach));
00842 }
00843 }
00844 break;
00845 }
00846 case Alarm::Display:
00847 action = ICAL_ACTION_DISPLAY;
00848 icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
00849 break;
00850 case Alarm::Invalid:
00851 default:
00852 kdDebug(5800) << "Unknown type of alarm" << endl;
00853 action = ICAL_ACTION_NONE;
00854 break;
00855 }
00856 icalcomponent_add_property(a,icalproperty_new_action(action));
00857
00858
00859 icaltriggertype trigger;
00860 if ( alarm->hasTime() ) {
00861 trigger.time = writeICalDateTime(alarm->time());
00862 trigger.duration = icaldurationtype_null_duration();
00863 } else {
00864 trigger.time = icaltime_null_time();
00865 Duration offset;
00866 if ( alarm->hasStartOffset() )
00867 offset = alarm->startOffset();
00868 else
00869 offset = alarm->endOffset();
00870 trigger.duration = icaldurationtype_from_int( offset.asSeconds() );
00871 }
00872 icalproperty *p = icalproperty_new_trigger(trigger);
00873 if ( alarm->hasEndOffset() )
00874 icalproperty_add_parameter(p,icalparameter_new_related(ICAL_RELATED_END));
00875 icalcomponent_add_property(a,p);
00876
00877
00878 if (alarm->repeatCount()) {
00879 icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount()));
00880 icalcomponent_add_property(a,icalproperty_new_duration(
00881 icaldurationtype_from_int(alarm->snoozeTime()*60)));
00882 }
00883
00884
00885 QMap<QCString, QString> custom = alarm->customProperties();
00886 for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
00887 icalproperty *p = icalproperty_new_x(c.data().utf8());
00888 icalproperty_set_x_name(p,c.key());
00889 icalcomponent_add_property(a,p);
00890 }
00891
00892 return a;
00893 }
00894
00895 Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo)
00896 {
00897 Todo *todo = new Todo;
00898
00899 readIncidence(vtodo, 0, todo);
00900
00901 icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY);
00902
00903
00904 icaltimetype icaltime;
00905
00906 QStringList categories;
00907
00908 while (p) {
00909 icalproperty_kind kind = icalproperty_isa(p);
00910 switch (kind) {
00911
00912 case ICAL_DUE_PROPERTY:
00913 icaltime = icalproperty_get_due(p);
00914 if (icaltime.is_date) {
00915 todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0)),true);
00916 } else {
00917 todo->setDtDue(readICalDateTime(icaltime),true);
00918 todo->setFloats(false);
00919 }
00920 todo->setHasDueDate(true);
00921 break;
00922
00923 case ICAL_COMPLETED_PROPERTY:
00924 icaltime = icalproperty_get_completed(p);
00925 todo->setCompleted(readICalDateTime(icaltime));
00926 break;
00927
00928 case ICAL_PERCENTCOMPLETE_PROPERTY:
00929 todo->setPercentComplete(icalproperty_get_percentcomplete(p));
00930 break;
00931
00932 case ICAL_RELATEDTO_PROPERTY:
00933 todo->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
00934 mTodosRelate.append(todo);
00935 break;
00936
00937 case ICAL_DTSTART_PROPERTY: {
00938
00939 if ( todo->comments().grep("NoStartDate").count() )
00940 todo->setHasStartDate( false );
00941 else
00942 todo->setHasStartDate( true );
00943 break;
00944 }
00945
00946 case ICAL_RECURRENCEID_PROPERTY:
00947 icaltime = icalproperty_get_recurrenceid(p);
00948 todo->setDtRecurrence( readICalDateTime(icaltime) );
00949 break;
00950
00951 default:
00952
00953
00954 break;
00955 }
00956
00957 p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY);
00958 }
00959
00960 if (mCompat) mCompat->fixEmptySummary( todo );
00961
00962 return todo;
00963 }
00964
00965 Event *ICalFormatImpl::readEvent( icalcomponent *vevent, icalcomponent *vtimezone )
00966 {
00967 Event *event = new Event;
00968
00969
00970 icaltimezone *tz = icaltimezone_new();
00971 if ( !icaltimezone_set_component( tz, vtimezone ) ) {
00972 icaltimezone_free( tz, 1 );
00973 tz = 0;
00974 }
00975
00976 readIncidence( vevent, tz, event);
00977
00978 icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY);
00979
00980
00981 icaltimetype icaltime;
00982
00983 QStringList categories;
00984 icalproperty_transp transparency;
00985
00986 bool dtEndProcessed = false;
00987
00988 while (p) {
00989 icalproperty_kind kind = icalproperty_isa(p);
00990 switch (kind) {
00991
00992 case ICAL_DTEND_PROPERTY:
00993 icaltime = icalproperty_get_dtend(p);
00994 if (icaltime.is_date) {
00995
00996 QDate endDate = readICalDate( icaltime ).addDays( -1 );
00997 if ( mCompat ) mCompat->fixFloatingEnd( endDate );
00998 if ( endDate < event->dtStart().date() ) {
00999 endDate = event->dtStart().date();
01000 }
01001 event->setDtEnd( QDateTime( endDate, QTime( 0, 0, 0 ) ) );
01002 } else {
01003 event->setDtEnd(readICalDateTime(icaltime, tz));
01004 event->setFloats( false );
01005 }
01006 dtEndProcessed = true;
01007 break;
01008
01009 case ICAL_RELATEDTO_PROPERTY:
01010 event->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
01011 mEventsRelate.append(event);
01012 break;
01013
01014
01015 case ICAL_TRANSP_PROPERTY:
01016 transparency = icalproperty_get_transp(p);
01017 if( transparency == ICAL_TRANSP_TRANSPARENT )
01018 event->setTransparency( Event::Transparent );
01019 else
01020 event->setTransparency( Event::Opaque );
01021 break;
01022
01023 default:
01024
01025
01026 break;
01027 }
01028
01029 p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY);
01030 }
01031
01032
01033
01034 if ( !dtEndProcessed && !event->hasDuration() ) {
01035 event->setDtEnd( event->dtStart() );
01036 }
01037
01038 QString msade = event->nonKDECustomProperty("X-MICROSOFT-CDO-ALLDAYEVENT");
01039 if (!msade.isNull()) {
01040 bool floats = (msade == QString::fromLatin1("TRUE"));
01041
01042 event->setFloats(floats);
01043 if (floats) {
01044 QDateTime endDate = event->dtEnd();
01045 event->setDtEnd(endDate.addDays(-1));
01046 }
01047 }
01048
01049 if ( mCompat ) mCompat->fixEmptySummary( event );
01050
01051 return event;
01052 }
01053
01054 FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy)
01055 {
01056 FreeBusy *freebusy = new FreeBusy;
01057
01058 readIncidenceBase(vfreebusy, freebusy);
01059
01060 icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY);
01061
01062 icaltimetype icaltime;
01063 PeriodList periods;
01064
01065 while (p) {
01066 icalproperty_kind kind = icalproperty_isa(p);
01067 switch (kind) {
01068
01069 case ICAL_DTSTART_PROPERTY:
01070 icaltime = icalproperty_get_dtstart(p);
01071 freebusy->setDtStart(readICalDateTime(icaltime));
01072 break;
01073
01074 case ICAL_DTEND_PROPERTY:
01075 icaltime = icalproperty_get_dtend(p);
01076 freebusy->setDtEnd(readICalDateTime(icaltime));
01077 break;
01078
01079 case ICAL_FREEBUSY_PROPERTY: {
01080 icalperiodtype icalperiod = icalproperty_get_freebusy(p);
01081 QDateTime period_start = readICalDateTime(icalperiod.start);
01082 Period period;
01083 if ( !icaltime_is_null_time(icalperiod.end) ) {
01084 QDateTime period_end = readICalDateTime(icalperiod.end);
01085 period = Period(period_start, period_end);
01086 } else {
01087 Duration duration = readICalDuration( icalperiod.duration );
01088 period = Period(period_start, duration);
01089 }
01090 QCString param = icalproperty_get_parameter_as_string( p, "X-SUMMARY" );
01091 period.setSummary( QString::fromUtf8( KCodecs::base64Decode( param ) ) );
01092 param = icalproperty_get_parameter_as_string( p, "X-LOCATION" );
01093 period.setLocation( QString::fromUtf8( KCodecs::base64Decode( param ) ) );
01094 periods.append( period );
01095 break;}
01096
01097 default:
01098
01099
01100 break;
01101 }
01102 p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY);
01103 }
01104 freebusy->addPeriods( periods );
01105
01106 return freebusy;
01107 }
01108
01109 Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal)
01110 {
01111 Journal *journal = new Journal;
01112
01113 readIncidence(vjournal, 0, journal);
01114
01115 return journal;
01116 }
01117
01118 Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee)
01119 {
01120 icalparameter *p = 0;
01121
01122 QString email = QString::fromUtf8(icalproperty_get_attendee(attendee));
01123 if ( email.startsWith( "mailto:", false ) ) {
01124 email = email.mid( 7 );
01125 }
01126
01127 QString name;
01128 QString uid = QString::null;
01129 p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER);
01130 if (p) {
01131 name = QString::fromUtf8(icalparameter_get_cn(p));
01132 } else {
01133 }
01134
01135 bool rsvp=false;
01136 p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER);
01137 if (p) {
01138 icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p);
01139 if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true;
01140 }
01141
01142 Attendee::PartStat status = Attendee::NeedsAction;
01143 p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER);
01144 if (p) {
01145 icalparameter_partstat partStatParameter = icalparameter_get_partstat(p);
01146 switch(partStatParameter) {
01147 default:
01148 case ICAL_PARTSTAT_NEEDSACTION:
01149 status = Attendee::NeedsAction;
01150 break;
01151 case ICAL_PARTSTAT_ACCEPTED:
01152 status = Attendee::Accepted;
01153 break;
01154 case ICAL_PARTSTAT_DECLINED:
01155 status = Attendee::Declined;
01156 break;
01157 case ICAL_PARTSTAT_TENTATIVE:
01158 status = Attendee::Tentative;
01159 break;
01160 case ICAL_PARTSTAT_DELEGATED:
01161 status = Attendee::Delegated;
01162 break;
01163 case ICAL_PARTSTAT_COMPLETED:
01164 status = Attendee::Completed;
01165 break;
01166 case ICAL_PARTSTAT_INPROCESS:
01167 status = Attendee::InProcess;
01168 break;
01169 }
01170 }
01171
01172 Attendee::Role role = Attendee::ReqParticipant;
01173 p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER);
01174 if (p) {
01175 icalparameter_role roleParameter = icalparameter_get_role(p);
01176 switch(roleParameter) {
01177 case ICAL_ROLE_CHAIR:
01178 role = Attendee::Chair;
01179 break;
01180 default:
01181 case ICAL_ROLE_REQPARTICIPANT:
01182 role = Attendee::ReqParticipant;
01183 break;
01184 case ICAL_ROLE_OPTPARTICIPANT:
01185 role = Attendee::OptParticipant;
01186 break;
01187 case ICAL_ROLE_NONPARTICIPANT:
01188 role = Attendee::NonParticipant;
01189 break;
01190 }
01191 }
01192
01193 p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER);
01194 uid = icalparameter_get_xvalue(p);
01195
01196
01197
01198
01199
01200
01201
01202
01203 Attendee *a = new Attendee( name, email, rsvp, status, role, uid );
01204
01205 p = icalproperty_get_first_parameter( attendee, ICAL_DELEGATEDTO_PARAMETER );
01206 if ( p )
01207 a->setDelegate( icalparameter_get_delegatedto( p ) );
01208
01209 p = icalproperty_get_first_parameter( attendee, ICAL_DELEGATEDFROM_PARAMETER );
01210 if ( p )
01211 a->setDelegator( icalparameter_get_delegatedfrom( p ) );
01212
01213 return a;
01214 }
01215
01216 Person ICalFormatImpl::readOrganizer( icalproperty *organizer )
01217 {
01218 QString email = QString::fromUtf8(icalproperty_get_organizer(organizer));
01219 if ( email.startsWith( "mailto:", false ) ) {
01220 email = email.mid( 7 );
01221 }
01222 QString cn;
01223
01224 icalparameter *p = icalproperty_get_first_parameter(
01225 organizer, ICAL_CN_PARAMETER );
01226
01227 if ( p ) {
01228 cn = QString::fromUtf8( icalparameter_get_cn( p ) );
01229 }
01230 Person org( cn, email );
01231
01232 return org;
01233 }
01234
01235 Attachment *ICalFormatImpl::readAttachment(icalproperty *attach)
01236 {
01237 Attachment *attachment = 0;
01238
01239 icalvalue_kind value_kind = icalvalue_isa(icalproperty_get_value(attach));
01240
01241 if ( value_kind == ICAL_ATTACH_VALUE || value_kind == ICAL_BINARY_VALUE ) {
01242 icalattach *a = icalproperty_get_attach(attach);
01243
01244 int isurl = icalattach_get_is_url (a);
01245 if (isurl == 0)
01246 attachment = new Attachment((const char*)icalattach_get_data(a));
01247 else {
01248 attachment = new Attachment(QString::fromUtf8(icalattach_get_url(a)));
01249 }
01250 }
01251 else if ( value_kind == ICAL_URI_VALUE ) {
01252 attachment = new Attachment(QString::fromUtf8(icalvalue_get_uri(icalproperty_get_value(attach))));
01253 }
01254
01255 icalparameter *p = icalproperty_get_first_parameter(attach, ICAL_FMTTYPE_PARAMETER);
01256 if (p && attachment)
01257 attachment->setMimeType(QString(icalparameter_get_fmttype(p)));
01258
01259 p = icalproperty_get_first_parameter(attach,ICAL_X_PARAMETER);
01260 while (p) {
01261 if ( strncmp (icalparameter_get_xname(p), "X-LABEL", 7) == 0 )
01262 attachment->setLabel( icalparameter_get_xvalue(p) );
01263 p = icalproperty_get_next_parameter(attach, ICAL_X_PARAMETER);
01264 }
01265
01266 return attachment;
01267 }
01268
01269 void ICalFormatImpl::readIncidence(icalcomponent *parent, icaltimezone *tz, Incidence *incidence)
01270 {
01271 readIncidenceBase(parent,incidence);
01272
01273 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
01274
01275 const char *text;
01276 int intvalue, inttext;
01277 icaltimetype icaltime;
01278 icaldurationtype icalduration;
01279
01280 QStringList categories;
01281
01282 while (p) {
01283 icalproperty_kind kind = icalproperty_isa(p);
01284 switch (kind) {
01285
01286 case ICAL_CREATED_PROPERTY:
01287 icaltime = icalproperty_get_created(p);
01288 incidence->setCreated(readICalDateTime(icaltime, tz));
01289 break;
01290
01291 case ICAL_SEQUENCE_PROPERTY:
01292 intvalue = icalproperty_get_sequence(p);
01293 incidence->setRevision(intvalue);
01294 break;
01295
01296 case ICAL_LASTMODIFIED_PROPERTY:
01297 icaltime = icalproperty_get_lastmodified(p);
01298 incidence->setLastModified(readICalDateTime(icaltime, tz));
01299 break;
01300
01301 case ICAL_DTSTART_PROPERTY:
01302 icaltime = icalproperty_get_dtstart(p);
01303 if (icaltime.is_date) {
01304 incidence->setDtStart(QDateTime(readICalDate(icaltime),QTime(0,0,0)));
01305 incidence->setFloats( true );
01306 } else {
01307 incidence->setDtStart(readICalDateTime(icaltime, tz));
01308 incidence->setFloats( false );
01309 }
01310 break;
01311
01312 case ICAL_DURATION_PROPERTY:
01313 icalduration = icalproperty_get_duration(p);
01314 incidence->setDuration(readICalDuration(icalduration));
01315 break;
01316
01317 case ICAL_DESCRIPTION_PROPERTY:
01318 text = icalproperty_get_description(p);
01319 incidence->setDescription(QString::fromUtf8(text));
01320 break;
01321
01322 case ICAL_SUMMARY_PROPERTY:
01323 text = icalproperty_get_summary(p);
01324 incidence->setSummary(QString::fromUtf8(text));
01325 break;
01326
01327 case ICAL_LOCATION_PROPERTY:
01328 text = icalproperty_get_location(p);
01329 incidence->setLocation(QString::fromUtf8(text));
01330 break;
01331
01332 case ICAL_STATUS_PROPERTY: {
01333 Incidence::Status stat;
01334 switch (icalproperty_get_status(p)) {
01335 case ICAL_STATUS_TENTATIVE: stat = Incidence::StatusTentative; break;
01336 case ICAL_STATUS_CONFIRMED: stat = Incidence::StatusConfirmed; break;
01337 case ICAL_STATUS_COMPLETED: stat = Incidence::StatusCompleted; break;
01338 case ICAL_STATUS_NEEDSACTION: stat = Incidence::StatusNeedsAction; break;
01339 case ICAL_STATUS_CANCELLED: stat = Incidence::StatusCanceled; break;
01340 case ICAL_STATUS_INPROCESS: stat = Incidence::StatusInProcess; break;
01341 case ICAL_STATUS_DRAFT: stat = Incidence::StatusDraft; break;
01342 case ICAL_STATUS_FINAL: stat = Incidence::StatusFinal; break;
01343 case ICAL_STATUS_X:
01344 incidence->setCustomStatus(QString::fromUtf8(icalvalue_get_x(icalproperty_get_value(p))));
01345 stat = Incidence::StatusX;
01346 break;
01347 case ICAL_STATUS_NONE:
01348 default: stat = Incidence::StatusNone; break;
01349 }
01350 if (stat != Incidence::StatusX)
01351 incidence->setStatus(stat);
01352 break;
01353 }
01354
01355 case ICAL_PRIORITY_PROPERTY:
01356 intvalue = icalproperty_get_priority( p );
01357 if ( mCompat )
01358 intvalue = mCompat->fixPriority( intvalue );
01359 incidence->setPriority( intvalue );
01360 break;
01361
01362 case ICAL_CATEGORIES_PROPERTY:
01363 text = icalproperty_get_categories(p);
01364 categories.append(QString::fromUtf8(text));
01365 break;
01366
01367 case ICAL_RRULE_PROPERTY:
01368 readRecurrenceRule( p, incidence );
01369 break;
01370
01371 case ICAL_RDATE_PROPERTY: {
01372 icaldatetimeperiodtype rd = icalproperty_get_rdate( p );
01373 if ( icaltime_is_valid_time( rd.time ) ) {
01374 if ( icaltime_is_date( rd.time ) ) {
01375 incidence->recurrence()->addRDate( readICalDate( rd.time ) );
01376 } else {
01377 incidence->recurrence()->addRDateTime( readICalDateTime( rd.time, tz ) );
01378 }
01379 } else {
01380
01381 }
01382 break; }
01383
01384 case ICAL_EXRULE_PROPERTY:
01385 readExceptionRule( p, incidence );
01386 break;
01387
01388 case ICAL_EXDATE_PROPERTY:
01389 icaltime = icalproperty_get_exdate(p);
01390 if ( icaltime_is_date(icaltime) ) {
01391 incidence->recurrence()->addExDate( readICalDate(icaltime) );
01392 } else {
01393 incidence->recurrence()->addExDateTime( readICalDateTime(icaltime, tz) );
01394 }
01395 break;
01396
01397 case ICAL_CLASS_PROPERTY:
01398 inttext = icalproperty_get_class(p);
01399 if (inttext == ICAL_CLASS_PUBLIC ) {
01400 incidence->setSecrecy(Incidence::SecrecyPublic);
01401 } else if (inttext == ICAL_CLASS_CONFIDENTIAL ) {
01402 incidence->setSecrecy(Incidence::SecrecyConfidential);
01403 } else {
01404 incidence->setSecrecy(Incidence::SecrecyPrivate);
01405 }
01406 break;
01407
01408 case ICAL_ATTACH_PROPERTY:
01409 incidence->addAttachment(readAttachment(p));
01410 break;
01411
01412 default:
01413
01414
01415 break;
01416 }
01417
01418 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
01419 }
01420
01421
01422 const QString uid = incidence->customProperty( "LIBKCAL", "ID" );
01423 if ( !uid.isNull() ) {
01424
01425
01426
01427 incidence->setSchedulingID( incidence->uid() );
01428 incidence->setUid( uid );
01429 }
01430
01431
01432
01433 if ( incidence->doesRecur() && mCompat )
01434 mCompat->fixRecurrence( incidence );
01435
01436
01437 incidence->setCategories(categories);
01438
01439
01440 for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT);
01441 alarm;
01442 alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) {
01443 readAlarm(alarm,incidence);
01444 }
01445
01446 if ( mCompat ) mCompat->fixAlarms( incidence );
01447
01448 }
01449
01450 void ICalFormatImpl::readIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase)
01451 {
01452 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
01453
01454 while (p) {
01455 icalproperty_kind kind = icalproperty_isa(p);
01456 switch (kind) {
01457
01458 case ICAL_UID_PROPERTY:
01459 incidenceBase->setUid(QString::fromUtf8(icalproperty_get_uid(p)));
01460 break;
01461
01462 case ICAL_ORGANIZER_PROPERTY:
01463 incidenceBase->setOrganizer( readOrganizer(p));
01464 break;
01465
01466 case ICAL_ATTENDEE_PROPERTY:
01467 incidenceBase->addAttendee(readAttendee(p));
01468 break;
01469
01470 case ICAL_COMMENT_PROPERTY:
01471 incidenceBase->addComment(
01472 QString::fromUtf8(icalproperty_get_comment(p)));
01473 break;
01474
01475 default:
01476 break;
01477 }
01478
01479 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
01480 }
01481
01482
01483
01484
01485
01486
01487
01488 icalproperty *next =0;
01489
01490 for ( p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY);
01491 p != 0;
01492 p = next )
01493 {
01494
01495 next = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY);
01496
01497 QString value = QString::fromUtf8(icalproperty_get_x(p));
01498 QString name = icalproperty_get_x_name(p);
01499
01500 if (name == "X-PILOTID" && !value.isEmpty()) {
01501 incidenceBase->setPilotId(value.toInt());
01502 icalcomponent_remove_property(parent,p);
01503 } else if (name == "X-PILOTSTAT" && !value.isEmpty()) {
01504 incidenceBase->setSyncStatus(value.toInt());
01505 icalcomponent_remove_property(parent,p);
01506 }
01507 }
01508
01509
01510 readCustomProperties(parent, incidenceBase);
01511 }
01512
01513 void ICalFormatImpl::readCustomProperties(icalcomponent *parent,CustomProperties *properties)
01514 {
01515 QMap<QCString, QString> customProperties;
01516 QString lastProperty;
01517
01518 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY);
01519
01520 while (p) {
01521
01522 QString value = QString::fromUtf8(icalproperty_get_x(p));
01523 const char *name = icalproperty_get_x_name(p);
01524 if ( lastProperty != name ) {
01525 customProperties[name] = value;
01526 } else {
01527 customProperties[name] = customProperties[name].append( "," ).append( value );
01528 }
01529
01530 p = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY);
01531 lastProperty = name;
01532 }
01533
01534 properties->setCustomProperties(customProperties);
01535 }
01536
01537
01538
01539 void ICalFormatImpl::readRecurrenceRule(icalproperty *rrule,Incidence *incidence )
01540 {
01541
01542
01543 Recurrence *recur = incidence->recurrence();
01544
01545 struct icalrecurrencetype r = icalproperty_get_rrule(rrule);
01546
01547
01548 RecurrenceRule *recurrule = new RecurrenceRule( );
01549 recurrule->setStartDt( incidence->dtStart() );
01550 readRecurrence( r, recurrule );
01551 recur->addRRule( recurrule );
01552 }
01553
01554 void ICalFormatImpl::readExceptionRule( icalproperty *rrule, Incidence *incidence )
01555 {
01556
01557
01558 struct icalrecurrencetype r = icalproperty_get_exrule(rrule);
01559
01560
01561 RecurrenceRule *recurrule = new RecurrenceRule( );
01562 recurrule->setStartDt( incidence->dtStart() );
01563 readRecurrence( r, recurrule );
01564
01565 Recurrence *recur = incidence->recurrence();
01566 recur->addExRule( recurrule );
01567 }
01568
01569 void ICalFormatImpl::readRecurrence( const struct icalrecurrencetype &r, RecurrenceRule* recur )
01570 {
01571
01572 recur->mRRule = QString( icalrecurrencetype_as_string( const_cast<struct icalrecurrencetype*>(&r) ) );
01573
01574 switch ( r.freq ) {
01575 case ICAL_SECONDLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rSecondly ); break;
01576 case ICAL_MINUTELY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rMinutely ); break;
01577 case ICAL_HOURLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rHourly ); break;
01578 case ICAL_DAILY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rDaily ); break;
01579 case ICAL_WEEKLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rWeekly ); break;
01580 case ICAL_MONTHLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rMonthly ); break;
01581 case ICAL_YEARLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rYearly ); break;
01582 case ICAL_NO_RECURRENCE:
01583 default:
01584 recur->setRecurrenceType( RecurrenceRule::rNone );
01585 }
01586
01587 recur->setFrequency( r.interval );
01588
01589
01590 if ( !icaltime_is_null_time( r.until ) ) {
01591 icaltimetype t;
01592 t = r.until;
01593
01594 QDateTime endDate( readICalDateTime(t) );
01595 recur->setEndDt( endDate );
01596 } else {
01597 if (r.count == 0)
01598 recur->setDuration( -1 );
01599 else
01600 recur->setDuration( r.count );
01601 }
01602
01603
01604 int wkst = (r.week_start + 5)%7 + 1;
01605 recur->setWeekStart( wkst );
01606
01607
01608 QValueList<int> lst;
01609 int i;
01610 int index = 0;
01611
01612 #define readSetByList(rrulecomp,setfunc) \
01613 index = 0; \
01614 lst.clear(); \
01615 while ( (i = r.rrulecomp[index++] ) != ICAL_RECURRENCE_ARRAY_MAX ) \
01616 lst.append( i ); \
01617 if ( !lst.isEmpty() ) recur->setfunc( lst );
01618
01619
01620
01621
01622 readSetByList( by_second, setBySeconds );
01623 readSetByList( by_minute, setByMinutes );
01624 readSetByList( by_hour, setByHours );
01625 readSetByList( by_month_day, setByMonthDays );
01626 readSetByList( by_year_day, setByYearDays );
01627 readSetByList( by_week_no, setByWeekNumbers );
01628 readSetByList( by_month, setByMonths );
01629 readSetByList( by_set_pos, setBySetPos );
01630 #undef readSetByList
01631
01632
01633 QValueList<RecurrenceRule::WDayPos> wdlst;
01634 short day;
01635 index=0;
01636 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01637 RecurrenceRule::WDayPos pos;
01638 pos.setDay( ( icalrecurrencetype_day_day_of_week( day ) + 5 )%7 + 1 );
01639 pos.setPos( icalrecurrencetype_day_position( day ) );
01640
01641 wdlst.append( pos );
01642 }
01643 if ( !wdlst.isEmpty() ) recur->setByDays( wdlst );
01644
01645
01646
01647
01648 }
01649
01650
01651 void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence)
01652 {
01653
01654
01655 Alarm* ialarm = incidence->newAlarm();
01656 ialarm->setRepeatCount(0);
01657 ialarm->setEnabled(true);
01658
01659
01660 icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ACTION_PROPERTY);
01661 Alarm::Type type = Alarm::Display;
01662 icalproperty_action action = ICAL_ACTION_DISPLAY;
01663 if ( !p ) {
01664 kdDebug(5800) << "Unknown type of alarm, using default" << endl;
01665
01666 } else {
01667
01668 action = icalproperty_get_action(p);
01669 switch ( action ) {
01670 case ICAL_ACTION_DISPLAY: type = Alarm::Display; break;
01671 case ICAL_ACTION_AUDIO: type = Alarm::Audio; break;
01672 case ICAL_ACTION_PROCEDURE: type = Alarm::Procedure; break;
01673 case ICAL_ACTION_EMAIL: type = Alarm::Email; break;
01674 default:
01675 kdDebug(5800) << "Unknown type of alarm: " << action << endl;
01676
01677 }
01678 }
01679 ialarm->setType(type);
01680
01681
01682 p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY);
01683 while (p) {
01684 icalproperty_kind kind = icalproperty_isa(p);
01685
01686 switch (kind) {
01687
01688 case ICAL_TRIGGER_PROPERTY: {
01689 icaltriggertype trigger = icalproperty_get_trigger(p);
01690 if (icaltime_is_null_time(trigger.time)) {
01691 if (icaldurationtype_is_null_duration(trigger.duration)) {
01692 kdDebug(5800) << "ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl;
01693 } else {
01694 Duration duration = icaldurationtype_as_int( trigger.duration );
01695 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_RELATED_PARAMETER);
01696 if (param && icalparameter_get_related(param) == ICAL_RELATED_END)
01697 ialarm->setEndOffset(duration);
01698 else
01699 ialarm->setStartOffset(duration);
01700 }
01701 } else {
01702 ialarm->setTime(readICalDateTime(trigger.time));
01703 }
01704 break;
01705 }
01706 case ICAL_DURATION_PROPERTY: {
01707 icaldurationtype duration = icalproperty_get_duration(p);
01708 ialarm->setSnoozeTime(icaldurationtype_as_int(duration)/60);
01709 break;
01710 }
01711 case ICAL_REPEAT_PROPERTY:
01712 ialarm->setRepeatCount(icalproperty_get_repeat(p));
01713 break;
01714
01715
01716 case ICAL_DESCRIPTION_PROPERTY: {
01717 QString description = QString::fromUtf8(icalproperty_get_description(p));
01718 switch ( action ) {
01719 case ICAL_ACTION_DISPLAY:
01720 ialarm->setText( description );
01721 break;
01722 case ICAL_ACTION_PROCEDURE:
01723 ialarm->setProgramArguments( description );
01724 break;
01725 case ICAL_ACTION_EMAIL:
01726 ialarm->setMailText( description );
01727 break;
01728 default:
01729 break;
01730 }
01731 break;
01732 }
01733
01734 case ICAL_SUMMARY_PROPERTY:
01735 ialarm->setMailSubject(QString::fromUtf8(icalproperty_get_summary(p)));
01736 break;
01737
01738
01739 case ICAL_ATTENDEE_PROPERTY: {
01740 QString email = QString::fromUtf8(icalproperty_get_attendee(p));
01741 if ( email.startsWith("mailto:", false ) ) {
01742 email = email.mid( 7 );
01743 }
01744 QString name;
01745 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_CN_PARAMETER);
01746 if (param) {
01747 name = QString::fromUtf8(icalparameter_get_cn(param));
01748 }
01749 ialarm->addMailAddress(Person(name, email));
01750 break;
01751 }
01752
01753 case ICAL_ATTACH_PROPERTY: {
01754 Attachment *attach = readAttachment( p );
01755 if ( attach && attach->isUri() ) {
01756 switch ( action ) {
01757 case ICAL_ACTION_AUDIO:
01758 ialarm->setAudioFile( attach->uri() );
01759 break;
01760 case ICAL_ACTION_PROCEDURE:
01761 ialarm->setProgramFile( attach->uri() );
01762 break;
01763 case ICAL_ACTION_EMAIL:
01764 ialarm->addMailAttachment( attach->uri() );
01765 break;
01766 default:
01767 break;
01768 }
01769 } else {
01770 kdDebug() << "Alarm attachments currently only support URIs, but "
01771 "no binary data" << endl;
01772 }
01773 delete attach;
01774 break;
01775 }
01776 default:
01777 break;
01778 }
01779
01780 p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY);
01781 }
01782
01783
01784 readCustomProperties(alarm, ialarm);
01785
01786
01787 }
01788
01789 icaldatetimeperiodtype ICalFormatImpl::writeICalDatePeriod( const QDate &date )
01790 {
01791 icaldatetimeperiodtype t;
01792 t.time = writeICalDate( date );
01793 t.period = icalperiodtype_null_period();
01794 return t;
01795 }
01796
01797 icaldatetimeperiodtype ICalFormatImpl::writeICalDateTimePeriod( const QDateTime &date )
01798 {
01799 icaldatetimeperiodtype t;
01800 t.time = writeICalDateTime( date );
01801 t.period = icalperiodtype_null_period();
01802 return t;
01803 }
01804
01805 icaltimetype ICalFormatImpl::writeICalDate(const QDate &date)
01806 {
01807 icaltimetype t = icaltime_null_time();
01808
01809 t.year = date.year();
01810 t.month = date.month();
01811 t.day = date.day();
01812
01813 t.hour = 0;
01814 t.minute = 0;
01815 t.second = 0;
01816
01817 t.is_date = 1;
01818
01819 t.is_utc = 0;
01820
01821 t.zone = 0;
01822
01823 return t;
01824 }
01825
01826 icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &datetime)
01827 {
01828 icaltimetype t = icaltime_null_time();
01829
01830 t.year = datetime.date().year();
01831 t.month = datetime.date().month();
01832 t.day = datetime.date().day();
01833
01834 t.hour = datetime.time().hour();
01835 t.minute = datetime.time().minute();
01836 t.second = datetime.time().second();
01837
01838 t.is_date = 0;
01839 t.zone = icaltimezone_get_builtin_timezone ( mParent->timeZoneId().latin1() );
01840 t.is_utc = 0;
01841
01842
01843
01844
01845
01846 if (mParent->timeZoneId().isEmpty())
01847 t = icaltime_convert_to_zone( t, 0 );
01848 else {
01849 icaltimezone* tz = icaltimezone_get_builtin_timezone ( mParent->timeZoneId().latin1() );
01850 icaltimezone* utc = icaltimezone_get_utc_timezone();
01851 if ( tz != utc ) {
01852 t.zone = tz;
01853 t = icaltime_convert_to_zone( t, utc );
01854 } else {
01855 t.is_utc = 1;
01856 t.zone = utc;
01857 }
01858 }
01859
01860
01861 return t;
01862 }
01863
01864 QDateTime ICalFormatImpl::readICalDateTime( icaltimetype& t, icaltimezone* tz )
01865 {
01866
01867 icaltimezone *zone = tz;
01868 if ( tz && t.is_utc == 0 ) {
01869
01870
01871 t.zone = tz;
01872 t.is_utc = (tz == icaltimezone_get_utc_timezone())?1:0;
01873 } else {
01874 zone = icaltimezone_get_utc_timezone();
01875 }
01876
01877
01878
01879 if ( !mParent->timeZoneId().isEmpty() && t.zone ) {
01880
01881 icaltimezone* viewTimeZone = icaltimezone_get_builtin_timezone ( mParent->timeZoneId().latin1() );
01882 icaltimezone_convert_time( &t, zone, viewTimeZone );
01883
01884 }
01885
01886 return ICalDate2QDate(t);
01887 }
01888
01889 QDate ICalFormatImpl::readICalDate(icaltimetype t)
01890 {
01891 return ICalDate2QDate(t).date();
01892 }
01893
01894 icaldurationtype ICalFormatImpl::writeICalDuration(int seconds)
01895 {
01896 icaldurationtype d;
01897
01898 d.is_neg = (seconds<0)?1:0;
01899 if (seconds<0) seconds = -seconds;
01900
01901 d.weeks = seconds / gSecondsPerWeek;
01902 seconds %= gSecondsPerWeek;
01903 d.days = seconds / gSecondsPerDay;
01904 seconds %= gSecondsPerDay;
01905 d.hours = seconds / gSecondsPerHour;
01906 seconds %= gSecondsPerHour;
01907 d.minutes = seconds / gSecondsPerMinute;
01908 seconds %= gSecondsPerMinute;
01909 d.seconds = seconds;
01910
01911 return d;
01912 }
01913
01914 int ICalFormatImpl::readICalDuration(icaldurationtype d)
01915 {
01916 int result = 0;
01917
01918 result += d.weeks * gSecondsPerWeek;
01919 result += d.days * gSecondsPerDay;
01920 result += d.hours * gSecondsPerHour;
01921 result += d.minutes * gSecondsPerMinute;
01922 result += d.seconds;
01923
01924 if (d.is_neg) result *= -1;
01925
01926 return result;
01927 }
01928
01929 icalcomponent *ICalFormatImpl::createCalendarComponent(Calendar *cal)
01930 {
01931 icalcomponent *calendar;
01932
01933
01934 calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
01935
01936 icalproperty *p;
01937
01938
01939 p = icalproperty_new_prodid(CalFormat::productId().utf8());
01940 icalcomponent_add_property(calendar,p);
01941
01942
01943
01944
01945 p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION));
01946 icalcomponent_add_property(calendar,p);
01947
01948
01949 if( cal != 0 )
01950 writeCustomProperties(calendar, cal);
01951
01952 return calendar;
01953 }
01954
01955
01956
01957
01958
01959
01960 bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar)
01961 {
01962
01963
01964
01965 if (!calendar) return false;
01966
01967
01968
01969 icalproperty *p;
01970
01971 p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY);
01972 if (!p) {
01973 kdDebug(5800) << "No PRODID property found" << endl;
01974 mLoadedProductId = "";
01975 } else {
01976 mLoadedProductId = QString::fromUtf8(icalproperty_get_prodid(p));
01977
01978
01979 delete mCompat;
01980 mCompat = CompatFactory::createCompat( mLoadedProductId );
01981 }
01982
01983 p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY);
01984 if (!p) {
01985 kdDebug(5800) << "No VERSION property found" << endl;
01986 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
01987 return false;
01988 } else {
01989 const char *version = icalproperty_get_version(p);
01990
01991
01992 if (strcmp(version,"1.0") == 0) {
01993 kdDebug(5800) << "Expected iCalendar, got vCalendar" << endl;
01994 mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1,
01995 i18n("Expected iCalendar format")));
01996 return false;
01997 } else if (strcmp(version,"2.0") != 0) {
01998 kdDebug(5800) << "Expected iCalendar, got unknown format" << endl;
01999 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
02000 return false;
02001 }
02002 }
02003
02004
02005 readCustomProperties(calendar, cal);
02006
02007
02008
02009
02010 icalcomponent *ctz =
02011 icalcomponent_get_first_component( calendar, ICAL_VTIMEZONE_COMPONENT );
02012
02013
02014 mEventsRelate.clear();
02015 mTodosRelate.clear();
02016
02017
02018 icalcomponent *c;
02019
02020
02021 c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT);
02022 while (c) {
02023
02024 Todo *todo = readTodo(c);
02025 if (todo) {
02026 if (!cal->todo(todo->uid())) {
02027 cal->addTodo(todo);
02028 } else {
02029 delete todo;
02030 mTodosRelate.remove( todo );
02031 }
02032 }
02033 c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT);
02034 }
02035
02036
02037 c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT);
02038 while (c) {
02039
02040 Event *event = readEvent(c, ctz);
02041 if (event) {
02042 if (!cal->event(event->uid())) {
02043 cal->addEvent(event);
02044 } else {
02045 delete event;
02046 mEventsRelate.remove( event );
02047 }
02048 }
02049 c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT);
02050 }
02051
02052
02053 c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT);
02054 while (c) {
02055
02056 Journal *journal = readJournal(c);
02057 if (journal) {
02058 if (!cal->journal(journal->uid())) {
02059 cal->addJournal(journal);
02060 } else {
02061 delete journal;
02062 }
02063 }
02064 c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT);
02065 }
02066
02067
02068 Event::List::ConstIterator eIt;
02069 for ( eIt = mEventsRelate.begin(); eIt != mEventsRelate.end(); ++eIt ) {
02070 (*eIt)->setRelatedTo( cal->incidence( (*eIt)->relatedToUid() ) );
02071 }
02072 Todo::List::ConstIterator tIt;
02073 for ( tIt = mTodosRelate.begin(); tIt != mTodosRelate.end(); ++tIt ) {
02074 (*tIt)->setRelatedTo( cal->incidence( (*tIt)->relatedToUid() ) );
02075 }
02076
02077 return true;
02078 }
02079
02080 QString ICalFormatImpl::extractErrorProperty(icalcomponent *c)
02081 {
02082
02083
02084
02085 QString errorMessage;
02086
02087 icalproperty *error;
02088 error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY);
02089 while(error) {
02090 errorMessage += icalproperty_get_xlicerror(error);
02091 errorMessage += "\n";
02092 error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY);
02093 }
02094
02095
02096
02097 return errorMessage;
02098 }
02099
02100 void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r)
02101 {
02102 int i;
02103
02104 kdDebug(5800) << " Freq: " << r.freq << endl;
02105 kdDebug(5800) << " Until: " << icaltime_as_ical_string(r.until) << endl;
02106 kdDebug(5800) << " Count: " << r.count << endl;
02107 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02108 int index = 0;
02109 QString out = " By Day: ";
02110 while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02111 out.append(QString::number(i) + " ");
02112 }
02113 kdDebug(5800) << out << endl;
02114 }
02115 if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02116 int index = 0;
02117 QString out = " By Month Day: ";
02118 while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02119 out.append(QString::number(i) + " ");
02120 }
02121 kdDebug(5800) << out << endl;
02122 }
02123 if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02124 int index = 0;
02125 QString out = " By Year Day: ";
02126 while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02127 out.append(QString::number(i) + " ");
02128 }
02129 kdDebug(5800) << out << endl;
02130 }
02131 if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02132 int index = 0;
02133 QString out = " By Month: ";
02134 while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02135 out.append(QString::number(i) + " ");
02136 }
02137 kdDebug(5800) << out << endl;
02138 }
02139 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02140 int index = 0;
02141 QString out = " By Set Pos: ";
02142 while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02143 kdDebug(5800) << "========= " << i << endl;
02144 out.append(QString::number(i) + " ");
02145 }
02146 kdDebug(5800) << out << endl;
02147 }
02148 }
02149
02150 icalcomponent *ICalFormatImpl::createScheduleComponent(IncidenceBase *incidence,
02151 Scheduler::Method method)
02152 {
02153 icalcomponent *message = createCalendarComponent();
02154
02155 icalproperty_method icalmethod = ICAL_METHOD_NONE;
02156
02157 switch (method) {
02158 case Scheduler::Publish:
02159 icalmethod = ICAL_METHOD_PUBLISH;
02160 break;
02161 case Scheduler::Request:
02162 icalmethod = ICAL_METHOD_REQUEST;
02163 break;
02164 case Scheduler::Refresh:
02165 icalmethod = ICAL_METHOD_REFRESH;
02166 break;
02167 case Scheduler::Cancel:
02168 icalmethod = ICAL_METHOD_CANCEL;
02169 break;
02170 case Scheduler::Add:
02171 icalmethod = ICAL_METHOD_ADD;
02172 break;
02173 case Scheduler::Reply:
02174 icalmethod = ICAL_METHOD_REPLY;
02175 break;
02176 case Scheduler::Counter:
02177 icalmethod = ICAL_METHOD_COUNTER;
02178 break;
02179 case Scheduler::Declinecounter:
02180 icalmethod = ICAL_METHOD_DECLINECOUNTER;
02181 break;
02182 default:
02183 kdDebug(5800) << "ICalFormat::createScheduleMessage(): Unknow method" << endl;
02184 return message;
02185 }
02186
02187 icalcomponent_add_property(message,icalproperty_new_method(icalmethod));
02188
02189 icalcomponent *inc = writeIncidence( incidence, method );
02190
02191
02192
02193
02194
02195
02196
02197
02198 if ( icalmethod == ICAL_METHOD_REPLY ) {
02199 struct icalreqstattype rst;
02200 rst.code = ICAL_2_0_SUCCESS_STATUS;
02201 rst.desc = 0;
02202 rst.debug = 0;
02203 icalcomponent_add_property( inc, icalproperty_new_requeststatus( rst ) );
02204 }
02205 icalcomponent_add_component( message, inc );
02206
02207 return message;
02208 }