-rw-r--r-- | libkcal/icalformatimpl.cpp | 2173 |
1 files changed, 2173 insertions, 0 deletions
diff --git a/libkcal/icalformatimpl.cpp b/libkcal/icalformatimpl.cpp new file mode 100644 index 0000000..e5c27a0 --- a/dev/null +++ b/libkcal/icalformatimpl.cpp | |||
@@ -0,0 +1,2173 @@ | |||
1 | /* | ||
2 | This file is part of libkcal. | ||
3 | Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> | ||
4 | |||
5 | This library is free software; you can redistribute it and/or | ||
6 | modify it under the terms of the GNU Library General Public | ||
7 | License as published by the Free Software Foundation; either | ||
8 | version 2 of the License, or (at your option) any later version. | ||
9 | |||
10 | This library is distributed in the hope that it will be useful, | ||
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
13 | Library General Public License for more details. | ||
14 | |||
15 | You should have received a copy of the GNU Library General Public License | ||
16 | along with this library; see the file COPYING.LIB. If not, write to | ||
17 | the Free Software Foundation, Inc., 59 Temple Place - Suite 330, | ||
18 | Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include <qdatetime.h> | ||
22 | #include <qstring.h> | ||
23 | #include <qptrlist.h> | ||
24 | #include <qfile.h> | ||
25 | |||
26 | #include <kdebug.h> | ||
27 | #include <klocale.h> | ||
28 | #include <kglobal.h> | ||
29 | |||
30 | extern "C" { | ||
31 | #include <ical.h> | ||
32 | #include <icalss.h> | ||
33 | #include <icalparser.h> | ||
34 | #include <icalrestriction.h> | ||
35 | } | ||
36 | |||
37 | #include "calendar.h" | ||
38 | #include "journal.h" | ||
39 | #include "icalformat.h" | ||
40 | #include "icalformatimpl.h" | ||
41 | #include "compat.h" | ||
42 | |||
43 | #define _ICAL_VERSION "2.0" | ||
44 | |||
45 | using namespace KCal; | ||
46 | |||
47 | const int gSecondsPerMinute = 60; | ||
48 | const int gSecondsPerHour = gSecondsPerMinute * 60; | ||
49 | const int gSecondsPerDay = gSecondsPerHour * 24; | ||
50 | const int gSecondsPerWeek = gSecondsPerDay * 7; | ||
51 | |||
52 | ICalFormatImpl::ICalFormatImpl( ICalFormat *parent ) : | ||
53 | mParent( parent ), mCalendarVersion( 0 ) | ||
54 | { | ||
55 | mCompat = new Compat; | ||
56 | } | ||
57 | |||
58 | ICalFormatImpl::~ICalFormatImpl() | ||
59 | { | ||
60 | delete mCompat; | ||
61 | } | ||
62 | |||
63 | class ToStringVisitor : public Incidence::Visitor | ||
64 | { | ||
65 | public: | ||
66 | ToStringVisitor( ICalFormatImpl *impl ) : mImpl( impl ), mComponent( 0 ) {} | ||
67 | |||
68 | bool visit( Event *e ) { mComponent = mImpl->writeEvent( e ); return true; } | ||
69 | bool visit( Todo *e ) { mComponent = mImpl->writeTodo( e ); return true; } | ||
70 | bool visit( Journal *e ) { mComponent = mImpl->writeJournal( e ); return true; } | ||
71 | |||
72 | icalcomponent *component() { return mComponent; } | ||
73 | |||
74 | private: | ||
75 | ICalFormatImpl *mImpl; | ||
76 | icalcomponent *mComponent; | ||
77 | }; | ||
78 | |||
79 | icalcomponent *ICalFormatImpl::writeIncidence(Incidence *incidence) | ||
80 | { | ||
81 | ToStringVisitor v( this ); | ||
82 | incidence->accept(v); | ||
83 | return v.component(); | ||
84 | } | ||
85 | |||
86 | icalcomponent *ICalFormatImpl::writeTodo(Todo *todo) | ||
87 | { | ||
88 | QString tmpStr; | ||
89 | QStringList tmpStrList; | ||
90 | |||
91 | icalcomponent *vtodo = icalcomponent_new(ICAL_VTODO_COMPONENT); | ||
92 | |||
93 | writeIncidence(vtodo,todo); | ||
94 | |||
95 | // due date | ||
96 | if (todo->hasDueDate()) { | ||
97 | icaltimetype due; | ||
98 | if (todo->doesFloat()) { | ||
99 | due = writeICalDate(todo->dtDue().date()); | ||
100 | } else { | ||
101 | due = writeICalDateTime(todo->dtDue()); | ||
102 | } | ||
103 | icalcomponent_add_property(vtodo,icalproperty_new_due(due)); | ||
104 | } | ||
105 | |||
106 | // start time | ||
107 | if (todo->hasStartDate()) { | ||
108 | icaltimetype start; | ||
109 | if (todo->doesFloat()) { | ||
110 | // kdDebug(5800) << "§§ Incidence " << todo->summary() << " floats." << endl; | ||
111 | start = writeICalDate(todo->dtStart().date()); | ||
112 | } else { | ||
113 | // kdDebug(5800) << "§§ incidence " << todo->summary() << " has time." << endl; | ||
114 | start = writeICalDateTime(todo->dtStart()); | ||
115 | } | ||
116 | icalcomponent_add_property(vtodo,icalproperty_new_dtstart(start)); | ||
117 | } | ||
118 | |||
119 | // completion date | ||
120 | if (todo->isCompleted()) { | ||
121 | if (!todo->hasCompletedDate()) { | ||
122 | // If todo was created by KOrganizer <2.2 it has no correct completion | ||
123 | // date. Set it to now. | ||
124 | todo->setCompleted(QDateTime::currentDateTime()); | ||
125 | } | ||
126 | icaltimetype completed = writeICalDateTime(todo->completed()); | ||
127 | icalcomponent_add_property(vtodo,icalproperty_new_completed(completed)); | ||
128 | } | ||
129 | |||
130 | icalcomponent_add_property(vtodo, | ||
131 | icalproperty_new_percentcomplete(todo->percentComplete())); | ||
132 | |||
133 | return vtodo; | ||
134 | } | ||
135 | |||
136 | icalcomponent *ICalFormatImpl::writeEvent(Event *event) | ||
137 | { | ||
138 | kdDebug(5800) << "Write Event '" << event->summary() << "' (" << event->uid() | ||
139 | << ")" << endl; | ||
140 | |||
141 | QString tmpStr; | ||
142 | QStringList tmpStrList; | ||
143 | |||
144 | icalcomponent *vevent = icalcomponent_new(ICAL_VEVENT_COMPONENT); | ||
145 | |||
146 | writeIncidence(vevent,event); | ||
147 | |||
148 | // start time | ||
149 | icaltimetype start; | ||
150 | if (event->doesFloat()) { | ||
151 | // kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl; | ||
152 | start = writeICalDate(event->dtStart().date()); | ||
153 | } else { | ||
154 | // kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl; | ||
155 | start = writeICalDateTime(event->dtStart()); | ||
156 | } | ||
157 | icalcomponent_add_property(vevent,icalproperty_new_dtstart(start)); | ||
158 | |||
159 | if (event->hasEndDate()) { | ||
160 | // end time | ||
161 | icaltimetype end; | ||
162 | if (event->doesFloat()) { | ||
163 | // kdDebug(5800) << "§§ Event " << event->summary() << " floats." << endl; | ||
164 | // +1 day because end date is non-inclusive. | ||
165 | end = writeICalDate( event->dtEnd().date().addDays( 1 ) ); | ||
166 | } else { | ||
167 | // kdDebug(5800) << "§§ Event " << event->summary() << " has time." << endl; | ||
168 | end = writeICalDateTime(event->dtEnd()); | ||
169 | } | ||
170 | icalcomponent_add_property(vevent,icalproperty_new_dtend(end)); | ||
171 | } | ||
172 | |||
173 | // TODO: attachments, resources | ||
174 | #if 0 | ||
175 | // attachments | ||
176 | tmpStrList = anEvent->attachments(); | ||
177 | for ( QStringList::Iterator it = tmpStrList.begin(); | ||
178 | it != tmpStrList.end(); | ||
179 | ++it ) | ||
180 | addPropValue(vevent, VCAttachProp, (*it).utf8()); | ||
181 | |||
182 | // resources | ||
183 | tmpStrList = anEvent->resources(); | ||
184 | tmpStr = tmpStrList.join(";"); | ||
185 | if (!tmpStr.isEmpty()) | ||
186 | addPropValue(vevent, VCResourcesProp, tmpStr.utf8()); | ||
187 | |||
188 | #endif | ||
189 | |||
190 | // Transparency | ||
191 | switch( event->transparency() ) { | ||
192 | case Event::Transparent: | ||
193 | icalcomponent_add_property(vevent, icalproperty_new_transp("TRANSPARENT")); | ||
194 | break; | ||
195 | case Event::Opaque: | ||
196 | icalcomponent_add_property(vevent, icalproperty_new_transp("OPAQUE")); | ||
197 | break; | ||
198 | } | ||
199 | |||
200 | return vevent; | ||
201 | } | ||
202 | |||
203 | icalcomponent *ICalFormatImpl::writeFreeBusy(FreeBusy *freebusy, | ||
204 | Scheduler::Method method) | ||
205 | { | ||
206 | #if QT_VERSION >= 300 | ||
207 | kdDebug(5800) << "icalformatimpl: writeFreeBusy: startDate: " | ||
208 | << freebusy->dtStart().toString("ddd MMMM d yyyy: h:m:s ap") << " End Date: " | ||
209 | << freebusy->dtEnd().toString("ddd MMMM d yyyy: h:m:s ap") << endl; | ||
210 | #endif | ||
211 | |||
212 | icalcomponent *vfreebusy = icalcomponent_new(ICAL_VFREEBUSY_COMPONENT); | ||
213 | |||
214 | writeIncidenceBase(vfreebusy,freebusy); | ||
215 | |||
216 | icalcomponent_add_property(vfreebusy, icalproperty_new_dtstart( | ||
217 | writeICalDateTime(freebusy->dtStart()))); | ||
218 | |||
219 | icalcomponent_add_property(vfreebusy, icalproperty_new_dtend( | ||
220 | writeICalDateTime(freebusy->dtEnd()))); | ||
221 | |||
222 | if (method == Scheduler::Request) { | ||
223 | icalcomponent_add_property(vfreebusy,icalproperty_new_uid( | ||
224 | freebusy->uid().utf8())); | ||
225 | } | ||
226 | |||
227 | //Loops through all the periods in the freebusy object | ||
228 | QValueList<Period> list = freebusy->busyPeriods(); | ||
229 | QValueList<Period>::Iterator it; | ||
230 | icalperiodtype period; | ||
231 | for (it = list.begin(); it!= list.end(); ++it) { | ||
232 | period.start = writeICalDateTime((*it).start()); | ||
233 | period.end = writeICalDateTime((*it).end()); | ||
234 | icalcomponent_add_property(vfreebusy, icalproperty_new_freebusy(period) ); | ||
235 | } | ||
236 | |||
237 | return vfreebusy; | ||
238 | } | ||
239 | |||
240 | icalcomponent *ICalFormatImpl::writeJournal(Journal *journal) | ||
241 | { | ||
242 | icalcomponent *vjournal = icalcomponent_new(ICAL_VJOURNAL_COMPONENT); | ||
243 | |||
244 | writeIncidence(vjournal,journal); | ||
245 | |||
246 | // start time | ||
247 | if (journal->dtStart().isValid()) { | ||
248 | icaltimetype start; | ||
249 | if (journal->doesFloat()) { | ||
250 | // kdDebug(5800) << "§§ Incidence " << event->summary() << " floats." << endl; | ||
251 | start = writeICalDate(journal->dtStart().date()); | ||
252 | } else { | ||
253 | // kdDebug(5800) << "§§ incidence " << event->summary() << " has time." << endl; | ||
254 | start = writeICalDateTime(journal->dtStart()); | ||
255 | } | ||
256 | icalcomponent_add_property(vjournal,icalproperty_new_dtstart(start)); | ||
257 | } | ||
258 | |||
259 | return vjournal; | ||
260 | } | ||
261 | |||
262 | void ICalFormatImpl::writeIncidence(icalcomponent *parent,Incidence *incidence) | ||
263 | { | ||
264 | // pilot sync stuff | ||
265 | // TODO: move this application-specific code to kpilot | ||
266 | if (incidence->pilotId()) { | ||
267 | incidence->setNonKDECustomProperty("X-PILOTID", QString::number(incidence->pilotId())); | ||
268 | incidence->setNonKDECustomProperty("X-PILOTSTAT", QString::number(incidence->syncStatus())); | ||
269 | } | ||
270 | if (incidence->zaurusId() >= 0) { | ||
271 | incidence->setNonKDECustomProperty("X-ZAURUSID", QString::number(incidence->zaurusId())); | ||
272 | } | ||
273 | |||
274 | if (incidence->zaurusUid() > 0) { | ||
275 | incidence->setNonKDECustomProperty("X-ZAURUSUID", QString::number(incidence->zaurusUid())); | ||
276 | } | ||
277 | if (incidence->zaurusStat() > 0) { | ||
278 | incidence->setNonKDECustomProperty("X-ZAURUSSTAT", QString::number(incidence->zaurusStat())); | ||
279 | } | ||
280 | |||
281 | writeIncidenceBase(parent,incidence); | ||
282 | if (incidence->cancelled()) { | ||
283 | icalcomponent_add_property(parent,icalproperty_new_status(ICAL_STATUS_CANCELLED)); | ||
284 | } | ||
285 | |||
286 | // creation date | ||
287 | icalcomponent_add_property(parent,icalproperty_new_created( | ||
288 | writeICalDateTime(incidence->created()))); | ||
289 | |||
290 | // unique id | ||
291 | icalcomponent_add_property(parent,icalproperty_new_uid( | ||
292 | incidence->uid().utf8())); | ||
293 | |||
294 | // revision | ||
295 | icalcomponent_add_property(parent,icalproperty_new_sequence( | ||
296 | incidence->revision())); | ||
297 | |||
298 | // last modification date | ||
299 | icalcomponent_add_property(parent,icalproperty_new_lastmodified( | ||
300 | writeICalDateTime(incidence->lastModified()))); | ||
301 | |||
302 | // description | ||
303 | if (!incidence->description().isEmpty()) { | ||
304 | icalcomponent_add_property(parent,icalproperty_new_description( | ||
305 | incidence->description().utf8())); | ||
306 | } | ||
307 | |||
308 | // summary | ||
309 | if (!incidence->summary().isEmpty()) { | ||
310 | icalcomponent_add_property(parent,icalproperty_new_summary( | ||
311 | incidence->summary().utf8())); | ||
312 | } | ||
313 | |||
314 | // location | ||
315 | if (!incidence->location().isEmpty()) { | ||
316 | icalcomponent_add_property(parent,icalproperty_new_location( | ||
317 | incidence->location().utf8())); | ||
318 | } | ||
319 | |||
320 | // TODO: | ||
321 | // status | ||
322 | // addPropValue(parent, VCStatusProp, incidence->getStatusStr().utf8()); | ||
323 | |||
324 | // secrecy | ||
325 | const char *classStr; | ||
326 | switch (incidence->secrecy()) { | ||
327 | case Incidence::SecrecyPublic: | ||
328 | classStr = "PUBLIC"; | ||
329 | break; | ||
330 | case Incidence::SecrecyConfidential: | ||
331 | classStr = "CONFIDENTIAL"; | ||
332 | break; | ||
333 | case Incidence::SecrecyPrivate: | ||
334 | default: | ||
335 | classStr = "PRIVATE"; | ||
336 | break; | ||
337 | } | ||
338 | icalcomponent_add_property(parent,icalproperty_new_class(classStr)); | ||
339 | |||
340 | // priority | ||
341 | icalcomponent_add_property(parent,icalproperty_new_priority( | ||
342 | incidence->priority())); | ||
343 | |||
344 | // categories | ||
345 | QStringList categories = incidence->categories(); | ||
346 | QStringList::Iterator it; | ||
347 | for(it = categories.begin(); it != categories.end(); ++it ) { | ||
348 | icalcomponent_add_property(parent,icalproperty_new_categories((*it).utf8())); | ||
349 | } | ||
350 | // TODO: Ensure correct concatenation of categories properties. | ||
351 | |||
352 | /* | ||
353 | // categories | ||
354 | tmpStrList = incidence->getCategories(); | ||
355 | tmpStr = ""; | ||
356 | QString catStr; | ||
357 | for ( QStringList::Iterator it = tmpStrList.begin(); | ||
358 | it != tmpStrList.end(); | ||
359 | ++it ) { | ||
360 | catStr = *it; | ||
361 | if (catStr[0] == ' ') | ||
362 | tmpStr += catStr.mid(1); | ||
363 | else | ||
364 | tmpStr += catStr; | ||
365 | // this must be a ';' character as the vCalendar specification requires! | ||
366 | // vcc.y has been hacked to translate the ';' to a ',' when the vcal is | ||
367 | // read in. | ||
368 | tmpStr += ";"; | ||
369 | } | ||
370 | if (!tmpStr.isEmpty()) { | ||
371 | tmpStr.truncate(tmpStr.length()-1); | ||
372 | icalcomponent_add_property(parent,icalproperty_new_categories( | ||
373 | writeText(incidence->getCategories().join(";")))); | ||
374 | } | ||
375 | */ | ||
376 | |||
377 | // related event | ||
378 | if (incidence->relatedTo()) { | ||
379 | icalcomponent_add_property(parent,icalproperty_new_relatedto( | ||
380 | incidence->relatedTo()->uid().utf8())); | ||
381 | } | ||
382 | |||
383 | // recurrence rule stuff | ||
384 | Recurrence *recur = incidence->recurrence(); | ||
385 | if (recur->doesRecur()) { | ||
386 | |||
387 | icalcomponent_add_property(parent,writeRecurrenceRule(recur)); | ||
388 | } | ||
389 | |||
390 | // recurrence excpetion dates | ||
391 | DateList dateList = incidence->exDates(); | ||
392 | DateList::ConstIterator exIt; | ||
393 | for(exIt = dateList.begin(); exIt != dateList.end(); ++exIt) { | ||
394 | icalcomponent_add_property(parent,icalproperty_new_exdate( | ||
395 | writeICalDate(*exIt))); | ||
396 | } | ||
397 | |||
398 | // attachments | ||
399 | QPtrList<Attachment> attachments = incidence->attachments(); | ||
400 | for (Attachment *at = attachments.first(); at; at = attachments.next()) | ||
401 | icalcomponent_add_property(parent,writeAttachment(at)); | ||
402 | |||
403 | // alarms | ||
404 | QPtrList<Alarm> alarms = incidence->alarms(); | ||
405 | Alarm* alarm; | ||
406 | for (alarm = alarms.first(); alarm; alarm = alarms.next()) { | ||
407 | if (alarm->enabled()) { | ||
408 | kdDebug(5800) << "Write alarm for " << incidence->summary() << endl; | ||
409 | icalcomponent_add_component(parent,writeAlarm(alarm)); | ||
410 | } | ||
411 | } | ||
412 | |||
413 | // duration | ||
414 | |||
415 | // turned off as it always is set to PTS0 (and must not occur together with DTEND | ||
416 | |||
417 | // if (incidence->hasDuration()) { | ||
418 | // icaldurationtype duration; | ||
419 | // duration = writeICalDuration(incidence->duration()); | ||
420 | // icalcomponent_add_property(parent,icalproperty_new_duration(duration)); | ||
421 | // } | ||
422 | } | ||
423 | |||
424 | void ICalFormatImpl::writeIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase) | ||
425 | { | ||
426 | icalcomponent_add_property(parent,icalproperty_new_dtstamp( | ||
427 | writeICalDateTime(QDateTime::currentDateTime()))); | ||
428 | |||
429 | // organizer stuff | ||
430 | icalcomponent_add_property(parent,icalproperty_new_organizer( | ||
431 | ("MAILTO:" + incidenceBase->organizer()).utf8())); | ||
432 | |||
433 | // attendees | ||
434 | if (incidenceBase->attendeeCount() != 0) { | ||
435 | QPtrList<Attendee> al = incidenceBase->attendees(); | ||
436 | QPtrListIterator<Attendee> ai(al); | ||
437 | for (; ai.current(); ++ai) { | ||
438 | icalcomponent_add_property(parent,writeAttendee(ai.current())); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | // custom properties | ||
443 | writeCustomProperties(parent, incidenceBase); | ||
444 | } | ||
445 | |||
446 | void ICalFormatImpl::writeCustomProperties(icalcomponent *parent,CustomProperties *properties) | ||
447 | { | ||
448 | QMap<QCString, QString> custom = properties->customProperties(); | ||
449 | for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) { | ||
450 | icalproperty *p = icalproperty_new_x(c.data().utf8()); | ||
451 | icalproperty_set_x_name(p,c.key()); | ||
452 | icalcomponent_add_property(parent,p); | ||
453 | } | ||
454 | } | ||
455 | |||
456 | icalproperty *ICalFormatImpl::writeAttendee(Attendee *attendee) | ||
457 | { | ||
458 | icalproperty *p = icalproperty_new_attendee("mailto:" + attendee->email().utf8()); | ||
459 | |||
460 | if (!attendee->name().isEmpty()) { | ||
461 | icalproperty_add_parameter(p,icalparameter_new_cn(attendee->name().utf8())); | ||
462 | } | ||
463 | |||
464 | |||
465 | icalproperty_add_parameter(p,icalparameter_new_rsvp( | ||
466 | attendee->RSVP() ? ICAL_RSVP_TRUE : ICAL_RSVP_FALSE )); | ||
467 | |||
468 | icalparameter_partstat status = ICAL_PARTSTAT_NEEDSACTION; | ||
469 | switch (attendee->status()) { | ||
470 | default: | ||
471 | case Attendee::NeedsAction: | ||
472 | status = ICAL_PARTSTAT_NEEDSACTION; | ||
473 | break; | ||
474 | case Attendee::Accepted: | ||
475 | status = ICAL_PARTSTAT_ACCEPTED; | ||
476 | break; | ||
477 | case Attendee::Declined: | ||
478 | status = ICAL_PARTSTAT_DECLINED; | ||
479 | break; | ||
480 | case Attendee::Tentative: | ||
481 | status = ICAL_PARTSTAT_TENTATIVE; | ||
482 | break; | ||
483 | case Attendee::Delegated: | ||
484 | status = ICAL_PARTSTAT_DELEGATED; | ||
485 | break; | ||
486 | case Attendee::Completed: | ||
487 | status = ICAL_PARTSTAT_COMPLETED; | ||
488 | break; | ||
489 | case Attendee::InProcess: | ||
490 | status = ICAL_PARTSTAT_INPROCESS; | ||
491 | break; | ||
492 | } | ||
493 | icalproperty_add_parameter(p,icalparameter_new_partstat(status)); | ||
494 | |||
495 | icalparameter_role role = ICAL_ROLE_REQPARTICIPANT; | ||
496 | switch (attendee->role()) { | ||
497 | case Attendee::Chair: | ||
498 | role = ICAL_ROLE_CHAIR; | ||
499 | break; | ||
500 | default: | ||
501 | case Attendee::ReqParticipant: | ||
502 | role = ICAL_ROLE_REQPARTICIPANT; | ||
503 | break; | ||
504 | case Attendee::OptParticipant: | ||
505 | role = ICAL_ROLE_OPTPARTICIPANT; | ||
506 | break; | ||
507 | case Attendee::NonParticipant: | ||
508 | role = ICAL_ROLE_NONPARTICIPANT; | ||
509 | break; | ||
510 | } | ||
511 | icalproperty_add_parameter(p,icalparameter_new_role(role)); | ||
512 | |||
513 | if (!attendee->uid().isEmpty()) { | ||
514 | icalparameter* icalparameter_uid = icalparameter_new_x(attendee->uid().utf8()); | ||
515 | icalparameter_set_xname(icalparameter_uid,"X-UID"); | ||
516 | icalproperty_add_parameter(p,icalparameter_uid); | ||
517 | } | ||
518 | |||
519 | return p; | ||
520 | } | ||
521 | |||
522 | icalproperty *ICalFormatImpl::writeAttachment(Attachment *att) | ||
523 | { | ||
524 | icalattachtype* attach = icalattachtype_new(); | ||
525 | if (att->isURI()) | ||
526 | icalattachtype_set_url(attach, att->uri().utf8().data()); | ||
527 | else | ||
528 | icalattachtype_set_base64(attach, att->data(), 0); | ||
529 | |||
530 | icalproperty *p = icalproperty_new_attach(attach); | ||
531 | |||
532 | if (!att->mimeType().isEmpty()) | ||
533 | icalproperty_add_parameter(p,icalparameter_new_fmttype(att->mimeType().utf8().data())); | ||
534 | |||
535 | if (att->isBinary()) { | ||
536 | icalproperty_add_parameter(p,icalparameter_new_value(ICAL_VALUE_BINARY)); | ||
537 | icalproperty_add_parameter(p,icalparameter_new_encoding(ICAL_ENCODING_BASE64)); | ||
538 | } | ||
539 | return p; | ||
540 | } | ||
541 | |||
542 | icalproperty *ICalFormatImpl::writeRecurrenceRule(Recurrence *recur) | ||
543 | { | ||
544 | // kdDebug(5800) << "ICalFormatImpl::writeRecurrenceRule()" << endl; | ||
545 | |||
546 | icalrecurrencetype r; | ||
547 | |||
548 | icalrecurrencetype_clear(&r); | ||
549 | |||
550 | int index = 0; | ||
551 | int index2 = 0; | ||
552 | |||
553 | QPtrList<Recurrence::rMonthPos> tmpPositions; | ||
554 | QPtrList<int> tmpDays; | ||
555 | int *tmpDay; | ||
556 | Recurrence::rMonthPos *tmpPos; | ||
557 | bool datetime = false; | ||
558 | int day; | ||
559 | int i; | ||
560 | |||
561 | switch(recur->doesRecur()) { | ||
562 | case Recurrence::rMinutely: | ||
563 | r.freq = ICAL_MINUTELY_RECURRENCE; | ||
564 | datetime = true; | ||
565 | break; | ||
566 | case Recurrence::rHourly: | ||
567 | r.freq = ICAL_HOURLY_RECURRENCE; | ||
568 | datetime = true; | ||
569 | break; | ||
570 | case Recurrence::rDaily: | ||
571 | r.freq = ICAL_DAILY_RECURRENCE; | ||
572 | break; | ||
573 | case Recurrence::rWeekly: | ||
574 | r.freq = ICAL_WEEKLY_RECURRENCE; | ||
575 | r.week_start = static_cast<icalrecurrencetype_weekday>(recur->weekStart()%7 + 1); | ||
576 | for (i = 0; i < 7; i++) { | ||
577 | if (recur->days().testBit(i)) { | ||
578 | day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1 | ||
579 | r.by_day[index++] = icalrecurrencetype_day_day_of_week(day); | ||
580 | } | ||
581 | } | ||
582 | // r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; | ||
583 | break; | ||
584 | case Recurrence::rMonthlyPos: | ||
585 | r.freq = ICAL_MONTHLY_RECURRENCE; | ||
586 | |||
587 | tmpPositions = recur->monthPositions(); | ||
588 | for (tmpPos = tmpPositions.first(); | ||
589 | tmpPos; | ||
590 | tmpPos = tmpPositions.next()) { | ||
591 | for (i = 0; i < 7; i++) { | ||
592 | if (tmpPos->rDays.testBit(i)) { | ||
593 | day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1 | ||
594 | day += tmpPos->rPos*8; | ||
595 | if (tmpPos->negative) day = -day; | ||
596 | r.by_day[index++] = day; | ||
597 | } | ||
598 | } | ||
599 | } | ||
600 | // r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; | ||
601 | break; | ||
602 | case Recurrence::rMonthlyDay: | ||
603 | r.freq = ICAL_MONTHLY_RECURRENCE; | ||
604 | |||
605 | tmpDays = recur->monthDays(); | ||
606 | for (tmpDay = tmpDays.first(); | ||
607 | tmpDay; | ||
608 | tmpDay = tmpDays.next()) { | ||
609 | r.by_month_day[index++] = icalrecurrencetype_day_position(*tmpDay*8);//*tmpDay); | ||
610 | } | ||
611 | // r.by_day[index] = ICAL_RECURRENCE_ARRAY_MAX; | ||
612 | break; | ||
613 | case Recurrence::rYearlyMonth: | ||
614 | case Recurrence::rYearlyPos: | ||
615 | r.freq = ICAL_YEARLY_RECURRENCE; | ||
616 | |||
617 | tmpDays = recur->yearNums(); | ||
618 | for (tmpDay = tmpDays.first(); | ||
619 | tmpDay; | ||
620 | tmpDay = tmpDays.next()) { | ||
621 | r.by_month[index++] = *tmpDay; | ||
622 | } | ||
623 | // r.by_set_pos[index] = ICAL_RECURRENCE_ARRAY_MAX; | ||
624 | if (recur->doesRecur() == Recurrence::rYearlyPos) { | ||
625 | tmpPositions = recur->monthPositions(); | ||
626 | for (tmpPos = tmpPositions.first(); | ||
627 | tmpPos; | ||
628 | tmpPos = tmpPositions.next()) { | ||
629 | for (i = 0; i < 7; i++) { | ||
630 | if (tmpPos->rDays.testBit(i)) { | ||
631 | day = (i + 1)%7 + 1; // convert from Monday=0 to Sunday=1 | ||
632 | day += tmpPos->rPos*8; | ||
633 | if (tmpPos->negative) day = -day; | ||
634 | r.by_day[index2++] = day; | ||
635 | } | ||
636 | } | ||
637 | } | ||
638 | // r.by_day[index2] = ICAL_RECURRENCE_ARRAY_MAX; | ||
639 | } | ||
640 | break; | ||
641 | case Recurrence::rYearlyDay: | ||
642 | r.freq = ICAL_YEARLY_RECURRENCE; | ||
643 | |||
644 | tmpDays = recur->yearNums(); | ||
645 | for (tmpDay = tmpDays.first(); | ||
646 | tmpDay; | ||
647 | tmpDay = tmpDays.next()) { | ||
648 | r.by_year_day[index++] = *tmpDay; | ||
649 | } | ||
650 | // r.by_year_day[index] = ICAL_RECURRENCE_ARRAY_MAX; | ||
651 | break; | ||
652 | default: | ||
653 | r.freq = ICAL_NO_RECURRENCE; | ||
654 | kdDebug(5800) << "ICalFormatImpl::writeRecurrence(): no recurrence" << endl; | ||
655 | break; | ||
656 | } | ||
657 | |||
658 | r.interval = recur->frequency(); | ||
659 | |||
660 | if (recur->duration() > 0) { | ||
661 | r.count = recur->duration(); | ||
662 | } else if (recur->duration() == -1) { | ||
663 | r.count = 0; | ||
664 | } else { | ||
665 | if (datetime) | ||
666 | r.until = writeICalDateTime(recur->endDateTime()); | ||
667 | else | ||
668 | r.until = writeICalDate(recur->endDate()); | ||
669 | } | ||
670 | |||
671 | // Debug output | ||
672 | #if 0 | ||
673 | const char *str = icalrecurrencetype_as_string(&r); | ||
674 | if (str) { | ||
675 | kdDebug(5800) << " String: " << str << endl; | ||
676 | } else { | ||
677 | kdDebug(5800) << " No String" << endl; | ||
678 | } | ||
679 | #endif | ||
680 | |||
681 | return icalproperty_new_rrule(r); | ||
682 | } | ||
683 | |||
684 | icalcomponent *ICalFormatImpl::writeAlarm(Alarm *alarm) | ||
685 | { | ||
686 | icalcomponent *a = icalcomponent_new(ICAL_VALARM_COMPONENT); | ||
687 | |||
688 | icalproperty_action action; | ||
689 | icalattachtype *attach = 0; | ||
690 | |||
691 | switch (alarm->type()) { | ||
692 | case Alarm::Procedure: | ||
693 | action = ICAL_ACTION_PROCEDURE; | ||
694 | attach = icalattachtype_new(); | ||
695 | icalattachtype_set_url(attach,QFile::encodeName(alarm->programFile()).data()); | ||
696 | icalcomponent_add_property(a,icalproperty_new_attach(attach)); | ||
697 | icalattachtype_free(attach); | ||
698 | if (!alarm->programArguments().isEmpty()) { | ||
699 | icalcomponent_add_property(a,icalproperty_new_description(alarm->programArguments().utf8())); | ||
700 | } | ||
701 | break; | ||
702 | case Alarm::Audio: | ||
703 | action = ICAL_ACTION_AUDIO; | ||
704 | if (!alarm->audioFile().isEmpty()) { | ||
705 | attach = icalattachtype_new(); | ||
706 | icalattachtype_set_url(attach,QFile::encodeName( alarm->audioFile() ).data()); | ||
707 | icalcomponent_add_property(a,icalproperty_new_attach(attach)); | ||
708 | icalattachtype_free(attach); | ||
709 | } | ||
710 | break; | ||
711 | case Alarm::Email: { | ||
712 | action = ICAL_ACTION_EMAIL; | ||
713 | QValueList<Person> addresses = alarm->mailAddresses(); | ||
714 | for (QValueList<Person>::Iterator ad = addresses.begin(); ad != addresses.end(); ++ad) { | ||
715 | icalproperty *p = icalproperty_new_attendee("MAILTO:" + (*ad).email().utf8()); | ||
716 | if (!(*ad).name().isEmpty()) { | ||
717 | icalproperty_add_parameter(p,icalparameter_new_cn((*ad).name().utf8())); | ||
718 | } | ||
719 | icalcomponent_add_property(a,p); | ||
720 | } | ||
721 | icalcomponent_add_property(a,icalproperty_new_summary(alarm->mailSubject().utf8())); | ||
722 | icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8())); | ||
723 | QStringList attachments = alarm->mailAttachments(); | ||
724 | if (attachments.count() > 0) { | ||
725 | for (QStringList::Iterator at = attachments.begin(); at != attachments.end(); ++at) { | ||
726 | attach = icalattachtype_new(); | ||
727 | icalattachtype_set_url(attach,QFile::encodeName( *at ).data()); | ||
728 | icalcomponent_add_property(a,icalproperty_new_attach(attach)); | ||
729 | icalattachtype_free(attach); | ||
730 | } | ||
731 | } | ||
732 | break; | ||
733 | } | ||
734 | case Alarm::Display: | ||
735 | action = ICAL_ACTION_DISPLAY; | ||
736 | icalcomponent_add_property(a,icalproperty_new_description(alarm->text().utf8())); | ||
737 | break; | ||
738 | case Alarm::Invalid: | ||
739 | default: | ||
740 | kdDebug(5800) << "Unknown type of alarm" << endl; | ||
741 | action = ICAL_ACTION_NONE; | ||
742 | break; | ||
743 | } | ||
744 | icalcomponent_add_property(a,icalproperty_new_action(action)); | ||
745 | |||
746 | // Trigger time | ||
747 | icaltriggertype trigger; | ||
748 | if ( alarm->hasTime() ) { | ||
749 | trigger.time = writeICalDateTime(alarm->time()); | ||
750 | trigger.duration = icaldurationtype_null_duration(); | ||
751 | } else { | ||
752 | trigger.time = icaltime_null_time(); | ||
753 | Duration offset; | ||
754 | if ( alarm->hasStartOffset() ) | ||
755 | offset = alarm->startOffset(); | ||
756 | else | ||
757 | offset = alarm->endOffset(); | ||
758 | trigger.duration = icaldurationtype_from_int( offset.asSeconds() ); | ||
759 | } | ||
760 | icalproperty *p = icalproperty_new_trigger(trigger); | ||
761 | if ( alarm->hasEndOffset() ) | ||
762 | icalproperty_add_parameter(p,icalparameter_new_related(ICAL_RELATED_END)); | ||
763 | icalcomponent_add_property(a,p); | ||
764 | |||
765 | // Repeat count and duration | ||
766 | if (alarm->repeatCount()) { | ||
767 | icalcomponent_add_property(a,icalproperty_new_repeat(alarm->repeatCount())); | ||
768 | icalcomponent_add_property(a,icalproperty_new_duration( | ||
769 | icaldurationtype_from_int(alarm->snoozeTime()*60))); | ||
770 | } | ||
771 | |||
772 | // Custom properties | ||
773 | QMap<QCString, QString> custom = alarm->customProperties(); | ||
774 | for (QMap<QCString, QString>::Iterator c = custom.begin(); c != custom.end(); ++c) { | ||
775 | icalproperty *p = icalproperty_new_x(c.data().utf8()); | ||
776 | icalproperty_set_x_name(p,c.key()); | ||
777 | icalcomponent_add_property(a,p); | ||
778 | } | ||
779 | |||
780 | return a; | ||
781 | } | ||
782 | |||
783 | Todo *ICalFormatImpl::readTodo(icalcomponent *vtodo) | ||
784 | { | ||
785 | Todo *todo = new Todo; | ||
786 | |||
787 | readIncidence(vtodo,todo); | ||
788 | |||
789 | icalproperty *p = icalcomponent_get_first_property(vtodo,ICAL_ANY_PROPERTY); | ||
790 | |||
791 | // int intvalue; | ||
792 | icaltimetype icaltime; | ||
793 | |||
794 | QStringList categories; | ||
795 | |||
796 | while (p) { | ||
797 | icalproperty_kind kind = icalproperty_isa(p); | ||
798 | switch (kind) { | ||
799 | |||
800 | case ICAL_DUE_PROPERTY: // due date | ||
801 | icaltime = icalproperty_get_due(p); | ||
802 | if (icaltime.is_date) { | ||
803 | todo->setDtDue(QDateTime(readICalDate(icaltime),QTime(0,0,0))); | ||
804 | todo->setFloats(true); | ||
805 | |||
806 | } else { | ||
807 | todo->setDtDue(readICalDateTime(icaltime)); | ||
808 | todo->setFloats(false); | ||
809 | } | ||
810 | todo->setHasDueDate(true); | ||
811 | break; | ||
812 | |||
813 | case ICAL_COMPLETED_PROPERTY: // completion date | ||
814 | icaltime = icalproperty_get_completed(p); | ||
815 | todo->setCompleted(readICalDateTime(icaltime)); | ||
816 | break; | ||
817 | |||
818 | case ICAL_PERCENTCOMPLETE_PROPERTY: // Percent completed | ||
819 | todo->setPercentComplete(icalproperty_get_percentcomplete(p)); | ||
820 | break; | ||
821 | |||
822 | case ICAL_RELATEDTO_PROPERTY: // related todo (parent) | ||
823 | todo->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p))); | ||
824 | mTodosRelate.append(todo); | ||
825 | break; | ||
826 | |||
827 | case ICAL_DTSTART_PROPERTY: | ||
828 | // Flag that todo has start date. Value is read in by readIncidence(). | ||
829 | todo->setHasStartDate(true); | ||
830 | break; | ||
831 | |||
832 | default: | ||
833 | // kdDebug(5800) << "ICALFormat::readTodo(): Unknown property: " << kind | ||
834 | // << endl; | ||
835 | break; | ||
836 | } | ||
837 | |||
838 | p = icalcomponent_get_next_property(vtodo,ICAL_ANY_PROPERTY); | ||
839 | } | ||
840 | |||
841 | return todo; | ||
842 | } | ||
843 | |||
844 | Event *ICalFormatImpl::readEvent(icalcomponent *vevent) | ||
845 | { | ||
846 | Event *event = new Event; | ||
847 | event->setFloats(false); | ||
848 | |||
849 | readIncidence(vevent,event); | ||
850 | |||
851 | icalproperty *p = icalcomponent_get_first_property(vevent,ICAL_ANY_PROPERTY); | ||
852 | |||
853 | // int intvalue; | ||
854 | icaltimetype icaltime; | ||
855 | |||
856 | QStringList categories; | ||
857 | QString transparency; | ||
858 | |||
859 | while (p) { | ||
860 | icalproperty_kind kind = icalproperty_isa(p); | ||
861 | switch (kind) { | ||
862 | |||
863 | case ICAL_DTEND_PROPERTY: // start date and time | ||
864 | icaltime = icalproperty_get_dtend(p); | ||
865 | if (icaltime.is_date) { | ||
866 | event->setFloats( true ); | ||
867 | // End date is non-inclusive | ||
868 | QDate endDate = readICalDate( icaltime ).addDays( -1 ); | ||
869 | mCompat->fixFloatingEnd( endDate ); | ||
870 | if ( endDate < event->dtStart().date() ) { | ||
871 | endDate = event->dtStart().date(); | ||
872 | } | ||
873 | event->setDtEnd( QDateTime( endDate, QTime( 0, 0, 0 ) ) ); | ||
874 | } else { | ||
875 | event->setDtEnd(readICalDateTime(icaltime)); | ||
876 | } | ||
877 | break; | ||
878 | |||
879 | // TODO: | ||
880 | // at this point, there should be at least a start or end time. | ||
881 | // fix up for events that take up no time but have a time associated | ||
882 | #if 0 | ||
883 | if (!(vo = isAPropertyOf(vevent, VCDTstartProp))) | ||
884 | anEvent->setDtStart(anEvent->dtEnd()); | ||
885 | if (!(vo = isAPropertyOf(vevent, VCDTendProp))) | ||
886 | anEvent->setDtEnd(anEvent->dtStart()); | ||
887 | #endif | ||
888 | |||
889 | // TODO: exdates | ||
890 | #if 0 | ||
891 | // recurrence exceptions | ||
892 | if ((vo = isAPropertyOf(vevent, VCExDateProp)) != 0) { | ||
893 | anEvent->setExDates(s = fakeCString(vObjectUStringZValue(vo))); | ||
894 | deleteStr(s); | ||
895 | } | ||
896 | #endif | ||
897 | |||
898 | #if 0 | ||
899 | // secrecy | ||
900 | if ((vo = isAPropertyOf(vevent, VCClassProp)) != 0) { | ||
901 | anEvent->setSecrecy(s = fakeCString(vObjectUStringZValue(vo))); | ||
902 | deleteStr(s); | ||
903 | } | ||
904 | else | ||
905 | anEvent->setSecrecy("PUBLIC"); | ||
906 | |||
907 | // attachments | ||
908 | tmpStrList.clear(); | ||
909 | initPropIterator(&voi, vevent); | ||
910 | while (moreIteration(&voi)) { | ||
911 | vo = nextVObject(&voi); | ||
912 | if (strcmp(vObjectName(vo), VCAttachProp) == 0) { | ||
913 | tmpStrList.append(s = fakeCString(vObjectUStringZValue(vo))); | ||
914 | deleteStr(s); | ||
915 | } | ||
916 | } | ||
917 | anEvent->setAttachments(tmpStrList); | ||
918 | |||
919 | // resources | ||
920 | if ((vo = isAPropertyOf(vevent, VCResourcesProp)) != 0) { | ||
921 | QString resources = (s = fakeCString(vObjectUStringZValue(vo))); | ||
922 | deleteStr(s); | ||
923 | tmpStrList.clear(); | ||
924 | index1 = 0; | ||
925 | index2 = 0; | ||
926 | QString resource; | ||
927 | while ((index2 = resources.find(';', index1)) != -1) { | ||
928 | resource = resources.mid(index1, (index2 - index1)); | ||
929 | tmpStrList.append(resource); | ||
930 | index1 = index2; | ||
931 | } | ||
932 | anEvent->setResources(tmpStrList); | ||
933 | } | ||
934 | #endif | ||
935 | |||
936 | case ICAL_RELATEDTO_PROPERTY: // releated event (parent) | ||
937 | event->setRelatedToUid(QString::fromUtf8(icalproperty_get_relatedto(p))); | ||
938 | mEventsRelate.append(event); | ||
939 | break; | ||
940 | |||
941 | |||
942 | case ICAL_TRANSP_PROPERTY: // Transparency | ||
943 | transparency = QString::fromUtf8(icalproperty_get_transp(p)); | ||
944 | if( transparency == "TRANSPARENT" ) | ||
945 | event->setTransparency( Event::Transparent ); | ||
946 | else | ||
947 | event->setTransparency( Event::Opaque ); | ||
948 | break; | ||
949 | |||
950 | default: | ||
951 | // kdDebug(5800) << "ICALFormat::readEvent(): Unknown property: " << kind | ||
952 | // << endl; | ||
953 | break; | ||
954 | } | ||
955 | |||
956 | p = icalcomponent_get_next_property(vevent,ICAL_ANY_PROPERTY); | ||
957 | } | ||
958 | |||
959 | QString msade = event->nonKDECustomProperty("X-MICROSOFT-CDO-ALLDAYEVENT"); | ||
960 | if (!msade.isNull()) { | ||
961 | bool floats = (msade == QString::fromLatin1("TRUE")); | ||
962 | kdDebug(5800) << "ICALFormat::readEvent(): all day event: " << floats << endl; | ||
963 | event->setFloats(floats); | ||
964 | if (floats) { | ||
965 | QDateTime endDate = event->dtEnd(); | ||
966 | event->setDtEnd(endDate.addDays(-1)); | ||
967 | } | ||
968 | } | ||
969 | |||
970 | // some stupid vCal exporters ignore the standard and use Description | ||
971 | // instead of Summary for the default field. Correct for this. | ||
972 | if (event->summary().isEmpty() && | ||
973 | !(event->description().isEmpty())) { | ||
974 | QString tmpStr = event->description().simplifyWhiteSpace(); | ||
975 | event->setDescription(""); | ||
976 | event->setSummary(tmpStr); | ||
977 | } | ||
978 | |||
979 | return event; | ||
980 | } | ||
981 | |||
982 | FreeBusy *ICalFormatImpl::readFreeBusy(icalcomponent *vfreebusy) | ||
983 | { | ||
984 | FreeBusy *freebusy = new FreeBusy; | ||
985 | |||
986 | readIncidenceBase(vfreebusy,freebusy); | ||
987 | |||
988 | icalproperty *p = icalcomponent_get_first_property(vfreebusy,ICAL_ANY_PROPERTY); | ||
989 | |||
990 | icaltimetype icaltime; | ||
991 | icalperiodtype icalperiod; | ||
992 | QDateTime period_start, period_end; | ||
993 | |||
994 | while (p) { | ||
995 | icalproperty_kind kind = icalproperty_isa(p); | ||
996 | switch (kind) { | ||
997 | |||
998 | case ICAL_DTSTART_PROPERTY: // start date and time | ||
999 | icaltime = icalproperty_get_dtstart(p); | ||
1000 | freebusy->setDtStart(readICalDateTime(icaltime)); | ||
1001 | break; | ||
1002 | |||
1003 | case ICAL_DTEND_PROPERTY: // start End Date and Time | ||
1004 | icaltime = icalproperty_get_dtend(p); | ||
1005 | freebusy->setDtEnd(readICalDateTime(icaltime)); | ||
1006 | break; | ||
1007 | |||
1008 | case ICAL_FREEBUSY_PROPERTY: //Any FreeBusy Times | ||
1009 | icalperiod = icalproperty_get_freebusy(p); | ||
1010 | period_start = readICalDateTime(icalperiod.start); | ||
1011 | period_end = readICalDateTime(icalperiod.end); | ||
1012 | freebusy->addPeriod(period_start, period_end); | ||
1013 | break; | ||
1014 | |||
1015 | default: | ||
1016 | kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind | ||
1017 | << endl; | ||
1018 | break; | ||
1019 | } | ||
1020 | p = icalcomponent_get_next_property(vfreebusy,ICAL_ANY_PROPERTY); | ||
1021 | } | ||
1022 | |||
1023 | return freebusy; | ||
1024 | } | ||
1025 | |||
1026 | Journal *ICalFormatImpl::readJournal(icalcomponent *vjournal) | ||
1027 | { | ||
1028 | Journal *journal = new Journal; | ||
1029 | |||
1030 | readIncidence(vjournal,journal); | ||
1031 | |||
1032 | return journal; | ||
1033 | } | ||
1034 | |||
1035 | Attendee *ICalFormatImpl::readAttendee(icalproperty *attendee) | ||
1036 | { | ||
1037 | icalparameter *p = 0; | ||
1038 | |||
1039 | QString email = QString::fromUtf8(icalproperty_get_attendee(attendee)); | ||
1040 | |||
1041 | QString name; | ||
1042 | QString uid = QString::null; | ||
1043 | p = icalproperty_get_first_parameter(attendee,ICAL_CN_PARAMETER); | ||
1044 | if (p) { | ||
1045 | name = QString::fromUtf8(icalparameter_get_cn(p)); | ||
1046 | } else { | ||
1047 | } | ||
1048 | |||
1049 | bool rsvp=false; | ||
1050 | p = icalproperty_get_first_parameter(attendee,ICAL_RSVP_PARAMETER); | ||
1051 | if (p) { | ||
1052 | icalparameter_rsvp rsvpParameter = icalparameter_get_rsvp(p); | ||
1053 | if (rsvpParameter == ICAL_RSVP_TRUE) rsvp = true; | ||
1054 | } | ||
1055 | |||
1056 | Attendee::PartStat status = Attendee::NeedsAction; | ||
1057 | p = icalproperty_get_first_parameter(attendee,ICAL_PARTSTAT_PARAMETER); | ||
1058 | if (p) { | ||
1059 | icalparameter_partstat partStatParameter = icalparameter_get_partstat(p); | ||
1060 | switch(partStatParameter) { | ||
1061 | default: | ||
1062 | case ICAL_PARTSTAT_NEEDSACTION: | ||
1063 | status = Attendee::NeedsAction; | ||
1064 | break; | ||
1065 | case ICAL_PARTSTAT_ACCEPTED: | ||
1066 | status = Attendee::Accepted; | ||
1067 | break; | ||
1068 | case ICAL_PARTSTAT_DECLINED: | ||
1069 | status = Attendee::Declined; | ||
1070 | break; | ||
1071 | case ICAL_PARTSTAT_TENTATIVE: | ||
1072 | status = Attendee::Tentative; | ||
1073 | break; | ||
1074 | case ICAL_PARTSTAT_DELEGATED: | ||
1075 | status = Attendee::Delegated; | ||
1076 | break; | ||
1077 | case ICAL_PARTSTAT_COMPLETED: | ||
1078 | status = Attendee::Completed; | ||
1079 | break; | ||
1080 | case ICAL_PARTSTAT_INPROCESS: | ||
1081 | status = Attendee::InProcess; | ||
1082 | break; | ||
1083 | } | ||
1084 | } | ||
1085 | |||
1086 | Attendee::Role role = Attendee::ReqParticipant; | ||
1087 | p = icalproperty_get_first_parameter(attendee,ICAL_ROLE_PARAMETER); | ||
1088 | if (p) { | ||
1089 | icalparameter_role roleParameter = icalparameter_get_role(p); | ||
1090 | switch(roleParameter) { | ||
1091 | case ICAL_ROLE_CHAIR: | ||
1092 | role = Attendee::Chair; | ||
1093 | break; | ||
1094 | default: | ||
1095 | case ICAL_ROLE_REQPARTICIPANT: | ||
1096 | role = Attendee::ReqParticipant; | ||
1097 | break; | ||
1098 | case ICAL_ROLE_OPTPARTICIPANT: | ||
1099 | role = Attendee::OptParticipant; | ||
1100 | break; | ||
1101 | case ICAL_ROLE_NONPARTICIPANT: | ||
1102 | role = Attendee::NonParticipant; | ||
1103 | break; | ||
1104 | } | ||
1105 | } | ||
1106 | |||
1107 | p = icalproperty_get_first_parameter(attendee,ICAL_X_PARAMETER); | ||
1108 | uid = icalparameter_get_xvalue(p); | ||
1109 | // This should be added, but there seems to be a libical bug here. | ||
1110 | /*while (p) { | ||
1111 | // if (icalparameter_get_xname(p) == "X-UID") { | ||
1112 | uid = icalparameter_get_xvalue(p); | ||
1113 | p = icalproperty_get_next_parameter(attendee,ICAL_X_PARAMETER); | ||
1114 | } */ | ||
1115 | |||
1116 | return new Attendee( name, email, rsvp, status, role, uid ); | ||
1117 | } | ||
1118 | |||
1119 | Attachment *ICalFormatImpl::readAttachment(icalproperty *attach) | ||
1120 | { | ||
1121 | icalattachtype *a = icalproperty_get_attach(attach); | ||
1122 | icalparameter_value v = ICAL_VALUE_NONE; | ||
1123 | icalparameter_encoding e = ICAL_ENCODING_NONE; | ||
1124 | |||
1125 | Attachment *attachment = 0; | ||
1126 | |||
1127 | icalparameter *vp = icalproperty_get_first_parameter(attach, ICAL_VALUE_PARAMETER); | ||
1128 | if (vp) | ||
1129 | v = icalparameter_get_value(vp); | ||
1130 | |||
1131 | icalparameter *ep = icalproperty_get_first_parameter(attach, ICAL_ENCODING_PARAMETER); | ||
1132 | if (ep) | ||
1133 | e = icalparameter_get_encoding(ep); | ||
1134 | |||
1135 | if (v == ICAL_VALUE_BINARY && e == ICAL_ENCODING_BASE64) | ||
1136 | attachment = new Attachment(icalattachtype_get_base64(a)); | ||
1137 | else if ((v == ICAL_VALUE_NONE || v == ICAL_VALUE_URI) && (e == ICAL_ENCODING_NONE || e == ICAL_ENCODING_8BIT)) { | ||
1138 | attachment = new Attachment(QString(icalattachtype_get_url(a))); | ||
1139 | } else { | ||
1140 | kdWarning(5800) << "Unsupported attachment format, discarding it!" << endl; | ||
1141 | return 0; | ||
1142 | } | ||
1143 | |||
1144 | icalparameter *p = icalproperty_get_first_parameter(attach, ICAL_FMTTYPE_PARAMETER); | ||
1145 | if (p) | ||
1146 | attachment->setMimeType(QString(icalparameter_get_fmttype(p))); | ||
1147 | |||
1148 | return attachment; | ||
1149 | } | ||
1150 | #include <qtextcodec.h> | ||
1151 | void ICalFormatImpl::readIncidence(icalcomponent *parent,Incidence *incidence) | ||
1152 | { | ||
1153 | readIncidenceBase(parent,incidence); | ||
1154 | |||
1155 | icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY); | ||
1156 | bool readrec = false; | ||
1157 | const char *text; | ||
1158 | int intvalue; | ||
1159 | icaltimetype icaltime; | ||
1160 | icaldurationtype icalduration; | ||
1161 | struct icalrecurrencetype rectype; | ||
1162 | QStringList categories; | ||
1163 | |||
1164 | while (p) { | ||
1165 | icalproperty_kind kind = icalproperty_isa(p); | ||
1166 | switch (kind) { | ||
1167 | |||
1168 | case ICAL_CREATED_PROPERTY: | ||
1169 | icaltime = icalproperty_get_created(p); | ||
1170 | incidence->setCreated(readICalDateTime(icaltime)); | ||
1171 | break; | ||
1172 | |||
1173 | case ICAL_SEQUENCE_PROPERTY: // sequence | ||
1174 | intvalue = icalproperty_get_sequence(p); | ||
1175 | incidence->setRevision(intvalue); | ||
1176 | break; | ||
1177 | |||
1178 | case ICAL_LASTMODIFIED_PROPERTY: // last modification date | ||
1179 | icaltime = icalproperty_get_lastmodified(p); | ||
1180 | incidence->setLastModified(readICalDateTime(icaltime)); | ||
1181 | break; | ||
1182 | |||
1183 | case ICAL_DTSTART_PROPERTY: // start date and time | ||
1184 | icaltime = icalproperty_get_dtstart(p); | ||
1185 | if (icaltime.is_date) { | ||
1186 | incidence->setDtStart(QDateTime(readICalDate(icaltime),QTime(0,0,0))); | ||
1187 | incidence->setFloats(true); | ||
1188 | } else { | ||
1189 | incidence->setDtStart(readICalDateTime(icaltime)); | ||
1190 | } | ||
1191 | break; | ||
1192 | |||
1193 | case ICAL_DURATION_PROPERTY: // start date and time | ||
1194 | icalduration = icalproperty_get_duration(p); | ||
1195 | incidence->setDuration(readICalDuration(icalduration)); | ||
1196 | break; | ||
1197 | |||
1198 | case ICAL_DESCRIPTION_PROPERTY: // description | ||
1199 | text = icalproperty_get_description(p); | ||
1200 | incidence->setDescription(QString::fromUtf8(text)); | ||
1201 | break; | ||
1202 | |||
1203 | case ICAL_SUMMARY_PROPERTY: // summary | ||
1204 | { | ||
1205 | text = icalproperty_get_summary(p); | ||
1206 | incidence->setSummary(QString::fromUtf8(text)); | ||
1207 | } | ||
1208 | break; | ||
1209 | case ICAL_STATUS_PROPERTY: // summary | ||
1210 | { | ||
1211 | if ( ICAL_STATUS_CANCELLED == icalproperty_get_status(p) ) | ||
1212 | incidence->setCancelled( true ); | ||
1213 | } | ||
1214 | break; | ||
1215 | |||
1216 | case ICAL_LOCATION_PROPERTY: // location | ||
1217 | text = icalproperty_get_location(p); | ||
1218 | incidence->setLocation(QString::fromUtf8(text)); | ||
1219 | break; | ||
1220 | |||
1221 | #if 0 | ||
1222 | // status | ||
1223 | if ((vo = isAPropertyOf(vincidence, VCStatusProp)) != 0) { | ||
1224 | incidence->setStatus(s = fakeCString(vObjectUStringZValue(vo))); | ||
1225 | deleteStr(s); | ||
1226 | } | ||
1227 | else | ||
1228 | incidence->setStatus("NEEDS ACTION"); | ||
1229 | #endif | ||
1230 | |||
1231 | case ICAL_PRIORITY_PROPERTY: // priority | ||
1232 | intvalue = icalproperty_get_priority(p); | ||
1233 | incidence->setPriority(intvalue); | ||
1234 | break; | ||
1235 | |||
1236 | case ICAL_CATEGORIES_PROPERTY: // categories | ||
1237 | text = icalproperty_get_categories(p); | ||
1238 | categories.append(QString::fromUtf8(text)); | ||
1239 | break; | ||
1240 | //******************************************* | ||
1241 | case ICAL_RRULE_PROPERTY: | ||
1242 | // we do need (maybe )start datetime of incidence for recurrence | ||
1243 | // such that we can read recurrence only after we read incidence completely | ||
1244 | readrec = true; | ||
1245 | rectype = icalproperty_get_rrule(p); | ||
1246 | break; | ||
1247 | |||
1248 | case ICAL_EXDATE_PROPERTY: | ||
1249 | icaltime = icalproperty_get_exdate(p); | ||
1250 | incidence->addExDate(readICalDate(icaltime)); | ||
1251 | break; | ||
1252 | |||
1253 | case ICAL_CLASS_PROPERTY: | ||
1254 | text = icalproperty_get_class(p); | ||
1255 | if (strcmp(text,"PUBLIC") == 0) { | ||
1256 | incidence->setSecrecy(Incidence::SecrecyPublic); | ||
1257 | } else if (strcmp(text,"CONFIDENTIAL") == 0) { | ||
1258 | incidence->setSecrecy(Incidence::SecrecyConfidential); | ||
1259 | } else { | ||
1260 | incidence->setSecrecy(Incidence::SecrecyPrivate); | ||
1261 | } | ||
1262 | break; | ||
1263 | |||
1264 | case ICAL_ATTACH_PROPERTY: // attachments | ||
1265 | incidence->addAttachment(readAttachment(p)); | ||
1266 | break; | ||
1267 | |||
1268 | default: | ||
1269 | // kdDebug(5800) << "ICALFormat::readIncidence(): Unknown property: " << kind | ||
1270 | // << endl; | ||
1271 | break; | ||
1272 | } | ||
1273 | |||
1274 | p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY); | ||
1275 | } | ||
1276 | if ( readrec ) { | ||
1277 | readRecurrenceRule(rectype,incidence); | ||
1278 | } | ||
1279 | // kpilot stuff | ||
1280 | // TODO: move this application-specific code to kpilot | ||
1281 | QString kp = incidence->nonKDECustomProperty("X-PILOTID"); | ||
1282 | if (!kp.isNull()) { | ||
1283 | incidence->setPilotId(kp.toInt()); | ||
1284 | } | ||
1285 | kp = incidence->nonKDECustomProperty("X-PILOTSTAT"); | ||
1286 | if (!kp.isNull()) { | ||
1287 | incidence->setSyncStatus(kp.toInt()); | ||
1288 | } | ||
1289 | kp = incidence->nonKDECustomProperty("X-ZAURUSID"); | ||
1290 | if (!kp.isNull()) { | ||
1291 | incidence->setZaurusId(kp.toInt()); | ||
1292 | } | ||
1293 | |||
1294 | kp = incidence->nonKDECustomProperty("X-ZAURUSUID"); | ||
1295 | if (!kp.isNull()) { | ||
1296 | incidence->setZaurusUid(kp.toInt()); | ||
1297 | } | ||
1298 | |||
1299 | kp = incidence->nonKDECustomProperty("X-ZAURUSSTAT"); | ||
1300 | if (!kp.isNull()) { | ||
1301 | incidence->setZaurusStat(kp.toInt()); | ||
1302 | } | ||
1303 | |||
1304 | // Cancel backwards compatibility mode for subsequent changes by the application | ||
1305 | incidence->recurrence()->setCompatVersion(); | ||
1306 | |||
1307 | // add categories | ||
1308 | incidence->setCategories(categories); | ||
1309 | |||
1310 | // iterate through all alarms | ||
1311 | for (icalcomponent *alarm = icalcomponent_get_first_component(parent,ICAL_VALARM_COMPONENT); | ||
1312 | alarm; | ||
1313 | alarm = icalcomponent_get_next_component(parent,ICAL_VALARM_COMPONENT)) { | ||
1314 | readAlarm(alarm,incidence); | ||
1315 | } | ||
1316 | } | ||
1317 | |||
1318 | void ICalFormatImpl::readIncidenceBase(icalcomponent *parent,IncidenceBase *incidenceBase) | ||
1319 | { | ||
1320 | icalproperty *p = icalcomponent_get_first_property(parent,ICAL_ANY_PROPERTY); | ||
1321 | |||
1322 | while (p) { | ||
1323 | icalproperty_kind kind = icalproperty_isa(p); | ||
1324 | switch (kind) { | ||
1325 | |||
1326 | case ICAL_UID_PROPERTY: // unique id | ||
1327 | incidenceBase->setUid(QString::fromUtf8(icalproperty_get_uid(p))); | ||
1328 | break; | ||
1329 | |||
1330 | case ICAL_ORGANIZER_PROPERTY: // organizer | ||
1331 | incidenceBase->setOrganizer(QString::fromUtf8(icalproperty_get_organizer(p))); | ||
1332 | break; | ||
1333 | |||
1334 | case ICAL_ATTENDEE_PROPERTY: // attendee | ||
1335 | incidenceBase->addAttendee(readAttendee(p)); | ||
1336 | break; | ||
1337 | |||
1338 | default: | ||
1339 | break; | ||
1340 | } | ||
1341 | |||
1342 | p = icalcomponent_get_next_property(parent,ICAL_ANY_PROPERTY); | ||
1343 | } | ||
1344 | |||
1345 | // custom properties | ||
1346 | readCustomProperties(parent, incidenceBase); | ||
1347 | } | ||
1348 | |||
1349 | void ICalFormatImpl::readCustomProperties(icalcomponent *parent,CustomProperties *properties) | ||
1350 | { | ||
1351 | QMap<QCString, QString> customProperties; | ||
1352 | |||
1353 | icalproperty *p = icalcomponent_get_first_property(parent,ICAL_X_PROPERTY); | ||
1354 | |||
1355 | while (p) { | ||
1356 | |||
1357 | QString value = QString::fromUtf8(icalproperty_get_x(p)); | ||
1358 | customProperties[icalproperty_get_name(p)] = value; | ||
1359 | |||
1360 | p = icalcomponent_get_next_property(parent,ICAL_X_PROPERTY); | ||
1361 | } | ||
1362 | |||
1363 | properties->setCustomProperties(customProperties); | ||
1364 | } | ||
1365 | |||
1366 | void ICalFormatImpl::readRecurrenceRule(struct icalrecurrencetype rrule,Incidence *incidence) | ||
1367 | { | ||
1368 | // kdDebug(5800) << "Read recurrence for " << incidence->summary() << endl; | ||
1369 | |||
1370 | Recurrence *recur = incidence->recurrence(); | ||
1371 | recur->setCompatVersion(mCalendarVersion); | ||
1372 | recur->unsetRecurs(); | ||
1373 | |||
1374 | struct icalrecurrencetype r = rrule; | ||
1375 | |||
1376 | dumpIcalRecurrence(r); | ||
1377 | readRecurrence( r, recur, incidence); | ||
1378 | } | ||
1379 | |||
1380 | void ICalFormatImpl::readRecurrence( const struct icalrecurrencetype &r, Recurrence* recur, Incidence *incidence) | ||
1381 | { | ||
1382 | int wkst; | ||
1383 | int index = 0; | ||
1384 | short day = 0; | ||
1385 | QBitArray qba(7); | ||
1386 | int frequ = r.freq; | ||
1387 | int interv = r.interval; | ||
1388 | // preprocessing for odd recurrence definitions | ||
1389 | |||
1390 | if ( r.freq == ICAL_MONTHLY_RECURRENCE ) { | ||
1391 | if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1392 | interv = 12; | ||
1393 | } | ||
1394 | } | ||
1395 | if ( r.freq == ICAL_YEARLY_RECURRENCE ) { | ||
1396 | if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX && r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX ) { | ||
1397 | frequ = ICAL_MONTHLY_RECURRENCE; | ||
1398 | interv = 12; | ||
1399 | } | ||
1400 | } | ||
1401 | |||
1402 | switch (frequ) { | ||
1403 | case ICAL_MINUTELY_RECURRENCE: | ||
1404 | if (!icaltime_is_null_time(r.until)) { | ||
1405 | recur->setMinutely(interv,readICalDateTime(r.until)); | ||
1406 | } else { | ||
1407 | if (r.count == 0) | ||
1408 | recur->setMinutely(interv,-1); | ||
1409 | else | ||
1410 | recur->setMinutely(interv,r.count); | ||
1411 | } | ||
1412 | break; | ||
1413 | case ICAL_HOURLY_RECURRENCE: | ||
1414 | if (!icaltime_is_null_time(r.until)) { | ||
1415 | recur->setHourly(interv,readICalDateTime(r.until)); | ||
1416 | } else { | ||
1417 | if (r.count == 0) | ||
1418 | recur->setHourly(interv,-1); | ||
1419 | else | ||
1420 | recur->setHourly(interv,r.count); | ||
1421 | } | ||
1422 | break; | ||
1423 | case ICAL_DAILY_RECURRENCE: | ||
1424 | if (!icaltime_is_null_time(r.until)) { | ||
1425 | recur->setDaily(interv,readICalDate(r.until)); | ||
1426 | } else { | ||
1427 | if (r.count == 0) | ||
1428 | recur->setDaily(interv,-1); | ||
1429 | else | ||
1430 | recur->setDaily(interv,r.count); | ||
1431 | } | ||
1432 | break; | ||
1433 | case ICAL_WEEKLY_RECURRENCE: | ||
1434 | // kdDebug(5800) << "WEEKLY_RECURRENCE" << endl; | ||
1435 | wkst = (r.week_start + 5)%7 + 1; | ||
1436 | if (!icaltime_is_null_time(r.until)) { | ||
1437 | recur->setWeekly(interv,qba,readICalDate(r.until),wkst); | ||
1438 | } else { | ||
1439 | if (r.count == 0) | ||
1440 | recur->setWeekly(interv,qba,-1,wkst); | ||
1441 | else | ||
1442 | recur->setWeekly(interv,qba,r.count,wkst); | ||
1443 | } | ||
1444 | if ( r.by_day[0] == ICAL_RECURRENCE_ARRAY_MAX) { | ||
1445 | int wday = incidence->dtStart().date().dayOfWeek ()-1; | ||
1446 | //qDebug("weekly error found "); | ||
1447 | qba.setBit(wday); | ||
1448 | } else { | ||
1449 | while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1450 | // kdDebug(5800) << " " << day << endl; | ||
1451 | qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 | ||
1452 | } | ||
1453 | } | ||
1454 | break; | ||
1455 | case ICAL_MONTHLY_RECURRENCE: | ||
1456 | |||
1457 | if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1458 | if (!icaltime_is_null_time(r.until)) { | ||
1459 | recur->setMonthly(Recurrence::rMonthlyPos,interv, | ||
1460 | readICalDate(r.until)); | ||
1461 | } else { | ||
1462 | if (r.count == 0) | ||
1463 | recur->setMonthly(Recurrence::rMonthlyPos,interv,-1); | ||
1464 | else | ||
1465 | recur->setMonthly(Recurrence::rMonthlyPos,interv,r.count); | ||
1466 | } | ||
1467 | bool useSetPos = false; | ||
1468 | short pos = 0; | ||
1469 | while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1470 | // kdDebug(5800) << "----a " << index << ": " << day << endl; | ||
1471 | pos = icalrecurrencetype_day_position(day); | ||
1472 | if (pos) { | ||
1473 | day = icalrecurrencetype_day_day_of_week(day); | ||
1474 | QBitArray ba(7); // don't wipe qba | ||
1475 | ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 | ||
1476 | recur->addMonthlyPos(pos,ba); | ||
1477 | } else { | ||
1478 | qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 | ||
1479 | useSetPos = true; | ||
1480 | } | ||
1481 | } | ||
1482 | if (useSetPos) { | ||
1483 | if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1484 | recur->addMonthlyPos(r.by_set_pos[0],qba); | ||
1485 | } | ||
1486 | } | ||
1487 | } else if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1488 | if (!icaltime_is_null_time(r.until)) { | ||
1489 | recur->setMonthly(Recurrence::rMonthlyDay,interv, | ||
1490 | readICalDate(r.until)); | ||
1491 | } else { | ||
1492 | if (r.count == 0) | ||
1493 | recur->setMonthly(Recurrence::rMonthlyDay,interv,-1); | ||
1494 | else | ||
1495 | recur->setMonthly(Recurrence::rMonthlyDay,interv,r.count); | ||
1496 | } | ||
1497 | while((day = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1498 | // kdDebug(5800) << "----b " << day << endl; | ||
1499 | recur->addMonthlyDay(day); | ||
1500 | } | ||
1501 | } | ||
1502 | break; | ||
1503 | case ICAL_YEARLY_RECURRENCE: | ||
1504 | if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1505 | if (!icaltime_is_null_time(r.until)) { | ||
1506 | recur->setYearly(Recurrence::rYearlyDay,interv, | ||
1507 | readICalDate(r.until)); | ||
1508 | } else { | ||
1509 | if (r.count == 0) | ||
1510 | recur->setYearly(Recurrence::rYearlyDay,interv,-1); | ||
1511 | else | ||
1512 | recur->setYearly(Recurrence::rYearlyDay,interv,r.count); | ||
1513 | } | ||
1514 | while((day = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1515 | recur->addYearlyNum(day); | ||
1516 | } | ||
1517 | } else if ( true /*r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX*/) { | ||
1518 | if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1519 | if (!icaltime_is_null_time(r.until)) { | ||
1520 | recur->setYearly(Recurrence::rYearlyPos,interv, | ||
1521 | readICalDate(r.until)); | ||
1522 | } else { | ||
1523 | if (r.count == 0) | ||
1524 | recur->setYearly(Recurrence::rYearlyPos,interv,-1); | ||
1525 | else | ||
1526 | recur->setYearly(Recurrence::rYearlyPos,interv,r.count); | ||
1527 | } | ||
1528 | bool useSetPos = false; | ||
1529 | short pos = 0; | ||
1530 | while((day = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1531 | // kdDebug(5800) << "----a " << index << ": " << day << endl; | ||
1532 | pos = icalrecurrencetype_day_position(day); | ||
1533 | if (pos) { | ||
1534 | day = icalrecurrencetype_day_day_of_week(day); | ||
1535 | QBitArray ba(7); // don't wipe qba | ||
1536 | ba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 | ||
1537 | recur->addYearlyMonthPos(pos,ba); | ||
1538 | } else { | ||
1539 | qba.setBit((day+5)%7); // convert from Sunday=1 to Monday=0 | ||
1540 | useSetPos = true; | ||
1541 | } | ||
1542 | } | ||
1543 | if (useSetPos) { | ||
1544 | if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1545 | recur->addYearlyMonthPos(r.by_set_pos[0],qba); | ||
1546 | } | ||
1547 | } | ||
1548 | } else { | ||
1549 | if (!icaltime_is_null_time(r.until)) { | ||
1550 | recur->setYearly(Recurrence::rYearlyMonth,interv, | ||
1551 | readICalDate(r.until)); | ||
1552 | } else { | ||
1553 | if (r.count == 0) | ||
1554 | recur->setYearly(Recurrence::rYearlyMonth,interv,-1); | ||
1555 | else | ||
1556 | recur->setYearly(Recurrence::rYearlyMonth,interv,r.count); | ||
1557 | } | ||
1558 | } | ||
1559 | if ( r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX ) { | ||
1560 | index = 0; | ||
1561 | while((day = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
1562 | recur->addYearlyNum(day); | ||
1563 | } | ||
1564 | } else { | ||
1565 | recur->addYearlyNum(incidence->dtStart().date().month()); | ||
1566 | } | ||
1567 | } | ||
1568 | break; | ||
1569 | default: | ||
1570 | ; | ||
1571 | break; | ||
1572 | } | ||
1573 | } | ||
1574 | |||
1575 | void ICalFormatImpl::readAlarm(icalcomponent *alarm,Incidence *incidence) | ||
1576 | { | ||
1577 | //kdDebug(5800) << "Read alarm for " << incidence->summary() << endl; | ||
1578 | |||
1579 | Alarm* ialarm = incidence->newAlarm(); | ||
1580 | ialarm->setRepeatCount(0); | ||
1581 | ialarm->setEnabled(true); | ||
1582 | |||
1583 | // Determine the alarm's action type | ||
1584 | icalproperty *p = icalcomponent_get_first_property(alarm,ICAL_ACTION_PROPERTY); | ||
1585 | if ( !p ) { | ||
1586 | return; | ||
1587 | } | ||
1588 | |||
1589 | icalproperty_action action = icalproperty_get_action(p); | ||
1590 | Alarm::Type type = Alarm::Display; | ||
1591 | switch ( action ) { | ||
1592 | case ICAL_ACTION_DISPLAY: type = Alarm::Display; break; | ||
1593 | case ICAL_ACTION_AUDIO: type = Alarm::Audio; break; | ||
1594 | case ICAL_ACTION_PROCEDURE: type = Alarm::Procedure; break; | ||
1595 | case ICAL_ACTION_EMAIL: type = Alarm::Email; break; | ||
1596 | default: | ||
1597 | ; | ||
1598 | return; | ||
1599 | } | ||
1600 | ialarm->setType(type); | ||
1601 | |||
1602 | p = icalcomponent_get_first_property(alarm,ICAL_ANY_PROPERTY); | ||
1603 | while (p) { | ||
1604 | icalproperty_kind kind = icalproperty_isa(p); | ||
1605 | |||
1606 | switch (kind) { | ||
1607 | case ICAL_TRIGGER_PROPERTY: { | ||
1608 | icaltriggertype trigger = icalproperty_get_trigger(p); | ||
1609 | if (icaltime_is_null_time(trigger.time)) { | ||
1610 | if (icaldurationtype_is_null_duration(trigger.duration)) { | ||
1611 | kdDebug(5800) << "ICalFormatImpl::readAlarm(): Trigger has no time and no duration." << endl; | ||
1612 | } else { | ||
1613 | Duration duration = icaldurationtype_as_int( trigger.duration ); | ||
1614 | icalparameter *param = icalproperty_get_first_parameter(p,ICAL_RELATED_PARAMETER); | ||
1615 | if (param && icalparameter_get_related(param) == ICAL_RELATED_END) | ||
1616 | ialarm->setEndOffset(duration); | ||
1617 | else | ||
1618 | ialarm->setStartOffset(duration); | ||
1619 | } | ||
1620 | } else { | ||
1621 | ialarm->setTime(readICalDateTime(trigger.time)); | ||
1622 | } | ||
1623 | break; | ||
1624 | } | ||
1625 | case ICAL_DURATION_PROPERTY: { | ||
1626 | icaldurationtype duration = icalproperty_get_duration(p); | ||
1627 | ialarm->setSnoozeTime(icaldurationtype_as_int(duration)/60); | ||
1628 | break; | ||
1629 | } | ||
1630 | case ICAL_REPEAT_PROPERTY: | ||
1631 | ialarm->setRepeatCount(icalproperty_get_repeat(p)); | ||
1632 | break; | ||
1633 | |||
1634 | // Only in DISPLAY and EMAIL and PROCEDURE alarms | ||
1635 | case ICAL_DESCRIPTION_PROPERTY: { | ||
1636 | QString description = QString::fromUtf8(icalproperty_get_description(p)); | ||
1637 | switch ( action ) { | ||
1638 | case ICAL_ACTION_DISPLAY: | ||
1639 | ialarm->setText( description ); | ||
1640 | break; | ||
1641 | case ICAL_ACTION_PROCEDURE: | ||
1642 | ialarm->setProgramArguments( description ); | ||
1643 | break; | ||
1644 | case ICAL_ACTION_EMAIL: | ||
1645 | ialarm->setMailText( description ); | ||
1646 | break; | ||
1647 | default: | ||
1648 | break; | ||
1649 | } | ||
1650 | break; | ||
1651 | } | ||
1652 | // Only in EMAIL alarm | ||
1653 | case ICAL_SUMMARY_PROPERTY: | ||
1654 | ialarm->setMailSubject(QString::fromUtf8(icalproperty_get_summary(p))); | ||
1655 | break; | ||
1656 | |||
1657 | // Only in EMAIL alarm | ||
1658 | case ICAL_ATTENDEE_PROPERTY: { | ||
1659 | QString email = QString::fromUtf8(icalproperty_get_attendee(p)); | ||
1660 | QString name; | ||
1661 | icalparameter *param = icalproperty_get_first_parameter(p,ICAL_CN_PARAMETER); | ||
1662 | if (param) { | ||
1663 | name = QString::fromUtf8(icalparameter_get_cn(param)); | ||
1664 | } | ||
1665 | ialarm->addMailAddress(Person(name, email)); | ||
1666 | break; | ||
1667 | } | ||
1668 | // Only in AUDIO and EMAIL and PROCEDURE alarms | ||
1669 | case ICAL_ATTACH_PROPERTY: { | ||
1670 | icalattachtype *attach = icalproperty_get_attach(p); | ||
1671 | QString url = QFile::decodeName(icalattachtype_get_url(attach)); | ||
1672 | switch ( action ) { | ||
1673 | case ICAL_ACTION_AUDIO: | ||
1674 | ialarm->setAudioFile( url ); | ||
1675 | break; | ||
1676 | case ICAL_ACTION_PROCEDURE: | ||
1677 | ialarm->setProgramFile( url ); | ||
1678 | break; | ||
1679 | case ICAL_ACTION_EMAIL: | ||
1680 | ialarm->addMailAttachment( url ); | ||
1681 | break; | ||
1682 | default: | ||
1683 | break; | ||
1684 | } | ||
1685 | break; | ||
1686 | } | ||
1687 | default: | ||
1688 | break; | ||
1689 | } | ||
1690 | |||
1691 | p = icalcomponent_get_next_property(alarm,ICAL_ANY_PROPERTY); | ||
1692 | } | ||
1693 | |||
1694 | // custom properties | ||
1695 | readCustomProperties(alarm, ialarm); | ||
1696 | |||
1697 | // TODO: check for consistency of alarm properties | ||
1698 | } | ||
1699 | |||
1700 | icaltimetype ICalFormatImpl::writeICalDate(const QDate &date) | ||
1701 | { | ||
1702 | icaltimetype t; | ||
1703 | |||
1704 | t.year = date.year(); | ||
1705 | t.month = date.month(); | ||
1706 | t.day = date.day(); | ||
1707 | |||
1708 | t.hour = 0; | ||
1709 | t.minute = 0; | ||
1710 | t.second = 0; | ||
1711 | |||
1712 | t.is_date = 1; | ||
1713 | |||
1714 | t.is_utc = 0; | ||
1715 | |||
1716 | t.zone = 0; | ||
1717 | |||
1718 | return t; | ||
1719 | } | ||
1720 | |||
1721 | icaltimetype ICalFormatImpl::writeICalDateTime(const QDateTime &dt ) | ||
1722 | { | ||
1723 | icaltimetype t; | ||
1724 | t.is_date = 0; | ||
1725 | t.zone = 0; | ||
1726 | QDateTime datetime; | ||
1727 | if ( mParent->utc() ) { | ||
1728 | int offset = KGlobal::locale()->localTimeOffset( dt ); | ||
1729 | datetime = dt.addSecs ( -offset*60); | ||
1730 | t.is_utc = 1; | ||
1731 | } | ||
1732 | else { | ||
1733 | datetime = dt; | ||
1734 | t.is_utc = 0; | ||
1735 | |||
1736 | } | ||
1737 | t.year = datetime.date().year(); | ||
1738 | t.month = datetime.date().month(); | ||
1739 | t.day = datetime.date().day(); | ||
1740 | |||
1741 | t.hour = datetime.time().hour(); | ||
1742 | t.minute = datetime.time().minute(); | ||
1743 | t.second = datetime.time().second(); | ||
1744 | |||
1745 | //qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() ); | ||
1746 | |||
1747 | // if ( mParent->utc() ) { | ||
1748 | // datetime = KGlobal::locale()->localTime( dt ); | ||
1749 | // qDebug("*** time %s localtime %s ",dt .toString().latin1() ,datetime .toString().latin1() ); | ||
1750 | // if (mParent->timeZoneId().isEmpty()) | ||
1751 | // t = icaltime_as_utc(t, 0); | ||
1752 | // else | ||
1753 | // t = icaltime_as_utc(t,mParent->timeZoneId().local8Bit()); | ||
1754 | // } | ||
1755 | |||
1756 | return t; | ||
1757 | } | ||
1758 | |||
1759 | QDateTime ICalFormatImpl::readICalDateTime(icaltimetype t) | ||
1760 | { | ||
1761 | QDateTime dt (QDate(t.year,t.month,t.day), | ||
1762 | QTime(t.hour,t.minute,t.second) ); | ||
1763 | |||
1764 | if (t.is_utc) { | ||
1765 | int offset = KGlobal::locale()->localTimeOffset( dt ); | ||
1766 | dt = dt.addSecs ( offset*60); | ||
1767 | } | ||
1768 | |||
1769 | return dt; | ||
1770 | } | ||
1771 | |||
1772 | QDate ICalFormatImpl::readICalDate(icaltimetype t) | ||
1773 | { | ||
1774 | return QDate(t.year,t.month,t.day); | ||
1775 | } | ||
1776 | |||
1777 | icaldurationtype ICalFormatImpl::writeICalDuration(int seconds) | ||
1778 | { | ||
1779 | icaldurationtype d; | ||
1780 | |||
1781 | d.weeks = seconds % gSecondsPerWeek; | ||
1782 | seconds -= d.weeks * gSecondsPerWeek; | ||
1783 | d.days = seconds % gSecondsPerDay; | ||
1784 | seconds -= d.days * gSecondsPerDay; | ||
1785 | d.hours = seconds % gSecondsPerHour; | ||
1786 | seconds -= d.hours * gSecondsPerHour; | ||
1787 | d.minutes = seconds % gSecondsPerMinute; | ||
1788 | seconds -= d.minutes * gSecondsPerMinute; | ||
1789 | d.seconds = seconds; | ||
1790 | d.is_neg = 0; | ||
1791 | |||
1792 | return d; | ||
1793 | } | ||
1794 | |||
1795 | int ICalFormatImpl::readICalDuration(icaldurationtype d) | ||
1796 | { | ||
1797 | int result = 0; | ||
1798 | |||
1799 | result += d.weeks * gSecondsPerWeek; | ||
1800 | result += d.days * gSecondsPerDay; | ||
1801 | result += d.hours * gSecondsPerHour; | ||
1802 | result += d.minutes * gSecondsPerMinute; | ||
1803 | result += d.seconds; | ||
1804 | |||
1805 | if (d.is_neg) result *= -1; | ||
1806 | |||
1807 | return result; | ||
1808 | } | ||
1809 | |||
1810 | icalcomponent *ICalFormatImpl::createCalendarComponent(Calendar *cal) | ||
1811 | { | ||
1812 | icalcomponent *calendar; | ||
1813 | |||
1814 | // Root component | ||
1815 | calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT); | ||
1816 | |||
1817 | icalproperty *p; | ||
1818 | |||
1819 | // Product Identifier | ||
1820 | p = icalproperty_new_prodid(CalFormat::productId().utf8()); | ||
1821 | icalcomponent_add_property(calendar,p); | ||
1822 | |||
1823 | // TODO: Add time zone | ||
1824 | |||
1825 | // iCalendar version (2.0) | ||
1826 | p = icalproperty_new_version(const_cast<char *>(_ICAL_VERSION)); | ||
1827 | icalcomponent_add_property(calendar,p); | ||
1828 | |||
1829 | // Custom properties | ||
1830 | if( cal != 0 ) | ||
1831 | writeCustomProperties(calendar, cal); | ||
1832 | |||
1833 | return calendar; | ||
1834 | } | ||
1835 | |||
1836 | |||
1837 | |||
1838 | // take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc. | ||
1839 | // and break it down from its tree-like format into the dictionary format | ||
1840 | // that is used internally in the ICalFormatImpl. | ||
1841 | bool ICalFormatImpl::populate( Calendar *cal, icalcomponent *calendar) | ||
1842 | { | ||
1843 | // this function will populate the caldict dictionary and other event | ||
1844 | // lists. It turns vevents into Events and then inserts them. | ||
1845 | |||
1846 | if (!calendar) return false; | ||
1847 | |||
1848 | // TODO: check for METHOD | ||
1849 | #if 0 | ||
1850 | if ((curVO = isAPropertyOf(vcal, ICMethodProp)) != 0) { | ||
1851 | char *methodType = 0; | ||
1852 | methodType = fakeCString(vObjectUStringZValue(curVO)); | ||
1853 | if (mEnableDialogs) | ||
1854 | KMessageBox::information(mTopWidget, | ||
1855 | i18n("This calendar is an iTIP transaction of type \"%1\".") | ||
1856 | .arg(methodType), | ||
1857 | i18n("%1: iTIP Transaction").arg(CalFormat::application())); | ||
1858 | delete methodType; | ||
1859 | } | ||
1860 | #endif | ||
1861 | |||
1862 | icalproperty *p; | ||
1863 | |||
1864 | p = icalcomponent_get_first_property(calendar,ICAL_PRODID_PROPERTY); | ||
1865 | if (!p) { | ||
1866 | // TODO: does no PRODID really matter? | ||
1867 | // mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); | ||
1868 | // return false; | ||
1869 | mLoadedProductId = ""; | ||
1870 | mCalendarVersion = 0; | ||
1871 | } else { | ||
1872 | mLoadedProductId = QString::fromUtf8(icalproperty_get_prodid(p)); | ||
1873 | mCalendarVersion = CalFormat::calendarVersion(mLoadedProductId); | ||
1874 | |||
1875 | delete mCompat; | ||
1876 | mCompat = CompatFactory::createCompat( mLoadedProductId ); | ||
1877 | } | ||
1878 | |||
1879 | // TODO: check for unknown PRODID | ||
1880 | #if 0 | ||
1881 | if (!mCalendarVersion | ||
1882 | && CalFormat::productId() != mLoadedProductId) { | ||
1883 | // warn the user that we might have trouble reading non-known calendar. | ||
1884 | if (mEnableDialogs) | ||
1885 | KMessageBox::information(mTopWidget, | ||
1886 | i18n("This vCalendar file was not created by KOrganizer " | ||
1887 | "or any other product we support. Loading anyway..."), | ||
1888 | i18n("%1: Unknown vCalendar Vendor").arg(CalFormat::application())); | ||
1889 | } | ||
1890 | #endif | ||
1891 | |||
1892 | p = icalcomponent_get_first_property(calendar,ICAL_VERSION_PROPERTY); | ||
1893 | if (!p) { | ||
1894 | mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); | ||
1895 | return false; | ||
1896 | } else { | ||
1897 | const char *version = icalproperty_get_version(p); | ||
1898 | |||
1899 | if (strcmp(version,"1.0") == 0) { | ||
1900 | mParent->setException(new ErrorFormat(ErrorFormat::CalVersion1, | ||
1901 | i18n("Expected iCalendar format"))); | ||
1902 | return false; | ||
1903 | } else if (strcmp(version,"2.0") != 0) { | ||
1904 | mParent->setException(new ErrorFormat(ErrorFormat::CalVersionUnknown)); | ||
1905 | return false; | ||
1906 | } | ||
1907 | } | ||
1908 | |||
1909 | |||
1910 | // TODO: check for calendar format version | ||
1911 | #if 0 | ||
1912 | // warn the user we might have trouble reading this unknown version. | ||
1913 | if ((curVO = isAPropertyOf(vcal, VCVersionProp)) != 0) { | ||
1914 | char *s = fakeCString(vObjectUStringZValue(curVO)); | ||
1915 | if (strcmp(_VCAL_VERSION, s) != 0) | ||
1916 | if (mEnableDialogs) | ||
1917 | KMessageBox::sorry(mTopWidget, | ||
1918 | i18n("This vCalendar file has version %1.\n" | ||
1919 | "We only support %2.") | ||
1920 | .arg(s).arg(_VCAL_VERSION), | ||
1921 | i18n("%1: Unknown vCalendar Version").arg(CalFormat::application())); | ||
1922 | deleteStr(s); | ||
1923 | } | ||
1924 | #endif | ||
1925 | |||
1926 | // custom properties | ||
1927 | readCustomProperties(calendar, cal); | ||
1928 | |||
1929 | // TODO: set time zone | ||
1930 | #if 0 | ||
1931 | // set the time zone | ||
1932 | if ((curVO = isAPropertyOf(vcal, VCTimeZoneProp)) != 0) { | ||
1933 | char *s = fakeCString(vObjectUStringZValue(curVO)); | ||
1934 | cal->setTimeZone(s); | ||
1935 | deleteStr(s); | ||
1936 | } | ||
1937 | #endif | ||
1938 | |||
1939 | // Store all events with a relatedTo property in a list for post-processing | ||
1940 | mEventsRelate.clear(); | ||
1941 | mTodosRelate.clear(); | ||
1942 | // TODO: make sure that only actually added ecvens go to this lists. | ||
1943 | |||
1944 | icalcomponent *c; | ||
1945 | |||
1946 | // Iterate through all todos | ||
1947 | c = icalcomponent_get_first_component(calendar,ICAL_VTODO_COMPONENT); | ||
1948 | while (c) { | ||
1949 | // kdDebug(5800) << "----Todo found" << endl; | ||
1950 | Todo *todo = readTodo(c); | ||
1951 | if (!cal->todo(todo->uid())) cal->addTodo(todo); | ||
1952 | c = icalcomponent_get_next_component(calendar,ICAL_VTODO_COMPONENT); | ||
1953 | } | ||
1954 | |||
1955 | // Iterate through all events | ||
1956 | c = icalcomponent_get_first_component(calendar,ICAL_VEVENT_COMPONENT); | ||
1957 | while (c) { | ||
1958 | // kdDebug(5800) << "----Event found" << endl; | ||
1959 | Event *event = readEvent(c); | ||
1960 | if (!cal->event(event->uid())) cal->addEvent(event); | ||
1961 | c = icalcomponent_get_next_component(calendar,ICAL_VEVENT_COMPONENT); | ||
1962 | } | ||
1963 | |||
1964 | // Iterate through all journals | ||
1965 | c = icalcomponent_get_first_component(calendar,ICAL_VJOURNAL_COMPONENT); | ||
1966 | while (c) { | ||
1967 | // kdDebug(5800) << "----Journal found" << endl; | ||
1968 | Journal *journal = readJournal(c); | ||
1969 | if (!cal->journal(journal->uid())) cal->addJournal(journal); | ||
1970 | c = icalcomponent_get_next_component(calendar,ICAL_VJOURNAL_COMPONENT); | ||
1971 | } | ||
1972 | |||
1973 | #if 0 | ||
1974 | initPropIterator(&i, vcal); | ||
1975 | |||
1976 | // go through all the vobjects in the vcal | ||
1977 | while (moreIteration(&i)) { | ||
1978 | curVO = nextVObject(&i); | ||
1979 | |||
1980 | /************************************************************************/ | ||
1981 | |||
1982 | // now, check to see that the object is an event or todo. | ||
1983 | if (strcmp(vObjectName(curVO), VCEventProp) == 0) { | ||
1984 | |||
1985 | if ((curVOProp = isAPropertyOf(curVO, KPilotStatusProp)) != 0) { | ||
1986 | char *s; | ||
1987 | s = fakeCString(vObjectUStringZValue(curVOProp)); | ||
1988 | // check to see if event was deleted by the kpilot conduit | ||
1989 | if (atoi(s) == Event::SYNCDEL) { | ||
1990 | deleteStr(s); | ||
1991 | goto SKIP; | ||
1992 | } | ||
1993 | deleteStr(s); | ||
1994 | } | ||
1995 | |||
1996 | // this code checks to see if we are trying to read in an event | ||
1997 | // that we already find to be in the calendar. If we find this | ||
1998 | // to be the case, we skip the event. | ||
1999 | if ((curVOProp = isAPropertyOf(curVO, VCUniqueStringProp)) != 0) { | ||
2000 | char *s = fakeCString(vObjectUStringZValue(curVOProp)); | ||
2001 | QString tmpStr(s); | ||
2002 | deleteStr(s); | ||
2003 | |||
2004 | if (cal->event(tmpStr)) { | ||
2005 | goto SKIP; | ||
2006 | } | ||
2007 | if (cal->todo(tmpStr)) { | ||
2008 | goto SKIP; | ||
2009 | } | ||
2010 | } | ||
2011 | |||
2012 | if ((!(curVOProp = isAPropertyOf(curVO, VCDTstartProp))) && | ||
2013 | (!(curVOProp = isAPropertyOf(curVO, VCDTendProp)))) { | ||
2014 | kdDebug(5800) << "found a VEvent with no DTSTART and no DTEND! Skipping..." << endl; | ||
2015 | goto SKIP; | ||
2016 | } | ||
2017 | |||
2018 | anEvent = VEventToEvent(curVO); | ||
2019 | // we now use addEvent instead of insertEvent so that the | ||
2020 | // signal/slot get connected. | ||
2021 | if (anEvent) | ||
2022 | cal->addEvent(anEvent); | ||
2023 | else { | ||
2024 | // some sort of error must have occurred while in translation. | ||
2025 | goto SKIP; | ||
2026 | } | ||
2027 | } else if (strcmp(vObjectName(curVO), VCTodoProp) == 0) { | ||
2028 | anEvent = VTodoToEvent(curVO); | ||
2029 | cal->addTodo(anEvent); | ||
2030 | } else if ((strcmp(vObjectName(curVO), VCVersionProp) == 0) || | ||
2031 | (strcmp(vObjectName(curVO), VCProdIdProp) == 0) || | ||
2032 | (strcmp(vObjectName(curVO), VCTimeZoneProp) == 0)) { | ||
2033 | // do nothing, we know these properties and we want to skip them. | ||
2034 | // we have either already processed them or are ignoring them. | ||
2035 | ; | ||
2036 | } else { | ||
2037 | ; | ||
2038 | } | ||
2039 | SKIP: | ||
2040 | ; | ||
2041 | } // while | ||
2042 | #endif | ||
2043 | |||
2044 | // Post-Process list of events with relations, put Event objects in relation | ||
2045 | Event *ev; | ||
2046 | for ( ev=mEventsRelate.first(); ev != 0; ev=mEventsRelate.next() ) { | ||
2047 | ev->setRelatedTo(cal->event(ev->relatedToUid())); | ||
2048 | } | ||
2049 | Todo *todo; | ||
2050 | for ( todo=mTodosRelate.first(); todo != 0; todo=mTodosRelate.next() ) { | ||
2051 | todo->setRelatedTo(cal->todo(todo->relatedToUid())); | ||
2052 | } | ||
2053 | |||
2054 | return true; | ||
2055 | } | ||
2056 | |||
2057 | QString ICalFormatImpl::extractErrorProperty(icalcomponent *c) | ||
2058 | { | ||
2059 | // kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " | ||
2060 | // << icalcomponent_as_ical_string(c) << endl; | ||
2061 | |||
2062 | QString errorMessage; | ||
2063 | |||
2064 | icalproperty *error; | ||
2065 | error = icalcomponent_get_first_property(c,ICAL_XLICERROR_PROPERTY); | ||
2066 | while(error) { | ||
2067 | errorMessage += icalproperty_get_xlicerror(error); | ||
2068 | errorMessage += "\n"; | ||
2069 | error = icalcomponent_get_next_property(c,ICAL_XLICERROR_PROPERTY); | ||
2070 | } | ||
2071 | |||
2072 | // kdDebug(5800) << "ICalFormatImpl:extractErrorProperty: " << errorMessage << endl; | ||
2073 | |||
2074 | return errorMessage; | ||
2075 | } | ||
2076 | |||
2077 | void ICalFormatImpl::dumpIcalRecurrence(icalrecurrencetype r) | ||
2078 | { | ||
2079 | int i; | ||
2080 | |||
2081 | |||
2082 | if (r.by_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2083 | int index = 0; | ||
2084 | QString out = " By Day: "; | ||
2085 | while((i = r.by_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2086 | out.append(QString::number(i) + " "); | ||
2087 | } | ||
2088 | } | ||
2089 | if (r.by_month_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2090 | int index = 0; | ||
2091 | QString out = " By Month Day: "; | ||
2092 | while((i = r.by_month_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2093 | out.append(QString::number(i) + " "); | ||
2094 | } | ||
2095 | } | ||
2096 | if (r.by_year_day[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2097 | int index = 0; | ||
2098 | QString out = " By Year Day: "; | ||
2099 | while((i = r.by_year_day[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2100 | out.append(QString::number(i) + " "); | ||
2101 | } | ||
2102 | } | ||
2103 | if (r.by_month[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2104 | int index = 0; | ||
2105 | QString out = " By Month: "; | ||
2106 | while((i = r.by_month[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2107 | out.append(QString::number(i) + " "); | ||
2108 | } | ||
2109 | } | ||
2110 | if (r.by_set_pos[0] != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2111 | int index = 0; | ||
2112 | QString out = " By Set Pos: "; | ||
2113 | while((i = r.by_set_pos[index++]) != ICAL_RECURRENCE_ARRAY_MAX) { | ||
2114 | out.append(QString::number(i) + " "); | ||
2115 | } | ||
2116 | } | ||
2117 | } | ||
2118 | |||
2119 | icalcomponent *ICalFormatImpl::createScheduleComponent(IncidenceBase *incidence, | ||
2120 | Scheduler::Method method) | ||
2121 | { | ||
2122 | icalcomponent *message = createCalendarComponent(); | ||
2123 | |||
2124 | icalproperty_method icalmethod = ICAL_METHOD_NONE; | ||
2125 | |||
2126 | switch (method) { | ||
2127 | case Scheduler::Publish: | ||
2128 | icalmethod = ICAL_METHOD_PUBLISH; | ||
2129 | break; | ||
2130 | case Scheduler::Request: | ||
2131 | icalmethod = ICAL_METHOD_REQUEST; | ||
2132 | break; | ||
2133 | case Scheduler::Refresh: | ||
2134 | icalmethod = ICAL_METHOD_REFRESH; | ||
2135 | break; | ||
2136 | case Scheduler::Cancel: | ||
2137 | icalmethod = ICAL_METHOD_CANCEL; | ||
2138 | break; | ||
2139 | case Scheduler::Add: | ||
2140 | icalmethod = ICAL_METHOD_ADD; | ||
2141 | break; | ||
2142 | case Scheduler::Reply: | ||
2143 | icalmethod = ICAL_METHOD_REPLY; | ||
2144 | break; | ||
2145 | case Scheduler::Counter: | ||
2146 | icalmethod = ICAL_METHOD_COUNTER; | ||
2147 | break; | ||
2148 | case Scheduler::Declinecounter: | ||
2149 | icalmethod = ICAL_METHOD_DECLINECOUNTER; | ||
2150 | break; | ||
2151 | default: | ||
2152 | |||
2153 | return message; | ||
2154 | } | ||
2155 | |||
2156 | icalcomponent_add_property(message,icalproperty_new_method(icalmethod)); | ||
2157 | |||
2158 | // TODO: check, if dynamic cast is required | ||
2159 | if(incidence->type() == "Todo") { | ||
2160 | Todo *todo = static_cast<Todo *>(incidence); | ||
2161 | icalcomponent_add_component(message,writeTodo(todo)); | ||
2162 | } | ||
2163 | if(incidence->type() == "Event") { | ||
2164 | Event *event = static_cast<Event *>(incidence); | ||
2165 | icalcomponent_add_component(message,writeEvent(event)); | ||
2166 | } | ||
2167 | if(incidence->type() == "FreeBusy") { | ||
2168 | FreeBusy *freebusy = static_cast<FreeBusy *>(incidence); | ||
2169 | icalcomponent_add_component(message,writeFreeBusy(freebusy, method)); | ||
2170 | } | ||
2171 | |||
2172 | return message; | ||
2173 | } | ||