00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
#include <qdatetime.h>
00023
#include <qstring.h>
00024
#include <qptrlist.h>
00025
#include <qfile.h>
00026
#include <cstdlib>
00027
00028
#include <kdebug.h>
00029
#include <klocale.h>
00030
00031
extern "C" {
00032
#include <ical.h>
00033
#include <icalss.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
namespace KCal {
00049
00054
typedef struct icaltimezonephase icaltimezonephase;
00055
class TimezonePhase :
private icaltimezonephase {
00056
public:
00060 TimezonePhase(ICalFormatImpl *parent, icalcomponent *c)
00061 {
00062 tzname = (
const char *)0;
00063 is_stdandard = 1;
00064 mIsStandard = 1;
00065 dtstart = icaltime_null_time();
00066 offsetto = 0;
00067 tzoffsetfrom = 0;
00068 comment = (
const char *)0;
00069 rdate.time = icaltime_null_time();
00070 rdate.period = icalperiodtype_null_period();
00071 rrule = (
const char *)0;
00072 mRrule =
new Recurrence((
Incidence *)0);
00073
00074
00075 icalproperty *p = icalcomponent_get_first_property(c,ICAL_ANY_PROPERTY);
00076
while (p) {
00077 icalproperty_kind kind = icalproperty_isa(p);
00078
switch (kind) {
00079
00080
case ICAL_TZNAME_PROPERTY:
00081 tzname = icalproperty_get_tzname(p);
00082
break;
00083
00084
case ICAL_DTSTART_PROPERTY:
00085 dtstart = icalproperty_get_dtstart(p);
00086
break;
00087
00088
case ICAL_TZOFFSETTO_PROPERTY:
00089 offsetto = icalproperty_get_tzoffsetto(p);
00090
break;
00091
00092
case ICAL_TZOFFSETFROM_PROPERTY:
00093 tzoffsetfrom = icalproperty_get_tzoffsetfrom(p);
00094
break;
00095
00096
case ICAL_COMMENT_PROPERTY:
00097 comment = icalproperty_get_comment(p);
00098
break;
00099
00100
case ICAL_RDATE_PROPERTY:
00101 rdate = icalproperty_get_rdate(p);
00102
break;
00103
00104
case ICAL_RRULE_PROPERTY:
00105 {
00106
struct icalrecurrencetype r = icalproperty_get_rrule(p);
00107
00108 parent->readRecurrence(r,mRrule);
00109 }
00110
break;
00111
00112
default:
00113 kdDebug(5800) <<
"TimezonePhase::TimezonePhase(): Unknown property: " << kind
00114 << endl;
00115
break;
00116 }
00117 p = icalcomponent_get_next_property(c,ICAL_ANY_PROPERTY);
00118 }
00119 }
00120
00124 ~TimezonePhase()
00125 {
00126
delete mRrule;
00127 }
00128
00132
QDateTime nearestStart(
const QDateTime &t)
const
00133
{
00134
QDateTime tmp(
QDate(dtstart.year,dtstart.month,dtstart.day),
QTime(dtstart.hour,dtstart.minute,dtstart.second));
00135
00136
if (tmp > t) {
00137 kdDebug(5800) <<
"TimezonePhase::nearestStart(): Phase not valid" << endl;
00138
return QDateTime();
00139 }
00140
00141
00142
00143
00144
QDateTime previous = mRrule->getPreviousDateTime(tmp);
00145
if (mRrule->getNextDateTime(previous) < tmp)
00146 previous = mRrule->getNextDateTime(previous);
00147
return previous;
00148 }
00149
00153
int offset()
const
00154
{
00155
return offsetto;
00156 }
00157
00158
00159
int mIsStandard;
00160
00161
00162
Recurrence *mRrule;
00163 };
00164
00168
typedef struct icaltimezonetype icaltimezonetype;
00169
class Timezone :
private icaltimezonetype {
00170
public:
00174 Timezone(ICalFormatImpl *parent, icalcomponent *vtimezone)
00175 {
00176 tzid = (
const char *)0;
00177 last_mod = icaltime_null_time();
00178 tzurl = (
const char *)0;
00179
00180
00181
00182 phases = (icaltimezonephase *)malloc(
sizeof(*phases));
00183 phases[0].tzname = (
const char *)0;
00184 mPhases.setAutoDelete(
true );
00185
00186
00187 icalproperty *p = icalcomponent_get_first_property(vtimezone,ICAL_ANY_PROPERTY);
00188
while (p) {
00189 icalproperty_kind kind = icalproperty_isa(p);
00190
switch (kind) {
00191
00192
case ICAL_TZID_PROPERTY:
00193
00194
00195
00196
00197 tzid = icalproperty_get_tzid(p);
00198
break;
00199
00200
case ICAL_TZURL_PROPERTY:
00201 tzurl = icalproperty_get_tzurl(p);
00202
break;
00203
00204
default:
00205 kdDebug(5800) <<
"Timezone::Timezone(): Unknown property: " << kind
00206 << endl;
00207
break;
00208 }
00209 p = icalcomponent_get_next_property(vtimezone,ICAL_ANY_PROPERTY);
00210 }
00211 kdDebug(5800) <<
"---zoneId: \"" << tzid <<
'"' << endl;
00212
00213 icalcomponent *c;
00214
00215 TimezonePhase *phase;
00216
00217
00218
00219
00220 c = icalcomponent_get_first_component(vtimezone,ICAL_ANY_COMPONENT);
00221
while (c) {
00222 icalcomponent_kind kind = icalcomponent_isa(c);
00223
switch (kind) {
00224
00225
case ICAL_XSTANDARD_COMPONENT:
00226 kdDebug(5800) <<
"---standard phase: found" << endl;
00227 phase =
new TimezonePhase(parent,c);
00228 phase->mIsStandard = 1;
00229 mPhases.append(phase);
00230
break;
00231
00232
case ICAL_XDAYLIGHT_COMPONENT:
00233 kdDebug(5800) <<
"---daylight phase: found" << endl;
00234 phase =
new TimezonePhase(parent,c);
00235 phase->mIsStandard = 0;
00236 mPhases.append(phase);
00237
break;
00238
00239
default:
00240 kdDebug(5800) <<
"Timezone::Timezone(): Unknown component: " << kind
00241 << endl;
00242
break;
00243 }
00244 c = icalcomponent_get_next_component(vtimezone,ICAL_ANY_COMPONENT);
00245 }
00246 }
00247
00251 ~Timezone()
00252 {
00253 free(phases);
00254 }
00255
00259
QString id()
const
00260
{
00261
if (tzid[0] !=
'"') {
00262
return QString(
"\"") + tzid +
'"';
00263 }
else {
00264
return tzid;
00265 }
00266 }
00267
00271
const TimezonePhase *nearestStart(
const QDateTime &t)
00272 {
00273
unsigned i;
00274
unsigned result = 0;
00275
QDateTime previous;
00276
QDateTime next;
00277
00278
00279
for (i = 0; i < mPhases.count(); i++) {
00280 next = mPhases.at(i)->nearestStart(t);
00281
if (previous.isNull() || previous < next) {
00282 previous = next;
00283 result = i;
00284 }
00285 }
00286
return mPhases.at(result);
00287 }
00288
00292
int offset(icaltimetype t)
00293 {
00294
QDateTime tmp(
QDate(t.year,t.month,t.day),
QTime(t.hour,t.minute,t.second));
00295
const TimezonePhase *phase = nearestStart(tmp);
00296
00297
if (phase) {
00298
return phase->offset();
00299 }
else {
00300 kdError(5800) <<
"Timezone::offset() cannot find phase for " << tmp << endl;
00301
return 0;
00302 }
00303 }
00304
00305
00306
QPtrList<TimezonePhase> mPhases;
00307 };
00308
00309 }
00310
00311
const int gSecondsPerMinute = 60;
00312
const int gSecondsPerHour = gSecondsPerMinute * 60;
00313
const int gSecondsPerDay = gSecondsPerHour * 24;
00314
const int gSecondsPerWeek = gSecondsPerDay * 7;
00315
00316 ICalFormatImpl::ICalFormatImpl(
ICalFormat *parent ) :
00317 mParent( parent ), mCalendarVersion( 0 )
00318 {
00319 mCompat =
new Compat;
00320 mTimezones.setAutoDelete(
true );
00321 }
00322
00323 ICalFormatImpl::~ICalFormatImpl()
00324 {
00325
delete mCompat;
00326 }
00327
00328
class ToStringVisitor :
public Incidence::Visitor
00329 {
00330
public:
00331 ToStringVisitor( ICalFormatImpl *impl ) : mImpl( impl ), mComponent( 0 ) {}
00332
00333
bool visit(
Event *e ) { mComponent = mImpl->writeEvent( e );
return true; }
00334
bool visit(
Todo *e ) { mComponent = mImpl->writeTodo( e );
return true; }
00335
bool visit(
Journal *e ) { mComponent = mImpl->writeJournal( e );
return true; }
00336
00337 icalcomponent *component() {
return mComponent; }
00338
00339
private:
00340 ICalFormatImpl *mImpl;
00341 icalcomponent *mComponent;
00342 };
00343
00344 icalcomponent *ICalFormatImpl::writeIncidence(
Incidence *incidence)
00345 {
00346 ToStringVisitor v(
this );
00347 incidence->
accept(v);
00348
return v.component();
00349 }
00350
00351 icalcomponent *ICalFormatImpl::writeTodo(
Todo *todo)
00352 {
00353
QString tmpStr;
00354
QStringList tmpStrList;
00355
00356 icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT);
00357
00358 writeIncidence(vtodo,todo);
00359
00360
00361
if (todo->
hasDueDate()) {
00362 icaltimetype due;
00363
if (todo->
doesFloat()) {
00364 due = writeICalDate(todo->
dtDue(
true).date());
00365 }
else {
00366 due = writeICalDateTime(todo->
dtDue(
true));
00367 }
00368 icalcomponent_add_property(vtodo,icalproperty_new_due(due));
00369 }
00370
00371
00372
if ( todo->
hasStartDate() || todo->
doesRecur() ) {
00373 icaltimetype start;
00374
if (todo->
doesFloat()) {
00375
00376 start = writeICalDate(todo->
dtStart(
true).date());
00377 }
else {
00378
00379 start = writeICalDateTime(todo->
dtStart(
true));
00380 }
00381 icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start));
00382 }
00383
00384
00385
if (todo->
isCompleted()) {
00386
if (!todo->
hasCompletedDate()) {
00387
00388
00389 todo->
setCompleted(QDateTime::currentDateTime());
00390 }
00391 icaltimetype completed = writeICalDateTime(todo->
completed());
00392 icalcomponent_add_property(vtodo,icalproperty_new_completed(completed));
00393 }
00394
00395 icalcomponent_add_property(vtodo,
00396 icalproperty_new_percentcomplete(todo->
percentComplete()));
00397
00398
if( todo->
doesRecur() ) {
00399 icalcomponent_add_property(vtodo,
00400 icalproperty_new_recurrenceid( writeICalDateTime( todo->
dtDue())));
00401 }
00402
00403
return vtodo;
00404 }
00405
00406 icalcomponent *ICalFormatImpl::writeEvent(
Event *event)
00407 {
00408
#if 0
00409
kdDebug(5800) <<
"Write Event '" << event->
summary() <<
"' (" << event->
uid()
00410 <<
")" << endl;
00411
#endif
00412
00413
QString tmpStr;
00414
QStringList tmpStrList;
00415
00416 icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
00417
00418 writeIncidence(vevent,event);
00419
00420
00421 icaltimetype start;
00422
if (event->
doesFloat()) {
00423
00424 start = writeICalDate(event->
dtStart().date());
00425 }
else {
00426
00427 start = writeICalDateTime(event->
dtStart());
00428 }
00429 icalcomponent_add_property(vevent,icalproperty_new_dtstart(start));
00430
00431
if (event->
hasEndDate()) {
00432
00433 icaltimetype end;
00434
if (event->
doesFloat()) {
00435
00436
00437 end = writeICalDate( event->
dtEnd().date().addDays( 1 ) );
00438 }
else {
00439
00440 end = writeICalDateTime(event->
dtEnd());
00441 }
00442 icalcomponent_add_property(vevent,icalproperty_new_dtend(end));
00443 }
00444
00445
00446
#if 0
00447
00448 tmpStrList = anEvent->resources();
00449 tmpStr = tmpStrList.join(
";");
00450
if (!tmpStr.isEmpty())
00451 addPropValue(vevent, VCResourcesProp, tmpStr.utf8());
00452
00453
#endif
00454
00455
00456
switch( event->
transparency() ) {
00457
case Event::Transparent:
00458 icalcomponent_add_property(vevent, icalproperty_new_transp(
"TRANSPARENT"));
00459
break;
00460
case Event::Opaque:
00461 icalcomponent_add_property(vevent, icalproperty_new_transp(
"OPAQUE"));
00462
break;
00463 }
00464
00465
return vevent;
00466 }
00467
00468 icalcomponent *ICalFormatImpl::writeFreeBusy(
FreeBusy *freebusy,
00469 Scheduler::Method method)
00470 {
00471
#if QT_VERSION >= 300
00472
kdDebug(5800) <<
"icalformatimpl: writeFreeBusy: startDate: "
00473 << freebusy->
dtStart().toString(
"ddd MMMM d yyyy: h:m:s ap") <<
" End Date: "
00474 << freebusy->
dtEnd().toString(
"ddd MMMM d yyyy: h:m:s ap") << endl;
00475
#endif
00476
00477 icalcomponent *vfreebusy = icalcomponent_new(ICAL_VFREEBUSY_COMPONENT);
00478
00479 writeIncidenceBase(vfreebusy,freebusy);
00480
00481 icalcomponent_add_property(vfreebusy, icalproperty_new_dtstart(
00482 writeICalDateTime(freebusy->
dtStart())));
00483
00484 icalcomponent_add_property(vfreebusy, icalproperty_new_dtend(
00485 writeICalDateTime(freebusy->
dtEnd())));
00486
00487
if (method == Scheduler::Request) {
00488 icalcomponent_add_property(vfreebusy,icalproperty_new_uid(
00489 freebusy->
uid().utf8()));
00490 }
00491
00492
00493
QValueList<Period> list = freebusy->
busyPeriods();
00494
QValueList<Period>::Iterator it;
00495 icalperiodtype period;
00496
for (it = list.begin(); it!= list.end(); ++it) {
00497 period.start = writeICalDateTime((*it).start());
00498 period.end = writeICalDateTime((*it).end());
00499 icalcomponent_add_property(vfreebusy, icalproperty_new_freebusy(period) );
00500 }
00501
00502
return vfreebusy;
00503 }
00504
00505 icalcomponent *ICalFormatImpl::writeJournal(
Journal *journal)
00506 {
00507 icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT);
00508
00509 writeIncidence(vjournal,journal);
00510
00511
00512
if (journal->
dtStart().isValid()) {
00513 icaltimetype start;
00514
if (journal->
doesFloat()) {
00515
00516 start = writeICalDate(journal->
dtStart().date());
00517 }
else {
00518
00519 start = writeICalDateTime(journal->
dtStart());
00520 }
00521 icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start));
00522 }
00523
00524
return vjournal;
00525 }
00526
00527
void ICalFormatImpl::writeIncidence(icalcomponent *parent,
Incidence *incidence)
00528 {
00529
00530
00531
if (incidence->
pilotId()) {
00532 incidence->
setNonKDECustomProperty(
"X-PILOTID", QString::number(incidence->
pilotId()));
00533 incidence->
setNonKDECustomProperty(
"X-PILOTSTAT", QString::number(incidence->
syncStatus()));
00534 }
00535
00536 writeIncidenceBase(parent,incidence);
00537
00538
00539 icalcomponent_add_property(parent,icalproperty_new_created(
00540 writeICalDateTime(incidence->
created())));
00541
00542
00543 icalcomponent_add_property(parent,icalproperty_new_uid(
00544 incidence->
uid().utf8()));
00545
00546
00547 icalcomponent_add_property(parent,icalproperty_new_sequence(
00548 incidence->
revision()));
00549
00550
00551 icalcomponent_add_property(parent,icalproperty_new_lastmodified(
00552 writeICalDateTime(incidence->
lastModified())));
00553
00554
00555
if (!incidence->
description().isEmpty()) {
00556 icalcomponent_add_property(parent,icalproperty_new_description(
00557 incidence->
description().utf8()));
00558 }
00559
00560
00561
if (!incidence->
summary().isEmpty()) {
00562 icalcomponent_add_property(parent,icalproperty_new_summary(
00563 incidence->
summary().utf8()));
00564 }
00565
00566
00567
if (!incidence->
location().isEmpty()) {
00568 icalcomponent_add_property(parent,icalproperty_new_location(
00569 incidence->
location().utf8()));
00570 }
00571
00572
00573 icalproperty_status status = ICAL_STATUS_NONE;
00574
switch (incidence->
status()) {
00575
case Incidence::StatusTentative: status = ICAL_STATUS_TENTATIVE;
break;
00576
case Incidence::StatusConfirmed: status = ICAL_STATUS_CONFIRMED;
break;
00577
case Incidence::StatusCompleted: status = ICAL_STATUS_COMPLETED;
break;
00578
case Incidence::StatusNeedsAction: status = ICAL_STATUS_NEEDSACTION;
break;
00579
case Incidence::StatusCanceled: status = ICAL_STATUS_CANCELLED;
break;
00580
case Incidence::StatusInProcess: status = ICAL_STATUS_INPROCESS;
break;
00581
case Incidence::StatusDraft: status = ICAL_STATUS_DRAFT;
break;
00582
case Incidence::StatusFinal: status = ICAL_STATUS_FINAL;
break;
00583
case Incidence::StatusX: {
00584 icalproperty* p = icalproperty_new_status(ICAL_STATUS_X);
00585 icalvalue_set_x(icalproperty_get_value(p), incidence->
statusStr().utf8());
00586 icalcomponent_add_property(parent, p);
00587
break;
00588 }
00589
case Incidence::StatusNone:
00590
default:
00591
break;
00592 }
00593
if (status != ICAL_STATUS_NONE)
00594 icalcomponent_add_property(parent, icalproperty_new_status(status));
00595
00596
00597
const char *classStr;
00598
switch (incidence->
secrecy()) {
00599
case Incidence::SecrecyPublic:
00600 classStr =
"PUBLIC";
00601
break;
00602
case Incidence::SecrecyConfidential:
00603 classStr =
"CONFIDENTIAL";
00604
break;
00605
case Incidence::SecrecyPrivate:
00606
default:
00607 classStr =
"PRIVATE";
00608
break;
00609 }
00610 icalcomponent_add_property(parent,icalproperty_new_class(classStr));
00611
00612
00613 icalcomponent_add_property(parent,icalproperty_new_priority(
00614 incidence->
priority()));
00615
00616
00617
QStringList categories = incidence->
categories();
00618 QStringList::Iterator it;
00619
for(it = categories.begin(); it != categories.end(); ++it ) {
00620 icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8()));
00621 }
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634
00635
00636
00637
00638
00639
00640
00641
00642
00643
00644
00645
00646
00647
00648
00649
00650
if (incidence->
relatedTo()) {
00651 icalcomponent_add_property(parent,icalproperty_new_relatedto(
00652 incidence->
relatedTo()->
uid().utf8()));
00653 }
00654
00655
00656
if (incidence->
doesRecur()) {
00657 kdDebug(5800) <<
"Write recurrence for '" << incidence->
summary() <<
"' (" << incidence->
uid()
00658 <<
")" << endl;
00659 icalcomponent_add_property(parent,writeRecurrenceRule(incidence->
recurrence()));
00660 }
00661
00662
00663
DateList dateList = incidence->
exDates();
00664 DateList::ConstIterator exIt;
00665
for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) {
00666 icalcomponent_add_property(parent,icalproperty_new_exdate(
00667 writeICalDate(*exIt)));
00668 }
00669
DateTimeList dateTimeList = incidence->
exDateTimes();
00670 DateTimeList::ConstIterator extIt;
00671
for(extIt = dateTimeList.begin(); extIt != dateTimeList.end(); ++extIt) {
00672 icalcomponent_add_property(parent,icalproperty_new_exdate(
00673 writeICalDateTime(*extIt)));
00674 }
00675
00676
00677
Attachment::List attachments = incidence->
attachments();
00678 Attachment::List::ConstIterator atIt;
00679
for ( atIt = attachments.begin(); atIt != attachments.end(); ++atIt )
00680 icalcomponent_add_property( parent, writeAttachment( *atIt ) );
00681
00682
00683 Alarm::List::ConstIterator alarmIt;
00684
for ( alarmIt = incidence->
alarms().begin();
00685 alarmIt != incidence->
alarms().end(); ++alarmIt ) {
00686
if ( (*alarmIt)->enabled() ) {
00687 kdDebug(5800) <<
"Write alarm for " << incidence->
summary() << endl;
00688 icalcomponent_add_component( parent, writeAlarm( *alarmIt ) );
00689 }
00690 }
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701 }
00702
00703
void ICalFormatImpl::writeIncidenceBase( icalcomponent *parent,
00704
IncidenceBase * incidenceBase )
00705 {
00706 icalcomponent_add_property( parent, icalproperty_new_dtstamp(
00707 writeICalDateTime( QDateTime::currentDateTime() ) ) );
00708
00709
00710 icalcomponent_add_property( parent, icalproperty_new_organizer(
00711 (
"MAILTO:" + incidenceBase->
organizer() ).utf8() ) );
00712
00713
00714
if ( incidenceBase->
attendeeCount() > 0 ) {
00715 Attendee::List::ConstIterator it;
00716
for( it = incidenceBase->
attendees().begin();
00717 it != incidenceBase->
attendees().end(); ++it ) {
00718 icalcomponent_add_property( parent, writeAttendee( *it ) );
00719 }
00720 }
00721
00722
00723
QStringList comments = incidenceBase->
comments();
00724
for (QStringList::Iterator it=comments.begin(); it!=comments.end(); ++it) {
00725 icalcomponent_add_property(parent, icalproperty_new_comment((*it).utf8()));
00726 }
00727
00728
00729 writeCustomProperties( parent, incidenceBase );
00730 }
00731
00732
void ICalFormatImpl::writeCustomProperties(icalcomponent *parent,
CustomProperties *properties)
00733 {
00734
QMap<QCString, QString> custom = properties->
customProperties();
00735
for (
QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
00736 icalproperty *p = icalproperty_new_x(c.data().utf8());
00737 icalproperty_set_x_name(p,c.key());
00738 icalcomponent_add_property(parent,p);
00739 }
00740 }
00741
00742 icalproperty *ICalFormatImpl::writeAttendee(
Attendee *attendee)
00743 {
00744 icalproperty *p = icalproperty_new_attendee(
"mailto:" + attendee->
email().utf8());
00745
00746
if (!attendee->
name().isEmpty()) {
00747 icalproperty_add_parameter(p,icalparameter_new_cn(attendee->
name().utf8()));
00748 }
00749
00750
00751 icalproperty_add_parameter(p,icalparameter_new_rsvp(
00752 attendee->
RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE ));
00753
00754 icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION;
00755
switch (attendee->
status()) {
00756
default:
00757
case Attendee::NeedsAction:
00758 status = ICAL_PARTSTAT_NEEDSACTION;
00759
break;
00760
case Attendee::Accepted:
00761 status = ICAL_PARTSTAT_ACCEPTED;
00762
break;
00763
case Attendee::Declined:
00764 status = ICAL_PARTSTAT_DECLINED;
00765
break;
00766
case Attendee::Tentative:
00767 status = ICAL_PARTSTAT_TENTATIVE;
00768
break;
00769
case Attendee::Delegated:
00770 status = ICAL_PARTSTAT_DELEGATED;
00771
break;
00772
case Attendee::Completed:
00773 status = ICAL_PARTSTAT_COMPLETED;
00774
break;
00775
case Attendee::InProcess:
00776 status = ICAL_PARTSTAT_INPROCESS;
00777
break;
00778 }
00779 icalproperty_add_parameter(p,icalparameter_new_partstat(status));
00780
00781 icalparameter_role role = ICAL_ROLE_REQPARTICIPANT;
00782
switch (attendee->
role()) {
00783
case Attendee::Chair:
00784 role = ICAL_ROLE_CHAIR;
00785
break;
00786
default:
00787
case Attendee::ReqParticipant:
00788 role = ICAL_ROLE_REQPARTICIPANT;
00789
break;
00790
case Attendee::OptParticipant:
00791 role = ICAL_ROLE_OPTPARTICIPANT;
00792
break;
00793
case Attendee::NonParticipant:
00794 role = ICAL_ROLE_NONPARTICIPANT;
00795
break;
00796 }
00797 icalproperty_add_parameter(p,icalparameter_new_role(role));
00798
00799
if (!attendee->
uid().isEmpty()) {
00800 icalparameter* icalparameter_uid = icalparameter_new_x(attendee->
uid().utf8());
00801 icalparameter_set_xname(icalparameter_uid,
"X-UID");
00802 icalproperty_add_parameter(p,icalparameter_uid);
00803 }
00804
00805
return p;
00806 }
00807
00808 icalproperty *ICalFormatImpl::writeAttachment(
Attachment *att)
00809 {
00810 icalattachtype *attach = icalattachtype_new();
00811
if ( att->
isUri() )
00812 icalattachtype_set_url( attach, att->
uri().utf8().data() );
00813
else
00814 icalattachtype_set_base64( attach, att->
data(), 0 );
00815
00816 icalproperty *p = icalproperty_new_attach( attach );
00817 icalattachtype_free( attach );
00818
00819
if ( !att->
mimeType().isEmpty() ) {
00820 icalproperty_add_parameter( p,
00821 icalparameter_new_fmttype( att->
mimeType().utf8().data() ) );
00822 }
00823
00824
if ( att->
isBinary() ) {
00825 icalproperty_add_parameter( p,
00826 icalparameter_new_value( ICAL_VALUE_BINARY ) );
00827 icalproperty_add_parameter( p,
00828 icalparameter_new_encoding( ICAL_ENCODING_BASE64 ) );
00829 }
00830
return p;
00831 }
00832
00833 icalproperty *ICalFormatImpl::writeRecurrenceRule(
Recurrence *recur)
00834 {
00835
00836
00837 icalrecurrencetype r;
00838
00839 icalrecurrencetype_clear(&r);
00840
00841
int index = 0;
00842
int index2 = 0;
00843
00844
QPtrList<Recurrence::rMonthPos> tmpPositions;
00845
QPtrList<int> tmpDays;
00846
int *tmpDay;
00847 Recurrence::rMonthPos *tmpPos;
00848
bool datetime =
false;
00849
int day;
00850
int i;
00851
00852
switch(recur->
doesRecur()) {
00853
case Recurrence::rMinutely:
00854 r.freq = ICAL_MINUTELY_RECURRENCE;
00855 datetime =
true;
00856
break;
00857
case Recurrence::rHourly:
00858 r.freq = ICAL_HOURLY_RECURRENCE;
00859 datetime =
true;
00860
break;
00861
case Recurrence::rDaily:
00862 r.freq = ICAL_DAILY_RECURRENCE;
00863
break;
00864
case Recurrence::rWeekly:
00865 r.freq = ICAL_WEEKLY_RECURRENCE;
00866 r.week_start = static_cast<icalrecurrencetype_weekday>(recur->
weekStart()%7 + 1);
00867
for (i = 0; i < 7; i++) {
00868
if (recur->
days().testBit(i)) {
00869 day = (i + 1)%7 + 1;
00870 r.by_day[index++] = icalrecurrencetype_day_day_of_week(day);
00871 }
00872 }
00873
00874
break;
00875
case Recurrence::rMonthlyPos:
00876 r.freq = ICAL_MONTHLY_RECURRENCE;
00877
00878 tmpPositions = recur->
monthPositions();
00879
for (tmpPos = tmpPositions.first();
00880 tmpPos;
00881 tmpPos = tmpPositions.next()) {
00882
for (i = 0; i < 7; i++) {
00883
if (tmpPos->rDays.testBit(i)) {
00884 day = (i + 1)%7 + 1;
00885 day += tmpPos->rPos*8;
00886
if (tmpPos->negative) day = -day;
00887 r.by_day[index++] = day;
00888 }
00889 }
00890 }
00891
00892
break;
00893
case Recurrence::rMonthlyDay:
00894 r.freq = ICAL_MONTHLY_RECURRENCE;
00895
00896 tmpDays = recur->
monthDays();
00897
for (tmpDay = tmpDays.first();
00898 tmpDay;
00899 tmpDay = tmpDays.next()) {
00900 r.by_month_day[index++] = icalrecurrencetype_day_position(*tmpDay*8);
00901 }
00902
00903
break;
00904
case Recurrence::rYearlyMonth:
00905
case Recurrence::rYearlyPos:
00906 r.freq = ICAL_YEARLY_RECURRENCE;
00907
00908 tmpDays = recur->
yearNums();
00909
for (tmpDay = tmpDays.first();
00910 tmpDay;
00911 tmpDay = tmpDays.next()) {
00912 r.by_month[index++] = *tmpDay;
00913 }
00914
00915
if (recur->
doesRecur() == Recurrence::rYearlyPos) {
00916 tmpPositions = recur->
monthPositions();
00917
for (tmpPos = tmpPositions.first();
00918 tmpPos;
00919 tmpPos = tmpPositions.next()) {
00920
for (i = 0; i < 7; i++) {
00921
if (tmpPos->rDays.testBit(i)) {
00922 day = (i + 1)%7 + 1;
00923 day += tmpPos->rPos*8;
00924
if (tmpPos->negative) day = -day;
00925 r.by_day[index2++] = day;
00926 }
00927 }
00928 }
00929
00930 }
00931
else {
00932 tmpDays = recur->
monthDays();
00933
for (tmpDay = tmpDays.first();
00934 tmpDay;
00935 tmpDay = tmpDays.next()) {
00936 r.by_month_day[index2++] = icalrecurrencetype_day_position(*tmpDay*8);
00937 }
00938
00939 }
00940
break;
00941
case Recurrence::rYearlyDay:
00942 r.freq = ICAL_YEARLY_RECURRENCE;
00943
00944 tmpDays = recur->
yearNums();
00945
for (tmpDay = tmpDays.first();
00946 tmpDay;
00947 tmpDay = tmpDays.next()) {
00948 r.by_year_day[index++] = *tmpDay;
00949 }
00950
00951
break;
00952
default:
00953 r.freq = ICAL_NO_RECURRENCE;
00954 kdDebug(5800) <<
"ICalFormatImpl::writeRecurrence(): no recurrence" << endl;
00955
break;
00956 }
00957
00958 r.interval = recur->
frequency();
00959
00960
if (recur->
duration() > 0) {
00961 r.count = recur->
duration();
00962 }
else if (recur->
duration() == -1) {
00963 r.count = 0;
00964 }
else {
00965
if (datetime)
00966 r.until = writeICalDateTime(recur->
endDateTime());
00967
else
00968 r.until = writeICalDate(recur->
endDate());
00969 }
00970
00971
00972
#if 0
00973
const char *str = icalrecurrencetype_as_string(&r);
00974
if (str) {
00975 kdDebug(5800) <<
" String: " << str << endl;
00976 }
else {
00977 kdDebug(5800) <<
" No String" << endl;
00978 }
00979
#endif
00980
00981
return icalproperty_new_rrule(r);
00982 }
00983
00984 icalcomponent *ICalFormatImpl::writeAlarm(
Alarm *alarm)
00985 {
00986 icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT);
00987
00988 icalproperty_action action;
00989 icalattachtype *attach = 0;
00990
00991
switch (alarm->
type()) {
00992
case Alarm::Procedure:
00993 action = ICAL_ACTION_PROCEDURE;
00994 attach = icalattachtype_new();
00995 icalattachtype_set_url(attach,QFile::encodeName(alarm->
programFile()).data());
00996 icalcomponent_add_property(a,icalproperty_new_attach(attach));
00997 icalattachtype_free(attach);
00998
if (!alarm->
programArguments().isEmpty()) {
00999 icalcomponent_add_property(a,icalproperty_new_description(alarm->
programArguments().utf8()));
01000 }
01001
break;
01002
case Alarm::Audio:
01003 action = ICAL_ACTION_AUDIO;
01004
if (!alarm->
audioFile().isEmpty()) {
01005 attach = icalattachtype_new();
01006 icalattachtype_set_url(attach,QFile::encodeName( alarm->
audioFile() ).data());
01007 icalcomponent_add_property(a,icalproperty_new_attach(attach));
01008 icalattachtype_free(attach);
01009 }
01010
break;
01011
case Alarm::Email: {
01012 action = ICAL_ACTION_EMAIL;
01013
QValueList<Person> addresses = alarm->
mailAddresses();
01014
for (
QValueList<Person>::Iterator ad = addresses.begin(); ad != addresses.end(); ++ad) {
01015 icalproperty *p = icalproperty_new_attendee(
"MAILTO:" + (*ad).email().utf8());
01016
if (!(*ad).name().isEmpty()) {
01017 icalproperty_add_parameter(p,icalparameter_new_cn((*ad).name().utf8()));
01018 }
01019 icalcomponent_add_property(a,p);
01020 }
01021 icalcomponent_add_property(a,icalproperty_new_summary(alarm->
mailSubject().utf8()));
01022 icalcomponent_add_property(a,icalproperty_new_description(alarm->
mailText().utf8()));
01023
QStringList attachments = alarm->
mailAttachments();
01024
if (attachments.count() > 0) {
01025
for (QStringList::Iterator at = attachments.begin(); at != attachments.end(); ++at) {
01026 attach = icalattachtype_new();
01027 icalattachtype_set_url(attach,QFile::encodeName( *at ).data());
01028 icalcomponent_add_property(a,icalproperty_new_attach(attach));
01029 icalattachtype_free(attach);
01030 }
01031 }
01032
break;
01033 }
01034
case Alarm::Display:
01035 action = ICAL_ACTION_DISPLAY;
01036 icalcomponent_add_property(a,icalproperty_new_description(alarm->
text().utf8()));
01037
break;
01038
case Alarm::Invalid:
01039
default:
01040 kdDebug(5800) <<
"Unknown type of alarm" << endl;
01041 action = ICAL_ACTION_NONE;
01042
break;
01043 }
01044 icalcomponent_add_property(a,icalproperty_new_action(action));
01045
01046
01047 icaltriggertype trigger;
01048
if ( alarm->
hasTime() ) {
01049 trigger.time = writeICalDateTime(alarm->
time());
01050 trigger.duration = icaldurationtype_null_duration();
01051 }
else {
01052 trigger.time = icaltime_null_time();
01053
Duration offset;
01054
if ( alarm->
hasStartOffset() )
01055 offset = alarm->
startOffset();
01056
else
01057 offset = alarm->
endOffset();
01058 trigger.duration = icaldurationtype_from_int( offset.
asSeconds() );
01059 }
01060 icalproperty *p = icalproperty_new_trigger(trigger);
01061
if ( alarm->
hasEndOffset() )
01062 icalproperty_add_parameter(p,icalparameter_new_related(ICAL_RELATED_END));
01063 icalcomponent_add_property(a,p);
01064
01065
01066
if (alarm->
repeatCount()) {
01067 icalcomponent_add_property(a,icalproperty_new_repeat(alarm->
repeatCount()));
01068 icalcomponent_add_property(a,icalproperty_new_duration(
01069 icaldurationtype_from_int(alarm->
snoozeTime()*60)));
01070 }
01071
01072
01073
QMap<QCString, QString> custom = alarm->
customProperties();
01074
for (
QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
01075 icalproperty *p = icalproperty_new_x(c.data().utf8());
01076 icalproperty_set_x_name(p,c.key());
01077 icalcomponent_add_property(a,p);
01078 }
01079
01080
return a;
01081 }
01082
01083
01084
01085
01086
void ICalFormatImpl::readTimezone(icalcomponent *vtimezone)
01087 {
01088 Timezone *timezone =
new Timezone(
this, vtimezone);
01089
01090 mTimezones.insert(timezone->id(), timezone);
01091 }
01092
01093
Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo)
01094 {
01095
Todo *todo =
new Todo;
01096
01097 readIncidence(vtodo,todo);
01098
01099 icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY);
01100
01101
01102 icaltimetype icaltime;
01103
01104
QStringList categories;
01105
01106
while (p) {
01107 icalproperty_kind kind = icalproperty_isa(p);
01108
switch (kind) {
01109
01110
case ICAL_DUE_PROPERTY:
01111 icaltime = icalproperty_get_due(p);
01112 readTzidParameter(p,icaltime);
01113
if (icaltime.is_date) {
01114 todo->
setDtDue(
QDateTime(readICalDate(icaltime),
QTime(0,0,0)),
true);
01115 todo->
setFloats(
true);
01116
01117 }
else {
01118 todo->
setDtDue(readICalDateTime(icaltime),
true);
01119 todo->
setFloats(
false);
01120 }
01121 todo->
setHasDueDate(
true);
01122
break;
01123
01124
case ICAL_COMPLETED_PROPERTY:
01125 icaltime = icalproperty_get_completed(p);
01126 readTzidParameter(p,icaltime);
01127 todo->
setCompleted(readICalDateTime(icaltime));
01128
break;
01129
01130
case ICAL_PERCENTCOMPLETE_PROPERTY:
01131 todo->
setPercentComplete(icalproperty_get_percentcomplete(p));
01132
break;
01133
01134
case ICAL_RELATEDTO_PROPERTY:
01135 todo->
setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
01136 mTodosRelate.append(todo);
01137
break;
01138
01139
case ICAL_DTSTART_PROPERTY: {
01140
01141
if ( todo->
comments().grep(
"NoStartDate").count() )
01142 todo->
setHasStartDate(
false );
01143
else
01144 todo->
setHasStartDate(
true );
01145
break;
01146 }
01147
01148
case ICAL_RECURRENCEID_PROPERTY:
01149 icaltime = icalproperty_get_recurrenceid(p);
01150 readTzidParameter(p,icaltime);
01151 todo->
setDtRecurrence( readICalDateTime(icaltime) );
01152
break;
01153
01154
default:
01155
01156
01157
break;
01158 }
01159
01160 p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY);
01161 }
01162
01163 mCompat->fixEmptySummary( todo );
01164
01165
return todo;
01166 }
01167
01168
Event *ICalFormatImpl::readEvent(icalcomponent *vevent)
01169 {
01170
Event *event =
new Event;
01171 event->
setFloats(
false);
01172
01173 readIncidence(vevent,event);
01174
01175 icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY);
01176
01177
01178 icaltimetype icaltime;
01179
01180
QStringList categories;
01181
QString transparency;
01182
01183
while (p) {
01184 icalproperty_kind kind = icalproperty_isa(p);
01185
switch (kind) {
01186
01187
case ICAL_DTEND_PROPERTY:
01188 icaltime = icalproperty_get_dtend(p);
01189 readTzidParameter(p,icaltime);
01190
if (icaltime.is_date) {
01191 event->
setFloats(
true );
01192
01193
QDate endDate = readICalDate( icaltime ).addDays( -1 );
01194 mCompat->fixFloatingEnd( endDate );
01195
if ( endDate < event->
dtStart().date() ) {
01196 endDate = event->
dtStart().date();
01197 }
01198 event->
setDtEnd(
QDateTime( endDate,
QTime( 0, 0, 0 ) ) );
01199 }
else {
01200 event->
setDtEnd(readICalDateTime(icaltime));
01201 }
01202
break;
01203
01204
01205
01206
01207
#if 0
01208
if (!(vo = isAPropertyOf(vevent, VCDTstartProp)))
01209 anEvent->setDtStart(anEvent->dtEnd());
01210
if (!(vo = isAPropertyOf(vevent, VCDTendProp)))
01211 anEvent->setDtEnd(anEvent->dtStart());
01212
#endif
01213
01214
#if 0
01215
01216
if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) {
01217 anEvent->setSecrecy(s = fakeCString(vObjectUStringZValue(vo)));
01218 deleteStr(s);
01219 }
01220
else
01221 anEvent->setSecrecy(
"PUBLIC");
01222
01223
01224 tmpStrList.clear();
01225 initPropIterator(&voi, vevent);
01226
while (moreIteration(&voi)) {
01227 vo = nextVObject(&voi);
01228
if (strcmp(vObjectName(vo), VCAttachProp) == 0) {
01229 tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo)));
01230 deleteStr(s);
01231 }
01232 }
01233 anEvent->setAttachments(tmpStrList);
01234
01235
01236
if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) {
01237
QString resources = (s = fakeCString(vObjectUStringZValue(vo)));
01238 deleteStr(s);
01239 tmpStrList.clear();
01240 index1 = 0;
01241 index2 = 0;
01242
QString resource;
01243
while ((index2 = resources.find(
';', index1)) != -1) {
01244 resource = resources.mid(index1, (index2 - index1));
01245 tmpStrList.append(resource);
01246 index1 = index2;
01247 }
01248 anEvent->setResources(tmpStrList);
01249 }
01250
#endif
01251
01252
case ICAL_RELATEDTO_PROPERTY:
01253 event->
setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p)));
01254 mEventsRelate.append(event);
01255
break;
01256
01257
01258
case ICAL_TRANSP_PROPERTY:
01259 transparency = QString::fromUtf8(icalproperty_get_transp(p));
01260
if( transparency ==
"TRANSPARENT" )
01261 event->
setTransparency( Event::Transparent );
01262
else
01263 event->
setTransparency( Event::Opaque );
01264
break;
01265
01266
default:
01267
01268
01269
break;
01270 }
01271
01272 p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY);
01273 }
01274
01275
QString msade = event->
nonKDECustomProperty(
"X-MICROSOFT-CDO-ALLDAYEVENT");
01276
if (!msade.isNull()) {
01277
bool floats = (msade == QString::fromLatin1(
"TRUE"));
01278 kdDebug(5800) <<
"ICALFormat::readEvent(): all day event: " << floats << endl;
01279 event->
setFloats(floats);
01280
if (floats) {
01281
QDateTime endDate = event->
dtEnd();
01282 event->
setDtEnd(endDate.addDays(-1));
01283 }
01284 }
01285
01286 mCompat->fixEmptySummary( event );
01287
01288
return event;
01289 }
01290
01291
FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy)
01292 {
01293
FreeBusy *freebusy =
new FreeBusy;
01294
01295 readIncidenceBase(vfreebusy,freebusy);
01296
01297 icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY);
01298
01299 icaltimetype icaltime;
01300 icalperiodtype icalperiod;
01301
QDateTime period_start, period_end;
01302
01303
while (p) {
01304 icalproperty_kind kind = icalproperty_isa(p);
01305
switch (kind) {
01306
01307
case ICAL_DTSTART_PROPERTY:
01308 icaltime = icalproperty_get_dtstart(p);
01309 readTzidParameter(p,icaltime);
01310 freebusy->
setDtStart(readICalDateTime(icaltime));
01311
break;
01312
01313
case ICAL_DTEND_PROPERTY:
01314 icaltime = icalproperty_get_dtend(p);
01315 readTzidParameter(p,icaltime);
01316 freebusy->
setDtEnd(readICalDateTime(icaltime));
01317
break;
01318
01319
case ICAL_FREEBUSY_PROPERTY:
01320 icalperiod = icalproperty_get_freebusy(p);
01321 readTzidParameter(p,icalperiod.start);
01322 readTzidParameter(p,icalperiod.end);
01323 period_start = readICalDateTime(icalperiod.start);
01324 period_end = readICalDateTime(icalperiod.end);
01325 freebusy->
addPeriod(period_start, period_end);
01326
break;
01327
01328
default:
01329
01330
01331
break;
01332 }
01333 p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY);
01334 }
01335
01336
return freebusy;
01337 }
01338
01339
Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal)
01340 {
01341
Journal *journal =
new Journal;
01342
01343 readIncidence(vjournal,journal);
01344
01345
return journal;
01346 }
01347
01348
Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee)
01349 {
01350 icalparameter *p = 0;
01351
01352
QString email = QString::fromUtf8(icalproperty_get_attendee(attendee));
01353
01354
QString name;
01355
QString uid = QString::null;
01356 p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER);
01357
if (p) {
01358 name = QString::fromUtf8(icalparameter_get_cn(p));
01359 }
else {
01360 }
01361
01362
bool rsvp=
false;
01363 p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER);
01364
if (p) {
01365 icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p);
01366
if (rsvpParameter == ICAL_RSVP_TRUE) rsvp =
true;
01367 }
01368
01369 Attendee::PartStat status = Attendee::NeedsAction;
01370 p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER);
01371
if (p) {
01372 icalparameter_partstat partStatParameter = icalparameter_get_partstat(p);
01373
switch(partStatParameter) {
01374
default:
01375
case ICAL_PARTSTAT_NEEDSACTION:
01376 status = Attendee::NeedsAction;
01377
break;
01378
case ICAL_PARTSTAT_ACCEPTED:
01379 status = Attendee::Accepted;
01380
break;
01381
case ICAL_PARTSTAT_DECLINED:
01382 status = Attendee::Declined;
01383
break;
01384
case ICAL_PARTSTAT_TENTATIVE:
01385 status = Attendee::Tentative;
01386
break;
01387
case ICAL_PARTSTAT_DELEGATED:
01388 status = Attendee::Delegated;
01389
break;
01390
case ICAL_PARTSTAT_COMPLETED:
01391 status = Attendee::Completed;
01392
break;
01393
case ICAL_PARTSTAT_INPROCESS:
01394 status = Attendee::InProcess;
01395
break;
01396 }
01397 }
01398
01399 Attendee::Role role = Attendee::ReqParticipant;
01400 p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER);
01401
if (p) {
01402 icalparameter_role roleParameter = icalparameter_get_role(p);
01403
switch(roleParameter) {
01404
case ICAL_ROLE_CHAIR:
01405 role = Attendee::Chair;
01406
break;
01407
default:
01408
case ICAL_ROLE_REQPARTICIPANT:
01409 role = Attendee::ReqParticipant;
01410
break;
01411
case ICAL_ROLE_OPTPARTICIPANT:
01412 role = Attendee::OptParticipant;
01413
break;
01414
case ICAL_ROLE_NONPARTICIPANT:
01415 role = Attendee::NonParticipant;
01416
break;
01417 }
01418 }
01419
01420 p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER);
01421 uid = icalparameter_get_xvalue(p);
01422
01423
01424
01425
01426
01427
01428
01429
return new Attendee( name, email, rsvp, status, role, uid );
01430 }
01431
01432
Attachment *ICalFormatImpl::readAttachment(icalproperty *attach)
01433 {
01434 icalattachtype *a = icalproperty_get_attach(attach);
01435 icalparameter_value v = ICAL_VALUE_NONE;
01436 icalparameter_encoding e = ICAL_ENCODING_NONE;
01437
01438
Attachment *attachment = 0;
01439
01440 icalparameter *vp = icalproperty_get_first_parameter(attach, ICAL_VALUE_PARAMETER);
01441
if (vp)
01442 v = icalparameter_get_value(vp);
01443
01444 icalparameter *ep = icalproperty_get_first_parameter(attach, ICAL_ENCODING_PARAMETER);
01445
if (ep)
01446 e = icalparameter_get_encoding(ep);
01447
01448
if (v == ICAL_VALUE_BINARY && e == ICAL_ENCODING_BASE64) {
01449 attachment =
new Attachment(icalattachtype_get_base64(a));
01450 }
else if ((v == ICAL_VALUE_NONE || v == ICAL_VALUE_URI) && (e == ICAL_ENCODING_NONE || e == ICAL_ENCODING_8BIT)) {
01451 attachment =
new Attachment(
QString(icalattachtype_get_url(a)));
01452 }
else {
01453 kdWarning(5800) <<
"Unsupported attachment format, discarding it!" << endl;
01454
return 0;
01455 }
01456
01457 icalparameter *p = icalproperty_get_first_parameter(attach, ICAL_FMTTYPE_PARAMETER);
01458
if (p)
01459 attachment->
setMimeType(
QString(icalparameter_get_fmttype(p)));
01460
01461
return attachment;
01462 }
01463
01464
void ICalFormatImpl::readIncidence(icalcomponent *parent,
Incidence *incidence)
01465 {
01466 readIncidenceBase(parent,incidence);
01467
01468 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
01469
01470
const char *text;
01471
int intvalue;
01472 icaltimetype icaltime;
01473 icaldurationtype icalduration;
01474
01475
QStringList categories;
01476
01477
while (p) {
01478 icalproperty_kind kind = icalproperty_isa(p);
01479
switch (kind) {
01480
01481
case ICAL_CREATED_PROPERTY:
01482 icaltime = icalproperty_get_created(p);
01483 readTzidParameter(p,icaltime);
01484 incidence->
setCreated(readICalDateTime(icaltime));
01485
break;
01486
01487
case ICAL_SEQUENCE_PROPERTY:
01488 intvalue = icalproperty_get_sequence(p);
01489 incidence->
setRevision(intvalue);
01490
break;
01491
01492
case ICAL_LASTMODIFIED_PROPERTY:
01493 icaltime = icalproperty_get_lastmodified(p);
01494 readTzidParameter(p,icaltime);
01495 incidence->
setLastModified(readICalDateTime(icaltime));
01496
break;
01497
01498
case ICAL_DTSTART_PROPERTY:
01499 icaltime = icalproperty_get_dtstart(p);
01500 readTzidParameter(p,icaltime);
01501
if (icaltime.is_date) {
01502 incidence->
setDtStart(
QDateTime(readICalDate(icaltime),
QTime(0,0,0)));
01503 incidence->
setFloats(
true);
01504 }
else {
01505 incidence->
setDtStart(readICalDateTime(icaltime));
01506 }
01507
break;
01508
01509
case ICAL_DURATION_PROPERTY:
01510 icalduration = icalproperty_get_duration(p);
01511 incidence->
setDuration(readICalDuration(icalduration));
01512
break;
01513
01514
case ICAL_DESCRIPTION_PROPERTY:
01515 text = icalproperty_get_description(p);
01516 incidence->
setDescription(QString::fromUtf8(text));
01517
break;
01518
01519
case ICAL_SUMMARY_PROPERTY:
01520 text = icalproperty_get_summary(p);
01521 incidence->
setSummary(QString::fromUtf8(text));
01522
break;
01523
01524
case ICAL_LOCATION_PROPERTY:
01525 text = icalproperty_get_location(p);
01526 incidence->
setLocation(QString::fromUtf8(text));
01527
break;
01528
01529
case ICAL_STATUS_PROPERTY: {
01530 Incidence::Status stat;
01531
switch (icalproperty_get_status(p)) {
01532
case ICAL_STATUS_TENTATIVE: stat = Incidence::StatusTentative;
break;
01533
case ICAL_STATUS_CONFIRMED: stat = Incidence::StatusConfirmed;
break;
01534
case ICAL_STATUS_COMPLETED: stat = Incidence::StatusCompleted;
break;
01535
case ICAL_STATUS_NEEDSACTION: stat = Incidence::StatusNeedsAction;
break;
01536
case ICAL_STATUS_CANCELLED: stat = Incidence::StatusCanceled;
break;
01537
case ICAL_STATUS_INPROCESS: stat = Incidence::StatusInProcess;
break;
01538
case ICAL_STATUS_DRAFT: stat = Incidence::StatusDraft;
break;
01539
case ICAL_STATUS_FINAL: stat = Incidence::StatusFinal;
break;
01540
case ICAL_STATUS_X:
01541 incidence->
setCustomStatus(QString::fromUtf8(icalvalue_get_x(icalproperty_get_value(p))));
01542 stat = Incidence::StatusX;
01543
break;
01544
case ICAL_STATUS_NONE:
01545
default: stat = Incidence::StatusNone;
break;
01546 }
01547
if (stat != Incidence::StatusX)
01548 incidence->
setStatus(stat);
01549
break;
01550 }
01551
01552
case ICAL_PRIORITY_PROPERTY:
01553 intvalue = icalproperty_get_priority(p);
01554 incidence->
setPriority(intvalue);
01555
break;
01556
01557
case ICAL_CATEGORIES_PROPERTY:
01558 text = icalproperty_get_categories(p);
01559 categories.append(QString::fromUtf8(text));
01560
break;
01561
01562
case ICAL_RRULE_PROPERTY:
01563 readRecurrenceRule(p,incidence);
01564
break;
01565
01566
case ICAL_EXDATE_PROPERTY:
01567 icaltime = icalproperty_get_exdate(p);
01568 readTzidParameter(p,icaltime);
01569
if (icaltime.is_date) {
01570 incidence->
addExDate(readICalDate(icaltime));
01571 }
else {
01572 incidence->
addExDateTime(readICalDateTime(icaltime));
01573 }
01574
break;
01575
01576
case ICAL_CLASS_PROPERTY:
01577 text = icalproperty_get_class(p);
01578
if (strcmp(text,
"PUBLIC") == 0) {
01579 incidence->
setSecrecy(Incidence::SecrecyPublic);
01580 }
else if (strcmp(text,
"CONFIDENTIAL") == 0) {
01581 incidence->
setSecrecy(Incidence::SecrecyConfidential);
01582 }
else {
01583 incidence->
setSecrecy(Incidence::SecrecyPrivate);
01584 }
01585
break;
01586
01587
case ICAL_ATTACH_PROPERTY:
01588 incidence->
addAttachment(readAttachment(p));
01589
break;
01590
01591
default:
01592
01593
01594
break;
01595 }
01596
01597 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
01598 }
01599
01600
01601
01602
QString kp = incidence->
nonKDECustomProperty(
"X-PILOTID");
01603
if (!kp.isNull()) {
01604 incidence->
setPilotId(kp.toInt());
01605 }
01606 kp = incidence->
nonKDECustomProperty(
"X-PILOTSTAT");
01607
if (!kp.isNull()) {
01608 incidence->
setSyncStatus(kp.toInt());
01609 }
01610
01611
01612
01613
if (incidence->
doesRecur())
01614 mCompat->fixRecurrence( incidence );
01615
01616
01617 incidence->
setCategories(categories);
01618
01619
01620
for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT);
01621 alarm;
01622 alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) {
01623 readAlarm(alarm,incidence);
01624 }
01625 }
01626
01627
void ICalFormatImpl::readIncidenceBase(icalcomponent *parent,
IncidenceBase *incidenceBase)
01628 {
01629 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
01630
01631
while (p) {
01632 icalproperty_kind kind = icalproperty_isa(p);
01633
switch (kind) {
01634
01635
case ICAL_UID_PROPERTY:
01636 incidenceBase->
setUid(QString::fromUtf8(icalproperty_get_uid(p)));
01637
break;
01638
01639
case ICAL_ORGANIZER_PROPERTY:
01640 incidenceBase->
setOrganizer(QString::fromUtf8(icalproperty_get_organizer(p)));
01641
break;
01642
01643
case ICAL_ATTENDEE_PROPERTY:
01644 incidenceBase->
addAttendee(readAttendee(p));
01645
break;
01646
01647
case ICAL_COMMENT_PROPERTY:
01648 incidenceBase->
addComment(
01649 QString::fromUtf8(icalproperty_get_comment(p)));
01650
break;
01651
01652
default:
01653
break;
01654 }
01655
01656 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
01657 }
01658
01659
01660 readCustomProperties(parent, incidenceBase);
01661 }
01662
01663
void ICalFormatImpl::readCustomProperties(icalcomponent *parent,
CustomProperties *properties)
01664 {
01665
QMap<QCString, QString> customProperties;
01666
01667 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY);
01668
01669
while (p) {
01670
01671
QString value = QString::fromUtf8(icalproperty_get_x(p));
01672 customProperties[icalproperty_get_name(p)] = value;
01673
01674 p = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY);
01675 }
01676
01677 properties->
setCustomProperties(customProperties);
01678 }
01679
01680
void ICalFormatImpl::readRecurrenceRule(icalproperty *rrule,
Incidence *incidence)
01681 {
01682
01683
01684
Recurrence *recur = incidence->
recurrence();
01685 recur->
setCompatVersion(mCalendarVersion);
01686 recur->
unsetRecurs();
01687
01688
struct icalrecurrencetype r = icalproperty_get_rrule(rrule);
01689
01690 dumpIcalRecurrence(r);
01691
01692 readRecurrence( r, recur );
01693 }
01694
01695
void ICalFormatImpl::readRecurrence(
const struct icalrecurrencetype &r,
Recurrence* recur )
01696 {
01697
int wkst;
01698
int index = 0;
01699
short day = 0;
01700
QBitArray qba(7);
01701
01702
switch (r.freq) {
01703
case ICAL_MINUTELY_RECURRENCE:
01704
if (!icaltime_is_null_time(r.until)) {
01705 recur->
setMinutely(r.interval,readICalDateTime(r.until));
01706 }
else {
01707
if (r.count == 0)
01708 recur->
setMinutely(r.interval,-1);
01709
else
01710 recur->
setMinutely(r.interval,r.count);
01711 }
01712
break;
01713
case ICAL_HOURLY_RECURRENCE:
01714
if (!icaltime_is_null_time(r.until)) {
01715 recur->
setHourly(r.interval,readICalDateTime(r.until));
01716 }
else {
01717
if (r.count == 0)
01718 recur->
setHourly(r.interval,-1);
01719
else
01720 recur->
setHourly(r.interval,r.count);
01721 }
01722
break;
01723
case ICAL_DAILY_RECURRENCE:
01724
if (!icaltime_is_null_time(r.until)) {
01725 recur->
setDaily(r.interval,readICalDate(r.until));
01726 }
else {
01727
if (r.count == 0)
01728 recur->
setDaily(r.interval,-1);
01729
else
01730 recur->
setDaily(r.interval,r.count);
01731 }
01732
break;
01733
case ICAL_WEEKLY_RECURRENCE:
01734
01735 wkst = (r.week_start + 5)%7 + 1;
01736
if (!icaltime_is_null_time(r.until)) {
01737 recur->
setWeekly(r.interval,qba,readICalDate(r.until),wkst);
01738 }
else {
01739
if (r.count == 0)
01740 recur->
setWeekly(r.interval,qba,-1,wkst);
01741
else
01742 recur->
setWeekly(r.interval,qba,r.count,wkst);
01743 }
01744
while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01745
01746 qba.setBit((day+5)%7);
01747 }
01748
break;
01749
case ICAL_MONTHLY_RECURRENCE:
01750
if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01751
if (!icaltime_is_null_time(r.until)) {
01752 recur->
setMonthly(Recurrence::rMonthlyPos,r.interval,
01753 readICalDate(r.until));
01754 }
else {
01755
if (r.count == 0)
01756 recur->
setMonthly(Recurrence::rMonthlyPos,r.interval,-1);
01757
else
01758 recur->
setMonthly(Recurrence::rMonthlyPos,r.interval,r.count);
01759 }
01760
bool useSetPos =
false;
01761
short pos = 0;
01762
while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01763
01764 pos = icalrecurrencetype_day_position(day);
01765
if (pos) {
01766 day = icalrecurrencetype_day_day_of_week(day);
01767
QBitArray ba(7);
01768 ba.setBit((day+5)%7);
01769 recur->
addMonthlyPos(pos,ba);
01770 }
else {
01771 qba.setBit((day+5)%7);
01772 useSetPos =
true;
01773 }
01774 }
01775
if (useSetPos) {
01776
if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01777 recur->
addMonthlyPos(r.by_set_pos[0],qba);
01778 }
01779 }
01780 }
else if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01781
if (!icaltime_is_null_time(r.until)) {
01782 recur->
setMonthly(Recurrence::rMonthlyDay,r.interval,
01783 readICalDate(r.until));
01784 }
else {
01785
if (r.count == 0)
01786 recur->
setMonthly(Recurrence::rMonthlyDay,r.interval,-1);
01787
else
01788 recur->
setMonthly(Recurrence::rMonthlyDay,r.interval,r.count);
01789 }
01790
while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01791
01792 recur->
addMonthlyDay(day);
01793 }
01794 }
01795
break;
01796
case ICAL_YEARLY_RECURRENCE:
01797
if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01798
if (!icaltime_is_null_time(r.until)) {
01799 recur->
setYearly(Recurrence::rYearlyDay,r.interval,
01800 readICalDate(r.until));
01801 }
else {
01802
if (r.count == 0)
01803 recur->
setYearly(Recurrence::rYearlyDay,r.interval,-1);
01804
else
01805 recur->
setYearly(Recurrence::rYearlyDay,r.interval,r.count);
01806 }
01807
while((day = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01808 recur->
addYearlyNum(day);
01809 }
01810 }
if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01811
if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01812
if (!icaltime_is_null_time(r.until)) {
01813 recur->
setYearly(Recurrence::rYearlyPos,r.interval,
01814 readICalDate(r.until));
01815 }
else {
01816
if (r.count == 0)
01817 recur->
setYearly(Recurrence::rYearlyPos,r.interval,-1);
01818
else
01819 recur->
setYearly(Recurrence::rYearlyPos,r.interval,r.count);
01820 }
01821
bool useSetPos =
false;
01822
short pos = 0;
01823
while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01824
01825 pos = icalrecurrencetype_day_position(day);
01826
if (pos) {
01827 day = icalrecurrencetype_day_day_of_week(day);
01828
QBitArray ba(7);
01829 ba.setBit((day+5)%7);
01830 recur->
addYearlyMonthPos(pos,ba);
01831 }
else {
01832 qba.setBit((day+5)%7);
01833 useSetPos =
true;
01834 }
01835 }
01836
if (useSetPos) {
01837
if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
01838 recur->
addYearlyMonthPos(r.by_set_pos[0],qba);
01839 }
01840 }
01841 }
else {
01842
if (!icaltime_is_null_time(r.until)) {
01843 recur->
setYearly(Recurrence::rYearlyMonth,r.interval,
01844 readICalDate(r.until));
01845 }
else {
01846
if (r.count == 0)
01847 recur->
setYearly(Recurrence::rYearlyMonth,r.interval,-1);
01848
else
01849 recur->
setYearly(Recurrence::rYearlyMonth,r.interval,r.count);
01850 }
01851
while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01852 recur->
addMonthlyDay(day);
01853 }
01854 }
01855 index = 0;
01856
while((day = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
01857 recur->
addYearlyNum(day);
01858 }
01859 }
01860
break;
01861
default:
01862 kdDebug(5800) <<
"Unknown type of recurrence: " << r.freq << endl;
01863
break;
01864 }
01865 }
01866
01867
void ICalFormatImpl::readAlarm(icalcomponent *alarm,
Incidence *incidence)
01868 {
01869
01870
01871
Alarm* ialarm = incidence->
newAlarm();
01872 ialarm->
setRepeatCount(0);
01873 ialarm->
setEnabled(
true);
01874
01875
01876 icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ACTION_PROPERTY);
01877 Alarm::Type type = Alarm::Display;
01878 icalproperty_action action = ICAL_ACTION_DISPLAY;
01879
if ( !p ) {
01880 kdDebug(5800) <<
"Unknown type of alarm, using default" << endl;
01881
01882 }
else {
01883
01884 action = icalproperty_get_action(p);
01885
switch ( action ) {
01886
case ICAL_ACTION_DISPLAY: type = Alarm::Display;
break;
01887
case ICAL_ACTION_AUDIO: type = Alarm::Audio;
break;
01888
case ICAL_ACTION_PROCEDURE: type = Alarm::Procedure;
break;
01889
case ICAL_ACTION_EMAIL: type = Alarm::Email;
break;
01890
default:
01891 kdDebug(5800) <<
"Unknown type of alarm: " << action << endl;
01892
01893 }
01894 }
01895 ialarm->
setType(type);
01896
01897 p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY);
01898
while (p) {
01899 icalproperty_kind kind = icalproperty_isa(p);
01900
01901
switch (kind) {
01902
01903
case ICAL_TRIGGER_PROPERTY: {
01904 icaltriggertype trigger = icalproperty_get_trigger(p);
01905
if (icaltime_is_null_time(trigger.time)) {
01906
if (icaldurationtype_is_null_duration(trigger.duration)) {
01907 kdDebug(5800) <<
"ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl;
01908 }
else {
01909
Duration duration = icaldurationtype_as_int( trigger.duration );
01910 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_RELATED_PARAMETER);
01911
if (param && icalparameter_get_related(param) == ICAL_RELATED_END)
01912 ialarm->
setEndOffset(duration);
01913
else
01914 ialarm->
setStartOffset(duration);
01915 }
01916 }
else {
01917 ialarm->
setTime(readICalDateTime(trigger.time));
01918 }
01919
break;
01920 }
01921
case ICAL_DURATION_PROPERTY: {
01922 icaldurationtype duration = icalproperty_get_duration(p);
01923 ialarm->
setSnoozeTime(icaldurationtype_as_int(duration)/60);
01924
break;
01925 }
01926
case ICAL_REPEAT_PROPERTY:
01927 ialarm->
setRepeatCount(icalproperty_get_repeat(p));
01928
break;
01929
01930
01931
case ICAL_DESCRIPTION_PROPERTY: {
01932
QString description = QString::fromUtf8(icalproperty_get_description(p));
01933
switch ( action ) {
01934
case ICAL_ACTION_DISPLAY:
01935 ialarm->
setText( description );
01936
break;
01937
case ICAL_ACTION_PROCEDURE:
01938 ialarm->
setProgramArguments( description );
01939
break;
01940
case ICAL_ACTION_EMAIL:
01941 ialarm->
setMailText( description );
01942
break;
01943
default:
01944
break;
01945 }
01946
break;
01947 }
01948
01949
case ICAL_SUMMARY_PROPERTY:
01950 ialarm->
setMailSubject(QString::fromUtf8(icalproperty_get_summary(p)));
01951
break;
01952
01953
01954
case ICAL_ATTENDEE_PROPERTY: {
01955
QString email = QString::fromUtf8(icalproperty_get_attendee(p));
01956
QString name;
01957 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_CN_PARAMETER);
01958
if (param) {
01959 name = QString::fromUtf8(icalparameter_get_cn(param));
01960 }
01961 ialarm->
addMailAddress(
Person(name, email));
01962
break;
01963 }
01964
01965
case ICAL_ATTACH_PROPERTY: {
01966 icalattachtype *attach = icalproperty_get_attach(p);
01967
QString url = QFile::decodeName(icalattachtype_get_url(attach));
01968
switch ( action ) {
01969
case ICAL_ACTION_AUDIO:
01970 ialarm->
setAudioFile( url );
01971
break;
01972
case ICAL_ACTION_PROCEDURE:
01973 ialarm->
setProgramFile( url );
01974
break;
01975
case ICAL_ACTION_EMAIL:
01976 ialarm->
addMailAttachment( url );
01977
break;
01978
default:
01979
break;
01980 }
01981
break;
01982 }
01983
default:
01984
break;
01985 }
01986
01987 p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY);
01988 }
01989
01990
01991 readCustomProperties(alarm, ialarm);
01992
01993
01994 }
01995
01996 icaltimetype ICalFormatImpl::writeICalDate(
const QDate &date)
01997 {
01998 icaltimetype t;
01999
02000 t.year = date.year();
02001 t.month = date.month();
02002 t.day = date.day();
02003
02004 t.hour = 0;
02005 t.minute = 0;
02006 t.second = 0;
02007
02008 t.is_date = 1;
02009
02010 t.is_utc = 0;
02011
02012 t.zone = 0;
02013
02014
return t;
02015 }
02016
02017 icaltimetype ICalFormatImpl::writeICalDateTime(
const QDateTime &datetime)
02018 {
02019 icaltimetype t;
02020
02021 t.year = datetime.date().year();
02022 t.month = datetime.date().month();
02023 t.day = datetime.date().day();
02024
02025 t.hour = datetime.time().hour();
02026 t.minute = datetime.time().minute();
02027 t.second = datetime.time().second();
02028
02029 t.is_date = 0;
02030 t.zone = 0;
02031 t.is_utc = 0;
02032
02033
if ( mParent->utc() ) {
02034
if (mParent->timeZoneId().isEmpty())
02035 t = icaltime_as_utc(t, 0);
02036
else
02037 t = icaltime_as_utc(t,mParent->timeZoneId().utf8());
02038 }
02039
02040
return t;
02041 }
02042
02043
QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t)
02044 {
02045
02046
02047
02048
02049
02050
02051
02052
02053
02054
02055
02056
02057
if ( !t.is_utc && t.zone ) {
02058 Timezone *timezone;
02059
02060
02061
if (t.zone[0] !=
'"') {
02062 timezone = mTimezones.find(
QString(
"\"") + t.zone +
'"');
02063 }
else {
02064 timezone = mTimezones.find(t.zone);
02065 }
02066
if (timezone) {
02067
02068 t.second -= timezone->offset(t);
02069 t = icaltime_normalize(t);
02070 t.is_utc = 1;
02071 }
else {
02072 kdError(5800) <<
"ICalFormatImpl::readICalDateTime() cannot find timezone "
02073 << t.zone << endl;
02074 }
02075 }
02076
02077
if ( t.is_utc && mCompat->useTimeZoneShift() ) {
02078
02079
if (mParent->timeZoneId().isEmpty())
02080 t = icaltime_as_zone(t, 0);
02081
else
02082 t = icaltime_as_zone(t,mParent->timeZoneId().utf8());
02083 }
02084
QDateTime result(
QDate(t.year,t.month,t.day),
02085
QTime(t.hour,t.minute,t.second));
02086
02087
return result;
02088 }
02089
02090
QDate ICalFormatImpl::readICalDate(icaltimetype t)
02091 {
02092
return QDate(t.year,t.month,t.day);
02093 }
02094
02095 icaldurationtype ICalFormatImpl::writeICalDuration(
int seconds)
02096 {
02097 icaldurationtype d;
02098
02099 d.weeks = seconds % gSecondsPerWeek;
02100 seconds -= d.weeks * gSecondsPerWeek;
02101 d.days = seconds % gSecondsPerDay;
02102 seconds -= d.days * gSecondsPerDay;
02103 d.hours = seconds % gSecondsPerHour;
02104 seconds -= d.hours * gSecondsPerHour;
02105 d.minutes = seconds % gSecondsPerMinute;
02106 seconds -= d.minutes * gSecondsPerMinute;
02107 d.seconds = seconds;
02108 d.is_neg = 0;
02109
02110
return d;
02111 }
02112
02113
int ICalFormatImpl::readICalDuration(icaldurationtype d)
02114 {
02115
int result = 0;
02116
02117 result += d.weeks * gSecondsPerWeek;
02118 result += d.days * gSecondsPerDay;
02119 result += d.hours * gSecondsPerHour;
02120 result += d.minutes * gSecondsPerMinute;
02121 result += d.seconds;
02122
02123
if (d.is_neg) result *= -1;
02124
02125
return result;
02126 }
02127
02128 icalcomponent *ICalFormatImpl::createCalendarComponent(
Calendar *cal)
02129 {
02130 icalcomponent *calendar;
02131
02132
02133 calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
02134
02135 icalproperty *p;
02136
02137
02138 p = icalproperty_new_prodid(CalFormat::productId().utf8());
02139 icalcomponent_add_property(calendar,p);
02140
02141
02142
02143
02144 p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION));
02145 icalcomponent_add_property(calendar,p);
02146
02147
02148
if( cal != 0 )
02149 writeCustomProperties(calendar, cal);
02150
02151
return calendar;
02152 }
02153
02154
02155
02156
02157
02158
02159
bool ICalFormatImpl::populate(
Calendar *cal, icalcomponent *calendar)
02160 {
02161
02162
02163
02164
if (!calendar)
return false;
02165
02166
02167
#if 0
02168
if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) {
02169
char *methodType = 0;
02170 methodType = fakeCString(vObjectUStringZValue(curVO));
02171
if (mEnableDialogs)
02172 KMessageBox::information(mTopWidget,
02173 i18n(
"This calendar is an iTIP transaction of type \"%1\".")
02174 .arg(methodType),
02175 i18n(
"%1: iTIP Transaction").arg(CalFormat::application()));
02176
delete methodType;
02177 }
02178
#endif
02179
02180 icalproperty *p;
02181
02182 p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY);
02183
if (!p) {
02184 kdDebug(5800) <<
"No PRODID property found" << endl;
02185
02186
02187
02188 mLoadedProductId =
"";
02189 mCalendarVersion = 0;
02190 }
else {
02191 mLoadedProductId = QString::fromUtf8(icalproperty_get_prodid(p));
02192 mCalendarVersion =
CalFormat::calendarVersion(mLoadedProductId.latin1());
02193
02194
02195
delete mCompat;
02196 mCompat = CompatFactory::createCompat( mLoadedProductId );
02197 }
02198
02199
02200
#if 0
02201
if (!mCalendarVersion
02202 &&
CalFormat::productId() != mLoadedProductId) {
02203
02204
if (mEnableDialogs)
02205 KMessageBox::information(mTopWidget,
02206 i18n(
"This vCalendar file was not created by KOrganizer "
02207
"or any other product we support. Loading anyway..."),
02208 i18n(
"%1: Unknown vCalendar Vendor").arg(CalFormat::application()));
02209 }
02210
#endif
02211
02212 p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY);
02213
if (!p) {
02214 kdDebug(5800) <<
"No VERSION property found" << endl;
02215 mParent->setException(
new ErrorFormat(ErrorFormat::CalVersionUnknown));
02216
return false;
02217 }
else {
02218
const char *version = icalproperty_get_version(p);
02219
02220
02221
if (strcmp(version,
"1.0") == 0) {
02222 kdDebug(5800) <<
"Expected iCalendar, got vCalendar" << endl;
02223 mParent->setException(
new ErrorFormat(ErrorFormat::CalVersion1,
02224 i18n(
"Expected iCalendar format")));
02225
return false;
02226 }
else if (strcmp(version,
"2.0") != 0) {
02227 kdDebug(5800) <<
"Expected iCalendar, got unknown format" << endl;
02228 mParent->setException(
new ErrorFormat(ErrorFormat::CalVersionUnknown));
02229
return false;
02230 }
02231 }
02232
02233
02234
02235
#if 0
02236
02237
if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) {
02238
char *s = fakeCString(vObjectUStringZValue(curVO));
02239
if (strcmp(_VCAL_VERSION, s) != 0)
02240
if (mEnableDialogs)
02241 KMessageBox::sorry(mTopWidget,
02242 i18n(
"This vCalendar file has version %1.\n"
02243
"We only support %2.")
02244 .arg(s).arg(_VCAL_VERSION),
02245 i18n(
"%1: Unknown vCalendar Version").arg(CalFormat::application()));
02246 deleteStr(s);
02247 }
02248
#endif
02249
02250
02251 readCustomProperties(calendar, cal);
02252
02253
02254
#if 0
02255
02256
if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) {
02257
char *s = fakeCString(vObjectUStringZValue(curVO));
02258 cal->setTimeZone(s);
02259 deleteStr(s);
02260 }
02261
#endif
02262
02263
02264 mEventsRelate.clear();
02265 mTodosRelate.clear();
02266
02267
02268 icalcomponent *c;
02269
02270
02271
02272
02273 c = icalcomponent_get_first_component(calendar,ICAL_VTIMEZONE_COMPONENT);
02274
while (c) {
02275
02276 readTimezone(c);
02277 c = icalcomponent_get_next_component(calendar,ICAL_VTIMEZONE_COMPONENT);
02278 }
02279
02280
02281 c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT);
02282
while (c) {
02283
02284 Todo *todo = readTodo(c);
02285
if (todo && !cal->
todo(todo->
uid())) cal->
addTodo(todo);
02286 c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT);
02287 }
02288
02289
02290 c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT);
02291
while (c) {
02292
02293 Event *event = readEvent(c);
02294
if (event && !cal->
event(event->
uid())) cal->
addEvent(event);
02295 c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT);
02296 }
02297
02298
02299 c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT);
02300
while (c) {
02301
02302
Journal *journal = readJournal(c);
02303
if (journal && !cal->
journal(journal->
uid())) cal->
addJournal(journal);
02304 c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT);
02305 }
02306
02307
#if 0
02308
initPropIterator(&i, vcal);
02309
02310
02311
while (moreIteration(&i)) {
02312 curVO = nextVObject(&i);
02313
02314
02315
02316
02317
if (strcmp(vObjectName(curVO), VCEventProp) == 0) {
02318
02319
if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) {
02320
char *s;
02321 s = fakeCString(vObjectUStringZValue(curVOProp));
02322
02323
if (atoi(s) == Event::SYNCDEL) {
02324 deleteStr(s);
02325 kdDebug(5800) <<
"skipping pilot-deleted event" << endl;
02326
goto SKIP;
02327 }
02328 deleteStr(s);
02329 }
02330
02331
02332
02333
02334
if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) {
02335
char *s = fakeCString(vObjectUStringZValue(curVOProp));
02336
QString tmpStr(s);
02337 deleteStr(s);
02338
02339
if (cal->
event(tmpStr)) {
02340
goto SKIP;
02341 }
02342
if (cal->
todo(tmpStr)) {
02343
goto SKIP;
02344 }
02345 }
02346
02347
if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) &&
02348 (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) {
02349 kdDebug(5800) <<
"found a VEvent with no DTSTART and no DTEND! Skipping..." << endl;
02350
goto SKIP;
02351 }
02352
02353 anEvent = VEventToEvent(curVO);
02354
02355
02356
if (anEvent)
02357 cal->
addEvent(anEvent);
02358
else {
02359
02360
goto SKIP;
02361 }
02362 }
else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) {
02363 anEvent = VTodoToEvent(curVO);
02364 cal->
addTodo(anEvent);
02365 }
else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) ||
02366 (strcmp(vObjectName(curVO), VCProdIdProp) == 0) ||
02367 (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) {
02368
02369
02370 ;
02371 }
else {
02372 kdDebug(5800) <<
"Ignoring unknown vObject \"" << vObjectName(curVO) <<
"\"" << endl;
02373 }
02374 SKIP:
02375 ;
02376 }
02377
#endif
02378
02379
02380 Event::List::ConstIterator eIt;
02381
for ( eIt = mEventsRelate.begin(); eIt != mEventsRelate.end(); ++eIt ) {
02382 (*eIt)->setRelatedTo( cal->
incidence( (*eIt)->relatedToUid() ) );
02383 }
02384 Todo::List::ConstIterator tIt;
02385
for ( tIt = mTodosRelate.begin(); tIt != mTodosRelate.end(); ++tIt ) {
02386 (*tIt)->setRelatedTo( cal->
incidence( (*tIt)->relatedToUid() ) );
02387 }
02388
02389
return true;
02390 }
02391
02392
QString ICalFormatImpl::extractErrorProperty(icalcomponent *c)
02393 {
02394
02395
02396
02397
QString errorMessage;
02398
02399 icalproperty *error;
02400 error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY);
02401
while(error) {
02402 errorMessage += icalproperty_get_xlicerror(error);
02403 errorMessage +=
"\n";
02404 error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY);
02405 }
02406
02407
02408
02409
return errorMessage;
02410 }
02411
02412
void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r)
02413 {
02414
int i;
02415
02416 kdDebug(5800) <<
" Freq: " << r.freq << endl;
02417 kdDebug(5800) <<
" Until: " << icaltime_as_ctime(r.until) << endl;
02418 kdDebug(5800) <<
" Count: " << r.count << endl;
02419
if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02420
int index = 0;
02421
QString out =
" By Day: ";
02422
while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02423 out.append(QString::number(i) +
" ");
02424 }
02425 kdDebug(5800) << out << endl;
02426 }
02427
if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02428
int index = 0;
02429
QString out =
" By Month Day: ";
02430
while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02431 out.append(QString::number(i) +
" ");
02432 }
02433 kdDebug(5800) << out << endl;
02434 }
02435
if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02436
int index = 0;
02437
QString out =
" By Year Day: ";
02438
while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02439 out.append(QString::number(i) +
" ");
02440 }
02441 kdDebug(5800) << out << endl;
02442 }
02443
if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02444
int index = 0;
02445
QString out =
" By Month: ";
02446
while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02447 out.append(QString::number(i) +
" ");
02448 }
02449 kdDebug(5800) << out << endl;
02450 }
02451
if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
02452
int index = 0;
02453
QString out =
" By Set Pos: ";
02454
while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
02455 kdDebug(5800) <<
"========= " << i << endl;
02456 out.append(QString::number(i) +
" ");
02457 }
02458 kdDebug(5800) << out << endl;
02459 }
02460 }
02461
02462 icalcomponent *ICalFormatImpl::createScheduleComponent(
IncidenceBase *incidence,
02463 Scheduler::Method method)
02464 {
02465 icalcomponent *message = createCalendarComponent();
02466
02467 icalproperty_method icalmethod = ICAL_METHOD_NONE;
02468
02469
switch (method) {
02470
case Scheduler::Publish:
02471 icalmethod = ICAL_METHOD_PUBLISH;
02472
break;
02473
case Scheduler::Request:
02474 icalmethod = ICAL_METHOD_REQUEST;
02475
break;
02476
case Scheduler::Refresh:
02477 icalmethod = ICAL_METHOD_REFRESH;
02478
break;
02479
case Scheduler::Cancel:
02480 icalmethod = ICAL_METHOD_CANCEL;
02481
break;
02482
case Scheduler::Add:
02483 icalmethod = ICAL_METHOD_ADD;
02484
break;
02485
case Scheduler::Reply:
02486 icalmethod = ICAL_METHOD_REPLY;
02487
break;
02488
case Scheduler::Counter:
02489 icalmethod = ICAL_METHOD_COUNTER;
02490
break;
02491
case Scheduler::Declinecounter:
02492 icalmethod = ICAL_METHOD_DECLINECOUNTER;
02493
break;
02494
default:
02495 kdDebug(5800) <<
"ICalFormat::createScheduleMessage(): Unknow method" << endl;
02496
return message;
02497 }
02498
02499 icalcomponent_add_property(message,icalproperty_new_method(icalmethod));
02500
02501
02502
if(incidence->
type() ==
"Todo") {
02503 Todo *todo = static_cast<Todo *>(incidence);
02504 icalcomponent_add_component(message,writeTodo(todo));
02505 }
02506
if(incidence->
type() ==
"Event") {
02507 Event *event = static_cast<Event *>(incidence);
02508 icalcomponent_add_component(message,writeEvent(event));
02509 }
02510
if(incidence->
type() ==
"FreeBusy") {
02511 FreeBusy *freebusy = static_cast<FreeBusy *>(incidence);
02512 icalcomponent_add_component(message,writeFreeBusy(freebusy, method));
02513 }
02514
if (incidence->
type() ==
"Journal" ) {
02515
Journal *journal = static_cast<Journal *>(incidence);
02516 icalcomponent_add_component( message, writeJournal( journal ) );
02517 }
02518
02519
return message;
02520 }
02521
02522
02523
02524
02525
void ICalFormatImpl::readTzidParameter( icalcomponent *p,
02526 icaltimetype &icaltime )
02527 {
02528 icalproperty *tzp = icalproperty_get_first_parameter( p,
02529 ICAL_TZID_PARAMETER );
02530
if ( tzp ) {
02531 icaltime.zone = icalparameter_get_tzid( tzp );
02532 }
02533 }
02534