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