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