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