• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepimlibs API Reference
  • KDE Home
  • Contact Us
 

KCal Library

  • sources
  • kde-4.12
  • kdepimlibs
  • kcal
vcalformat.cpp
Go to the documentation of this file.
1 /*
2  This file is part of the kcal library.
3 
4  Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
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 */
38 #include "vcalformat.h"
39 #include "calendar.h"
40 #include "versit/vcc.h"
41 #include "versit/vobject.h"
42 
43 #include <kdebug.h>
44 #include <kdatetime.h>
45 #include <klocalizedstring.h>
46 
47 #include <QtCore/QString>
48 #include <QtCore/QRegExp>
49 #include <QtCore/QFile>
50 #include <QtCore/QByteArray>
51 #include <QTextDocument>
52 
53 using namespace KCal;
54 
59 //@cond PRIVATE
60 class KCal::VCalFormat::Private
61 {
62  public:
63  Calendar *mCalendar;
64  Event::List mEventsRelate; // Events with relations
65  Todo::List mTodosRelate; // To-dos with relations
66 };
67 //@endcond
68 
69 VCalFormat::VCalFormat() : d( new KCal::VCalFormat::Private )
70 {
71 }
72 
73 VCalFormat::~VCalFormat()
74 {
75  delete d;
76 }
77 
78 bool VCalFormat::load( Calendar *calendar, const QString &fileName )
79 {
80  d->mCalendar = calendar;
81 
82  clearException();
83 
84  kDebug() << fileName;
85 
86  VObject *vcal = 0;
87 
88  // this is not necessarily only 1 vcal. Could be many vcals, or include
89  // a vcard...
90  vcal = Parse_MIME_FromFileName( const_cast<char *>( QFile::encodeName( fileName ).data() ) );
91 
92  if ( !vcal ) {
93  setException( new ErrorFormat( ErrorFormat::CalVersionUnknown ) );
94  return false;
95  }
96 
97  // any other top-level calendar stuff should be added/initialized here
98 
99  // put all vobjects into their proper places
100  populate( vcal );
101 
102  // clean up from vcal API stuff
103  cleanVObjects( vcal );
104  cleanStrTbl();
105 
106  return true;
107 }
108 
109 bool VCalFormat::save( Calendar *calendar, const QString &fileName )
110 {
111  d->mCalendar = calendar;
112 
113  QString tmpStr;
114  VObject *vcal, *vo;
115 
116  kDebug() << fileName;
117 
118  vcal = newVObject( VCCalProp );
119 
120  // addPropValue(vcal,VCLocationProp, "0.0");
121  addPropValue( vcal, VCProdIdProp, productId().toLatin1() );
122  addPropValue( vcal, VCVersionProp, _VCAL_VERSION );
123 
124  // TODO STUFF
125  Todo::List todoList = d->mCalendar->rawTodos();
126  Todo::List::ConstIterator it;
127  for ( it = todoList.constBegin(); it != todoList.constEnd(); ++it ) {
128  vo = eventToVTodo( *it );
129  addVObjectProp( vcal, vo );
130  }
131 
132  // EVENT STUFF
133  Event::List events = d->mCalendar->rawEvents();
134  Event::List::ConstIterator it2;
135  for ( it2 = events.constBegin(); it2 != events.constEnd(); ++it2 ) {
136  vo = eventToVEvent( *it2 );
137  addVObjectProp( vcal, vo );
138  }
139 
140  writeVObjectToFile( QFile::encodeName( fileName ).data(), vcal );
141  cleanVObjects( vcal );
142  cleanStrTbl();
143 
144  if ( QFile::exists( fileName ) ) {
145  return true;
146  } else {
147  return false; // error
148  }
149 
150  return false;
151 }
152 
153 bool VCalFormat::fromString( Calendar *calendar, const QString &string )
154 {
155  return fromRawString( calendar, string.toUtf8() );
156 }
157 
158 bool VCalFormat::fromRawString( Calendar *calendar, const QByteArray &string )
159 {
160  d->mCalendar = calendar;
161 
162  if ( !string.size() ) {
163  return false;
164  }
165 
166  VObject *vcal = Parse_MIME( string.data(), string.size() );
167  if ( !vcal ) {
168  return false;
169  }
170 
171  VObjectIterator i;
172  VObject *curvo;
173  initPropIterator( &i, vcal );
174 
175  // we only take the first object. TODO: parse all incidences.
176  do {
177  curvo = nextVObject( &i );
178  } while ( strcmp( vObjectName( curvo ), VCEventProp ) &&
179  strcmp( vObjectName( curvo ), VCTodoProp ) );
180 
181  if ( strcmp( vObjectName( curvo ), VCEventProp ) == 0 ) {
182  Event *event = VEventToEvent( curvo );
183  calendar->addEvent( event );
184  } else {
185  kDebug() << "Unknown object type.";
186  deleteVObject( vcal );
187  return false;
188  }
189 
190  deleteVObject( vcal );
191 
192  return true;
193 }
194 
195 QString VCalFormat::toString( Calendar *calendar )
196 {
197  // TODO: Factor out VCalFormat::asString()
198  d->mCalendar = calendar;
199 
200  VObject *vcal = newVObject( VCCalProp );
201 
202  addPropValue( vcal, VCProdIdProp, CalFormat::productId().toLatin1() );
203  addPropValue( vcal, VCVersionProp, _VCAL_VERSION );
204 
205  // TODO: Use all data.
206  Event::List events = calendar->events();
207  if( events.isEmpty() ) {
208  cleanVObject ( vcal );
209  return QString();
210  }
211  Event *event = events.first();
212  if ( !event ) {
213  cleanVObject ( vcal );
214  return QString();
215  }
216  VObject *vevent = eventToVEvent( event );
217 
218  addVObjectProp( vcal, vevent );
219 
220  char *buf = writeMemVObject( 0, 0, vcal );
221 
222  QString result( buf );
223 
224  cleanVObject( vcal );
225 
226  return result;
227 }
228 
229 VObject *VCalFormat::eventToVTodo( const Todo *anEvent )
230 {
231  VObject *vtodo;
232  QString tmpStr;
233 
234  vtodo = newVObject( VCTodoProp );
235 
236  // due date
237  if ( anEvent->hasDueDate() ) {
238  tmpStr = kDateTimeToISO( anEvent->dtDue(), !anEvent->allDay() );
239  addPropValue( vtodo, VCDueProp, tmpStr.toLocal8Bit() );
240  }
241 
242  // start date
243  if ( anEvent->hasStartDate() ) {
244  tmpStr = kDateTimeToISO( anEvent->dtStart(), !anEvent->allDay() );
245  addPropValue( vtodo, VCDTstartProp, tmpStr.toLocal8Bit() );
246  }
247 
248  // creation date
249  tmpStr = kDateTimeToISO( anEvent->created() );
250  addPropValue( vtodo, VCDCreatedProp, tmpStr.toLocal8Bit() );
251 
252  // unique id
253  addPropValue( vtodo, VCUniqueStringProp,
254  anEvent->uid().toLocal8Bit() );
255 
256  // revision
257  tmpStr.sprintf( "%i", anEvent->revision() );
258  addPropValue( vtodo, VCSequenceProp, tmpStr.toLocal8Bit() );
259 
260  // last modification date
261  tmpStr = kDateTimeToISO( anEvent->lastModified() );
262  addPropValue( vtodo, VCLastModifiedProp, tmpStr.toLocal8Bit() );
263 
264  // organizer stuff
265  // @TODO: How about the common name?
266  if ( !anEvent->organizer().email().isEmpty() ) {
267  tmpStr = "MAILTO:" + anEvent->organizer().email();
268  addPropValue( vtodo, ICOrganizerProp, tmpStr.toLocal8Bit() );
269  }
270 
271  // attendees
272  if ( anEvent->attendeeCount() > 0 ) {
273  Attendee::List::ConstIterator it;
274  Attendee *curAttendee;
275  for ( it = anEvent->attendees().begin(); it != anEvent->attendees().end();
276  ++it ) {
277  curAttendee = *it;
278  if ( !curAttendee->email().isEmpty() &&
279  !curAttendee->name().isEmpty() ) {
280  tmpStr = "MAILTO:" + curAttendee->name() + " <" + curAttendee->email() + '>';
281  } else if ( curAttendee->name().isEmpty() ) {
282  tmpStr = "MAILTO: " + curAttendee->email();
283  } else if ( curAttendee->email().isEmpty() ) {
284  tmpStr = "MAILTO: " + curAttendee->name();
285  } else if ( curAttendee->name().isEmpty() && curAttendee->email().isEmpty() ) {
286  kDebug() << "warning! this Event has an attendee w/o name or email!";
287  }
288  VObject *aProp = addPropValue( vtodo, VCAttendeeProp, tmpStr.toLocal8Bit() );
289  addPropValue( aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE" );
290  addPropValue( aProp, VCStatusProp, writeStatus( curAttendee->status() ) );
291  }
292  }
293 
294  // description BL:
295  if ( !anEvent->description().isEmpty() ) {
296  VObject *dObject = addPropValue( vtodo, VCDescriptionProp,
297  anEvent->description().toLocal8Bit() );
298  if ( anEvent->description().indexOf( '\n' ) != -1 ) {
299  addPropValue( dObject, VCEncodingProp, VCQuotedPrintableProp );
300  }
301  }
302 
303  // summary
304  if ( !anEvent->summary().isEmpty() ) {
305  addPropValue( vtodo, VCSummaryProp, anEvent->summary().toLocal8Bit() );
306  }
307 
308  // location
309  if ( !anEvent->location().isEmpty() ) {
310  addPropValue( vtodo, VCLocationProp, anEvent->location().toLocal8Bit() );
311  }
312 
313  // completed status
314  // backward compatibility, KOrganizer used to interpret only these two values
315  addPropValue( vtodo, VCStatusProp, anEvent->isCompleted() ? "COMPLETED" : "NEEDS_ACTION" );
316 
317  // completion date
318  if ( anEvent->hasCompletedDate() ) {
319  tmpStr = kDateTimeToISO( anEvent->completed() );
320  addPropValue( vtodo, VCCompletedProp, tmpStr.toLocal8Bit() );
321  }
322 
323  // priority
324  tmpStr.sprintf( "%i", anEvent->priority() );
325  addPropValue( vtodo, VCPriorityProp, tmpStr.toLocal8Bit() );
326 
327  // related event
328  if ( anEvent->relatedTo() ) {
329  addPropValue( vtodo, VCRelatedToProp,
330  anEvent->relatedTo()->uid().toLocal8Bit() );
331  }
332 
333  // categories
334  const QStringList tmpStrList = anEvent->categories();
335  tmpStr = "";
336  QString catStr;
337  QStringList::const_iterator its;
338  for ( its = tmpStrList.constBegin(); its != tmpStrList.constEnd(); ++its ) {
339  catStr = *its;
340  if ( catStr[0] == ' ' ) {
341  tmpStr += catStr.mid( 1 );
342  } else {
343  tmpStr += catStr;
344  }
345  // this must be a ';' character as the vCalendar specification requires!
346  // vcc.y has been hacked to translate the ';' to a ',' when the vcal is
347  // read in.
348  tmpStr += ';';
349  }
350  if ( !tmpStr.isEmpty() ) {
351  tmpStr.truncate( tmpStr.length() - 1 );
352  addPropValue( vtodo, VCCategoriesProp, tmpStr.toLocal8Bit() );
353  }
354 
355  // alarm stuff
356  Alarm::List::ConstIterator it;
357  for ( it = anEvent->alarms().begin(); it != anEvent->alarms().end(); ++it ) {
358  Alarm *alarm = *it;
359  if ( alarm->enabled() ) {
360  VObject *a = addProp( vtodo, VCDAlarmProp );
361  tmpStr = kDateTimeToISO( alarm->time() );
362  addPropValue( a, VCRunTimeProp, tmpStr.toLocal8Bit() );
363  addPropValue( a, VCRepeatCountProp, "1" );
364  addPropValue( a, VCDisplayStringProp, "beep!" );
365  if ( alarm->type() == Alarm::Audio ) {
366  a = addProp( vtodo, VCAAlarmProp );
367  addPropValue( a, VCRunTimeProp, tmpStr.toLocal8Bit() );
368  addPropValue( a, VCRepeatCountProp, "1" );
369  addPropValue( a, VCAudioContentProp, QFile::encodeName( alarm->audioFile() ) );
370  } else if ( alarm->type() == Alarm::Procedure ) {
371  a = addProp( vtodo, VCPAlarmProp );
372  addPropValue( a, VCRunTimeProp, tmpStr.toLocal8Bit() );
373  addPropValue( a, VCRepeatCountProp, "1" );
374  addPropValue( a, VCProcedureNameProp, QFile::encodeName( alarm->programFile() ) );
375  }
376  }
377  }
378 
379  QString pilotId = anEvent->nonKDECustomProperty( KPilotIdProp );
380  if ( !pilotId.isEmpty() ) {
381  // pilot sync stuff
382  addPropValue( vtodo, KPilotIdProp, pilotId.toLocal8Bit() );
383  addPropValue( vtodo, KPilotStatusProp,
384  anEvent->nonKDECustomProperty( KPilotStatusProp ).toLocal8Bit() );
385  }
386 
387  return vtodo;
388 }
389 
390 VObject *VCalFormat::eventToVEvent( const Event *anEvent )
391 {
392  VObject *vevent;
393  QString tmpStr;
394 
395  vevent = newVObject( VCEventProp );
396 
397  // start and end time
398  tmpStr = kDateTimeToISO( anEvent->dtStart(), !anEvent->allDay() );
399  addPropValue( vevent, VCDTstartProp, tmpStr.toLocal8Bit() );
400 
401  // events that have time associated but take up no time should
402  // not have both DTSTART and DTEND.
403  if ( anEvent->dtStart() != anEvent->dtEnd() ) {
404  tmpStr = kDateTimeToISO( anEvent->dtEnd(), !anEvent->allDay() );
405  addPropValue( vevent, VCDTendProp, tmpStr.toLocal8Bit() );
406  }
407 
408  // creation date
409  tmpStr = kDateTimeToISO( anEvent->created() );
410  addPropValue( vevent, VCDCreatedProp, tmpStr.toLocal8Bit() );
411 
412  // unique id
413  addPropValue( vevent, VCUniqueStringProp,
414  anEvent->uid().toLocal8Bit() );
415 
416  // revision
417  tmpStr.sprintf( "%i", anEvent->revision() );
418  addPropValue( vevent, VCSequenceProp, tmpStr.toLocal8Bit() );
419 
420  // last modification date
421  tmpStr = kDateTimeToISO( anEvent->lastModified() );
422  addPropValue( vevent, VCLastModifiedProp, tmpStr.toLocal8Bit() );
423 
424  // attendee and organizer stuff
425  // TODO: What to do with the common name?
426  if ( !anEvent->organizer().email().isEmpty() ) {
427  tmpStr = "MAILTO:" + anEvent->organizer().email();
428  addPropValue( vevent, ICOrganizerProp, tmpStr.toLocal8Bit() );
429  }
430 
431  // TODO: Put this functionality into Attendee class
432  if ( anEvent->attendeeCount() > 0 ) {
433  Attendee::List::ConstIterator it;
434  for ( it = anEvent->attendees().constBegin(); it != anEvent->attendees().constEnd();
435  ++it ) {
436  Attendee *curAttendee = *it;
437  if ( !curAttendee->email().isEmpty() && !curAttendee->name().isEmpty() ) {
438  tmpStr = "MAILTO:" + curAttendee->name() + " <" + curAttendee->email() + '>';
439  } else if ( curAttendee->name().isEmpty() ) {
440  tmpStr = "MAILTO: " + curAttendee->email();
441  } else if ( curAttendee->email().isEmpty() ) {
442  tmpStr = "MAILTO: " + curAttendee->name();
443  } else if ( curAttendee->name().isEmpty() && curAttendee->email().isEmpty() ) {
444  kDebug() << "warning! this Event has an attendee w/o name or email!";
445  }
446  VObject *aProp = addPropValue( vevent, VCAttendeeProp, tmpStr.toLocal8Bit() );
447  addPropValue( aProp, VCRSVPProp, curAttendee->RSVP() ? "TRUE" : "FALSE" );
448  addPropValue( aProp, VCStatusProp, writeStatus( curAttendee->status() ) );
449  }
450  }
451 
452  // recurrence rule stuff
453  const Recurrence *recur = anEvent->recurrence();
454  if ( recur->recurs() ) {
455  bool validRecur = true;
456  QString tmpStr2;
457  switch ( recur->recurrenceType() ) {
458  case Recurrence::rDaily:
459  tmpStr.sprintf( "D%i ", recur->frequency() );
460  break;
461  case Recurrence::rWeekly:
462  tmpStr.sprintf( "W%i ", recur->frequency() );
463  for ( int i = 0; i < 7; ++i ) {
464  QBitArray days ( recur->days() );
465  if ( days.testBit(i) ) {
466  tmpStr += dayFromNum( i );
467  }
468  }
469  break;
470  case Recurrence::rMonthlyPos:
471  {
472  tmpStr.sprintf( "MP%i ", recur->frequency() );
473  // write out all rMonthPos's
474  QList<RecurrenceRule::WDayPos> tmpPositions = recur->monthPositions();
475  for ( QList<RecurrenceRule::WDayPos>::ConstIterator posit = tmpPositions.constBegin();
476  posit != tmpPositions.constEnd(); ++posit ) {
477  int pos = (*posit).pos();
478  tmpStr2.sprintf( "%i", ( pos > 0 ) ? pos : (-pos) );
479  if ( pos < 0 ) {
480  tmpStr2 += "- ";
481  } else {
482  tmpStr2 += "+ ";
483  }
484  tmpStr += tmpStr2;
485  tmpStr += dayFromNum( (*posit).day() - 1 );
486  }
487  break;
488  }
489  case Recurrence::rMonthlyDay:
490  {
491  tmpStr.sprintf( "MD%i ", recur->frequency() );
492  // write out all rMonthDays;
493  const QList<int> tmpDays = recur->monthDays();
494  for ( QList<int>::ConstIterator tmpDay = tmpDays.constBegin();
495  tmpDay != tmpDays.constEnd(); ++tmpDay ) {
496  tmpStr2.sprintf( "%i ", *tmpDay );
497  tmpStr += tmpStr2;
498  }
499  break;
500  }
501  case Recurrence::rYearlyMonth:
502  {
503  tmpStr.sprintf( "YM%i ", recur->frequency() );
504  // write out all the months;'
505  // TODO: Any way to write out the day within the month???
506  const QList<int> months = recur->yearMonths();
507  for ( QList<int>::ConstIterator mit = months.constBegin();
508  mit != months.constEnd(); ++mit ) {
509  tmpStr2.sprintf( "%i ", *mit );
510  tmpStr += tmpStr2;
511  }
512  break;
513  }
514  case Recurrence::rYearlyDay:
515  {
516  tmpStr.sprintf( "YD%i ", recur->frequency() );
517  // write out all the rYearNums;
518  const QList<int> tmpDays = recur->yearDays();
519  for ( QList<int>::ConstIterator tmpDay = tmpDays.begin();
520  tmpDay != tmpDays.end(); ++tmpDay ) {
521  tmpStr2.sprintf( "%i ", *tmpDay );
522  tmpStr += tmpStr2;
523  }
524  break;
525  }
526  default:
527  // TODO: Write rYearlyPos and arbitrary rules!
528  kDebug() << "ERROR, it should never get here in eventToVEvent!";
529  validRecur = false;
530  break;
531  } // switch
532 
533  if ( recur->duration() > 0 ) {
534  tmpStr2.sprintf( "#%i", recur->duration() );
535  tmpStr += tmpStr2;
536  } else if ( recur->duration() == -1 ) {
537  tmpStr += "#0"; // defined as repeat forever
538  } else {
539  tmpStr += kDateTimeToISO( recur->endDateTime(), false );
540  }
541  // Only write out the rrule if we have a valid recurrence (i.e. a known
542  // type in thee switch above)
543  if ( validRecur ) {
544  addPropValue( vevent, VCRRuleProp, tmpStr.toLocal8Bit() );
545  }
546 
547  } // event repeats
548 
549  // exceptions to recurrence
550  DateList dateList = recur->exDates();
551  DateList::ConstIterator it;
552  QString tmpStr2;
553 
554  for ( it = dateList.constBegin(); it != dateList.constEnd(); ++it ) {
555  tmpStr = qDateToISO(*it) + ';';
556  tmpStr2 += tmpStr;
557  }
558  if ( !tmpStr2.isEmpty() ) {
559  tmpStr2.truncate( tmpStr2.length() - 1 );
560  addPropValue( vevent, VCExpDateProp, tmpStr2.toLocal8Bit() );
561  }
562 
563  // description
564  if ( !anEvent->description().isEmpty() ) {
565  VObject *dObject = addPropValue( vevent, VCDescriptionProp,
566  anEvent->description().toLocal8Bit() );
567  if ( anEvent->description().indexOf( '\n' ) != -1 ) {
568  addPropValue( dObject, VCEncodingProp, VCQuotedPrintableProp );
569  }
570  }
571 
572  // summary
573  if ( !anEvent->summary().isEmpty() ) {
574  addPropValue( vevent, VCSummaryProp, anEvent->summary().toLocal8Bit() );
575  }
576 
577  // location
578  if ( !anEvent->location().isEmpty() ) {
579  addPropValue( vevent, VCLocationProp, anEvent->location().toLocal8Bit() );
580  }
581 
582  // status
583 // TODO: define Event status
584 // addPropValue( vevent, VCStatusProp, anEvent->statusStr().toLocal8Bit() );
585 
586  // secrecy
587  const char *text = 0;
588  switch ( anEvent->secrecy() ) {
589  case Incidence::SecrecyPublic:
590  text = "PUBLIC";
591  break;
592  case Incidence::SecrecyPrivate:
593  text = "PRIVATE";
594  break;
595  case Incidence::SecrecyConfidential:
596  text = "CONFIDENTIAL";
597  break;
598  }
599  if ( text ) {
600  addPropValue( vevent, VCClassProp, text );
601  }
602 
603  // categories
604  QStringList tmpStrList = anEvent->categories();
605  tmpStr = "";
606  QString catStr;
607  for ( QStringList::const_iterator it = tmpStrList.constBegin(); it != tmpStrList.constEnd();
608  ++it ) {
609  catStr = *it;
610  if ( catStr[0] == ' ' ) {
611  tmpStr += catStr.mid( 1 );
612  } else {
613  tmpStr += catStr;
614  }
615  // this must be a ';' character as the vCalendar specification requires!
616  // vcc.y has been hacked to translate the ';' to a ',' when the vcal is
617  // read in.
618  tmpStr += ';';
619  }
620  if ( !tmpStr.isEmpty() ) {
621  tmpStr.truncate( tmpStr.length() - 1 );
622  addPropValue( vevent, VCCategoriesProp, tmpStr.toLocal8Bit() );
623  }
624 
625  // attachments
626  // TODO: handle binary attachments!
627  Attachment::List attachments = anEvent->attachments();
628  Attachment::List::ConstIterator atIt;
629  for ( atIt = attachments.constBegin(); atIt != attachments.constEnd(); ++atIt ) {
630  addPropValue( vevent, VCAttachProp, (*atIt)->uri().toLocal8Bit() );
631  }
632 
633  // resources
634  tmpStrList = anEvent->resources();
635  tmpStr = tmpStrList.join( ";" );
636  if ( !tmpStr.isEmpty() ) {
637  addPropValue( vevent, VCResourcesProp, tmpStr.toLocal8Bit() );
638  }
639 
640  // alarm stuff
641  Alarm::List::ConstIterator it2;
642  for ( it2 = anEvent->alarms().constBegin(); it2 != anEvent->alarms().constEnd(); ++it2 ) {
643  Alarm *alarm = *it2;
644  if ( alarm->enabled() ) {
645  VObject *a = addProp( vevent, VCDAlarmProp );
646  tmpStr = kDateTimeToISO( alarm->time() );
647  addPropValue( a, VCRunTimeProp, tmpStr.toLocal8Bit() );
648  addPropValue( a, VCRepeatCountProp, "1" );
649  addPropValue( a, VCDisplayStringProp, "beep!" );
650  if ( alarm->type() == Alarm::Audio ) {
651  a = addProp( vevent, VCAAlarmProp );
652  addPropValue( a, VCRunTimeProp, tmpStr.toLocal8Bit() );
653  addPropValue( a, VCRepeatCountProp, "1" );
654  addPropValue( a, VCAudioContentProp, QFile::encodeName( alarm->audioFile() ) );
655  }
656  if ( alarm->type() == Alarm::Procedure ) {
657  a = addProp( vevent, VCPAlarmProp );
658  addPropValue( a, VCRunTimeProp, tmpStr.toLocal8Bit() );
659  addPropValue( a, VCRepeatCountProp, "1" );
660  addPropValue( a, VCProcedureNameProp, QFile::encodeName( alarm->programFile() ) );
661  }
662  }
663  }
664 
665  // priority
666  tmpStr.sprintf( "%i", anEvent->priority() );
667  addPropValue( vevent, VCPriorityProp, tmpStr.toLocal8Bit() );
668 
669  // transparency
670  tmpStr.sprintf( "%i", anEvent->transparency() );
671  addPropValue( vevent, VCTranspProp, tmpStr.toLocal8Bit() );
672 
673  // related event
674  if ( anEvent->relatedTo() ) {
675  addPropValue( vevent, VCRelatedToProp, anEvent->relatedTo()->uid().toLocal8Bit() );
676  }
677 
678  QString pilotId = anEvent->nonKDECustomProperty( KPilotIdProp );
679  if ( !pilotId.isEmpty() ) {
680  // pilot sync stuff
681  addPropValue( vevent, KPilotIdProp, pilotId.toLocal8Bit() );
682  addPropValue( vevent, KPilotStatusProp,
683  anEvent->nonKDECustomProperty( KPilotStatusProp ).toLocal8Bit() );
684  }
685 
686  return vevent;
687 }
688 
689 Todo *VCalFormat::VTodoToEvent( VObject *vtodo )
690 {
691  VObject *vo;
692  VObjectIterator voi;
693  char *s;
694 
695  Todo *anEvent = new Todo;
696 
697  // creation date
698  if ( ( vo = isAPropertyOf( vtodo, VCDCreatedProp ) ) != 0 ) {
699  anEvent->setCreated( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
700  deleteStr( s );
701  }
702 
703  // unique id
704  vo = isAPropertyOf( vtodo, VCUniqueStringProp );
705  // while the UID property is preferred, it is not required. We'll use the
706  // default Event UID if none is given.
707  if ( vo ) {
708  anEvent->setUid( s = fakeCString( vObjectUStringZValue( vo ) ) );
709  deleteStr( s );
710  }
711 
712  // last modification date
713  if ( ( vo = isAPropertyOf( vtodo, VCLastModifiedProp ) ) != 0 ) {
714  anEvent->setLastModified( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
715  deleteStr( s );
716  } else {
717  anEvent->setLastModified( KDateTime::currentUtcDateTime() );
718  }
719 
720  // organizer
721  // if our extension property for the event's ORGANIZER exists, add it.
722  if ( ( vo = isAPropertyOf( vtodo, ICOrganizerProp ) ) != 0 ) {
723  anEvent->setOrganizer( s = fakeCString( vObjectUStringZValue( vo ) ) );
724  deleteStr( s );
725  } else {
726  anEvent->setOrganizer( d->mCalendar->owner() );
727  }
728 
729  // attendees.
730  initPropIterator( &voi, vtodo );
731  while ( moreIteration( &voi ) ) {
732  vo = nextVObject( &voi );
733  if ( strcmp( vObjectName( vo ), VCAttendeeProp ) == 0 ) {
734  Attendee *a;
735  VObject *vp;
736  s = fakeCString( vObjectUStringZValue( vo ) );
737  QString tmpStr = QString::fromLocal8Bit( s );
738  deleteStr( s );
739  tmpStr = tmpStr.simplified();
740  int emailPos1, emailPos2;
741  if ( ( emailPos1 = tmpStr.indexOf( '<' ) ) > 0 ) {
742  // both email address and name
743  emailPos2 = tmpStr.lastIndexOf( '>' );
744  a = new Attendee( tmpStr.left( emailPos1 - 1 ),
745  tmpStr.mid( emailPos1 + 1,
746  emailPos2 - ( emailPos1 + 1 ) ) );
747  } else if ( tmpStr.indexOf( '@' ) > 0 ) {
748  // just an email address
749  a = new Attendee( 0, tmpStr );
750  } else {
751  // just a name
752  // WTF??? Replacing the spaces of a name and using this as email?
753  QString email = tmpStr.replace( ' ', '.' );
754  a = new Attendee( tmpStr, email );
755  }
756 
757  // is there an RSVP property?
758  if ( ( vp = isAPropertyOf( vo, VCRSVPProp ) ) != 0 ) {
759  a->setRSVP( vObjectStringZValue( vp ) );
760  }
761  // is there a status property?
762  if ( ( vp = isAPropertyOf( vo, VCStatusProp ) ) != 0 ) {
763  a->setStatus( readStatus( vObjectStringZValue( vp ) ) );
764  }
765  // add the attendee
766  anEvent->addAttendee( a );
767  }
768  }
769 
770  // description for todo
771  if ( ( vo = isAPropertyOf( vtodo, VCDescriptionProp ) ) != 0 ) {
772  s = fakeCString( vObjectUStringZValue( vo ) );
773  anEvent->setDescription( QString::fromLocal8Bit( s ), Qt::mightBeRichText( s ) );
774  deleteStr( s );
775  }
776 
777  // summary
778  if ( ( vo = isAPropertyOf( vtodo, VCSummaryProp ) ) ) {
779  s = fakeCString( vObjectUStringZValue( vo ) );
780  anEvent->setSummary( QString::fromLocal8Bit( s ), Qt::mightBeRichText( s ) );
781  deleteStr( s );
782  }
783 
784  // location
785  if ( ( vo = isAPropertyOf( vtodo, VCLocationProp ) ) != 0 ) {
786  s = fakeCString( vObjectUStringZValue( vo ) );
787  anEvent->setLocation( QString::fromLocal8Bit( s ), Qt::mightBeRichText( s ) );
788  deleteStr( s );
789  }
790 
791  // completed
792  // was: status
793  if ( ( vo = isAPropertyOf( vtodo, VCStatusProp ) ) != 0 ) {
794  s = fakeCString( vObjectUStringZValue( vo ) );
795  if ( s && strcmp( s, "COMPLETED" ) == 0 ) {
796  anEvent->setCompleted( true );
797  } else {
798  anEvent->setCompleted( false );
799  }
800  deleteStr( s );
801  } else {
802  anEvent->setCompleted( false );
803  }
804 
805  // completion date
806  if ( ( vo = isAPropertyOf( vtodo, VCCompletedProp ) ) != 0 ) {
807  anEvent->setCompleted( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
808  deleteStr( s );
809  }
810 
811  // priority
812  if ( ( vo = isAPropertyOf( vtodo, VCPriorityProp ) ) ) {
813  s = fakeCString( vObjectUStringZValue( vo ) );
814  if ( s ) {
815  anEvent->setPriority( atoi( s ) );
816  deleteStr( s );
817  }
818  }
819 
820  // due date
821  if ( ( vo = isAPropertyOf( vtodo, VCDueProp ) ) != 0 ) {
822  anEvent->setDtDue( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
823  deleteStr( s );
824  anEvent->setHasDueDate( true );
825  } else {
826  anEvent->setHasDueDate( false );
827  }
828 
829  // start time
830  if ( ( vo = isAPropertyOf( vtodo, VCDTstartProp ) ) != 0 ) {
831  anEvent->setDtStart( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
832  deleteStr( s );
833  anEvent->setHasStartDate( true );
834  } else {
835  anEvent->setHasStartDate( false );
836  }
837 
838  // alarm stuff
839  if ( ( vo = isAPropertyOf( vtodo, VCDAlarmProp ) ) ) {
840  Alarm *alarm = anEvent->newAlarm();
841  VObject *a;
842  if ( ( a = isAPropertyOf( vo, VCRunTimeProp ) ) ) {
843  alarm->setTime( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( a ) ) ) );
844  deleteStr( s );
845  }
846  alarm->setEnabled( true );
847  if ( ( vo = isAPropertyOf( vtodo, VCPAlarmProp ) ) ) {
848  if ( ( a = isAPropertyOf( vo, VCProcedureNameProp ) ) ) {
849  s = fakeCString( vObjectUStringZValue( a ) );
850  alarm->setProcedureAlarm( QFile::decodeName( s ) );
851  deleteStr( s );
852  }
853  }
854  if ( ( vo = isAPropertyOf( vtodo, VCAAlarmProp ) ) ) {
855  if ( ( a = isAPropertyOf( vo, VCAudioContentProp ) ) ) {
856  s = fakeCString( vObjectUStringZValue( a ) );
857  alarm->setAudioAlarm( QFile::decodeName( s ) );
858  deleteStr( s );
859  }
860  }
861  }
862 
863  // related todo
864  if ( ( vo = isAPropertyOf( vtodo, VCRelatedToProp ) ) != 0 ) {
865  anEvent->setRelatedToUid( s = fakeCString( vObjectUStringZValue( vo ) ) );
866  deleteStr( s );
867  d->mTodosRelate.append( anEvent );
868  }
869 
870  // categories
871  if ( ( vo = isAPropertyOf( vtodo, VCCategoriesProp ) ) != 0 ) {
872  s = fakeCString( vObjectUStringZValue( vo ) );
873  QString categories = QString::fromLocal8Bit( s );
874  deleteStr( s );
875  QStringList tmpStrList = categories.split( ';' );
876  anEvent->setCategories( tmpStrList );
877  }
878 
879  /* PILOT SYNC STUFF */
880  if ( ( vo = isAPropertyOf( vtodo, KPilotIdProp ) ) ) {
881  anEvent->setNonKDECustomProperty(
882  KPilotIdProp, QString::fromLocal8Bit( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
883  deleteStr( s );
884  if ( ( vo = isAPropertyOf( vtodo, KPilotStatusProp ) ) ) {
885  anEvent->setNonKDECustomProperty(
886  KPilotStatusProp, QString::fromLocal8Bit( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
887  deleteStr( s );
888  } else {
889  anEvent->setNonKDECustomProperty( KPilotStatusProp, QString::number( SYNCMOD ) );
890  }
891  }
892 
893  return anEvent;
894 }
895 
896 Event *VCalFormat::VEventToEvent( VObject *vevent )
897 {
898  VObject *vo;
899  VObjectIterator voi;
900  char *s;
901 
902  Event *anEvent = new Event;
903 
904  // creation date
905  if ( ( vo = isAPropertyOf( vevent, VCDCreatedProp ) ) != 0 ) {
906  anEvent->setCreated( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
907  deleteStr( s );
908  }
909 
910  // unique id
911  vo = isAPropertyOf( vevent, VCUniqueStringProp );
912  // while the UID property is preferred, it is not required. We'll use the
913  // default Event UID if none is given.
914  if ( vo ) {
915  anEvent->setUid( s = fakeCString( vObjectUStringZValue( vo ) ) );
916  deleteStr( s );
917  }
918 
919  // revision
920  // again NSCAL doesn't give us much to work with, so we improvise...
921  anEvent->setRevision( 0 );
922  if ( ( vo = isAPropertyOf( vevent, VCSequenceProp ) ) != 0 ) {
923  s = fakeCString( vObjectUStringZValue( vo ) );
924  if ( s ) {
925  anEvent->setRevision( atoi( s ) );
926  deleteStr( s );
927  }
928  }
929 
930  // last modification date
931  if ( ( vo = isAPropertyOf( vevent, VCLastModifiedProp ) ) != 0 ) {
932  anEvent->setLastModified( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
933  deleteStr( s );
934  } else {
935  anEvent->setLastModified( KDateTime::currentUtcDateTime() );
936  }
937 
938  // organizer
939  // if our extension property for the event's ORGANIZER exists, add it.
940  if ( ( vo = isAPropertyOf( vevent, ICOrganizerProp ) ) != 0 ) {
941  // FIXME: Also use the full name, not just the email address
942  anEvent->setOrganizer( s = fakeCString( vObjectUStringZValue( vo ) ) );
943  deleteStr( s );
944  } else {
945  anEvent->setOrganizer( d->mCalendar->owner() );
946  }
947 
948  // deal with attendees.
949  initPropIterator( &voi, vevent );
950  while ( moreIteration( &voi ) ) {
951  vo = nextVObject( &voi );
952  if ( strcmp( vObjectName( vo ), VCAttendeeProp ) == 0 ) {
953  Attendee *a;
954  VObject *vp;
955  s = fakeCString( vObjectUStringZValue( vo ) );
956  QString tmpStr = QString::fromLocal8Bit( s );
957  deleteStr( s );
958  tmpStr = tmpStr.simplified();
959  int emailPos1, emailPos2;
960  if ( ( emailPos1 = tmpStr.indexOf( '<' ) ) > 0 ) {
961  // both email address and name
962  emailPos2 = tmpStr.lastIndexOf( '>' );
963  a = new Attendee( tmpStr.left( emailPos1 - 1 ),
964  tmpStr.mid( emailPos1 + 1,
965  emailPos2 - ( emailPos1 + 1 ) ) );
966  } else if ( tmpStr.indexOf( '@' ) > 0 ) {
967  // just an email address
968  a = new Attendee( 0, tmpStr );
969  } else {
970  // just a name
971  QString email = tmpStr.replace( ' ', '.' );
972  a = new Attendee( tmpStr, email );
973  }
974 
975  // is there an RSVP property?
976  if ( ( vp = isAPropertyOf( vo, VCRSVPProp ) ) != 0 ) {
977  a->setRSVP( vObjectStringZValue( vp ) );
978  }
979  // is there a status property?
980  if ( ( vp = isAPropertyOf( vo, VCStatusProp ) ) != 0 ) {
981  a->setStatus( readStatus( vObjectStringZValue( vp ) ) );
982  }
983  // add the attendee
984  anEvent->addAttendee( a );
985  }
986  }
987 
988  // This isn't strictly true. An event that doesn't have a start time
989  // or an end time isn't all-day, it has an anchor in time but it doesn't
990  // "take up" any time.
991  /*if ((isAPropertyOf(vevent, VCDTstartProp) == 0) ||
992  (isAPropertyOf(vevent, VCDTendProp) == 0)) {
993  anEvent->setAllDay(true);
994  } else {
995  }*/
996 
997  anEvent->setAllDay( false );
998 
999  // start time
1000  if ( ( vo = isAPropertyOf( vevent, VCDTstartProp ) ) != 0 ) {
1001  anEvent->setDtStart( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
1002  deleteStr( s );
1003  if ( anEvent->dtStart().time().isNull() ) {
1004  anEvent->setAllDay( true );
1005  }
1006  }
1007 
1008  // stop time
1009  if ( ( vo = isAPropertyOf( vevent, VCDTendProp ) ) != 0 ) {
1010  anEvent->setDtEnd( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
1011  deleteStr( s );
1012  if ( anEvent->dtEnd().time().isNull() ) {
1013  anEvent->setAllDay( true );
1014  }
1015  }
1016 
1017  // at this point, there should be at least a start or end time.
1018  // fix up for events that take up no time but have a time associated
1019  if ( !( vo = isAPropertyOf( vevent, VCDTstartProp ) ) ) {
1020  anEvent->setDtStart( anEvent->dtEnd() );
1021  }
1022  if ( !( vo = isAPropertyOf( vevent, VCDTendProp ) ) ) {
1023  anEvent->setDtEnd( anEvent->dtStart() );
1024  }
1025 
1027 
1028  // repeat stuff
1029  if ( ( vo = isAPropertyOf( vevent, VCRRuleProp ) ) != 0 ) {
1030  QString tmpStr = ( s = fakeCString( vObjectUStringZValue( vo ) ) );
1031  deleteStr( s );
1032  tmpStr.simplified();
1033  tmpStr = tmpStr.toUpper();
1034 
1035  // first, read the type of the recurrence
1036  int typelen = 1;
1037  uint type = Recurrence::rNone;
1038  if ( tmpStr.left(1) == "D" ) {
1039  type = Recurrence::rDaily;
1040  } else if ( tmpStr.left(1) == "W" ) {
1041  type = Recurrence::rWeekly;
1042  } else {
1043  typelen = 2;
1044  if ( tmpStr.left(2) == "MP" ) {
1045  type = Recurrence::rMonthlyPos;
1046  } else if ( tmpStr.left(2) == "MD" ) {
1047  type = Recurrence::rMonthlyDay;
1048  } else if ( tmpStr.left(2) == "YM" ) {
1049  type = Recurrence::rYearlyMonth;
1050  } else if ( tmpStr.left(2) == "YD" ) {
1051  type = Recurrence::rYearlyDay;
1052  }
1053  }
1054 
1055  if ( type != Recurrence::rNone ) {
1056 
1057  // Immediately after the type is the frequency
1058  int index = tmpStr.indexOf( ' ' );
1059  int last = tmpStr.lastIndexOf( ' ' ) + 1; // find last entry
1060  int rFreq = tmpStr.mid( typelen, ( index - 1 ) ).toInt();
1061  ++index; // advance to beginning of stuff after freq
1062 
1063  // Read the type-specific settings
1064  switch ( type ) {
1065  case Recurrence::rDaily:
1066  anEvent->recurrence()->setDaily(rFreq);
1067  break;
1068 
1069  case Recurrence::rWeekly:
1070  {
1071  QBitArray qba(7);
1072  QString dayStr;
1073  if ( index == last ) {
1074  // e.g. W1 #0
1075  qba.setBit( anEvent->dtStart().date().dayOfWeek() - 1 );
1076  } else {
1077  // e.g. W1 SU #0
1078  while ( index < last ) {
1079  dayStr = tmpStr.mid( index, 3 );
1080  int dayNum = numFromDay( dayStr );
1081  if ( dayNum >= 0 ) {
1082  qba.setBit( dayNum );
1083  }
1084  index += 3; // advance to next day, or possibly "#"
1085  }
1086  }
1087  anEvent->recurrence()->setWeekly( rFreq, qba );
1088  break;
1089  }
1090 
1091  case Recurrence::rMonthlyPos:
1092  {
1093  anEvent->recurrence()->setMonthly( rFreq );
1094 
1095  QBitArray qba(7);
1096  short tmpPos;
1097  if ( index == last ) {
1098  // e.g. MP1 #0
1099  tmpPos = anEvent->dtStart().date().day() / 7 + 1;
1100  if ( tmpPos == 5 ) {
1101  tmpPos = -1;
1102  }
1103  qba.setBit( anEvent->dtStart().date().dayOfWeek() - 1 );
1104  anEvent->recurrence()->addMonthlyPos( tmpPos, qba );
1105  } else {
1106  // e.g. MP1 1+ SU #0
1107  while ( index < last ) {
1108  tmpPos = tmpStr.mid( index, 1 ).toShort();
1109  index += 1;
1110  if ( tmpStr.mid( index, 1 ) == "-" ) {
1111  // convert tmpPos to negative
1112  tmpPos = 0 - tmpPos;
1113  }
1114  index += 2; // advance to day(s)
1115  while ( numFromDay( tmpStr.mid( index, 3 ) ) >= 0 ) {
1116  int dayNum = numFromDay( tmpStr.mid( index, 3 ) );
1117  qba.setBit( dayNum );
1118  index += 3; // advance to next day, or possibly pos or "#"
1119  }
1120  anEvent->recurrence()->addMonthlyPos( tmpPos, qba );
1121  qba.detach();
1122  qba.fill( false ); // clear out
1123  } // while != "#"
1124  }
1125  break;
1126  }
1127 
1128  case Recurrence::rMonthlyDay:
1129  anEvent->recurrence()->setMonthly( rFreq );
1130  if( index == last ) {
1131  // e.g. MD1 #0
1132  short tmpDay = anEvent->dtStart().date().day();
1133  anEvent->recurrence()->addMonthlyDate( tmpDay );
1134  } else {
1135  // e.g. MD1 3 #0
1136  while ( index < last ) {
1137  int index2 = tmpStr.indexOf( ' ', index );
1138  short tmpDay = tmpStr.mid( index, ( index2 - index ) ).toShort();
1139  index = index2 - 1;
1140  if ( tmpStr.mid( index, 1 ) == "-" ) {
1141  tmpDay = 0 - tmpDay;
1142  }
1143  index += 2; // advance the index;
1144  anEvent->recurrence()->addMonthlyDate( tmpDay );
1145  } // while != #
1146  }
1147  break;
1148 
1149  case Recurrence::rYearlyMonth:
1150  anEvent->recurrence()->setYearly( rFreq );
1151 
1152  if ( index == last ) {
1153  // e.g. YM1 #0
1154  short tmpMonth = anEvent->dtStart().date().month();
1155  anEvent->recurrence()->addYearlyMonth( tmpMonth );
1156  } else {
1157  // e.g. YM1 3 #0
1158  while ( index < last ) {
1159  int index2 = tmpStr.indexOf( ' ', index );
1160  short tmpMonth = tmpStr.mid( index, ( index2 - index ) ).toShort();
1161  index = index2 + 1;
1162  anEvent->recurrence()->addYearlyMonth( tmpMonth );
1163  } // while != #
1164  }
1165  break;
1166 
1167  case Recurrence::rYearlyDay:
1168  anEvent->recurrence()->setYearly( rFreq );
1169 
1170  if ( index == last ) {
1171  // e.g. YD1 #0
1172  short tmpDay = anEvent->dtStart().date().dayOfYear();
1173  anEvent->recurrence()->addYearlyDay( tmpDay );
1174  } else {
1175  // e.g. YD1 123 #0
1176  while ( index < last ) {
1177  int index2 = tmpStr.indexOf( ' ', index );
1178  short tmpDay = tmpStr.mid( index, ( index2 - index ) ).toShort();
1179  index = index2 + 1;
1180  anEvent->recurrence()->addYearlyDay( tmpDay );
1181  } // while != #
1182  }
1183  break;
1184 
1185  default:
1186  break;
1187  }
1188 
1189  // find the last field, which is either the duration or the end date
1190  index = last;
1191  if ( tmpStr.mid( index, 1 ) == "#" ) {
1192  // Nr of occurrences
1193  index++;
1194  int rDuration = tmpStr.mid( index, tmpStr.length() - index ).toInt();
1195  if ( rDuration > 0 ) {
1196  anEvent->recurrence()->setDuration( rDuration );
1197  }
1198  } else if ( tmpStr.indexOf( 'T', index ) != -1 ) {
1199  KDateTime rEndDate = ISOToKDateTime( tmpStr.mid( index, tmpStr.length() - index ) );
1200  rEndDate.setDateOnly( true );
1201  anEvent->recurrence()->setEndDateTime( rEndDate );
1202  }
1203 // anEvent->recurrence()->dump();
1204 
1205  } else {
1206  kDebug() << "we don't understand this type of recurrence!";
1207  } // if known recurrence type
1208  } // repeats
1209 
1210  // recurrence exceptions
1211  if ( ( vo = isAPropertyOf( vevent, VCExpDateProp ) ) != 0 ) {
1212  s = fakeCString( vObjectUStringZValue( vo ) );
1213  QStringList exDates = QString::fromLocal8Bit( s ).split( ',' );
1214  QStringList::ConstIterator it;
1215  for ( it = exDates.constBegin(); it != exDates.constEnd(); ++it ) {
1216  anEvent->recurrence()->addExDate( ISOToQDate(*it) );
1217  }
1218  deleteStr( s );
1219  }
1220 
1221  // summary
1222  if ( ( vo = isAPropertyOf( vevent, VCSummaryProp ) ) ) {
1223  s = fakeCString( vObjectUStringZValue( vo ) );
1224  anEvent->setSummary( QString::fromLocal8Bit( s ), Qt::mightBeRichText( s ) );
1225  deleteStr( s );
1226  }
1227 
1228  // description
1229  if ( ( vo = isAPropertyOf( vevent, VCDescriptionProp ) ) != 0 ) {
1230  s = fakeCString( vObjectUStringZValue( vo ) );
1231  bool isRich = Qt::mightBeRichText( s );
1232  if ( !anEvent->description().isEmpty() ) {
1233  anEvent->setDescription(
1234  anEvent->description() + '\n' + QString::fromLocal8Bit( s ), isRich );
1235  } else {
1236  anEvent->setDescription( QString::fromLocal8Bit( s ), isRich );
1237  }
1238  deleteStr( s );
1239  }
1240 
1241  // location
1242  if ( ( vo = isAPropertyOf( vevent, VCLocationProp ) ) != 0 ) {
1243  s = fakeCString( vObjectUStringZValue( vo ) );
1244  anEvent->setLocation( QString::fromLocal8Bit( s ), Qt::mightBeRichText( s ) );
1245  deleteStr( s );
1246  }
1247 
1248  // some stupid vCal exporters ignore the standard and use Description
1249  // instead of Summary for the default field. Correct for this.
1250  if ( anEvent->summary().isEmpty() && !( anEvent->description().isEmpty() ) ) {
1251  QString tmpStr = anEvent->description().simplified();
1252  anEvent->setDescription( "" );
1253  anEvent->setSummary( tmpStr );
1254  }
1255 
1256 #if 0
1257  // status
1258  if ( ( vo = isAPropertyOf( vevent, VCStatusProp ) ) != 0 ) {
1259  QString tmpStr( s = fakeCString( vObjectUStringZValue( vo ) ) );
1260  deleteStr( s );
1261 // TODO: Define Event status
1262 // anEvent->setStatus( tmpStr );
1263  } else {
1264 // anEvent->setStatus( "NEEDS ACTION" );
1265  }
1266 #endif
1267 
1268  // secrecy
1269  Incidence::Secrecy secrecy = Incidence::SecrecyPublic;
1270  if ( ( vo = isAPropertyOf( vevent, VCClassProp ) ) != 0 ) {
1271  s = fakeCString( vObjectUStringZValue( vo ) );
1272  if ( s && strcmp( s, "PRIVATE" ) == 0 ) {
1273  secrecy = Incidence::SecrecyPrivate;
1274  } else if ( s && strcmp( s, "CONFIDENTIAL" ) == 0 ) {
1275  secrecy = Incidence::SecrecyConfidential;
1276  }
1277  deleteStr( s );
1278  }
1279  anEvent->setSecrecy( secrecy );
1280 
1281  // categories
1282  if ( ( vo = isAPropertyOf( vevent, VCCategoriesProp ) ) != 0 ) {
1283  s = fakeCString( vObjectUStringZValue( vo ) );
1284  QString categories = QString::fromLocal8Bit( s );
1285  deleteStr( s );
1286  QStringList tmpStrList = categories.split( ',' );
1287  anEvent->setCategories( tmpStrList );
1288  }
1289 
1290  // attachments
1291  initPropIterator( &voi, vevent );
1292  while ( moreIteration( &voi ) ) {
1293  vo = nextVObject( &voi );
1294  if ( strcmp( vObjectName( vo ), VCAttachProp ) == 0 ) {
1295  s = fakeCString( vObjectUStringZValue( vo ) );
1296  anEvent->addAttachment( new Attachment( QString( s ) ) );
1297  deleteStr( s );
1298  }
1299  }
1300 
1301  // resources
1302  if ( ( vo = isAPropertyOf( vevent, VCResourcesProp ) ) != 0 ) {
1303  QString resources = ( s = fakeCString( vObjectUStringZValue( vo ) ) );
1304  deleteStr( s );
1305  QStringList tmpStrList = resources.split( ';' );
1306  anEvent->setResources( tmpStrList );
1307  }
1308 
1309  // alarm stuff
1310  if ( ( vo = isAPropertyOf( vevent, VCDAlarmProp ) ) ) {
1311  Alarm *alarm = anEvent->newAlarm();
1312  VObject *a;
1313  if ( ( a = isAPropertyOf( vo, VCRunTimeProp ) ) ) {
1314  alarm->setTime( ISOToKDateTime( s = fakeCString( vObjectUStringZValue( a ) ) ) );
1315  deleteStr( s );
1316  }
1317  alarm->setEnabled( true );
1318  if ( ( vo = isAPropertyOf( vevent, VCPAlarmProp ) ) ) {
1319  if ( ( a = isAPropertyOf( vo, VCProcedureNameProp ) ) ) {
1320  s = fakeCString( vObjectUStringZValue( a ) );
1321  alarm->setProcedureAlarm( QFile::decodeName( s ) );
1322  deleteStr( s );
1323  }
1324  }
1325  if ( ( vo = isAPropertyOf( vevent, VCAAlarmProp ) ) ) {
1326  if ( ( a = isAPropertyOf( vo, VCAudioContentProp ) ) ) {
1327  s = fakeCString( vObjectUStringZValue( a ) );
1328  alarm->setAudioAlarm( QFile::decodeName( s ) );
1329  deleteStr( s );
1330  }
1331  }
1332  }
1333 
1334  // priority
1335  if ( ( vo = isAPropertyOf( vevent, VCPriorityProp ) ) ) {
1336  s = fakeCString( vObjectUStringZValue( vo ) );
1337  if ( s ) {
1338  anEvent->setPriority( atoi( s ) );
1339  deleteStr( s );
1340  }
1341  }
1342 
1343  // transparency
1344  if ( ( vo = isAPropertyOf( vevent, VCTranspProp ) ) != 0 ) {
1345  s = fakeCString( vObjectUStringZValue( vo ) );
1346  if ( s ) {
1347  int i = atoi( s );
1348  anEvent->setTransparency( i == 1 ? Event::Transparent : Event::Opaque );
1349  deleteStr( s );
1350  }
1351  }
1352 
1353  // related event
1354  if ( ( vo = isAPropertyOf( vevent, VCRelatedToProp ) ) != 0 ) {
1355  anEvent->setRelatedToUid( s = fakeCString( vObjectUStringZValue( vo ) ) );
1356  deleteStr( s );
1357  d->mEventsRelate.append( anEvent );
1358  }
1359 
1360  /* PILOT SYNC STUFF */
1361  if ( ( vo = isAPropertyOf( vevent, KPilotIdProp ) ) ) {
1362  anEvent->setNonKDECustomProperty(
1363  KPilotIdProp, QString::fromLocal8Bit( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
1364  deleteStr( s );
1365  if ( ( vo = isAPropertyOf( vevent, KPilotStatusProp ) ) ) {
1366  anEvent->setNonKDECustomProperty(
1367  KPilotStatusProp, QString::fromLocal8Bit( s = fakeCString( vObjectUStringZValue( vo ) ) ) );
1368  deleteStr( s );
1369  } else {
1370  anEvent->setNonKDECustomProperty( KPilotStatusProp, QString::number( SYNCMOD ) );
1371  }
1372  }
1373 
1374  return anEvent;
1375 }
1376 
1377 QString VCalFormat::qDateToISO( const QDate &qd )
1378 {
1379  QString tmpStr;
1380 
1381  if ( !qd.isValid() ) {
1382  return QString();
1383  }
1384 
1385  tmpStr.sprintf( "%.2d%.2d%.2d", qd.year(), qd.month(), qd.day() );
1386  return tmpStr;
1387 
1388 }
1389 
1390 QString VCalFormat::kDateTimeToISO( const KDateTime &dt, bool zulu )
1391 {
1392  QString tmpStr;
1393 
1394  if ( !dt.isValid() ) {
1395  return QString();
1396  }
1397 
1398  QDateTime tmpDT;
1399  if ( zulu ) {
1400  tmpDT = dt.toUtc().dateTime();
1401  } else {
1402  tmpDT = dt.toTimeSpec( d->mCalendar->timeSpec() ).dateTime();
1403  }
1404  tmpStr.sprintf( "%.2d%.2d%.2dT%.2d%.2d%.2d",
1405  tmpDT.date().year(), tmpDT.date().month(),
1406  tmpDT.date().day(), tmpDT.time().hour(),
1407  tmpDT.time().minute(), tmpDT.time().second() );
1408  if ( zulu ) {
1409  tmpStr += 'Z';
1410  }
1411  return tmpStr;
1412 }
1413 
1414 KDateTime VCalFormat::ISOToKDateTime( const QString &dtStr )
1415 {
1416  QDate tmpDate;
1417  QTime tmpTime;
1418  QString tmpStr;
1419  int year, month, day, hour, minute, second;
1420 
1421  tmpStr = dtStr;
1422  year = tmpStr.left( 4 ).toInt();
1423  month = tmpStr.mid( 4, 2 ).toInt();
1424  day = tmpStr.mid( 6, 2 ).toInt();
1425  hour = tmpStr.mid( 9, 2 ).toInt();
1426  minute = tmpStr.mid( 11, 2 ).toInt();
1427  second = tmpStr.mid( 13, 2 ).toInt();
1428  tmpDate.setYMD( year, month, day );
1429  tmpTime.setHMS( hour, minute, second );
1430 
1431  if ( tmpDate.isValid() && tmpTime.isValid() ) {
1432  // correct for GMT if string is in Zulu format
1433  if ( dtStr.at( dtStr.length() - 1 ) == 'Z' ) {
1434  return KDateTime( tmpDate, tmpTime, KDateTime::UTC );
1435  } else {
1436  return KDateTime( tmpDate, tmpTime, d->mCalendar->timeSpec() );
1437  }
1438  } else {
1439  return KDateTime();
1440  }
1441 }
1442 
1443 QDate VCalFormat::ISOToQDate( const QString &dateStr )
1444 {
1445  int year, month, day;
1446 
1447  year = dateStr.left( 4 ).toInt();
1448  month = dateStr.mid( 4, 2 ).toInt();
1449  day = dateStr.mid( 6, 2 ).toInt();
1450 
1451  return QDate( year, month, day );
1452 }
1453 
1454 // take a raw vcalendar (i.e. from a file on disk, clipboard, etc. etc.
1455 // and break it down from it's tree-like format into the dictionary format
1456 // that is used internally in the VCalFormat.
1457 void VCalFormat::populate( VObject *vcal )
1458 {
1459  // this function will populate the caldict dictionary and other event
1460  // lists. It turns vevents into Events and then inserts them.
1461 
1462  VObjectIterator i;
1463  VObject *curVO, *curVOProp;
1464  Event *anEvent;
1465 
1466  if ( ( curVO = isAPropertyOf( vcal, ICMethodProp ) ) != 0 ) {
1467  char *methodType = 0;
1468  methodType = fakeCString( vObjectUStringZValue( curVO ) );
1469  kDebug() << "This calendar is an iTIP transaction of type '"
1470  << methodType << "'";
1471  deleteStr( methodType );
1472  }
1473 
1474  // warn the user that we might have trouble reading non-known calendar.
1475  if ( ( curVO = isAPropertyOf( vcal, VCProdIdProp ) ) != 0 ) {
1476  char *s = fakeCString( vObjectUStringZValue( curVO ) );
1477  if ( !s || strcmp( productId().toLocal8Bit(), s ) != 0 ) {
1478  kDebug() << "This vCalendar file was not created by KOrganizer or"
1479  << "any other product we support. Loading anyway...";
1480  }
1481  setLoadedProductId( s );
1482  deleteStr( s );
1483  }
1484 
1485  // warn the user we might have trouble reading this unknown version.
1486  if ( ( curVO = isAPropertyOf( vcal, VCVersionProp ) ) != 0 ) {
1487  char *s = fakeCString( vObjectUStringZValue( curVO ) );
1488  if ( !s || strcmp( _VCAL_VERSION, s ) != 0 ) {
1489  kDebug() << "This vCalendar file has version" << s
1490  << "We only support" << _VCAL_VERSION;
1491  }
1492  deleteStr( s );
1493  }
1494 
1495 #if 0
1496  // set the time zone (this is a property of the view, so just discard!)
1497  if ( ( curVO = isAPropertyOf( vcal, VCTimeZoneProp ) ) != 0 ) {
1498  char *s = fakeCString( vObjectUStringZValue( curVO ) );
1499  d->mCalendar->setTimeZone( s );
1500  deleteStr( s );
1501  }
1502 #endif
1503 
1504  // Store all events with a relatedTo property in a list for post-processing
1505  d->mEventsRelate.clear();
1506  d->mTodosRelate.clear();
1507 
1508  initPropIterator( &i, vcal );
1509 
1510  // go through all the vobjects in the vcal
1511  while ( moreIteration( &i ) ) {
1512  curVO = nextVObject( &i );
1513 
1514  /************************************************************************/
1515 
1516  // now, check to see that the object is an event or todo.
1517  if ( strcmp( vObjectName( curVO ), VCEventProp ) == 0 ) {
1518 
1519  if ( ( curVOProp = isAPropertyOf( curVO, KPilotStatusProp ) ) != 0 ) {
1520  char *s;
1521  s = fakeCString( vObjectUStringZValue( curVOProp ) );
1522  // check to see if event was deleted by the kpilot conduit
1523  if ( s ) {
1524  if ( atoi( s ) == SYNCDEL ) {
1525  deleteStr( s );
1526  kDebug() << "skipping pilot-deleted event";
1527  goto SKIP;
1528  }
1529  deleteStr( s );
1530  }
1531  }
1532 
1533  // this code checks to see if we are trying to read in an event
1534  // that we already find to be in the calendar. If we find this
1535  // to be the case, we skip the event.
1536  if ( ( curVOProp = isAPropertyOf( curVO, VCUniqueStringProp ) ) != 0 ) {
1537  char *s = fakeCString( vObjectUStringZValue( curVOProp ) );
1538  QString tmpStr( s );
1539  deleteStr( s );
1540 
1541  if ( d->mCalendar->incidence( tmpStr ) ) {
1542  goto SKIP;
1543  }
1544  }
1545 
1546  if ( ( !( curVOProp = isAPropertyOf( curVO, VCDTstartProp ) ) ) &&
1547  ( !( curVOProp = isAPropertyOf( curVO, VCDTendProp ) ) ) ) {
1548  kDebug() << "found a VEvent with no DTSTART and no DTEND! Skipping...";
1549  goto SKIP;
1550  }
1551 
1552  anEvent = VEventToEvent( curVO );
1553  // we now use addEvent instead of insertEvent so that the
1554  // signal/slot get connected.
1555  if ( anEvent ) {
1556  if ( anEvent->dtStart().isValid() && anEvent->dtEnd().isValid() ) {
1557  d->mCalendar->addEvent( anEvent );
1558  }
1559  } else {
1560  // some sort of error must have occurred while in translation.
1561  goto SKIP;
1562  }
1563  } else if ( strcmp( vObjectName( curVO ), VCTodoProp ) == 0 ) {
1564  Todo *aTodo = VTodoToEvent( curVO );
1565 
1566  Todo *old = d->mCalendar->todo( aTodo->uid() );
1567  if ( old ) {
1568  d->mCalendar->deleteTodo( old );
1569  d->mTodosRelate.removeAll( old );
1570  }
1571 
1572  d->mCalendar->addTodo( aTodo );
1573  } else if ( ( strcmp( vObjectName( curVO ), VCVersionProp ) == 0 ) ||
1574  ( strcmp( vObjectName( curVO ), VCProdIdProp ) == 0 ) ||
1575  ( strcmp( vObjectName( curVO ), VCTimeZoneProp ) == 0 ) ) {
1576  // do nothing, we know these properties and we want to skip them.
1577  // we have either already processed them or are ignoring them.
1578  ;
1579  } else {
1580  kDebug() << "Ignoring unknown vObject \"" << vObjectName(curVO) << "\"";
1581  }
1582  SKIP:
1583  ;
1584  } // while
1585 
1586  // Post-Process list of events with relations, put Event objects in relation
1587  Event::List::ConstIterator eIt;
1588  for ( eIt = d->mEventsRelate.constBegin(); eIt != d->mEventsRelate.constEnd(); ++eIt ) {
1589  (*eIt)->setRelatedTo( d->mCalendar->incidence( (*eIt)->relatedToUid() ) );
1590  }
1591  Todo::List::ConstIterator tIt;
1592  for ( tIt = d->mTodosRelate.constBegin(); tIt != d->mTodosRelate.constEnd(); ++tIt ) {
1593  (*tIt)->setRelatedTo( d->mCalendar->incidence( (*tIt)->relatedToUid() ) );
1594  }
1595 }
1596 
1597 const char *VCalFormat::dayFromNum( int day )
1598 {
1599  const char *days[7] = { "MO ", "TU ", "WE ", "TH ", "FR ", "SA ", "SU " };
1600 
1601  return days[day];
1602 }
1603 
1604 int VCalFormat::numFromDay( const QString &day )
1605 {
1606  if ( day == "MO " ) {
1607  return 0;
1608  }
1609  if ( day == "TU " ) {
1610  return 1;
1611  }
1612  if ( day == "WE " ) {
1613  return 2;
1614  }
1615  if ( day == "TH " ) {
1616  return 3;
1617  }
1618  if ( day == "FR " ) {
1619  return 4;
1620  }
1621  if ( day == "SA " ) {
1622  return 5;
1623  }
1624  if ( day == "SU " ) {
1625  return 6;
1626  }
1627 
1628  return -1; // something bad happened. :)
1629 }
1630 
1631 Attendee::PartStat VCalFormat::readStatus( const char *s ) const
1632 {
1633  QString statStr = s;
1634  statStr = statStr.toUpper();
1635  Attendee::PartStat status;
1636 
1637  if ( statStr == "X-ACTION" ) {
1638  status = Attendee::NeedsAction;
1639  } else if ( statStr == "NEEDS ACTION" ) {
1640  status = Attendee::NeedsAction;
1641  } else if ( statStr == "ACCEPTED" ) {
1642  status = Attendee::Accepted;
1643  } else if ( statStr == "SENT" ) {
1644  status = Attendee::NeedsAction;
1645  } else if ( statStr == "TENTATIVE" ) {
1646  status = Attendee::Tentative;
1647  } else if ( statStr == "CONFIRMED" ) {
1648  status = Attendee::Accepted;
1649  } else if ( statStr == "DECLINED" ) {
1650  status = Attendee::Declined;
1651  } else if ( statStr == "COMPLETED" ) {
1652  status = Attendee::Completed;
1653  } else if ( statStr == "DELEGATED" ) {
1654  status = Attendee::Delegated;
1655  } else {
1656  kDebug() << "error setting attendee mStatus, unknown mStatus!";
1657  status = Attendee::NeedsAction;
1658  }
1659 
1660  return status;
1661 }
1662 
1663 QByteArray VCalFormat::writeStatus( Attendee::PartStat status ) const
1664 {
1665  switch( status ) {
1666  default:
1667  case Attendee::NeedsAction:
1668  return "NEEDS ACTION";
1669  break;
1670  case Attendee::Accepted:
1671  return "ACCEPTED";
1672  break;
1673  case Attendee::Declined:
1674  return "DECLINED";
1675  break;
1676  case Attendee::Tentative:
1677  return "TENTATIVE";
1678  break;
1679  case Attendee::Delegated:
1680  return "DELEGATED";
1681  break;
1682  case Attendee::Completed:
1683  return "COMPLETED";
1684  break;
1685  case Attendee::InProcess:
1686  return "NEEDS ACTION";
1687  break;
1688  }
1689 }
KCal::Recurrence::addMonthlyPos
void addMonthlyPos(short pos, const QBitArray &days)
Adds a position (e.g.
Definition: recurrence.cpp:757
KCal::Incidence::setResources
void setResources(const QStringList &resources)
Sets a list of incidence resources.
Definition: incidence.cpp:770
KCal::Incidence::description
QString description() const
Returns the incidence description.
Definition: incidence.cpp:390
KCal::IncidenceBase::setLastModified
void setLastModified(const KDateTime &lm)
Sets the time the incidence was last modified to lm.
Definition: incidencebase.cpp:189
KCal::Person::email
QString email() const
Returns the email address for this person.
Definition: person.cpp:144
KCal::Incidence::setLocation
void setLocation(const QString &location, bool isRich)
Sets the incidence location.
Definition: incidence.cpp:946
KCal::Alarm::setEnabled
void setEnabled(bool enable)
Sets the enabled status of the alarm.
Definition: alarm.cpp:578
KCal::Incidence::relatedTo
Incidence * relatedTo() const
Returns a pointer for the incidence that is related to this one.
Definition: incidence.cpp:516
KCal::Recurrence::yearMonths
QList< int > yearMonths() const
Returns the months within a yearly recurrence.
Definition: recurrence.cpp:679
KCal::Incidence::setCreated
void setCreated(const KDateTime &dt)
Sets the incidence creation date/time.
Definition: incidence.cpp:316
KCal::IncidenceBase::attendees
const Attendee::List & attendees() const
Returns a list of incidence attendees.
Definition: incidencebase.cpp:378
KCal::Recurrence::setEndDateTime
void setEndDateTime(const KDateTime &endDateTime)
Sets the date and time of the last recurrence.
Definition: recurrence.cpp:472
KCal::CustomProperties::nonKDECustomProperty
QString nonKDECustomProperty(const QByteArray &name) const
Return the value of a non-KDE or non-standard custom calendar property.
Definition: customproperties.cpp:145
KCal::Todo::hasCompletedDate
bool hasCompletedDate() const
Returns true, if the to-do has a date associated with completion, otherwise return false...
Definition: todo.cpp:458
KCal::Todo
Provides a To-do in the sense of RFC2445.
Definition: todo.h:44
KCal::Calendar
Represents the main calendar class.
Definition: calendar.h:119
KCal::Recurrence::duration
int duration() const
Returns -1 if the event recurs infinitely, 0 if the end date is set, otherwise the total number of re...
Definition: recurrence.cpp:485
KCal::Alarm::setProcedureAlarm
void setProcedureAlarm(const QString &programFile, const QString &arguments=QString())
Sets the Procedure type for this alarm and the program (with arguments) to execute when the alarm is ...
Definition: alarm.cpp:237
KCal::Recurrence::yearDays
QList< int > yearDays() const
Returns the day numbers within a yearly recurrence.
Definition: recurrence.cpp:668
KCal::Recurrence::setYearly
void setYearly(int freq)
Sets an event to recur yearly.
Definition: recurrence.cpp:826
KCal::IncidenceBase::dtStart
virtual KDateTime dtStart() const
Returns an incidence's starting date/time as a KDateTime.
Definition: incidencebase.cpp:248
KCal::Recurrence::monthPositions
QList< RecurrenceRule::WDayPos > monthPositions() const
Returns list of day positions in months.
Definition: recurrence.cpp:660
KCal::Attendee
Represents information related to an attendee of an Calendar Incidence, typically a meeting or task (...
Definition: attendee.h:58
KCal::Alarm::programFile
QString programFile() const
Returns the program file name for a Procedure alarm type.
Definition: alarm.cpp:258
KCal::Event
This class provides an Event in the sense of RFC2445.
Definition: event.h:41
KCal::Alarm::Audio
Play an audio file.
Definition: alarm.h:77
KCal::Attendee::InProcess
To-do in process of being completed.
Definition: attendee.h:78
KCal::IncidenceBase::uid
QString uid() const
Returns the unique id (uid) for the incidence.
Definition: incidencebase.cpp:184
KCal::Recurrence::frequency
int frequency() const
Returns frequency of recurrence, in terms of the recurrence time period type.
Definition: recurrence.cpp:600
KCal::Recurrence::addMonthlyDate
void addMonthlyDate(short day)
Adds a date (e.g.
Definition: recurrence.cpp:807
KCal::Todo::dtStart
virtual KDateTime dtStart() const
Definition: todo.cpp:289
KCal::ErrorFormat::CalVersionUnknown
Unknown calendar format detected.
Definition: exceptions.h:96
KCal::Recurrence::days
QBitArray days() const
Returns week day mask (bit 0 = Monday).
Definition: recurrence.cpp:630
KCal::Incidence::setAllDay
void setAllDay(bool allDay)
Definition: incidence.cpp:305
KCal::Calendar::addEvent
virtual bool addEvent(Event *event)=0
Inserts an Event into the calendar.
KCal::Alarm::Procedure
Call a script.
Definition: alarm.h:75
KCal::Todo::dtDue
KDateTime dtDue(bool first=false) const
Returns due date and time.
Definition: todo.cpp:181
KCal::Incidence::created
KDateTime created() const
Returns the incidence creation date/time.
Definition: incidence.cpp:328
KCal::Incidence::newAlarm
Alarm * newAlarm()
Create a new incidence alarm.
Definition: incidence.cpp:911
KCal::Attendee::Completed
To-do completed.
Definition: attendee.h:77
KCal::Attendee::status
PartStat status() const
Returns the PartStat of the attendee.
Definition: attendee.cpp:125
KCal::Todo::isCompleted
bool isCompleted() const
Returns true if the todo is 100% completed, otherwise return false.
Definition: todo.cpp:411
KCal::Recurrence::setDuration
void setDuration(int duration)
Sets the total number of times the event is to occur, including both the first and last...
Definition: recurrence.cpp:503
KCal::Recurrence::recurs
bool recurs() const
Returns whether the event recurs at all.
Definition: recurrence.cpp:233
KCal::Attendee::PartStat
PartStat
The different types of participant status.
Definition: attendee.h:71
KCal::Attendee::Declined
Event, to-do or journal declined.
Definition: attendee.h:74
KCal::Recurrence::setMonthly
void setMonthly(int freq)
Sets an event to recur monthly.
Definition: recurrence.cpp:750
KCal::Incidence::setDescription
void setDescription(const QString &description, bool isRich)
Sets the incidence description.
Definition: incidence.cpp:375
KCal::Alarm::setAudioAlarm
void setAudioAlarm(const QString &audioFile=QString())
Sets the Audio type for this alarm and the name of the audio file to play when the alarm is triggered...
Definition: alarm.cpp:213
KCal::Incidence::setRelatedToUid
void setRelatedToUid(const QString &uid)
Relates another incidence to this one, by UID.
Definition: incidence.cpp:483
KCal::IncidenceBase::lastModified
KDateTime lastModified() const
Returns the time the incidence was last modified.
Definition: incidencebase.cpp:203
KCal::Todo::setDtStart
void setDtStart(const KDateTime &dtStart)
Sets the start date of the todo.
Definition: todo.cpp:308
KCal::Recurrence::setWeekly
void setWeekly(int freq, int weekStart=1)
Sets an event to recur weekly.
Definition: recurrence.cpp:729
KCal::Incidence::SecrecyPrivate
Secret to the owner.
Definition: incidence.h:164
KCal::Event::setDtEnd
void setDtEnd(const KDateTime &dtEnd)
Sets the event end date and time.
Definition: event.cpp:119
KCal::IncidenceBase::allDay
bool allDay() const
Returns true or false depending on whether the incidence is all-day.
Definition: incidencebase.cpp:310
KCal::Todo::setCompleted
void setCompleted(bool completed)
Sets completed state.
Definition: todo.cpp:420
KCal::Incidence::attachments
Attachment::List attachments() const
Returns a list of all incidence attachments.
Definition: incidence.cpp:715
calendar.h
This file is part of the API for handling calendar data and defines the Calendar class.
KCal::Person::name
QString name() const
Returns the person name string.
Definition: person.cpp:139
KCal::CustomProperties::setNonKDECustomProperty
void setNonKDECustomProperty(const QByteArray &name, const QString &value)
Create or modify a non-KDE or non-standard custom calendar property.
Definition: customproperties.cpp:129
KCal::Event::setTransparency
void setTransparency(Transparency transparency)
Sets the event's time transparency level.
Definition: event.cpp:261
KCal::Recurrence::addYearlyMonth
void addYearlyMonth(short _rNum)
Adds month in yearly recurrence.
Definition: recurrence.cpp:862
KCal::Todo::setHasDueDate
void setHasDueDate(bool hasDueDate)
Sets if the todo has a due date.
Definition: todo.cpp:257
KCal::IncidenceBase::organizer
Person organizer() const
Returns the Person associated with this incidence.
Definition: incidencebase.cpp:230
KCal::ListBase
This class provides a template for lists of pointers.
Definition: listbase.h:44
KCal::Todo::completed
KDateTime completed() const
Returns date and time when todo was completed.
Definition: todo.cpp:432
KCal::Attachment
Represents information related to an attachment for a Calendar Incidence.
Definition: attachment.h:57
KCal::Todo::hasDueDate
bool hasDueDate() const
Returns true if the todo has a due date, otherwise return false.
Definition: todo.cpp:252
KCal::Incidence::resources
QStringList resources() const
Returns the incidence resources as a list of strings.
Definition: incidence.cpp:780
KCal::IncidenceBase::setUid
void setUid(const QString &uid)
Returns the type of Incidence as a translated string.
Definition: incidencebase.cpp:178
KCal::Incidence::alarms
const Alarm::List & alarms() const
Returns a list of all incidence alarms.
Definition: incidence.cpp:906
KCal::Recurrence::endDateTime
KDateTime endDateTime() const
Returns the date/time of the last recurrence.
Definition: recurrence.cpp:432
KCal::ErrorFormat
Calendar format related error class.
Definition: exceptions.h:82
KCal::Event::Opaque
Event appears in free/busy time.
Definition: event.h:48
KCal::Attendee::Accepted
Event, to-do or journal accepted.
Definition: attendee.h:73
KCal::Incidence::Secrecy
Secrecy
The different types of incidence access classifications.
Definition: incidence.h:162
KCal::Attendee::NeedsAction
Event, to-do or journal needs action (default)
Definition: attendee.h:72
KCal::Alarm::audioFile
QString audioFile() const
Returns the audio file name for an Audio alarm type.
Definition: alarm.cpp:232
KCal::Incidence::addAttachment
void addAttachment(Attachment *attachment)
Adds an attachment to the incidence.
Definition: incidence.cpp:688
KCal::Attendee::RSVP
bool RSVP() const
Returns the attendee RSVP flag.
Definition: attendee.cpp:115
KCal::Incidence::SecrecyConfidential
Secret to the owner and some others.
Definition: incidence.h:165
KCal::Event::Transparent
Event does not appear in free/busy time.
Definition: event.h:49
KCal::IncidenceBase::attendeeCount
int attendeeCount() const
Returns the number of incidence attendees.
Definition: incidencebase.cpp:383
KCal::SortableList
A QList which can be sorted.
Definition: sortablelist.h:86
KCal::Attendee::setRSVP
void setRSVP(bool rsvp)
Sets the RSVP flag of the attendee to rsvp.
Definition: attendee.cpp:110
KCal::Todo::hasStartDate
bool hasStartDate() const
Returns true if the todo has a start date, otherwise return false.
Definition: todo.cpp:266
KCal::IncidenceBase::addAttendee
void addAttendee(Attendee *attendee, bool doUpdate=true)
Add Attendee to this incidence.
Definition: incidencebase.cpp:362
KCal::Incidence::setRevision
void setRevision(int rev)
Sets the number of revisions this incidence has seen.
Definition: incidence.cpp:333
KCal::Alarm::enabled
bool enabled() const
Returns the alarm enabled status: true (enabled) or false (disabled).
Definition: alarm.cpp:586
KCal::Alarm::type
Type type() const
Returns the Type of the alarm.
Definition: alarm.cpp:208
KCal::Incidence::setSecrecy
void setSecrecy(Secrecy secrecy)
Sets the incidence Secrecy.
Definition: incidence.cpp:862
KCal::Event::transparency
Transparency transparency() const
Returns the event's time transparency level.
Definition: event.cpp:270
KCal::Recurrence::setDaily
void setDaily(int freq)
Sets an event to recur daily.
Definition: recurrence.cpp:722
KCal::CalFormat::productId
static const QString & productId()
Returns the PRODID string to write into calendar files.
Definition: calformat.cpp:100
KCal::Incidence::recurrence
Recurrence * recurrence() const
Returns the recurrence rule associated with this incidence.
Definition: incidence.cpp:545
KCal::Incidence::priority
int priority() const
Returns the incidence priority.
Definition: incidence.cpp:795
KCal::Recurrence::addYearlyDay
void addYearlyDay(int day)
Adds day number of year within a yearly recurrence.
Definition: recurrence.cpp:834
KCal::Alarm::setTime
void setTime(const KDateTime &alarmTime)
Sets the trigger time of the alarm.
Definition: alarm.cpp:420
KCal::Recurrence::recurrenceType
ushort recurrenceType() const
Returns the event's recurrence status.
Definition: recurrence.cpp:238
KCal::Incidence::revision
int revision() const
Returns the number of revisions this incidence has seen.
Definition: incidence.cpp:344
KCal::Attendee::Delegated
Event or to-do delegated.
Definition: attendee.h:76
vcalformat.h
This file is part of the API for handling calendar data and defines the VCalFormat base class...
KCal::Incidence::categories
QStringList categories() const
Returns the incidence categories as a list of strings.
Definition: incidence.cpp:473
KCal::Incidence::location
QString location() const
Returns the incidence location.
Definition: incidence.cpp:962
KCal::Calendar::events
virtual Event::List events(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Returns a sorted, filtered list of all Events for this Calendar.
Definition: calendar.cpp:565
KCal::IncidenceBase::setOrganizer
void setOrganizer(const Person &organizer)
Sets the organizer for the incidence.
Definition: incidencebase.cpp:208
KCal::Alarm::time
KDateTime time() const
Returns the alarm trigger date/time.
Definition: alarm.cpp:430
KCal::Incidence::setPriority
void setPriority(int priority)
Sets the incidences priority.
Definition: incidence.cpp:785
KCal::Incidence::setSummary
void setSummary(const QString &summary, bool isRich)
Sets the incidence summary.
Definition: incidence.cpp:409
KCal::Attendee::setStatus
void setStatus(PartStat status)
Sets the PartStat of the attendee to status.
Definition: attendee.cpp:120
KCal::Todo::setHasStartDate
void setHasStartDate(bool hasStartDate)
Sets if the todo has a start date.
Definition: todo.cpp:271
KCal::Incidence::secrecy
Secrecy secrecy() const
Returns the incidence Secrecy.
Definition: incidence.cpp:872
KCal::Alarm
Represents an alarm notification.
Definition: alarm.h:66
KCal::Attendee::Tentative
Event or to-do tentatively accepted.
Definition: attendee.h:75
KCal::Recurrence::monthDays
QList< int > monthDays() const
Returns list of day numbers of a month.
Definition: recurrence.cpp:649
KCal::Incidence::setCategories
void setCategories(const QStringList &categories)
Sets the incidence category list.
Definition: incidence.cpp:443
KCal::Recurrence
This class represents a recurrence rule for a calendar incidence.
Definition: recurrence.h:91
KCal::Incidence::setDtStart
virtual void setDtStart(const KDateTime &dt)
Sets the incidence starting date/time.
Definition: incidence.cpp:349
KCal::Event::dtEnd
virtual KDateTime dtEnd() const
Returns the event end date and time.
Definition: event.cpp:132
KCal::Incidence::summary
QString summary() const
Returns the incidence summary.
Definition: incidence.cpp:424
KCal::Incidence::SecrecyPublic
Not secret (default)
Definition: incidence.h:163
KCal::Todo::setDtDue
void setDtDue(const KDateTime &dtDue, bool first=false)
Sets due date and time.
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:58 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCal Library

Skip menu "KCal Library"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

kdepimlibs API Reference

Skip menu "kdepimlibs API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kldap
  • kmbox
  • kmime
  • kpimidentities
  • kpimtextedit
  • kresources
  • ktnef
  • kxmlrpcclient
  • microblog

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal