libkcal

icalformatimpl.cpp
1/*
2 This file is part of libkcal.
3
4 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
5 Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
6
7 This library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Library General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Library General Public License for more details.
16
17 You should have received a copy of the GNU Library General Public License
18 along with this library; see the file COPYING.LIB. If not, write to
19 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
21*/
22
23#include <tqdatetime.h>
24#include <tqstring.h>
25#include <tqptrlist.h>
26#include <tqfile.h>
27#include <cstdlib>
28
29#include <kdebug.h>
30#include <tdelocale.h>
31#include <kmdcodec.h>
32
33extern "C" {
34 #include <libical/ical.h>
35 #include <libical/icalparser.h>
36 #include <libical/icalrestriction.h>
37}
38
39#include "calendar.h"
40#include "journal.h"
41#include "icalformat.h"
42#include "icalformatimpl.h"
43#include "compat.h"
44
45#include "config.h"
46
47#define _ICAL_VERSION "2.0"
48
49using namespace KCal;
50
51/* Static helpers */
52static TQDateTime ICalDate2TQDate(const icaltimetype& t)
53{
54 // Outlook sends dates starting from 1601-01-01, but TQDate()
55 // can only handle dates starting 1752-09-14.
56 const int year = (t.year>=1754) ? t.year : 1754;
57 return TQDateTime(TQDate(year,t.month,t.day), TQTime(t.hour,t.minute,t.second));
58}
59
60/*
61static void _dumpIcaltime( const icaltimetype& t)
62{
63 kdDebug(5800) << "--- Y: " << t.year << " M: " << t.month << " D: " << t.day
64 << endl;
65 kdDebug(5800) << "--- H: " << t.hour << " M: " << t.minute << " S: " << t.second
66 << endl;
67 kdDebug(5800) << "--- isUtc: " << icaltime_is_utc( t )<< endl;
68 kdDebug(5800) << "--- zoneId: " << icaltimezone_get_tzid( const_cast<icaltimezone*>( t.zone ) )<< endl;
69}
70*/
71
72const int gSecondsPerMinute = 60;
73const int gSecondsPerHour = gSecondsPerMinute * 60;
74const int gSecondsPerDay = gSecondsPerHour * 24;
75const int gSecondsPerWeek = gSecondsPerDay * 7;
76
77ICalFormatImpl::ICalFormatImpl( ICalFormat *parent ) :
78 mParent( parent ), mCompat( new Compat )
79{
80}
81
82ICalFormatImpl::~ICalFormatImpl()
83{
84 delete mCompat;
85}
86
87class ICalFormatImpl::ToComponentVisitor : public IncidenceBase::Visitor
88{
89 public:
90 ToComponentVisitor( ICalFormatImpl *impl, Scheduler::Method m ) : mImpl( impl ), mComponent( 0 ), mMethod( m ) {}
91
92 bool visit( Event *e ) { mComponent = mImpl->writeEvent( e ); return true; }
93 bool visit( Todo *e ) { mComponent = mImpl->writeTodo( e ); return true; }
94 bool visit( Journal *e ) { mComponent = mImpl->writeJournal( e ); return true; }
95 bool visit( FreeBusy *fb ) { mComponent = mImpl->writeFreeBusy( fb, mMethod ); return true; }
96
97 icalcomponent *component() { return mComponent; }
98
99 private:
100 ICalFormatImpl *mImpl;
101 icalcomponent *mComponent;
102 Scheduler::Method mMethod;
103};
104
105icalcomponent *ICalFormatImpl::writeIncidence( IncidenceBase *incidence, Scheduler::Method method )
106{
107 ToComponentVisitor v( this, method );
108 if ( incidence->accept(v) )
109 return v.component();
110 else return 0;
111}
112
113icalcomponent *ICalFormatImpl::writeTodo(Todo *todo)
114{
115 TQString tmpStr;
116 TQStringList tmpStrList;
117
118 icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT);
119
120 writeIncidence(vtodo,todo);
121
122 // due date
123 if (todo->hasDueDate()) {
124 icaltimetype due;
125 if (todo->doesFloat()) {
126 due = writeICalDate(todo->dtDue(true).date());
127 } else {
128 due = writeICalDateTime(todo->dtDue(true));
129 }
130 icalcomponent_add_property(vtodo,icalproperty_new_due(due));
131 }
132
133 // start time
134 if ( todo->hasStartDate() || todo->doesRecur() ) {
135 icaltimetype start;
136 if (todo->doesFloat()) {
137// kdDebug(5800) << " Incidence " << todo->summary() << " floats." << endl;
138 start = writeICalDate(todo->dtStart(true).date());
139 } else {
140// kdDebug(5800) << " incidence " << todo->summary() << " has time." << endl;
141 start = writeICalDateTime(todo->dtStart(true));
142 }
143 icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start));
144 }
145
146 // completion date
147 if (todo->isCompleted()) {
148 if (!todo->hasCompletedDate()) {
149 // If todo was created by KOrganizer <2.2 it has no correct completion
150 // date. Set it to now.
151 todo->setCompleted(TQDateTime::currentDateTime());
152 }
153 icaltimetype completed = writeICalDateTime(todo->completed());
154 icalcomponent_add_property(vtodo,icalproperty_new_completed(completed));
155 }
156
157 icalcomponent_add_property(vtodo,
158 icalproperty_new_percentcomplete(todo->percentComplete()));
159
160 if( todo->doesRecur() ) {
161 icalcomponent_add_property(vtodo,
162 icalproperty_new_recurrenceid( writeICalDateTime( todo->dtDue())));
163 }
164
165 return vtodo;
166}
167
168icalcomponent *ICalFormatImpl::writeEvent(Event *event)
169{
170#if 0
171 kdDebug(5800) << "Write Event '" << event->summary() << "' (" << event->uid()
172 << ")" << endl;
173#endif
174
175 TQString tmpStr;
176 TQStringList tmpStrList;
177
178 icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT);
179
180 writeIncidence(vevent,event);
181
182 // start time
183 icaltimetype start;
184 if (event->doesFloat()) {
185// kdDebug(5800) << " Incidence " << event->summary() << " floats." << endl;
186 start = writeICalDate(event->dtStart().date());
187 } else {
188// kdDebug(5800) << " incidence " << event->summary() << " has time." << endl;
189 start = writeICalDateTime(event->dtStart());
190 }
191 icalcomponent_add_property(vevent,icalproperty_new_dtstart(start));
192
193 if (event->hasEndDate()) {
194 // End time.
195 // RFC2445 says that if DTEND is present, it has to be greater than DTSTART.
196 icaltimetype end;
197 if (event->doesFloat()) {
198// kdDebug(5800) << " Event " << event->summary() << " floats." << endl;
199 // +1 day because end date is non-inclusive.
200 end = writeICalDate( event->dtEnd().date().addDays( 1 ) );
201 icalcomponent_add_property(vevent,icalproperty_new_dtend(end));
202 } else {
203// kdDebug(5800) << " Event " << event->summary() << " has time." << endl;
204 if (event->dtEnd() != event->dtStart()) {
205 end = writeICalDateTime(event->dtEnd());
206 icalcomponent_add_property(vevent,icalproperty_new_dtend(end));
207 }
208 }
209 }
210
211// TODO: resources
212#if 0
213 // resources
214 tmpStrList = anEvent->resources();
215 tmpStr = tmpStrList.join(";");
216 if (!tmpStr.isEmpty())
217 addPropValue(vevent, VCResourcesProp, tmpStr.utf8());
218
219#endif
220
221 // Transparency
222 switch( event->transparency() ) {
223 case Event::Transparent:
224 icalcomponent_add_property(
225 vevent,
226 icalproperty_new_transp( ICAL_TRANSP_TRANSPARENT ) );
227 break;
228 case Event::Opaque:
229 icalcomponent_add_property(
230 vevent,
231 icalproperty_new_transp( ICAL_TRANSP_OPAQUE ) );
232 break;
233 }
234
235 return vevent;
236}
237
238icalcomponent *ICalFormatImpl::writeFreeBusy(FreeBusy *freebusy,
239 Scheduler::Method method)
240{
241 kdDebug(5800) << "icalformatimpl: writeFreeBusy: startDate: "
242 << freebusy->dtStart().toString("ddd MMMM d yyyy: h:m:s ap") << " End Date: "
243 << freebusy->dtEnd().toString("ddd MMMM d yyyy: h:m:s ap") << endl;
244
245 icalcomponent *vfreebusy = icalcomponent_new(ICAL_VFREEBUSY_COMPONENT);
246
247 writeIncidenceBase(vfreebusy,freebusy);
248
249 icalcomponent_add_property(vfreebusy, icalproperty_new_dtstart(
250 writeICalDateTime(freebusy->dtStart())));
251
252 icalcomponent_add_property(vfreebusy, icalproperty_new_dtend(
253 writeICalDateTime(freebusy->dtEnd())));
254
255 if (method == Scheduler::Request) {
256 icalcomponent_add_property(vfreebusy,icalproperty_new_uid(
257 freebusy->uid().utf8()));
258 }
259
260 //Loops through all the periods in the freebusy object
261 TQValueList<Period> list = freebusy->busyPeriods();
262 TQValueList<Period>::Iterator it;
263 icalperiodtype period = icalperiodtype_null_period();
264 for (it = list.begin(); it!= list.end(); ++it) {
265 period.start = writeICalDateTime((*it).start());
266 if ( (*it).hasDuration() ) {
267 period.duration = writeICalDuration( (*it).duration().asSeconds() );
268 } else {
269 period.end = writeICalDateTime((*it).end());
270 }
271 icalcomponent_add_property(vfreebusy, icalproperty_new_freebusy(period) );
272 }
273
274 return vfreebusy;
275}
276
277icalcomponent *ICalFormatImpl::writeJournal(Journal *journal)
278{
279 icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT);
280
281 writeIncidence(vjournal,journal);
282
283 // start time
284 if (journal->dtStart().isValid()) {
285 icaltimetype start;
286 if (journal->doesFloat()) {
287// kdDebug(5800) << " Incidence " << event->summary() << " floats." << endl;
288 start = writeICalDate(journal->dtStart().date());
289 } else {
290// kdDebug(5800) << " incidence " << event->summary() << " has time." << endl;
291 start = writeICalDateTime(journal->dtStart());
292 }
293 icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start));
294 }
295
296 return vjournal;
297}
298
299void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence)
300{
301 // pilot sync stuff
302// TODO: move this application-specific code to kpilot
303 if (incidence->pilotId()) {
304 // NOTE: we can't do setNonKDECustomProperty here because this changes
305 // data and triggers an updated() event...
306 // incidence->setNonKDECustomProperty("X-PILOTSTAT", TQString::number(incidence->syncStatus()));
307 // incidence->setNonKDECustomProperty("X-PILOTID", TQString::number(incidence->pilotId()));
308
309 icalproperty *p = 0;
310 p = icalproperty_new_x(TQString::number(incidence->syncStatus()).utf8());
311 icalproperty_set_x_name(p,"X-PILOTSTAT");
312 icalcomponent_add_property(parent,p);
313
314 p = icalproperty_new_x(TQString::number(incidence->pilotId()).utf8());
315 icalproperty_set_x_name(p,"X-PILOTID");
316 icalcomponent_add_property(parent,p);
317 }
318
319 TQString modifiedUid;
320 if ( incidence->hasRecurrenceID() ) {
321 // Recurring incidences are special; they must match their parent's UID
322 // Each child has the parent set as the first item in the list
323 // So, get and set the UID...
324 IncidenceList il = incidence->childIncidences();
325 IncidenceListIterator it;
326 it = il.begin();
327 modifiedUid = (*it);
328 }
329 else {
330 modifiedUid = incidence->uid();
331 }
332
333 if ( incidence->schedulingID() != modifiedUid )
334 // We need to store the UID in here. The rawSchedulingID will
335 // go into the iCal UID component
336 incidence->setCustomProperty( "LIBKCAL", "ID", modifiedUid );
337 else
338 incidence->removeCustomProperty( "LIBKCAL", "ID" );
339
340 writeIncidenceBase(parent,incidence);
341
342 // creation date
343 icalcomponent_add_property(parent,icalproperty_new_created(
344 writeICalDateTime(incidence->created())));
345
346 // unique id
347 // If the scheduling ID is different from the real UID, the real
348 // one is stored on X-REALID above
349 if ( incidence->hasRecurrenceID() ) {
350 // Recurring incidences are special; they must match their parent's UID
351 icalcomponent_add_property(parent,icalproperty_new_uid(modifiedUid.utf8()));
352 }
353 else {
354 if ( !incidence->schedulingID().isEmpty() ) {
355 icalcomponent_add_property(parent,icalproperty_new_uid(
356 incidence->schedulingID().utf8()));
357 }
358 }
359
360 // revision
361 if ( incidence->revision() > 0 ) { // 0 is default, so don't write that out
362 icalcomponent_add_property(parent,icalproperty_new_sequence(
363 incidence->revision()));
364 }
365
366 // last modification date
367 if ( incidence->lastModified().isValid() ) {
368 icalcomponent_add_property(parent,icalproperty_new_lastmodified(
369 writeICalDateTime(incidence->lastModified())));
370 }
371
372 // description
373 if (!incidence->description().isEmpty()) {
374 icalcomponent_add_property(parent,icalproperty_new_description(
375 incidence->description().utf8()));
376 }
377
378 // summary
379 if (!incidence->summary().isEmpty()) {
380 icalcomponent_add_property(parent,icalproperty_new_summary(
381 incidence->summary().utf8()));
382 }
383
384 // location
385 if (!incidence->location().isEmpty()) {
386 icalcomponent_add_property(parent,icalproperty_new_location(
387 incidence->location().utf8()));
388 }
389
390 // status
391 icalproperty_status status = ICAL_STATUS_NONE;
392 switch (incidence->status()) {
393 case Incidence::StatusTentative: status = ICAL_STATUS_TENTATIVE; break;
394 case Incidence::StatusConfirmed: status = ICAL_STATUS_CONFIRMED; break;
395 case Incidence::StatusCompleted: status = ICAL_STATUS_COMPLETED; break;
396 case Incidence::StatusNeedsAction: status = ICAL_STATUS_NEEDSACTION; break;
397 case Incidence::StatusCanceled: status = ICAL_STATUS_CANCELLED; break;
398 case Incidence::StatusInProcess: status = ICAL_STATUS_INPROCESS; break;
399 case Incidence::StatusDraft: status = ICAL_STATUS_DRAFT; break;
400 case Incidence::StatusFinal: status = ICAL_STATUS_FINAL; break;
401 case Incidence::StatusX: {
402 icalproperty* p = icalproperty_new_status(ICAL_STATUS_X);
403 icalvalue_set_x(icalproperty_get_value(p), incidence->statusStr().utf8());
404 icalcomponent_add_property(parent, p);
405 break;
406 }
407 case Incidence::StatusNone:
408 default:
409 break;
410 }
411 if (status != ICAL_STATUS_NONE)
412 icalcomponent_add_property(parent, icalproperty_new_status(status));
413
414 // secrecy
415 icalproperty_class secClass;
416 switch (incidence->secrecy()) {
417 case Incidence::SecrecyPublic:
418 secClass = ICAL_CLASS_PUBLIC;
419 break;
420 case Incidence::SecrecyConfidential:
421 secClass = ICAL_CLASS_CONFIDENTIAL;
422 break;
423 case Incidence::SecrecyPrivate:
424 default:
425 secClass = ICAL_CLASS_PRIVATE;
426 break;
427 }
428 if ( secClass != ICAL_CLASS_PUBLIC ) {
429 icalcomponent_add_property(parent,icalproperty_new_class(secClass));
430 }
431
432 // priority
433 if ( incidence->priority() > 0 ) { // 0 is undefined priority
434 icalcomponent_add_property(parent,icalproperty_new_priority(
435 incidence->priority()));
436 }
437
438 // categories
439 TQStringList categories = incidence->categories();
440 TQStringList::Iterator it;
441 for(it = categories.begin(); it != categories.end(); ++it ) {
442 icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8()));
443 }
444
445 // related event
446 if ( !incidence->relatedToUid().isEmpty() ) {
447 icalcomponent_add_property(parent,icalproperty_new_relatedto(
448 incidence->relatedToUid().utf8()));
449 }
450
451 // recurrenceid
452 if ( incidence->hasRecurrenceID() ) {
453 icalcomponent_add_property(parent, icalproperty_new_recurrenceid( writeICalDateTime( incidence->recurrenceID() ) ));
454 }
455
456// kdDebug(5800) << "Write recurrence for '" << incidence->summary() << "' (" << incidence->uid()
457// << ")" << endl;
458
459 RecurrenceRule::List rrules( incidence->recurrence()->rRules() );
460 RecurrenceRule::List::ConstIterator rit;
461 for ( rit = rrules.begin(); rit != rrules.end(); ++rit ) {
462 icalcomponent_add_property( parent, icalproperty_new_rrule(
463 writeRecurrenceRule( (*rit) ) ) );
464 }
465
466 RecurrenceRule::List exrules( incidence->recurrence()->exRules() );
467 RecurrenceRule::List::ConstIterator exit;
468 for ( exit = exrules.begin(); exit != exrules.end(); ++exit ) {
469 icalcomponent_add_property( parent, icalproperty_new_rrule(
470 writeRecurrenceRule( (*exit) ) ) );
471 }
472
473 DateList dateList = incidence->recurrence()->exDates();
474 DateList::ConstIterator exIt;
475 for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) {
476 icalcomponent_add_property(parent,icalproperty_new_exdate(
477 writeICalDate(*exIt)));
478 }
479 DateTimeList dateTimeList = incidence->recurrence()->exDateTimes();
480 DateTimeList::ConstIterator extIt;
481 for(extIt = dateTimeList.begin(); extIt != dateTimeList.end(); ++extIt) {
482 icalcomponent_add_property(parent,icalproperty_new_exdate(
483 writeICalDateTime(*extIt)));
484 }
485
486
487 dateList = incidence->recurrence()->rDates();
488 DateList::ConstIterator rdIt;
489 for( rdIt = dateList.begin(); rdIt != dateList.end(); ++rdIt) {
490 icalcomponent_add_property( parent, icalproperty_new_rdate(
491 writeICalDatePeriod(*rdIt) ) );
492 }
493 dateTimeList = incidence->recurrence()->rDateTimes();
494 DateTimeList::ConstIterator rdtIt;
495 for( rdtIt = dateTimeList.begin(); rdtIt != dateTimeList.end(); ++rdtIt) {
496 icalcomponent_add_property( parent, icalproperty_new_rdate(
497 writeICalDateTimePeriod(*rdtIt) ) );
498 }
499
500 // attachments
501 Attachment::List attachments = incidence->attachments();
502 Attachment::List::ConstIterator atIt;
503 for ( atIt = attachments.begin(); atIt != attachments.end(); ++atIt ) {
504 icalcomponent_add_property( parent, writeAttachment( *atIt ) );
505 }
506
507 // alarms
508 Alarm::List::ConstIterator alarmIt;
509 for ( alarmIt = incidence->alarms().begin();
510 alarmIt != incidence->alarms().end(); ++alarmIt ) {
511 if ( (*alarmIt)->enabled() ) {
512// kdDebug(5800) << "Write alarm for " << incidence->summary() << endl;
513 icalcomponent_add_component( parent, writeAlarm( *alarmIt ) );
514 }
515 }
516
517 // duration
518 if (incidence->hasDuration()) {
519 icaldurationtype duration;
520 duration = writeICalDuration( incidence->duration() );
521 icalcomponent_add_property(parent,icalproperty_new_duration(duration));
522 }
523}
524
525void ICalFormatImpl::writeIncidenceBase( icalcomponent *parent,
526 IncidenceBase * incidenceBase )
527{
528 icalcomponent_add_property( parent, icalproperty_new_dtstamp(
529 writeICalDateTime( TQDateTime::currentDateTime() ) ) );
530
531 // organizer stuff
532 if ( !incidenceBase->organizer().isEmpty() ) {
533 icalcomponent_add_property( parent, writeOrganizer( incidenceBase->organizer() ) );
534 }
535
536 // attendees
537 if ( incidenceBase->attendeeCount() > 0 ) {
538 Attendee::List::ConstIterator it;
539 for( it = incidenceBase->attendees().begin();
540 it != incidenceBase->attendees().end(); ++it ) {
541 icalcomponent_add_property( parent, writeAttendee( *it ) );
542 }
543 }
544
545 // comments
546 TQStringList comments = incidenceBase->comments();
547 for (TQStringList::Iterator it=comments.begin(); it!=comments.end(); ++it) {
548 icalcomponent_add_property(parent, icalproperty_new_comment((*it).utf8()));
549 }
550
551 // custom properties
552 writeCustomProperties( parent, incidenceBase );
553}
554
555void ICalFormatImpl::writeCustomProperties(icalcomponent *parent,CustomProperties *properties)
556{
557 TQMap<TQCString, TQString> custom = properties->customProperties();
558 for (TQMap<TQCString, TQString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
559 icalproperty *p = icalproperty_new_x(c.data().utf8());
560 icalproperty_set_x_name(p,c.key());
561 icalcomponent_add_property(parent,p);
562 }
563}
564
565icalproperty *ICalFormatImpl::writeOrganizer( const Person &organizer )
566{
567 icalproperty *p = icalproperty_new_organizer("MAILTO:" + organizer.email().utf8());
568
569 if (!organizer.name().isEmpty()) {
570 icalproperty_add_parameter( p, icalparameter_new_cn(organizer.name().utf8()) );
571 }
572 // TODO: Write dir, sent-by and language
573
574 return p;
575}
576
577
578icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee)
579{
580 icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8());
581
582 if (!attendee->name().isEmpty()) {
583 icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8()));
584 }
585
586
587 icalproperty_add_parameter(p,icalparameter_new_rsvp(
588 attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE ));
589
590 icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION;
591 switch (attendee->status()) {
592 default:
593 case Attendee::NeedsAction:
594 status = ICAL_PARTSTAT_NEEDSACTION;
595 break;
596 case Attendee::Accepted:
597 status = ICAL_PARTSTAT_ACCEPTED;
598 break;
599 case Attendee::Declined:
600 status = ICAL_PARTSTAT_DECLINED;
601 break;
602 case Attendee::Tentative:
603 status = ICAL_PARTSTAT_TENTATIVE;
604 break;
605 case Attendee::Delegated:
606 status = ICAL_PARTSTAT_DELEGATED;
607 break;
608 case Attendee::Completed:
609 status = ICAL_PARTSTAT_COMPLETED;
610 break;
611 case Attendee::InProcess:
612 status = ICAL_PARTSTAT_INPROCESS;
613 break;
614 }
615 icalproperty_add_parameter(p,icalparameter_new_partstat(status));
616
617 icalparameter_role role = ICAL_ROLE_REQPARTICIPANT;
618 switch (attendee->role()) {
619 case Attendee::Chair:
620 role = ICAL_ROLE_CHAIR;
621 break;
622 default:
623 case Attendee::ReqParticipant:
624 role = ICAL_ROLE_REQPARTICIPANT;
625 break;
626 case Attendee::OptParticipant:
627 role = ICAL_ROLE_OPTPARTICIPANT;
628 break;
629 case Attendee::NonParticipant:
630 role = ICAL_ROLE_NONPARTICIPANT;
631 break;
632 }
633 icalproperty_add_parameter(p,icalparameter_new_role(role));
634
635 if (!attendee->uid().isEmpty()) {
636 icalparameter* icalparameter_uid = icalparameter_new_x(attendee->uid().utf8());
637 icalparameter_set_xname(icalparameter_uid,"X-UID");
638 icalproperty_add_parameter(p,icalparameter_uid);
639 }
640
641 if ( !attendee->delegate().isEmpty() ) {
642 icalparameter* icalparameter_delegate = icalparameter_new_delegatedto( attendee->delegate().utf8() );
643 icalproperty_add_parameter( p, icalparameter_delegate );
644 }
645
646 if ( !attendee->delegator().isEmpty() ) {
647 icalparameter* icalparameter_delegator = icalparameter_new_delegatedfrom( attendee->delegator().utf8() );
648 icalproperty_add_parameter( p, icalparameter_delegator );
649 }
650
651 return p;
652}
653
654icalproperty *ICalFormatImpl::writeAttachment( Attachment *att )
655{
656 icalattach *attach;
657 if ( att->isUri() ) {
658 attach = icalattach_new_from_url( att->uri().utf8().data() );
659 } else {
660#ifdef USE_LIBICAL_0_46
661 attach = icalattach_new_from_data ( (const char *)att->data(), 0, 0 );
662#else
663 attach = icalattach_new_from_data ( (unsigned char *)att->data(), 0, 0 );
664#endif
665 }
666 icalproperty *p = icalproperty_new_attach( attach );
667
668 if ( !att->mimeType().isEmpty() ) {
669 icalproperty_add_parameter( p,
670 icalparameter_new_fmttype( att->mimeType().utf8().data() ) );
671 }
672
673 if ( att->isBinary() ) {
674 icalproperty_add_parameter( p,
675 icalparameter_new_value( ICAL_VALUE_BINARY ) );
676 icalproperty_add_parameter( p,
677 icalparameter_new_encoding( ICAL_ENCODING_BASE64 ) );
678 }
679
680 if ( att->showInline() ) {
681 icalparameter* icalparameter_inline = icalparameter_new_x( "inline" );
682 icalparameter_set_xname( icalparameter_inline, "X-CONTENT-DISPOSITION" );
683 icalproperty_add_parameter( p, icalparameter_inline );
684 }
685
686 if ( !att->label().isEmpty() ) {
687 icalparameter* icalparameter_label = icalparameter_new_x( att->label().utf8() );
688 icalparameter_set_xname( icalparameter_label, "X-LABEL" );
689 icalproperty_add_parameter( p, icalparameter_label );
690 }
691
692 return p;
693}
694
695icalrecurrencetype ICalFormatImpl::writeRecurrenceRule( RecurrenceRule *recur )
696{
697// kdDebug(5800) << "ICalFormatImpl::writeRecurrenceRule()" << endl;
698
699 icalrecurrencetype r;
700 icalrecurrencetype_clear(&r);
701
702 switch( recur->recurrenceType() ) {
703 case RecurrenceRule::rSecondly:
704 r.freq = ICAL_SECONDLY_RECURRENCE;
705 break;
706 case RecurrenceRule::rMinutely:
707 r.freq = ICAL_MINUTELY_RECURRENCE;
708 break;
709 case RecurrenceRule::rHourly:
710 r.freq = ICAL_HOURLY_RECURRENCE;
711 break;
712 case RecurrenceRule::rDaily:
713 r.freq = ICAL_DAILY_RECURRENCE;
714 break;
715 case RecurrenceRule::rWeekly:
716 r.freq = ICAL_WEEKLY_RECURRENCE;
717 break;
718 case RecurrenceRule::rMonthly:
719 r.freq = ICAL_MONTHLY_RECURRENCE;
720 break;
721 case RecurrenceRule::rYearly:
722 r.freq = ICAL_YEARLY_RECURRENCE;
723 break;
724 default:
725 r.freq = ICAL_NO_RECURRENCE;
726 kdDebug(5800) << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl;
727 break;
728 }
729
730 int index = 0;
731 TQValueList<int> bys;
732 TQValueList<int>::ConstIterator it;
733
734 // Now write out the BY* parts:
735 bys = recur->bySeconds();
736 index = 0;
737 for ( it = bys.begin(); it != bys.end(); ++it ) {
738 r.by_second[index++] = *it;
739 }
740
741 bys = recur->byMinutes();
742 index = 0;
743 for ( it = bys.begin(); it != bys.end(); ++it ) {
744 r.by_minute[index++] = *it;
745 }
746
747 bys = recur->byHours();
748 index = 0;
749 for ( it = bys.begin(); it != bys.end(); ++it ) {
750 r.by_hour[index++] = *it;
751 }
752
753 bys = recur->byMonthDays();
754 index = 0;
755 for ( it = bys.begin(); it != bys.end(); ++it ) {
756 r.by_month_day[index++] = icalrecurrencetype_day_position( (*it) * 8 );
757 }
758
759 bys = recur->byYearDays();
760 index = 0;
761 for ( it = bys.begin(); it != bys.end(); ++it ) {
762 r.by_year_day[index++] = *it;
763 }
764
765 bys = recur->byWeekNumbers();
766 index = 0;
767 for ( it = bys.begin(); it != bys.end(); ++it ) {
768 r.by_week_no[index++] = *it;
769 }
770
771 bys = recur->byMonths();
772 index = 0;
773 for ( it = bys.begin(); it != bys.end(); ++it ) {
774 r.by_month[index++] = *it;
775 }
776
777 bys = recur->bySetPos();
778 index = 0;
779 for ( it = bys.begin(); it != bys.end(); ++it ) {
780 r.by_set_pos[index++] = *it;
781 }
782
783
784 TQValueList<RecurrenceRule::WDayPos> byd = recur->byDays();
785 int day;
786 index = 0;
787 for ( TQValueList<RecurrenceRule::WDayPos>::ConstIterator dit = byd.begin();
788 dit != byd.end(); ++dit ) {
789 day = (*dit).day() % 7 + 1; // convert from Monday=1 to Sunday=1
790 if ( (*dit).pos() < 0 ) {
791 day += (-(*dit).pos())*8;
792 day = -day;
793 } else {
794 day += (*dit).pos()*8;
795 }
796 r.by_day[index++] = day;
797 }
798
799 r.week_start = static_cast<icalrecurrencetype_weekday>(
800 recur->weekStart()%7 + 1);
801
802 if ( recur->frequency() > 1 ) {
803 // Dont' write out INTERVAL=1, because that's the default anyway
804 r.interval = recur->frequency();
805 }
806
807 if ( recur->duration() > 0 ) {
808 r.count = recur->duration();
809 } else if ( recur->duration() == -1 ) {
810 r.count = 0;
811 } else {
812 if ( recur->doesFloat() )
813 r.until = writeICalDate(recur->endDt().date());
814 else
815 r.until = writeICalDateTime(recur->endDt());
816 }
817
818// Debug output
819#if 0
820 const char *str = icalrecurrencetype_as_string(&r);
821 if (str) {
822 kdDebug(5800) << " String: " << str << endl;
823 } else {
824 kdDebug(5800) << " No String" << endl;
825 }
826#endif
827
828 return r;
829}
830
831
832icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm)
833{
834// kdDebug(5800) << " ICalFormatImpl::writeAlarm" << endl;
835 icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT);
836
837 icalproperty_action action;
838 icalattach *attach = 0;
839
840 switch (alarm->type()) {
841 case Alarm::Procedure:
842 action = ICAL_ACTION_PROCEDURE;
843 attach = icalattach_new_from_url(TQFile::encodeName(alarm->programFile()).data());
844 icalcomponent_add_property(a,icalproperty_new_attach(attach));
845 if (!alarm->programArguments().isEmpty()) {
846 icalcomponent_add_property(a,icalproperty_new_description(alarm->programArguments().utf8()));
847 }
848 break;
849 case Alarm::Audio:
850 action = ICAL_ACTION_AUDIO;
851// kdDebug(5800) << " It's an audio action, file: " << alarm->audioFile() << endl;
852 if (!alarm->audioFile().isEmpty()) {
853 attach = icalattach_new_from_url(TQFile::encodeName( alarm->audioFile() ).data());
854 icalcomponent_add_property(a,icalproperty_new_attach(attach));
855 }
856 break;
857 case Alarm::Email: {
858 action = ICAL_ACTION_EMAIL;
859 TQValueList<Person> addresses = alarm->mailAddresses();
860 for (TQValueList<Person>::Iterator ad = addresses.begin(); ad != addresses.end(); ++ad) {
861 icalproperty *p = icalproperty_new_attendee("MAILTO:" + (*ad).email().utf8());
862 if (!(*ad).name().isEmpty()) {
863 icalproperty_add_parameter(p,icalparameter_new_cn((*ad).name().utf8()));
864 }
865 icalcomponent_add_property(a,p);
866 }
867 icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject().utf8()));
868 icalcomponent_add_property(a,icalproperty_new_description(alarm->mailText().utf8()));
869 TQStringList attachments = alarm->mailAttachments();
870 if (attachments.count() > 0) {
871 for (TQStringList::Iterator at = attachments.begin(); at != attachments.end(); ++at) {
872 attach = icalattach_new_from_url(TQFile::encodeName( *at ).data());
873 icalcomponent_add_property(a,icalproperty_new_attach(attach));
874 }
875 }
876 break;
877 }
878 case Alarm::Display:
879 action = ICAL_ACTION_DISPLAY;
880 icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8()));
881 break;
882 case Alarm::Invalid:
883 default:
884 kdDebug(5800) << "Unknown type of alarm" << endl;
885 action = ICAL_ACTION_NONE;
886 break;
887 }
888 icalcomponent_add_property(a,icalproperty_new_action(action));
889
890 // Trigger time
891 icaltriggertype trigger;
892 if ( alarm->hasTime() ) {
893 trigger.time = writeICalDateTime(alarm->time());
894 trigger.duration = icaldurationtype_null_duration();
895 } else {
896 trigger.time = icaltime_null_time();
897 Duration offset;
898 if ( alarm->hasStartOffset() )
899 offset = alarm->startOffset();
900 else
901 offset = alarm->endOffset();
902 trigger.duration = writeICalDuration( offset.asSeconds() );
903 }
904 icalproperty *p = icalproperty_new_trigger(trigger);
905 if ( alarm->hasEndOffset() )
906 icalproperty_add_parameter(p,icalparameter_new_related(ICAL_RELATED_END));
907 icalcomponent_add_property(a,p);
908
909 // Repeat count and duration
910 if (alarm->repeatCount()) {
911 icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount()));
912 icalcomponent_add_property(a,icalproperty_new_duration(
913 writeICalDuration(alarm->snoozeTime().value())));
914 }
915
916 // Custom properties
917 TQMap<TQCString, TQString> custom = alarm->customProperties();
918 for (TQMap<TQCString, TQString>::Iterator c = custom.begin(); c != custom.end(); ++c) {
919 icalproperty *p = icalproperty_new_x(c.data().utf8());
920 icalproperty_set_x_name(p,c.key());
921 icalcomponent_add_property(a,p);
922 }
923
924 return a;
925}
926
927Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo)
928{
929 Todo *todo = new Todo;
930
931 readIncidence(vtodo, 0, todo); // FIXME timezone
932
933 icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY);
934
935// int intvalue;
936 icaltimetype icaltime;
937
938 TQStringList categories;
939
940 while (p) {
941 icalproperty_kind kind = icalproperty_isa(p);
942 switch (kind) {
943
944 case ICAL_DUE_PROPERTY: // due date
945 icaltime = icalproperty_get_due(p);
946 if (icaltime.is_date) {
947 todo->setDtDue(TQDateTime(readICalDate(icaltime),TQTime(0,0,0)),true);
948 } else {
949 todo->setDtDue(readICalDateTime(p, icaltime),true);
950 todo->setFloats(false);
951 }
952 todo->setHasDueDate(true);
953 break;
954
955 case ICAL_COMPLETED_PROPERTY: // completion date
956 icaltime = icalproperty_get_completed(p);
957 todo->setCompleted(readICalDateTime(p, icaltime));
958 break;
959
960 case ICAL_PERCENTCOMPLETE_PROPERTY: // Percent completed
961 todo->setPercentComplete(icalproperty_get_percentcomplete(p));
962 break;
963
964 case ICAL_RELATEDTO_PROPERTY: // related todo (parent)
965 todo->setRelatedToUid(TQString::fromUtf8(icalproperty_get_relatedto(p)));
966 mTodosRelate.append(todo);
967 break;
968
969 case ICAL_DTSTART_PROPERTY: {
970 // Flag that todo has start date. Value is read in by readIncidence().
971 if ( todo->comments().grep("NoStartDate").count() )
972 todo->setHasStartDate( false );
973 else
974 todo->setHasStartDate( true );
975 break;
976 }
977
978 case ICAL_RECURRENCEID_PROPERTY:
979 icaltime = icalproperty_get_recurrenceid(p);
980 todo->setDtRecurrence( readICalDateTime(p, icaltime) );
981 break;
982
983 default:
984// kdDebug(5800) << "ICALFormat::readTodo(): Unknown property: " << kind
985// << endl;
986 break;
987 }
988
989 p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY);
990 }
991
992 if (mCompat) mCompat->fixEmptySummary( todo );
993
994 return todo;
995}
996
997Event *ICalFormatImpl::readEvent( icalcomponent *vevent, icalcomponent *vtimezone )
998{
999 Event *event = new Event;
1000
1001 // FIXME where is this freed?
1002 icaltimezone *tz = icaltimezone_new();
1003 if ( !icaltimezone_set_component( tz, vtimezone ) ) {
1004 icaltimezone_free( tz, 1 );
1005 tz = 0;
1006 }
1007
1008 readIncidence( vevent, tz, event);
1009
1010 icalproperty *p = icalcomponent_get_first_property( vevent, ICAL_ANY_PROPERTY );
1011
1012 // int intvalue;
1013 icaltimetype icaltime;
1014
1015 TQStringList categories;
1016 icalproperty_transp transparency;
1017
1018 bool dtEndProcessed = false;
1019
1020 while ( p ) {
1021 icalproperty_kind kind = icalproperty_isa( p );
1022 switch ( kind ) {
1023
1024 case ICAL_DTEND_PROPERTY: // start date and time
1025 icaltime = icalproperty_get_dtend( p );
1026 if ( icaltime.is_date ) {
1027 // End date is non-inclusive
1028 TQDate endDate = readICalDate( icaltime ).addDays( -1 );
1029 if ( mCompat ) {
1030 mCompat->fixFloatingEnd( endDate );
1031 }
1032
1033 if ( endDate < event->dtStart().date() ) {
1034 endDate = event->dtStart().date();
1035 }
1036 event->setDtEnd( TQDateTime( endDate, TQTime( 0, 0, 0 ) ) );
1037 } else {
1038 event->setDtEnd(readICalDateTime(p, icaltime, tz));
1039 event->setFloats( false );
1040 }
1041 dtEndProcessed = true;
1042 break;
1043
1044 case ICAL_RELATEDTO_PROPERTY: // related event (parent)
1045 event->setRelatedToUid( TQString::fromUtf8( icalproperty_get_relatedto( p ) ) );
1046 mEventsRelate.append( event );
1047 break;
1048
1049 case ICAL_TRANSP_PROPERTY: // Transparency
1050 transparency = icalproperty_get_transp( p );
1051 if ( transparency == ICAL_TRANSP_TRANSPARENT ) {
1052 event->setTransparency( Event::Transparent );
1053 } else {
1054 event->setTransparency( Event::Opaque );
1055 }
1056 break;
1057
1058 default:
1059 // kdDebug(5800) << "ICALFormat::readEvent(): Unknown property: " << kind
1060 // << endl;
1061 break;
1062 }
1063
1064 p = icalcomponent_get_next_property( vevent, ICAL_ANY_PROPERTY );
1065 }
1066
1067 // according to rfc2445 the dtend shouldn't be written when it equals
1068 // start date. so assign one equal to start date.
1069 if ( !dtEndProcessed && !event->hasDuration() ) {
1070 event->setDtEnd( event->dtStart() );
1071 }
1072
1073 const TQString msade = event->nonKDECustomProperty("X-MICROSOFT-CDO-ALLDAYEVENT");
1074 if ( !msade.isEmpty() ) {
1075 const bool floats = ( msade == TQString::fromLatin1("TRUE") );
1076 event->setFloats(floats);
1077 }
1078
1079 if ( mCompat ) {
1080 mCompat->fixEmptySummary( event );
1081 }
1082
1083 return event;
1084}
1085
1086FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy)
1087{
1088 FreeBusy *freebusy = new FreeBusy;
1089
1090 readIncidenceBase(vfreebusy, freebusy);
1091
1092 icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY);
1093
1094 icaltimetype icaltime;
1095 PeriodList periods;
1096
1097 while (p) {
1098 icalproperty_kind kind = icalproperty_isa(p);
1099 switch (kind) {
1100
1101 case ICAL_DTSTART_PROPERTY: // start date and time
1102 icaltime = icalproperty_get_dtstart(p);
1103 freebusy->setDtStart(readICalDateTime(p, icaltime));
1104 break;
1105
1106 case ICAL_DTEND_PROPERTY: // end Date and Time
1107 icaltime = icalproperty_get_dtend(p);
1108 freebusy->setDtEnd(readICalDateTime(p, icaltime));
1109 break;
1110
1111 case ICAL_FREEBUSY_PROPERTY: //Any FreeBusy Times
1112 {
1113 icalperiodtype icalperiod = icalproperty_get_freebusy(p);
1114 TQDateTime period_start = readICalDateTime(p, icalperiod.start);
1115 Period period;
1116 if ( !icaltime_is_null_time(icalperiod.end) ) {
1117 TQDateTime period_end = readICalDateTime(p, icalperiod.end);
1118 period = Period(period_start, period_end);
1119 } else {
1120 Duration duration = readICalDuration( icalperiod.duration );
1121 period = Period(period_start, duration);
1122 }
1123 icalparameter *param = icalproperty_get_first_parameter( p, ICAL_X_PARAMETER );
1124 while ( param ) {
1125 if ( strncmp( icalparameter_get_xname( param ), "X-SUMMARY", 9 ) == 0 ) {
1126 period.setSummary( TQString::fromUtf8(
1127 KCodecs::base64Decode( TQCString( icalparameter_get_xvalue( param ) ) ) ) );
1128 }
1129 if ( strncmp( icalparameter_get_xname( param ), "X-LOCATION", 10 ) == 0 ) {
1130 period.setLocation( TQString::fromUtf8(
1131 KCodecs::base64Decode( TQCString( icalparameter_get_xvalue( param ) ) ) ) );
1132 }
1133 param = icalproperty_get_next_parameter( p, ICAL_X_PARAMETER );
1134 }
1135 periods.append( period );
1136 break;
1137 }
1138
1139 default:
1140// kdDebug(5800) << "ICalFormatImpl::readFreeBusy(): Unknown property: "
1141// << kind << endl;
1142 break;
1143 }
1144 p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY);
1145 }
1146 freebusy->addPeriods( periods );
1147
1148 return freebusy;
1149}
1150
1151Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal)
1152{
1153 Journal *journal = new Journal;
1154
1155 readIncidence(vjournal, 0, journal); // FIXME tz?
1156
1157 return journal;
1158}
1159
1160Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee)
1161{
1162 icalparameter *p = 0;
1163
1164 TQString email = TQString::fromUtf8(icalproperty_get_attendee(attendee));
1165 if ( email.startsWith( "mailto:", false ) ) {
1166 email = email.mid( 7 );
1167 }
1168
1169 TQString name;
1170 TQString uid = TQString();
1171 p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER);
1172 if (p) {
1173 name = TQString::fromUtf8(icalparameter_get_cn(p));
1174 } else {
1175 }
1176
1177 bool rsvp=false;
1178 p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER);
1179 if (p) {
1180 icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p);
1181 if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true;
1182 }
1183
1184 Attendee::PartStat status = Attendee::NeedsAction;
1185 p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER);
1186 if (p) {
1187 icalparameter_partstat partStatParameter = icalparameter_get_partstat(p);
1188 switch(partStatParameter) {
1189 default:
1190 case ICAL_PARTSTAT_NEEDSACTION:
1191 status = Attendee::NeedsAction;
1192 break;
1193 case ICAL_PARTSTAT_ACCEPTED:
1194 status = Attendee::Accepted;
1195 break;
1196 case ICAL_PARTSTAT_DECLINED:
1197 status = Attendee::Declined;
1198 break;
1199 case ICAL_PARTSTAT_TENTATIVE:
1200 status = Attendee::Tentative;
1201 break;
1202 case ICAL_PARTSTAT_DELEGATED:
1203 status = Attendee::Delegated;
1204 break;
1205 case ICAL_PARTSTAT_COMPLETED:
1206 status = Attendee::Completed;
1207 break;
1208 case ICAL_PARTSTAT_INPROCESS:
1209 status = Attendee::InProcess;
1210 break;
1211 }
1212 }
1213
1214 Attendee::Role role = Attendee::ReqParticipant;
1215 p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER);
1216 if (p) {
1217 icalparameter_role roleParameter = icalparameter_get_role(p);
1218 switch(roleParameter) {
1219 case ICAL_ROLE_CHAIR:
1220 role = Attendee::Chair;
1221 break;
1222 default:
1223 case ICAL_ROLE_REQPARTICIPANT:
1224 role = Attendee::ReqParticipant;
1225 break;
1226 case ICAL_ROLE_OPTPARTICIPANT:
1227 role = Attendee::OptParticipant;
1228 break;
1229 case ICAL_ROLE_NONPARTICIPANT:
1230 role = Attendee::NonParticipant;
1231 break;
1232 }
1233 }
1234
1235 p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER);
1236 uid = icalparameter_get_xvalue(p);
1237 // This should be added, but there seems to be a libical bug here.
1238 // TODO: does this work now in libical-0.24 or greater?
1239 /*while (p) {
1240 // if (icalparameter_get_xname(p) == "X-UID") {
1241 uid = icalparameter_get_xvalue(p);
1242 p = icalproperty_get_next_parameter(attendee,ICAL_X_PARAMETER);
1243 } */
1244
1245 Attendee *a = new Attendee( name, email, rsvp, status, role, uid );
1246
1247 p = icalproperty_get_first_parameter( attendee, ICAL_DELEGATEDTO_PARAMETER );
1248 if ( p )
1249 a->setDelegate( icalparameter_get_delegatedto( p ) );
1250
1251 p = icalproperty_get_first_parameter( attendee, ICAL_DELEGATEDFROM_PARAMETER );
1252 if ( p )
1253 a->setDelegator( icalparameter_get_delegatedfrom( p ) );
1254
1255 return a;
1256}
1257
1258Person ICalFormatImpl::readOrganizer( icalproperty *organizer )
1259{
1260 TQString email = TQString::fromUtf8(icalproperty_get_organizer(organizer));
1261 if ( email.startsWith( "mailto:", false ) ) {
1262 email = email.mid( 7 );
1263 }
1264 TQString cn;
1265
1266 icalparameter *p = icalproperty_get_first_parameter(
1267 organizer, ICAL_CN_PARAMETER );
1268
1269 if ( p ) {
1270 cn = TQString::fromUtf8( icalparameter_get_cn( p ) );
1271 }
1272 Person org( cn, email );
1273 // TODO: Treat sent-by, dir and language here, too
1274 return org;
1275}
1276
1277Attachment *ICalFormatImpl::readAttachment(icalproperty *attach)
1278{
1279 Attachment *attachment = 0;
1280
1281 const char *p;
1282 icalvalue *value = icalproperty_get_value( attach );
1283
1284 switch( icalvalue_isa( value ) ) {
1285 case ICAL_ATTACH_VALUE:
1286 {
1287 icalattach *a = icalproperty_get_attach( attach );
1288 if ( !icalattach_get_is_url( a ) ) {
1289 p = (const char *)icalattach_get_data( a );
1290 if ( p ) {
1291 attachment = new Attachment( p );
1292 }
1293 } else {
1294 p = icalattach_get_url( a );
1295 if ( p ) {
1296 attachment = new Attachment( TQString::fromUtf8( p ) );
1297 }
1298 }
1299 break;
1300 }
1301 case ICAL_BINARY_VALUE:
1302 {
1303 icalattach *a = icalproperty_get_attach( attach );
1304 p = (const char *)icalattach_get_data( a );
1305 if ( p ) {
1306 attachment = new Attachment( p );
1307 }
1308 break;
1309 }
1310 case ICAL_URI_VALUE:
1311 p = icalvalue_get_uri( value );
1312 attachment = new Attachment( TQString::fromUtf8( p ) );
1313 break;
1314 default:
1315 break;
1316 }
1317
1318 if ( attachment ) {
1319 icalparameter *p =
1320 icalproperty_get_first_parameter( attach, ICAL_FMTTYPE_PARAMETER );
1321 if ( p ) {
1322 attachment->setMimeType( TQString( icalparameter_get_fmttype( p ) ) );
1323 }
1324
1325 p = icalproperty_get_first_parameter( attach, ICAL_X_PARAMETER );
1326 while ( p ) {
1327 TQString xname = TQString( icalparameter_get_xname( p ) ).upper();
1328 TQString xvalue = TQString::fromUtf8( icalparameter_get_xvalue( p ) );
1329 if ( xname == "X-CONTENT-DISPOSITION" ) {
1330 attachment->setShowInline( xvalue.lower() == "inline" );
1331 }
1332 if ( xname == "X-LABEL" ) {
1333 attachment->setLabel( xvalue );
1334 }
1335 p = icalproperty_get_next_parameter( attach, ICAL_X_PARAMETER );
1336 }
1337
1338 p = icalproperty_get_first_parameter( attach, ICAL_X_PARAMETER );
1339 while ( p ) {
1340 if ( strncmp( icalparameter_get_xname( p ), "X-LABEL", 7 ) == 0 ) {
1341 attachment->setLabel( TQString::fromUtf8( icalparameter_get_xvalue( p ) ) );
1342 }
1343 p = icalproperty_get_next_parameter( attach, ICAL_X_PARAMETER );
1344 }
1345 }
1346
1347 return attachment;
1348}
1349
1350void ICalFormatImpl::readIncidence(icalcomponent *parent, icaltimezone *tz, Incidence *incidence)
1351{
1352 readIncidenceBase(parent,incidence);
1353
1354 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
1355
1356 const char *text;
1357 int intvalue, inttext;
1358 icaltimetype icaltime;
1359 icaldurationtype icalduration;
1360
1361 TQStringList categories;
1362
1363 while (p) {
1364 icalproperty_kind kind = icalproperty_isa(p);
1365 switch (kind) {
1366
1367 case ICAL_CREATED_PROPERTY:
1368 icaltime = icalproperty_get_created(p);
1369 incidence->setCreated(readICalDateTime(p, icaltime, tz));
1370 break;
1371
1372 case ICAL_SEQUENCE_PROPERTY: // sequence
1373 intvalue = icalproperty_get_sequence(p);
1374 incidence->setRevision(intvalue);
1375 break;
1376
1377 case ICAL_LASTMODIFIED_PROPERTY: // last modification date
1378 icaltime = icalproperty_get_lastmodified(p);
1379 incidence->setLastModified(readICalDateTime(p, icaltime, tz));
1380 break;
1381
1382 case ICAL_DTSTART_PROPERTY: // start date and time
1383 icaltime = icalproperty_get_dtstart(p);
1384 if (icaltime.is_date) {
1385 incidence->setDtStart(TQDateTime(readICalDate(icaltime),TQTime(0,0,0)));
1386 incidence->setFloats( true );
1387 } else {
1388 incidence->setDtStart(readICalDateTime(p, icaltime, tz));
1389 incidence->setFloats( false );
1390 }
1391 break;
1392
1393 case ICAL_DURATION_PROPERTY: // start date and time
1394 icalduration = icalproperty_get_duration(p);
1395 incidence->setDuration(readICalDuration(icalduration));
1396 break;
1397
1398 case ICAL_DESCRIPTION_PROPERTY: // description
1399 text = icalproperty_get_description(p);
1400 incidence->setDescription(TQString::fromUtf8(text));
1401 break;
1402
1403 case ICAL_SUMMARY_PROPERTY: // summary
1404 text = icalproperty_get_summary(p);
1405 incidence->setSummary(TQString::fromUtf8(text));
1406 break;
1407
1408 case ICAL_LOCATION_PROPERTY: // location
1409 text = icalproperty_get_location(p);
1410 incidence->setLocation(TQString::fromUtf8(text));
1411 break;
1412
1413 case ICAL_STATUS_PROPERTY: { // status
1414 Incidence::Status stat;
1415 switch (icalproperty_get_status(p)) {
1416 case ICAL_STATUS_TENTATIVE: stat = Incidence::StatusTentative; break;
1417 case ICAL_STATUS_CONFIRMED: stat = Incidence::StatusConfirmed; break;
1418 case ICAL_STATUS_COMPLETED: stat = Incidence::StatusCompleted; break;
1419 case ICAL_STATUS_NEEDSACTION: stat = Incidence::StatusNeedsAction; break;
1420 case ICAL_STATUS_CANCELLED: stat = Incidence::StatusCanceled; break;
1421 case ICAL_STATUS_INPROCESS: stat = Incidence::StatusInProcess; break;
1422 case ICAL_STATUS_DRAFT: stat = Incidence::StatusDraft; break;
1423 case ICAL_STATUS_FINAL: stat = Incidence::StatusFinal; break;
1424 case ICAL_STATUS_X:
1425 incidence->setCustomStatus(TQString::fromUtf8(icalvalue_get_x(icalproperty_get_value(p))));
1426 stat = Incidence::StatusX;
1427 break;
1428 case ICAL_STATUS_NONE:
1429 default: stat = Incidence::StatusNone; break;
1430 }
1431 if (stat != Incidence::StatusX)
1432 incidence->setStatus(stat);
1433 break;
1434 }
1435
1436 case ICAL_PRIORITY_PROPERTY: // priority
1437 intvalue = icalproperty_get_priority( p );
1438 if ( mCompat )
1439 intvalue = mCompat->fixPriority( intvalue );
1440 incidence->setPriority( intvalue );
1441 break;
1442
1443 case ICAL_CATEGORIES_PROPERTY: // categories
1444 text = icalproperty_get_categories(p);
1445 categories.append(TQString::fromUtf8(text));
1446 break;
1447
1448 case ICAL_RECURRENCEID_PROPERTY: // recurrenceID
1449 icaltime = icalproperty_get_recurrenceid(p);
1450 incidence->setRecurrenceID( readICalDateTime( p, icaltime ) );
1451 incidence->setHasRecurrenceID( true );
1452 break;
1453
1454 case ICAL_RRULE_PROPERTY:
1455 readRecurrenceRule( p, incidence );
1456 break;
1457
1458// case ICAL_CONTACT_PROPERTY:
1459// incidenceBase->addContact(
1460// TQString::fromUtf8( icalproperty_get_contact( p ) ) );
1461// break;
1462
1463 case ICAL_RDATE_PROPERTY: {
1464 icaldatetimeperiodtype rd = icalproperty_get_rdate( p );
1465 if ( icaltime_is_valid_time( rd.time ) ) {
1466 if ( icaltime_is_date( rd.time ) ) {
1467 incidence->recurrence()->addRDate( readICalDate( rd.time ) );
1468 } else {
1469 incidence->recurrence()->addRDateTime( readICalDateTime(p, rd.time, tz ) );
1470 }
1471 } else {
1472 // TODO: RDates as period are not yet implemented!
1473 }
1474 break; }
1475
1476 case ICAL_EXRULE_PROPERTY:
1477 readExceptionRule( p, incidence );
1478 break;
1479
1480 case ICAL_EXDATE_PROPERTY:
1481 icaltime = icalproperty_get_exdate(p);
1482 if ( icaltime_is_date(icaltime) ) {
1483 incidence->recurrence()->addExDate( readICalDate(icaltime) );
1484 } else {
1485 incidence->recurrence()->addExDateTime( readICalDateTime(p, icaltime, tz) );
1486 }
1487 break;
1488
1489 case ICAL_CLASS_PROPERTY:
1490 inttext = icalproperty_get_class(p);
1491 if (inttext == ICAL_CLASS_PUBLIC ) {
1492 incidence->setSecrecy(Incidence::SecrecyPublic);
1493 } else if (inttext == ICAL_CLASS_CONFIDENTIAL ) {
1494 incidence->setSecrecy(Incidence::SecrecyConfidential);
1495 } else {
1496 incidence->setSecrecy(Incidence::SecrecyPrivate);
1497 }
1498 break;
1499
1500 case ICAL_ATTACH_PROPERTY: // attachments
1501 incidence->addAttachment(readAttachment(p));
1502 break;
1503
1504 default:
1505// kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind
1506// << endl;
1507 break;
1508 }
1509
1510 p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY);
1511 }
1512
1513 // Set the scheduling ID
1514 const TQString uid = incidence->customProperty( "LIBKCAL", "ID" );
1515 if ( !uid.isNull() ) {
1516 // The UID stored in incidencebase is actually the scheduling ID
1517 // It has to be stored in the iCal UID component for compatibility
1518 // with other iCal applications
1519 incidence->setSchedulingID( incidence->uid() );
1520 incidence->setUid( uid );
1521 }
1522
1523 // Now that recurrence and exception stuff is completely set up,
1524 // do any backwards compatibility adjustments.
1525 if ( incidence->doesRecur() && mCompat )
1526 mCompat->fixRecurrence( incidence );
1527
1528 // add categories
1529 incidence->setCategories(categories);
1530
1531 // iterate through all alarms
1532 for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT);
1533 alarm;
1534 alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) {
1535 readAlarm(alarm,incidence);
1536 }
1537 // Fix incorrect alarm settings by other applications (like outloook 9)
1538 if ( mCompat ) mCompat->fixAlarms( incidence );
1539
1540}
1541
1542void ICalFormatImpl::readIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase)
1543{
1544 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY);
1545
1546 bool uidProcessed = false;
1547
1548 while ( p ) {
1549 icalproperty_kind kind = icalproperty_isa( p );
1550 switch (kind) {
1551
1552 case ICAL_UID_PROPERTY: // unique id
1553 uidProcessed = true;
1554 incidenceBase->setUid( TQString::fromUtf8(icalproperty_get_uid( p ) ) );
1555 break;
1556
1557 case ICAL_ORGANIZER_PROPERTY: // organizer
1558 incidenceBase->setOrganizer( readOrganizer( p ) );
1559 break;
1560
1561 case ICAL_ATTENDEE_PROPERTY: // attendee
1562 incidenceBase->addAttendee( readAttendee( p ) );
1563 break;
1564
1565 case ICAL_COMMENT_PROPERTY:
1566 incidenceBase->addComment(
1567 TQString::fromUtf8( icalproperty_get_comment( p ) ) );
1568 break;
1569
1570 default:
1571 break;
1572 }
1573
1574 p = icalcomponent_get_next_property( parent, ICAL_ANY_PROPERTY );
1575 }
1576
1577 if ( !uidProcessed ) {
1578 kdWarning() << "The incidence didn't have any UID! Report a bug "
1579 << "to the application that generated this file."
1580 << endl;
1581
1582 // Our in-memory incidence has a random uid generated in Event's ctor.
1583 // Make it empty so it matches what's in the file:
1584 incidenceBase->setUid( TQString() );
1585
1586 // Otherwise, next time we read the file, this function will return
1587 // an event with another random uid and we will have two events in the calendar.
1588 }
1589
1590 // kpilot stuff
1591 // TODO: move this application-specific code to kpilot
1592 // need to get X-PILOT* attributes out, set correct properties, and get
1593 // rid of them...
1594 // Pointer fun, as per libical documentation
1595 // (documented in UsingLibical.txt)
1596 icalproperty *next =0;
1597
1598 for ( p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY);
1599 p != 0;
1600 p = next )
1601 {
1602
1603 next = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY);
1604
1605 TQString value = TQString::fromUtf8(icalproperty_get_x(p));
1606 TQString name = icalproperty_get_x_name(p);
1607
1608 if (name == "X-PILOTID" && !value.isEmpty()) {
1609 incidenceBase->setPilotId(value.toInt());
1610 icalcomponent_remove_property(parent,p);
1611 } else if (name == "X-PILOTSTAT" && !value.isEmpty()) {
1612 incidenceBase->setSyncStatus(value.toInt());
1613 icalcomponent_remove_property(parent,p);
1614 }
1615 }
1616
1617 // custom properties
1618 readCustomProperties(parent, incidenceBase);
1619}
1620
1621void ICalFormatImpl::readCustomProperties(icalcomponent *parent,CustomProperties *properties)
1622{
1623 TQMap<TQCString, TQString> customProperties;
1624 TQString lastProperty;
1625
1626 icalproperty *p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY);
1627
1628 while (p) {
1629
1630 TQString value = TQString::fromUtf8(icalproperty_get_x(p));
1631 const char *name = icalproperty_get_x_name(p);
1632 if ( lastProperty != name ) {
1633 customProperties[name] = value;
1634 } else {
1635 customProperties[name] = customProperties[name].append( "," ).append( value );
1636 }
1637 // kdDebug(5800) << "Set custom property [" << name << '=' << value << ']' << endl;
1638 p = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY);
1639 lastProperty = name;
1640 }
1641
1642 properties->setCustomProperties(customProperties);
1643}
1644
1645
1646
1647void ICalFormatImpl::readRecurrenceRule(icalproperty *rrule,Incidence *incidence )
1648{
1649// kdDebug(5800) << "Read recurrence for " << incidence->summary() << endl;
1650
1651 Recurrence *recur = incidence->recurrence();
1652
1653 struct icalrecurrencetype r = icalproperty_get_rrule(rrule);
1654// dumpIcalRecurrence(r);
1655
1656 RecurrenceRule *recurrule = new RecurrenceRule( /*incidence*/ );
1657 recurrule->setStartDt( incidence->dtStart() );
1658 readRecurrence( r, recurrule );
1659 recur->addRRule( recurrule );
1660}
1661
1662void ICalFormatImpl::readExceptionRule( icalproperty *rrule, Incidence *incidence )
1663{
1664// kdDebug(5800) << "Read recurrence for " << incidence->summary() << endl;
1665
1666 struct icalrecurrencetype r = icalproperty_get_exrule(rrule);
1667// dumpIcalRecurrence(r);
1668
1669 RecurrenceRule *recurrule = new RecurrenceRule( /*incidence*/ );
1670 recurrule->setStartDt( incidence->dtStart() );
1671 readRecurrence( r, recurrule );
1672
1673 Recurrence *recur = incidence->recurrence();
1674 recur->addExRule( recurrule );
1675}
1676
1677void ICalFormatImpl::readRecurrence( const struct icalrecurrencetype &r, RecurrenceRule* recur )
1678{
1679 // Generate the RRULE string
1680 recur->mRRule = TQString( icalrecurrencetype_as_string( const_cast<struct icalrecurrencetype*>(&r) ) );
1681 // Period
1682 switch ( r.freq ) {
1683 case ICAL_SECONDLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rSecondly ); break;
1684 case ICAL_MINUTELY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rMinutely ); break;
1685 case ICAL_HOURLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rHourly ); break;
1686 case ICAL_DAILY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rDaily ); break;
1687 case ICAL_WEEKLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rWeekly ); break;
1688 case ICAL_MONTHLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rMonthly ); break;
1689 case ICAL_YEARLY_RECURRENCE: recur->setRecurrenceType( RecurrenceRule::rYearly ); break;
1690 case ICAL_NO_RECURRENCE:
1691 default:
1692 recur->setRecurrenceType( RecurrenceRule::rNone );
1693 }
1694 // Frequency
1695 recur->setFrequency( r.interval );
1696
1697 // Duration & End Date
1698 if ( !icaltime_is_null_time( r.until ) ) {
1699 icaltimetype t;
1700 t = r.until;
1701 // Convert to the correct time zone! it's in UTC by specification.
1702 TQDateTime endDate( readICalDateTime(0, t) );
1703 recur->setEndDt( endDate );
1704 } else {
1705 if (r.count == 0)
1706 recur->setDuration( -1 );
1707 else
1708 recur->setDuration( r.count );
1709 }
1710
1711 // Week start setting
1712 int wkst = (r.week_start + 5)%7 + 1;
1713 recur->setWeekStart( wkst );
1714
1715 // And now all BY*
1716 TQValueList<int> lst;
1717 int i;
1718 int index = 0;
1719
1720#define readSetByList(rrulecomp,setfunc) \
1721 index = 0; \
1722 lst.clear(); \
1723 while ( (i = r.rrulecomp[index++] ) != ICAL_RECURRENCE_ARRAY_MAX ) \
1724 lst.append( i ); \
1725 if ( !lst.isEmpty() ) recur->setfunc( lst );
1726
1727 // BYSECOND, MINUTE and HOUR, MONTHDAY, YEARDAY, WEEKNUMBER, MONTH
1728 // and SETPOS are standard int lists, so we can treat them with the
1729 // same macro
1730 readSetByList( by_second, setBySeconds );
1731 readSetByList( by_minute, setByMinutes );
1732 readSetByList( by_hour, setByHours );
1733 readSetByList( by_month_day, setByMonthDays );
1734 readSetByList( by_year_day, setByYearDays );
1735 readSetByList( by_week_no, setByWeekNumbers );
1736 readSetByList( by_month, setByMonths );
1737 readSetByList( by_set_pos, setBySetPos );
1738#undef readSetByList
1739
1740 // BYDAY is a special case, since it's not an int list
1741 TQValueList<RecurrenceRule::WDayPos> wdlst;
1742 short day;
1743 index=0;
1744 while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
1746 pos.setDay( ( icalrecurrencetype_day_day_of_week( day ) + 5 )%7 + 1 );
1747 pos.setPos( icalrecurrencetype_day_position( day ) );
1748// kdDebug(5800)<< " o) By day, index="<<index-1<<", pos="<<pos.Pos<<", day="<<pos.Day<<endl;
1749 wdlst.append( pos );
1750 }
1751 if ( !wdlst.isEmpty() ) recur->setByDays( wdlst );
1752
1753
1754 // TODO Store all X- fields of the RRULE inside the recurrence (so they are
1755 // preserved
1756}
1757
1758
1759void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence)
1760{
1761// kdDebug(5800) << "Read alarm for " << incidence->summary() << endl;
1762
1763 Alarm* ialarm = incidence->newAlarm();
1764 ialarm->setRepeatCount(0);
1765 ialarm->setEnabled(true);
1766
1767 // Determine the alarm's action type
1768 icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ACTION_PROPERTY);
1769 Alarm::Type type = Alarm::Display;
1770 icalproperty_action action = ICAL_ACTION_DISPLAY;
1771 if ( !p ) {
1772 kdDebug(5800) << "Unknown type of alarm, using default" << endl;
1773// return;
1774 } else {
1775
1776 action = icalproperty_get_action(p);
1777 switch ( action ) {
1778 case ICAL_ACTION_DISPLAY: type = Alarm::Display; break;
1779 case ICAL_ACTION_AUDIO: type = Alarm::Audio; break;
1780 case ICAL_ACTION_PROCEDURE: type = Alarm::Procedure; break;
1781 case ICAL_ACTION_EMAIL: type = Alarm::Email; break;
1782 default:
1783 kdDebug(5800) << "Unknown type of alarm: " << action << endl;
1784// type = Alarm::Invalid;
1785 }
1786 }
1787 ialarm->setType(type);
1788// kdDebug(5800) << " alarm type =" << type << endl;
1789
1790 p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY);
1791 while (p) {
1792 icalproperty_kind kind = icalproperty_isa(p);
1793
1794 switch (kind) {
1795
1796 case ICAL_TRIGGER_PROPERTY: {
1797 icaltriggertype trigger = icalproperty_get_trigger(p);
1798 if (icaltime_is_null_time(trigger.time)) {
1799 if (icaldurationtype_is_null_duration(trigger.duration)) {
1800 kdDebug(5800) << "ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl;
1801 } else {
1802 Duration duration = icaldurationtype_as_int( trigger.duration );
1803 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_RELATED_PARAMETER);
1804 if (param && icalparameter_get_related(param) == ICAL_RELATED_END)
1805 ialarm->setEndOffset(duration);
1806 else
1807 ialarm->setStartOffset(duration);
1808 }
1809 } else {
1810 ialarm->setTime(readICalDateTime(p, trigger.time));
1811 }
1812 break;
1813 }
1814 case ICAL_DURATION_PROPERTY: {
1815 icaldurationtype duration = icalproperty_get_duration(p);
1816 ialarm->setSnoozeTime( readICalDuration( duration ) );
1817 break;
1818 }
1819 case ICAL_REPEAT_PROPERTY:
1820 ialarm->setRepeatCount(icalproperty_get_repeat(p));
1821 break;
1822
1823 // Only in DISPLAY and EMAIL and PROCEDURE alarms
1824 case ICAL_DESCRIPTION_PROPERTY: {
1825 TQString description = TQString::fromUtf8(icalproperty_get_description(p));
1826 switch ( action ) {
1827 case ICAL_ACTION_DISPLAY:
1828 ialarm->setText( description );
1829 break;
1830 case ICAL_ACTION_PROCEDURE:
1831 ialarm->setProgramArguments( description );
1832 break;
1833 case ICAL_ACTION_EMAIL:
1834 ialarm->setMailText( description );
1835 break;
1836 default:
1837 break;
1838 }
1839 break;
1840 }
1841 // Only in EMAIL alarm
1842 case ICAL_SUMMARY_PROPERTY:
1843 ialarm->setMailSubject(TQString::fromUtf8(icalproperty_get_summary(p)));
1844 break;
1845
1846 // Only in EMAIL alarm
1847 case ICAL_ATTENDEE_PROPERTY: {
1848 TQString email = TQString::fromUtf8(icalproperty_get_attendee(p));
1849 if ( email.startsWith("mailto:", false ) ) {
1850 email = email.mid( 7 );
1851 }
1852 TQString name;
1853 icalparameter *param = icalproperty_get_first_parameter(p,ICAL_CN_PARAMETER);
1854 if (param) {
1855 name = TQString::fromUtf8(icalparameter_get_cn(param));
1856 }
1857 ialarm->addMailAddress(Person(name, email));
1858 break;
1859 }
1860 // Only in AUDIO and EMAIL and PROCEDURE alarms
1861 case ICAL_ATTACH_PROPERTY: {
1862 Attachment *attach = readAttachment( p );
1863 if ( attach && attach->isUri() ) {
1864 switch ( action ) {
1865 case ICAL_ACTION_AUDIO:
1866 ialarm->setAudioFile( attach->uri() );
1867 break;
1868 case ICAL_ACTION_PROCEDURE:
1869 ialarm->setProgramFile( attach->uri() );
1870 break;
1871 case ICAL_ACTION_EMAIL:
1872 ialarm->addMailAttachment( attach->uri() );
1873 break;
1874 default:
1875 break;
1876 }
1877 } else {
1878 kdDebug() << "Alarm attachments currently only support URIs, but "
1879 "no binary data" << endl;
1880 }
1881 delete attach;
1882 break;
1883 }
1884 default:
1885 break;
1886 }
1887
1888 p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY);
1889 }
1890
1891 // custom properties
1892 readCustomProperties(alarm, ialarm);
1893
1894 // TODO: check for consistency of alarm properties
1895}
1896
1897icaldatetimeperiodtype ICalFormatImpl::writeICalDatePeriod( const TQDate &date )
1898{
1899 icaldatetimeperiodtype t;
1900 t.time = writeICalDate( date );
1901 t.period = icalperiodtype_null_period();
1902 return t;
1903}
1904
1905icaldatetimeperiodtype ICalFormatImpl::writeICalDateTimePeriod( const TQDateTime &date )
1906{
1907 icaldatetimeperiodtype t;
1908 t.time = writeICalDateTime( date );
1909 t.period = icalperiodtype_null_period();
1910 return t;
1911}
1912
1913icaltimetype ICalFormatImpl::writeICalDate(const TQDate &date)
1914{
1915 icaltimetype t = icaltime_null_time();
1916
1917 t.year = date.year();
1918 t.month = date.month();
1919 t.day = date.day();
1920
1921 t.hour = 0;
1922 t.minute = 0;
1923 t.second = 0;
1924
1925 t.is_date = 1;
1926#ifndef USE_LIBICAL_3_0
1927 t.is_utc = 0;
1928#endif
1929 t.zone = 0;
1930
1931 return t;
1932}
1933
1934icaltimetype ICalFormatImpl::writeICalDateTime(const TQDateTime &datetime)
1935{
1936 icaltimetype t = icaltime_null_time();
1937
1938 t.year = datetime.date().year();
1939 t.month = datetime.date().month();
1940 t.day = datetime.date().day();
1941
1942 t.hour = datetime.time().hour();
1943 t.minute = datetime.time().minute();
1944 t.second = datetime.time().second();
1945
1946 t.is_date = 0;
1947 t.zone = icaltimezone_get_builtin_timezone ( mParent->timeZoneId().latin1() );
1948#ifndef USE_LIBICAL_3_0
1949 t.is_utc = 0;
1950#endif
1951
1952 // _dumpIcaltime( t );
1953 /* The TQDateTime we get passed in is to be considered in the timezone of
1954 * the current calendar (mParent's), or, if there is none, to be floating.
1955 * In the later case store a floating time, in the former normalize to utc. */
1956 if (mParent->timeZoneId().isEmpty())
1957 t = icaltime_convert_to_zone( t, 0 ); //make floating timezone
1958 else {
1959 icaltimezone* tz = icaltimezone_get_builtin_timezone ( mParent->timeZoneId().latin1() );
1960 icaltimezone* utc = icaltimezone_get_utc_timezone();
1961 if ( tz != utc ) {
1962 t.zone = tz;
1963 t = icaltime_convert_to_zone( t, utc );
1964 } else {
1965#ifndef USE_LIBICAL_3_0
1966 t.is_utc = 1;
1967#endif
1968 t.zone = utc;
1969 }
1970 }
1971// _dumpIcaltime( t );
1972
1973 return t;
1974}
1975
1976TQDateTime ICalFormatImpl::readICalDateTime( icalproperty *p, icaltimetype& t, icaltimezone* tz )
1977{
1978// kdDebug(5800) << "ICalFormatImpl::readICalDateTime()" << endl;
1979#ifdef USE_LIBICAL_3_0
1980 bool time_is_utc = icaltime_is_utc(t);
1981#else
1982 bool time_is_utc = t.is_utc;
1983#endif
1984 if ( !time_is_utc ) { // Only use the TZ if time is not UTC.{
1985 // FIXME: We'll need to make sure to apply the appropriate TZ, not just
1986 // the first one found.
1987 icalparameter *param = p ? icalproperty_get_first_parameter(p, ICAL_TZID_PARAMETER) : 0;
1988 const char *tzid = param ? icalparameter_get_tzid(param) : 0;
1989 if ( tzid ) {
1990 icaltimezone* icaltz;
1991 // Try to match the ID with the libical time zone's location property
1992 icaltz = icaltimezone_get_builtin_timezone( tzid );
1993 if ( icaltz ) {
1994 //kdDebug(5800) << "ICalFormatImpl::readICalDateTime(): time zone '" << tzid << "' read from libical database" << endl;
1995 }
1996 t.zone = icaltz;
1997 }
1998 else {
1999 if (tz && tz != icaltimezone_get_utc_timezone()) {
2000#ifndef USE_LIBICAL_3_0
2001 t.is_utc = 0;
2002#endif
2003 t.zone = tz;
2004 }
2005 else {
2006#ifndef USE_LIBICAL_3_0
2007 t.is_utc = 1;
2008#endif
2009 t.zone = icaltimezone_get_utc_timezone();
2010 }
2011 }
2012 } else {
2013 t.zone = icaltimezone_get_utc_timezone();
2014 }
2015 //_dumpIcaltime( t );
2016
2017 // Convert to view time
2018 if ( !mParent->timeZoneId().isEmpty() && t.zone ) {
2019// kdDebug(5800) << "--- Converting time from: " << icaltimezone_get_tzid( const_cast<icaltimezone*>( t.zone ) ) << " (" << ICalDate2TQDate(t) << ")." << endl;
2020 icaltimezone* viewTimeZone = icaltimezone_get_builtin_timezone ( mParent->timeZoneId().latin1() );
2021 icaltimezone_convert_time( &t, const_cast<icaltimezone*>(t.zone), viewTimeZone );
2022// kdDebug(5800) << "--- Converted to zone " << mParent->timeZoneId() << " (" << ICalDate2TQDate(t) << ")." << endl;
2023 }
2024
2025 return ICalDate2TQDate(t);
2026}
2027
2028TQDate ICalFormatImpl::readICalDate(icaltimetype t)
2029{
2030 return ICalDate2TQDate(t).date();
2031}
2032
2033icaldurationtype ICalFormatImpl::writeICalDuration(int seconds)
2034{
2035 // should be able to use icaldurationtype_from_int(), except we know
2036 // that some older tools do not properly support weeks. So we never
2037 // set a week duration, only days
2038
2039 icaldurationtype d;
2040
2041 d.is_neg = (seconds<0)?1:0;
2042 if (seconds<0) seconds = -seconds;
2043
2044 d.weeks = 0;
2045 d.days = seconds / gSecondsPerDay;
2046 seconds %= gSecondsPerDay;
2047 d.hours = seconds / gSecondsPerHour;
2048 seconds %= gSecondsPerHour;
2049 d.minutes = seconds / gSecondsPerMinute;
2050 seconds %= gSecondsPerMinute;
2051 d.seconds = seconds;
2052
2053 return d;
2054}
2055
2056int ICalFormatImpl::readICalDuration(icaldurationtype d)
2057{
2058 int result = 0;
2059
2060 result += d.weeks * gSecondsPerWeek;
2061 result += d.days * gSecondsPerDay;
2062 result += d.hours * gSecondsPerHour;
2063 result += d.minutes * gSecondsPerMinute;
2064 result += d.seconds;
2065
2066 if (d.is_neg) result *= -1;
2067
2068 return result;
2069}
2070
2071icalcomponent *ICalFormatImpl::createCalendarComponent(Calendar *cal)
2072{
2073 icalcomponent *calendar;
2074
2075 // Root component
2076 calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
2077
2078 icalproperty *p;
2079
2080 // Product Identifier
2081 p = icalproperty_new_prodid(CalFormat::productId().utf8());
2082 icalcomponent_add_property(calendar,p);
2083
2084 // TODO: Add time zone
2085
2086 // iCalendar version (2.0)
2087 p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION));
2088 icalcomponent_add_property(calendar,p);
2089
2090 // Custom properties
2091 if( cal != 0 )
2092 writeCustomProperties(calendar, cal);
2093
2094 return calendar;
2095}
2096
2097
2098
2099// take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
2100// and break it down from its tree-like format into the dictionary format
2101// that is used internally in the ICalFormatImpl.
2102bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar )
2103{
2104 // this function will populate the caldict dictionary and other event
2105 // lists. It turns vevents into Events and then inserts them.
2106
2107 if (!calendar) return false;
2108
2109// TODO: check for METHOD
2110
2111 icalproperty *p;
2112
2113 p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY);
2114 if (!p) {
2115 kdDebug(5800) << "No PRODID property found" << endl;
2116 mLoadedProductId = "";
2117 } else {
2118 mLoadedProductId = TQString::fromUtf8(icalproperty_get_prodid(p));
2119// kdDebug(5800) << "VCALENDAR prodid: '" << mLoadedProductId << "'" << endl;
2120
2121 delete mCompat;
2122 mCompat = CompatFactory::createCompat( mLoadedProductId );
2123 }
2124
2125 p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY);
2126 if (!p) {
2127 kdDebug(5800) << "No VERSION property found" << endl;
2128 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
2129 return false;
2130 } else {
2131 const char *version = icalproperty_get_version(p);
2132 if ( !version ) {
2133 kdDebug(5800) << "No VERSION property found" << endl;
2134 mParent->setException( new ErrorFormat(
2135 ErrorFormat::CalVersionUnknown,
2136 i18n( "No VERSION property found" ) ) );
2137 return false;
2138 }
2139
2140// kdDebug(5800) << "VCALENDAR version: '" << version << "'" << endl;
2141
2142 if (strcmp(version,"1.0") == 0) {
2143 kdDebug(5800) << "Expected iCalendar, got vCalendar" << endl;
2144 mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1,
2145 i18n("Expected iCalendar format")));
2146 return false;
2147 } else if (strcmp(version,"2.0") != 0) {
2148 kdDebug(5800) << "Expected iCalendar, got unknown format" << endl;
2149 mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown));
2150 return false;
2151 }
2152 }
2153
2154 // custom properties
2155 readCustomProperties(calendar, cal);
2156
2157// TODO: set time zone
2158
2159 // read a VTIMEZONE if there is one
2160 icalcomponent *ctz =
2161 icalcomponent_get_first_component( calendar, ICAL_VTIMEZONE_COMPONENT );
2162
2163 // Store all events with a relatedTo property in a list for post-processing
2164 mEventsRelate.clear();
2165 mTodosRelate.clear();
2166 // TODO: make sure that only actually added events go to this lists.
2167
2168 icalcomponent *c;
2169
2170 // Iterate through all todos
2171 c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT);
2172 while (c) {
2173// kdDebug(5800) << "----Todo found" << endl;
2174 Todo *todo = readTodo(c);
2175 if (todo) {
2176 if (todo->hasRecurrenceID()) {
2177 TQString originalUid = todo->uid();
2178 todo->setUid(originalUid + TQString("-recur-%1").arg(todo->recurrenceID().toTime_t()));
2179 if (!cal->todo(todo->uid())) {
2180 if ( !cal->addTodo( todo ) ) {
2181 cal->endBatchAdding();
2182 // If the user pressed cancel, return true, it's not an error.
2183 return cal->exception() && cal->exception()->errorCode() == ErrorFormat::UserCancel;
2184 }
2185 if (!cal->event(originalUid)) {
2186 printf("FIXME! [WARNING] Parent for child event does not yet exist!\n");
2187 }
2188 else {
2189 // Add this todo to its parent
2190 cal->todo(originalUid)->addChildIncidence(todo->uid());
2191 // And the parent to the child
2192 todo->addChildIncidence(cal->todo(originalUid)->uid());
2193 }
2194 }
2195 }
2196 else {
2197 if (!cal->todo(todo->uid())) {
2198 if ( !cal->addTodo( todo ) ) {
2199 cal->endBatchAdding();
2200 // If the user pressed cancel, return true, it's not an error.
2201 return cal->exception() && cal->exception()->errorCode() == ErrorFormat::UserCancel;
2202 }
2203 } else {
2204 delete todo;
2205 mTodosRelate.remove( todo );
2206 }
2207 }
2208 }
2209 c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT);
2210 }
2211
2212 // Iterate through all events
2213 c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT);
2214 while (c) {
2215// kdDebug(5800) << "----Event found" << endl;
2216 Event *event = readEvent(c, ctz);
2217 if (event) {
2218 if (event->hasRecurrenceID()) {
2219 TQString originalUid = event->uid();
2220 event->setUid(originalUid + TQString("-recur-%1").arg(event->recurrenceID().toTime_t()));
2221 if (!cal->event(event->uid())) {
2222 cal->addEvent(event);
2223 if (!cal->event(originalUid)) {
2224 printf("FIXME! [WARNING] Parent for child event does not yet exist!\n");
2225 }
2226 else {
2227 // Add this event to its parent
2228 cal->event(originalUid)->addChildIncidence(event->uid());
2229 // And the parent to the child
2230 event->addChildIncidence(cal->event(originalUid)->uid());
2231 }
2232 }
2233 }
2234 else {
2235 if (!cal->event(event->uid())) {
2236 if ( !cal->addEvent( event ) ) {
2237 cal->endBatchAdding();
2238 // If the user pressed cancel, return true, it's not an error.
2239 return cal->exception() && cal->exception()->errorCode() == ErrorFormat::UserCancel;
2240 }
2241 } else {
2242 delete event;
2243 mEventsRelate.remove( event );
2244 }
2245 }
2246 }
2247 c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT);
2248 }
2249
2250 // Iterate through all journals
2251 c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT);
2252 while (c) {
2253// kdDebug(5800) << "----Journal found" << endl;
2254 Journal *journal = readJournal(c);
2255 if (journal) {
2256 if (journal->hasRecurrenceID()) {
2257 TQString originalUid = journal->uid();
2258 journal->setUid(originalUid + TQString("-recur-%1").arg(journal->recurrenceID().toTime_t()));
2259 if (!cal->journal(journal->uid())) {
2260 cal->addJournal(journal);
2261 if (!cal->event(originalUid)) {
2262 printf("FIXME! [WARNING] Parent for child event does not yet exist!\n");
2263 }
2264 else {
2265 // Add this journal to its parent
2266 cal->journal(originalUid)->addChildIncidence(journal->uid());
2267 // And the parent to the child
2268 journal->addChildIncidence(cal->journal(originalUid)->uid());
2269 }
2270 }
2271 }
2272 else {
2273 if (!cal->journal(journal->uid())) {
2274 if ( !cal->addJournal(journal) ) {
2275 cal->endBatchAdding();
2276 // If the user pressed cancel, return true, it's not an error.
2277 return cal->exception() && cal->exception()->errorCode() == ErrorFormat::UserCancel;
2278 }
2279 } else {
2280 delete journal;
2281 }
2282 }
2283 }
2284 c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT);
2285 }
2286
2287 cal->endBatchAdding();
2288
2289 // Post-Process list of events with relations, put Event objects in relation
2290 Event::List::ConstIterator eIt;
2291 for ( eIt = mEventsRelate.begin(); eIt != mEventsRelate.end(); ++eIt ) {
2292 (*eIt)->setRelatedTo( cal->incidence( (*eIt)->relatedToUid() ) );
2293 }
2294 Todo::List::ConstIterator tIt;
2295 for ( tIt = mTodosRelate.begin(); tIt != mTodosRelate.end(); ++tIt ) {
2296 (*tIt)->setRelatedTo( cal->incidence( (*tIt)->relatedToUid() ) );
2297 }
2298
2299 return true;
2300}
2301
2302TQString ICalFormatImpl::extractErrorProperty(icalcomponent *c)
2303{
2304// kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: "
2305// << icalcomponent_as_ical_string(c) << endl;
2306
2307 TQString errorMessage;
2308
2309 icalproperty *error;
2310 error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY);
2311 while(error) {
2312 errorMessage += icalproperty_get_xlicerror(error);
2313 errorMessage += "\n";
2314 error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY);
2315 }
2316
2317// kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " << errorMessage << endl;
2318
2319 return errorMessage;
2320}
2321
2322void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r)
2323{
2324 int i;
2325
2326 kdDebug(5800) << " Freq: " << r.freq << endl;
2327 kdDebug(5800) << " Until: " << icaltime_as_ical_string(r.until) << endl;
2328 kdDebug(5800) << " Count: " << r.count << endl;
2329 if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2330 int index = 0;
2331 TQString out = " By Day: ";
2332 while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2333 out.append(TQString::number(i) + " ");
2334 }
2335 kdDebug(5800) << out << endl;
2336 }
2337 if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2338 int index = 0;
2339 TQString out = " By Month Day: ";
2340 while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2341 out.append(TQString::number(i) + " ");
2342 }
2343 kdDebug(5800) << out << endl;
2344 }
2345 if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2346 int index = 0;
2347 TQString out = " By Year Day: ";
2348 while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2349 out.append(TQString::number(i) + " ");
2350 }
2351 kdDebug(5800) << out << endl;
2352 }
2353 if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2354 int index = 0;
2355 TQString out = " By Month: ";
2356 while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2357 out.append(TQString::number(i) + " ");
2358 }
2359 kdDebug(5800) << out << endl;
2360 }
2361 if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) {
2362 int index = 0;
2363 TQString out = " By Set Pos: ";
2364 while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) {
2365 kdDebug(5800) << "========= " << i << endl;
2366 out.append(TQString::number(i) + " ");
2367 }
2368 kdDebug(5800) << out << endl;
2369 }
2370}
2371
2372icalcomponent *ICalFormatImpl::createScheduleComponent(IncidenceBase *incidence,
2373 Scheduler::Method method)
2374{
2375 icalcomponent *message = createCalendarComponent();
2376
2377 icalproperty_method icalmethod = ICAL_METHOD_NONE;
2378
2379 switch (method) {
2380 case Scheduler::Publish:
2381 icalmethod = ICAL_METHOD_PUBLISH;
2382 break;
2383 case Scheduler::Request:
2384 icalmethod = ICAL_METHOD_REQUEST;
2385 break;
2386 case Scheduler::Refresh:
2387 icalmethod = ICAL_METHOD_REFRESH;
2388 break;
2389 case Scheduler::Cancel:
2390 icalmethod = ICAL_METHOD_CANCEL;
2391 break;
2392 case Scheduler::Add:
2393 icalmethod = ICAL_METHOD_ADD;
2394 break;
2395 case Scheduler::Reply:
2396 icalmethod = ICAL_METHOD_REPLY;
2397 break;
2398 case Scheduler::Counter:
2399 icalmethod = ICAL_METHOD_COUNTER;
2400 break;
2401 case Scheduler::Declinecounter:
2402 icalmethod = ICAL_METHOD_DECLINECOUNTER;
2403 break;
2404 default:
2405 kdDebug(5800) << "ICalFormat::createScheduleMessage(): Unknow method" << endl;
2406 return message;
2407 }
2408
2409 icalcomponent_add_property(message,icalproperty_new_method(icalmethod));
2410
2411 icalcomponent *inc = writeIncidence( incidence, method );
2412 /*
2413 * RFC 2446 states in section 3.4.3 ( REPLY to a VTODO ), that
2414 * a REQUEST-STATUS property has to be present. For the other two, event and
2415 * free busy, it can be there, but is optional. Until we do more
2416 * fine grained handling, assume all is well. Note that this is the
2417 * status of the _request_, not the attendee. Just to avoid confusion.
2418 * - till
2419 */
2420 if ( icalmethod == ICAL_METHOD_REPLY ) {
2421 struct icalreqstattype rst;
2422 rst.code = ICAL_2_0_SUCCESS_STATUS;
2423 rst.desc = 0;
2424 rst.debug = 0;
2425 icalcomponent_add_property( inc, icalproperty_new_requeststatus( rst ) );
2426 }
2427 icalcomponent_add_component( message, inc );
2428
2429 return message;
2430}
Provides the main "calendar" object class.
This class represents an alarm notification.
Definition: alarm.h:46
bool hasStartOffset() const
Return whether the alarm is defined in terms of an offset relative to the start of the event.
Definition: alarm.cpp:456
TQString audioFile() const
Return the name of the audio file for the alarm.
Definition: alarm.cpp:164
Duration snoozeTime() const
Get how long the alarm snooze interval is.
Definition: alarm.cpp:362
void setMailSubject(const TQString &mailAlarmSubject)
Set the subject line of the mail.
Definition: alarm.cpp:244
TQString programFile() const
Return the name of the program file to execute when the alarm is triggered.
Definition: alarm.cpp:185
void addMailAttachment(const TQString &mailAttachFile)
Add this filename to the list of files to attach to the email.
Definition: alarm.cpp:274
void setRepeatCount(int alarmRepeatCount)
Set how many times an alarm is to repeat itself after its initial occurrence (w/snoozes).
Definition: alarm.cpp:367
TQString mailSubject() const
Return the subject line of the mail.
Definition: alarm.cpp:252
TQDateTime time() const
Return the date/time when an alarm goes off.
Definition: alarm.cpp:329
TQString text() const
Return the text string that displays when the alarm is triggered.
Definition: alarm.cpp:316
void setEnabled(bool enable)
Set the alarm enabled status.
Definition: alarm.cpp:432
void addMailAddress(const Person &mailAlarmAddress)
Add this address to the list of addresses to send mail to when the alarm is triggered.
Definition: alarm.cpp:231
Duration endOffset() const
Return offset of alarm in time relative to the end of the event.
Definition: alarm.cpp:474
bool hasEndOffset() const
Return whether the alarm is defined in terms of an offset relative to the end of the event.
Definition: alarm.cpp:461
Duration startOffset() const
Return offset of alarm in time relative to the start of the event.
Definition: alarm.cpp:451
void setSnoozeTime(const Duration &alarmSnoozeTime)
Set the interval between snoozes for the alarm.
Definition: alarm.cpp:354
TQString programArguments() const
Return the arguments to the program to run when the alarm is triggered.
Definition: alarm.cpp:198
void setEndOffset(const Duration &)
Set offset of alarm in time relative to the end of the event.
Definition: alarm.cpp:466
void setText(const TQString &text)
Set the text to be displayed when the alarm is triggered.
Definition: alarm.cpp:308
void setProgramArguments(const TQString &arguments)
Set the arguments to the program to execute when the alarm is triggered.
Definition: alarm.cpp:190
TQString mailText() const
Return the email body text.
Definition: alarm.cpp:295
bool hasTime() const
Return true, if the alarm has an explicit date/time.
Definition: alarm.cpp:349
void setStartOffset(const Duration &)
Set offset of alarm in time relative to the start of the event.
Definition: alarm.cpp:443
TQValueList< Person > mailAddresses() const
Return the addresses to send mail to when an alarm goes off.
Definition: alarm.cpp:239
void setTime(const TQDateTime &alarmTime)
Set the time to trigger an alarm.
Definition: alarm.cpp:321
Type type() const
Return the type of the alarm.
Definition: alarm.cpp:144
void setAudioFile(const TQString &audioFile)
Set the file to play when the audio alarm is triggered.
Definition: alarm.cpp:156
void setMailText(const TQString &text)
Set the email body text.
Definition: alarm.cpp:287
void setType(Type type)
Set the type of the alarm.
Definition: alarm.cpp:115
void setProgramFile(const TQString &programFile)
Set the program file to execute when the alarm is triggered.
Definition: alarm.cpp:177
int repeatCount() const
Get how many times an alarm repeats, after its initial occurrence.
Definition: alarm.cpp:373
TQStringList mailAttachments() const
Return the filenames to attach to the email.
Definition: alarm.cpp:282
This class represents information related to an attachment.
Definition: attachment.h:35
This class represents information related to an attendee of an event.
Definition: attendee.h:37
void setDelegator(const TQString &delegator)
Sets the delegator.
Definition: attendee.h:140
void setDelegate(const TQString &delegate)
Sets the delegate.
Definition: attendee.h:131
TQString uid() const
Return unique id of the attendee.
Definition: attendee.cpp:137
TQString delegate() const
Returns the delegate.
Definition: attendee.h:135
Role role() const
Return role of Attendee.
Definition: attendee.cpp:122
TQString delegator() const
Returns the delegator.
Definition: attendee.h:144
bool RSVP() const
Return, if Attendee is asked to reply.
Definition: attendee.h:126
PartStat status() const
Return status.
Definition: attendee.cpp:61
This is the main "calendar" object class.
Definition: calendar.h:171
virtual bool addJournal(Journal *journal)=0
Insert a Journal into the Calendar.
virtual bool addEvent(Event *event)=0
Insert an Event into the Calendar.
ErrorFormat * exception() const
Returns an exception, if there is any, containing information about the last error that occurred.
Definition: calendar.cpp:80
virtual bool addTodo(Todo *todo)=0
Insert a Todo into the Calendar.
virtual Todo * todo(const TQString &uid)=0
Returns the Todo associated with the given unique identifier.
virtual Journal * journal(const TQString &uid)=0
Returns the Journal associated with the given unique identifier.
Incidence * incidence(const TQString &uid)
Returns the Incidence associated with the given unique identifier.
Definition: calendar.cpp:576
virtual Event * event(const TQString &uid)=0
Returns the Event associated with the given unique identifier.
void endBatchAdding()
Emits the endBatchAdding() signal.
Definition: calendar.cpp:149
This class provides compatibility to older (broken) versions of KOrganizer.
Definition: compat.h:46
This class represents custom calendar properties.
void setCustomProperties(const TQMap< TQCString, TQString > &properties)
Initialise the alarm's custom calendar properties to the specified key/value pairs.
TQMap< TQCString, TQString > customProperties() const
Return all custom calendar property key/value pairs.
void setCustomProperty(const TQCString &app, const TQCString &key, const TQString &value)
Create or modify a custom calendar property.
TQString customProperty(const TQCString &app, const TQCString &key) const
Return the value of a custom calendar property.
void removeCustomProperty(const TQCString &app, const TQCString &key)
Delete a custom calendar property.
This class represents a duration.
Definition: duration.h:34
int value() const
Returns the length of the duration in seconds or days.
Definition: duration.cpp:175
int asSeconds() const
Returns the length of the duration in seconds.
Definition: duration.cpp:165
Calendar format related error class.
Definition: exceptions.h:65
ErrorCodeFormat errorCode()
Return format error code.
Definition: exceptions.cpp:101
This class provides an Event in the sense of RFC2445.
Definition: event.h:33
virtual TQDateTime dtEnd() const
Return end date and time.
Definition: event.cpp:85
Transparency transparency() const
Return the event's time transparency level.
Definition: event.cpp:145
bool hasEndDate() const
Return whether the event has an end date/time.
Definition: event.cpp:121
This class provides information about free/busy time of a calendar user.
Definition: freebusy.h:41
void addPeriods(const PeriodList &)
Adds a list of periods to the freebusy object and then sorts that list.
Definition: freebusy.cpp:194
This class implements the iCalendar format.
Definition: icalformat.h:44
This class provides the interface for a visitor of calendar components.
Definition: incidencebase.h:55
virtual bool visit(Event *)
Reimplement this function in your concrete subclass of IncidenceBase::Visitor to perform actions on a...
Definition: incidencebase.h:64
This class provides the base class common to all calendar components.
Definition: incidencebase.h:46
void setOrganizer(const Person &o)
sets the organizer for the event
int attendeeCount() const
Return number of attendees.
void setPilotId(unsigned long id)
Set Pilot Id.
unsigned long pilotId() const
Return Pilot Id.
TQStringList comments() const
Return all comments associated with this incidence.
bool doesFloat() const
Return true or false depending on whether the incidence "floats," i.e.
TQString uid() const
Return the unique id for the event.
const Attendee::List & attendees() const
Return list of attendees.
void addComment(const TQString &comment)
Add a comment to this incidence.
void setUid(const TQString &)
Set the unique id for the event.
int syncStatus() const
Return synchronisation status.
virtual TQDateTime dtStart() const
returns an event's starting date/time as a TQDateTime.
virtual bool accept(Visitor &)
Accept IncidenceVisitor.
virtual void setDtStart(const TQDateTime &dtStart)
for setting the event's starting date/time with a TQDateTime.
TQDateTime lastModified() const
Return the time the incidence was last modified.
void setSyncStatus(int status)
Set synchronisation satus.
void setLastModified(const TQDateTime &lm)
Sets the time the incidence was last modified.
void addAttendee(Attendee *attendee, bool doUpdate=true)
Add Attendee to this incidence.
This class provides the base class common to all calendar components.
Definition: incidence.h:48
TQString statusStr() const
Return the event's status string.
Definition: incidence.cpp:762
void addAttachment(Attachment *attachment)
Add attachment.
Definition: incidence.cpp:674
TQString relatedToUid() const
What event does this one relate to? This function should only be used when constructing a calendar be...
Definition: incidence.cpp:340
void setLocation(const TQString &location)
Set the event's/todo's location.
Definition: incidence.cpp:868
const Alarm::List & alarms() const
All alarms that are associated with this incidence.
Definition: incidence.cpp:828
void setSummary(const TQString &summary)
Set short summary.
Definition: incidence.cpp:286
void setCustomStatus(const TQString &status)
Sets the incidence status to a non-standard status value.
Definition: incidence.cpp:749
void setSchedulingID(const TQString &sid)
Set the event's/todo's scheduling ID.
Definition: incidence.cpp:880
Alarm * newAlarm()
Create a new alarm which is associated with this incidence.
Definition: incidence.cpp:833
TQDateTime created() const
Return time and date of creation.
Definition: incidence.cpp:246
int revision() const
Return the number of revisions this event has seen.
Definition: incidence.cpp:259
void setPriority(int priority)
Set the incidences priority.
Definition: incidence.cpp:729
void setSecrecy(int)
Sets secrecy status.
Definition: incidence.cpp:786
int secrecy() const
Return the event's secrecy.
Definition: incidence.cpp:793
IncidenceList childIncidences() const
Returns an EventList of all child incidences.
Definition: incidence.cpp:934
TQString description() const
Return long description.
Definition: incidence.cpp:280
Status
Enumeration for describing an event's status.
Definition: incidence.h:117
TQStringList categories() const
Return categories as a list of strings.
Definition: incidence.cpp:323
void setStatus(Status status)
Sets the incidence status to a standard status value.
Definition: incidence.cpp:741
void setDescription(const TQString &description)
Set the long description.
Definition: incidence.cpp:273
int priority() const
Return priority.
Definition: incidence.cpp:736
Status status() const
Return the event's status.
Definition: incidence.cpp:757
void setFloats(bool f)
Set whether the incidence floats, i.e.
Definition: incidence.cpp:229
void setRelatedToUid(const TQString &)
Point at some other event to which the event relates.
Definition: incidence.cpp:333
bool doesRecur() const
Forward to Recurrence::doesRecur().
Definition: incidence.cpp:416
virtual void setDtStart(const TQDateTime &dtStart)
Set starting date/time.
Definition: incidence.cpp:264
TQString schedulingID() const
Return the event's/todo's scheduling ID.
Definition: incidence.cpp:885
bool hasRecurrenceID() const
Returns true if the incidence has recurrenceID, otherwise return false.
Definition: incidence.cpp:893
TQDateTime recurrenceID() const
Returns the incidence recurrenceID.
Definition: incidence.cpp:908
void setCategories(const TQStringList &categories)
Set categories.
Definition: incidence.cpp:298
TQString location() const
Return the event's/todo's location.
Definition: incidence.cpp:875
Attachment::List attachments() const
Return list of all associated attachments.
Definition: incidence.cpp:695
TQString summary() const
Return short summary.
Definition: incidence.cpp:293
Recurrence * recurrence() const
Return the recurrence rule associated with this incidence.
Definition: incidence.cpp:390
void setRevision(int rev)
Set the number of revisions this event has seen.
Definition: incidence.cpp:251
void addChildIncidence(TQString childIncidence)
Attach a child incidence to a parent incidence.
Definition: incidence.cpp:924
void setCreated(const TQDateTime &)
Set creation date.
Definition: incidence.cpp:237
void setHasRecurrenceID(bool hasRecurrenceID)
Sets if the incidence has recurrenceID.
Definition: incidence.cpp:898
void setRecurrenceID(const TQDateTime &recurrenceID)
Set the incidences recurrenceID.
Definition: incidence.cpp:913
This class provides a Journal in the sense of RFC2445.
Definition: journal.h:34
This class represents a period of time.
Definition: period.h:36
This class represents a person.
Definition: person.h:35
structure for describing the n-th weekday of the month/year.
This class represents a recurrence rule for a calendar incidence.
TQDateTime endDt(bool *result=0) const
Returns the date and time of the last recurrence.
void setDuration(int duration)
Sets the total number of times the event is to occur, including both the first and last.
void setFrequency(int freq)
Sets the frequency of recurrence, in terms of the recurrence time period type.
void setEndDt(const TQDateTime &endDateTime)
Sets the date and time of the last recurrence.
uint frequency() const
Returns frequency of recurrence, in terms of the recurrence time period type.
int duration() const
Returns -1 if the event recurs infinitely, 0 if the end date is set, otherwise the total number of re...
bool doesFloat() const
Returns whether the start date has no time associated.
void setStartDt(const TQDateTime &start)
Set start of recurrence, as a date and time.
This class represents a recurrence rule for a calendar incidence.
Definition: recurrence.h:90
Method
iTIP methods.
Definition: scheduler.h:103
This class provides a Todo in the sense of RFC2445.
Definition: todo.h:32
bool hasDueDate() const
Returns true if the todo has a due date, otherwise return false.
Definition: todo.cpp:144
bool isCompleted() const
Returns true if the todo is 100% completed, otherwise return false.
Definition: todo.cpp:217
void setDtRecurrence(const TQDateTime &dt)
Sets the due date/time of the current occurrence if recurrent.
Definition: todo.cpp:279
bool hasStartDate() const
Returns true if the todo has a start date, otherwise return false.
Definition: todo.cpp:157
void setDtDue(const TQDateTime &dtDue, bool first=false)
Sets due date and time.
Definition: todo.cpp:85
void setCompleted(bool completed)
Set completed state.
Definition: todo.cpp:223
TQDateTime dtStart(bool first=false) const
Returns the startdate of the todo.
Definition: todo.cpp:177
TQDateTime completed() const
Returns date and time when todo was completed.
Definition: todo.cpp:235
void setHasStartDate(bool hasStartDate)
Set if the todo has a start date.
Definition: todo.cpp:162
int percentComplete() const
Returns how many percent of the task are completed.
Definition: todo.cpp:263
bool hasCompletedDate() const
Returns true, if todo has a date associated with completion, otherwise return false.
Definition: todo.cpp:258
TQDateTime dtDue(bool first=false) const
Returns due date and time.
Definition: todo.cpp:117
void setHasDueDate(bool hasDueDate)
Set if the todo has a due date.
Definition: todo.cpp:149
void setPercentComplete(int)
Set how many percent of the task are completed.
Definition: todo.cpp:268
Namespace KCal is for global classes, objects and/or functions in libkcal.
Definition: alarm.h:38