• 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
calendar.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) 2000-2004 Cornelius Schumacher <schumacher@kde.org>
6  Copyright (C) 2003-2004 Reinhold Kainhofer <reinhold@kainhofer.com>
7  Copyright (c) 2006 David Jarvie <software@astrojar.org.uk>
8 
9  This library is free software; you can redistribute it and/or
10  modify it under the terms of the GNU Library General Public
11  License as published by the Free Software Foundation; either
12  version 2 of the License, or (at your option) any later version.
13 
14  This library is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  Library General Public License for more details.
18 
19  You should have received a copy of the GNU Library General Public License
20  along with this library; see the file COPYING.LIB. If not, write to
21  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22  Boston, MA 02110-1301, USA.
23 */
38 #include "calendar.h"
39 #include "exceptions.h"
40 #include "calfilter.h"
41 #include "icaltimezones.h"
42 #include <kdebug.h>
43 #include <klocalizedstring.h>
44 
45 extern "C" {
46  #include <icaltimezone.h>
47 }
48 
49 using namespace KCal;
50 
55 //@cond PRIVATE
56 class KCal::Calendar::Private
57 {
58  public:
59  Private()
60  : mTimeZones( new ICalTimeZones ),
61  mModified( false ),
62  mNewObserver( false ),
63  mObserversEnabled( true ),
64  mDefaultFilter( new CalFilter )
65  {
66  // Setup default filter, which does nothing
67  mFilter = mDefaultFilter;
68  mFilter->setEnabled( false );
69 
70  // user information...
71  mOwner.setName( i18n( "Unknown Name" ) );
72  mOwner.setEmail( i18n( "unknown@nowhere" ) );
73  }
74 
75  ~Private()
76  {
77  delete mTimeZones;
78  if ( mFilter != mDefaultFilter ) {
79  delete mFilter;
80  }
81  delete mDefaultFilter;
82  }
83  KDateTime::Spec timeZoneIdSpec( const QString &timeZoneId, bool view );
84 
85  QString mProductId;
86  Person mOwner;
87  ICalTimeZones *mTimeZones; // collection of time zones used in this calendar
88  ICalTimeZone mBuiltInTimeZone; // cached time zone lookup
89  ICalTimeZone mBuiltInViewTimeZone; // cached viewing time zone lookup
90  KDateTime::Spec mTimeSpec;
91  mutable KDateTime::Spec mViewTimeSpec;
92  bool mModified;
93  bool mNewObserver;
94  bool mObserversEnabled;
95  QList<CalendarObserver*> mObservers;
96 
97  CalFilter *mDefaultFilter;
98  CalFilter *mFilter;
99 
100  // These lists are used to put together related To-dos
101  QMultiHash<QString, Incidence*> mOrphans;
102  QMultiHash<QString, Incidence*> mOrphanUids;
103 };
104 //@endcond
105 
106 Calendar::Calendar( const KDateTime::Spec &timeSpec )
107  : d( new KCal::Calendar::Private )
108 {
109  d->mTimeSpec = timeSpec;
110  d->mViewTimeSpec = timeSpec;
111 }
112 
113 Calendar::Calendar( const QString &timeZoneId )
114  : d( new KCal::Calendar::Private )
115 {
116  setTimeZoneId( timeZoneId );
117 }
118 
119 Calendar::~Calendar()
120 {
121  delete d;
122 }
123 
124 Person Calendar::owner() const
125 {
126  return d->mOwner;
127 }
128 
129 void Calendar::setOwner( const Person &owner )
130 {
131  d->mOwner = owner;
132 
133  setModified( true );
134 }
135 
136 void Calendar::setTimeSpec( const KDateTime::Spec &timeSpec )
137 {
138  d->mTimeSpec = timeSpec;
139  d->mBuiltInTimeZone = ICalTimeZone();
140  setViewTimeSpec( timeSpec );
141 
142  doSetTimeSpec( d->mTimeSpec );
143 }
144 
145 KDateTime::Spec Calendar::timeSpec() const
146 {
147  return d->mTimeSpec;
148 }
149 
150 void Calendar::setTimeZoneId( const QString &timeZoneId )
151 {
152  d->mTimeSpec = d->timeZoneIdSpec( timeZoneId, false );
153  d->mViewTimeSpec = d->mTimeSpec;
154  d->mBuiltInViewTimeZone = d->mBuiltInTimeZone;
155 
156  doSetTimeSpec( d->mTimeSpec );
157 }
158 
159 //@cond PRIVATE
160 KDateTime::Spec Calendar::Private::timeZoneIdSpec( const QString &timeZoneId,
161  bool view )
162 {
163  if ( view ) {
164  mBuiltInViewTimeZone = ICalTimeZone();
165  } else {
166  mBuiltInTimeZone = ICalTimeZone();
167  }
168  if ( timeZoneId == QLatin1String( "UTC" ) ) {
169  return KDateTime::UTC;
170  }
171  ICalTimeZone tz = mTimeZones->zone( timeZoneId );
172  if ( !tz.isValid() ) {
173  ICalTimeZoneSource tzsrc;
174  tz = tzsrc.parse( icaltimezone_get_builtin_timezone( timeZoneId.toLatin1() ) );
175  if ( view ) {
176  mBuiltInViewTimeZone = tz;
177  } else {
178  mBuiltInTimeZone = tz;
179  }
180  }
181  if ( tz.isValid() ) {
182  return tz;
183  } else {
184  return KDateTime::ClockTime;
185  }
186 }
187 //@endcond
188 
189 QString Calendar::timeZoneId() const
190 {
191  KTimeZone tz = d->mTimeSpec.timeZone();
192  return tz.isValid() ? tz.name() : QString();
193 }
194 
195 void Calendar::setViewTimeSpec( const KDateTime::Spec &timeSpec ) const
196 {
197  d->mViewTimeSpec = timeSpec;
198  d->mBuiltInViewTimeZone = ICalTimeZone();
199 }
200 
201 void Calendar::setViewTimeZoneId( const QString &timeZoneId ) const
202 {
203  d->mViewTimeSpec = d->timeZoneIdSpec( timeZoneId, true );
204 }
205 
206 KDateTime::Spec Calendar::viewTimeSpec() const
207 {
208  return d->mViewTimeSpec;
209 }
210 
211 QString Calendar::viewTimeZoneId() const
212 {
213  KTimeZone tz = d->mViewTimeSpec.timeZone();
214  return tz.isValid() ? tz.name() : QString();
215 }
216 
217 ICalTimeZones *Calendar::timeZones() const
218 {
219  return d->mTimeZones;
220 }
221 
222 void Calendar::shiftTimes( const KDateTime::Spec &oldSpec,
223  const KDateTime::Spec &newSpec )
224 {
225  setTimeSpec( newSpec );
226 
227  int i, end;
228  Event::List ev = events();
229  for ( i = 0, end = ev.count(); i < end; ++i ) {
230  ev[i]->shiftTimes( oldSpec, newSpec );
231  }
232 
233  Todo::List to = todos();
234  for ( i = 0, end = to.count(); i < end; ++i ) {
235  to[i]->shiftTimes( oldSpec, newSpec );
236  }
237 
238  Journal::List jo = journals();
239  for ( i = 0, end = jo.count(); i < end; ++i ) {
240  jo[i]->shiftTimes( oldSpec, newSpec );
241  }
242 }
243 
244 void Calendar::setFilter( CalFilter *filter )
245 {
246  if ( filter ) {
247  d->mFilter = filter;
248  } else {
249  d->mFilter = d->mDefaultFilter;
250  }
251 }
252 
253 CalFilter *Calendar::filter()
254 {
255  return d->mFilter;
256 }
257 
258 QStringList Calendar::categories()
259 {
260  Incidence::List rawInc( rawIncidences() );
261  QStringList cats, thisCats;
262  // @TODO: For now just iterate over all incidences. In the future,
263  // the list of categories should be built when reading the file.
264  for ( Incidence::List::ConstIterator i = rawInc.constBegin();
265  i != rawInc.constEnd(); ++i ) {
266  thisCats = (*i)->categories();
267  for ( QStringList::ConstIterator si = thisCats.constBegin();
268  si != thisCats.constEnd(); ++si ) {
269  if ( !cats.contains( *si ) ) {
270  cats.append( *si );
271  }
272  }
273  }
274  return cats;
275 }
276 
277 Incidence::List Calendar::incidences( const QDate &date )
278 {
279  return mergeIncidenceList( events( date ), todos( date ), journals( date ) );
280 }
281 
282 Incidence::List Calendar::incidences()
283 {
284  return mergeIncidenceList( events(), todos(), journals() );
285 }
286 
287 Incidence::List Calendar::rawIncidences()
288 {
289  return mergeIncidenceList( rawEvents(), rawTodos(), rawJournals() );
290 }
291 
292 Event::List Calendar::sortEvents( Event::List *eventList,
293  EventSortField sortField,
294  SortDirection sortDirection )
295 {
296  Event::List eventListSorted;
297  Event::List tempList;
298  Event::List alphaList;
299  Event::List::Iterator sortIt;
300  Event::List::Iterator eit;
301 
302  // Notice we alphabetically presort Summaries first.
303  // We do this so comparison "ties" stay in a nice order.
304 
305  switch( sortField ) {
306  case EventSortUnsorted:
307  eventListSorted = *eventList;
308  break;
309 
310  case EventSortStartDate:
311  alphaList = sortEvents( eventList, EventSortSummary, sortDirection );
312  for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
313  if ( (*eit)->dtStart().isDateOnly() ) {
314  tempList.append( *eit );
315  continue;
316  }
317  sortIt = eventListSorted.begin();
318  if ( sortDirection == SortDirectionAscending ) {
319  while ( sortIt != eventListSorted.end() &&
320  (*eit)->dtStart() >= (*sortIt)->dtStart() ) {
321  ++sortIt;
322  }
323  } else {
324  while ( sortIt != eventListSorted.end() &&
325  (*eit)->dtStart() < (*sortIt)->dtStart() ) {
326  ++sortIt;
327  }
328  }
329  eventListSorted.insert( sortIt, *eit );
330  }
331  if ( sortDirection == SortDirectionAscending ) {
332  // Prepend the list of all-day Events
333  tempList += eventListSorted;
334  eventListSorted = tempList;
335  } else {
336  // Append the list of all-day Events
337  eventListSorted += tempList;
338  }
339  break;
340 
341  case EventSortEndDate:
342  alphaList = sortEvents( eventList, EventSortSummary, sortDirection );
343  for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
344  if ( (*eit)->hasEndDate() ) {
345  sortIt = eventListSorted.begin();
346  if ( sortDirection == SortDirectionAscending ) {
347  while ( sortIt != eventListSorted.end() &&
348  (*eit)->dtEnd() >= (*sortIt)->dtEnd() ) {
349  ++sortIt;
350  }
351  } else {
352  while ( sortIt != eventListSorted.end() &&
353  (*eit)->dtEnd() < (*sortIt)->dtEnd() ) {
354  ++sortIt;
355  }
356  }
357  } else {
358  // Keep a list of the Events without End DateTimes
359  tempList.append( *eit );
360  }
361  eventListSorted.insert( sortIt, *eit );
362  }
363  if ( sortDirection == SortDirectionAscending ) {
364  // Append the list of Events without End DateTimes
365  eventListSorted += tempList;
366  } else {
367  // Prepend the list of Events without End DateTimes
368  tempList += eventListSorted;
369  eventListSorted = tempList;
370  }
371  break;
372 
373  case EventSortSummary:
374  for ( eit = eventList->begin(); eit != eventList->end(); ++eit ) {
375  sortIt = eventListSorted.begin();
376  if ( sortDirection == SortDirectionAscending ) {
377  while ( sortIt != eventListSorted.end() &&
378  (*eit)->summary() >= (*sortIt)->summary() ) {
379  ++sortIt;
380  }
381  } else {
382  while ( sortIt != eventListSorted.end() &&
383  (*eit)->summary() < (*sortIt)->summary() ) {
384  ++sortIt;
385  }
386  }
387  eventListSorted.insert( sortIt, *eit );
388  }
389  break;
390  }
391 
392  return eventListSorted;
393 }
394 
395 Event::List Calendar::sortEventsForDate( Event::List *eventList,
396  const QDate &date,
397  const KDateTime::Spec &timeSpec,
398  EventSortField sortField,
399  SortDirection sortDirection )
400 {
401  Event::List eventListSorted;
402  Event::List tempList;
403  Event::List alphaList;
404  Event::List::Iterator sortIt;
405  Event::List::Iterator eit;
406 
407  switch( sortField ) {
408  case EventSortStartDate:
409  alphaList = sortEvents( eventList, EventSortSummary, sortDirection );
410  for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
411  if ( (*eit)->allDay() ) {
412  tempList.append( *eit );
413  continue;
414  }
415  sortIt = eventListSorted.begin();
416  if ( sortDirection == SortDirectionAscending ) {
417  while ( sortIt != eventListSorted.end() ) {
418  if ( !(*eit)->recurs() ) {
419  if ( (*eit)->dtStart().time() >= (*sortIt)->dtStart().time() ) {
420  ++sortIt;
421  } else {
422  break;
423  }
424  } else {
425  if ( (*eit)->recursOn( date, timeSpec ) ) {
426  if ( (*eit)->dtStart().time() >= (*sortIt)->dtStart().time() ) {
427  ++sortIt;
428  } else {
429  break;
430  }
431  } else {
432  ++sortIt;
433  }
434  }
435  }
436  } else { // descending
437  while ( sortIt != eventListSorted.end() ) {
438  if ( !(*eit)->recurs() ) {
439  if ( (*eit)->dtStart().time() < (*sortIt)->dtStart().time() ) {
440  ++sortIt;
441  } else {
442  break;
443  }
444  } else {
445  if ( (*eit)->recursOn( date, timeSpec ) ) {
446  if ( (*eit)->dtStart().time() < (*sortIt)->dtStart().time() ) {
447  ++sortIt;
448  } else {
449  break;
450  }
451  } else {
452  ++sortIt;
453  }
454  }
455  }
456  }
457  eventListSorted.insert( sortIt, *eit );
458  }
459  if ( sortDirection == SortDirectionAscending ) {
460  // Prepend the list of all-day Events
461  tempList += eventListSorted;
462  eventListSorted = tempList;
463  } else {
464  // Append the list of all-day Events
465  eventListSorted += tempList;
466  }
467  break;
468 
469  case EventSortEndDate:
470  alphaList = sortEvents( eventList, EventSortSummary, sortDirection );
471  for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
472  if ( (*eit)->hasEndDate() ) {
473  sortIt = eventListSorted.begin();
474  if ( sortDirection == SortDirectionAscending ) {
475  while ( sortIt != eventListSorted.end() ) {
476  if ( !(*eit)->recurs() ) {
477  if ( (*eit)->dtEnd().time() >= (*sortIt)->dtEnd().time() ) {
478  ++sortIt;
479  } else {
480  break;
481  }
482  } else {
483  if ( (*eit)->recursOn( date, timeSpec ) ) {
484  if ( (*eit)->dtEnd().time() >= (*sortIt)->dtEnd().time() ) {
485  ++sortIt;
486  } else {
487  break;
488  }
489  } else {
490  ++sortIt;
491  }
492  }
493  }
494  } else { // descending
495  while ( sortIt != eventListSorted.end() ) {
496  if ( !(*eit)->recurs() ) {
497  if ( (*eit)->dtEnd().time() < (*sortIt)->dtEnd().time() ) {
498  ++sortIt;
499  } else {
500  break;
501  }
502  } else {
503  if ( (*eit)->recursOn( date, timeSpec ) ) {
504  if ( (*eit)->dtEnd().time() < (*sortIt)->dtEnd().time() ) {
505  ++sortIt;
506  } else {
507  break;
508  }
509  } else {
510  ++sortIt;
511  }
512  }
513  }
514  }
515  } else {
516  // Keep a list of the Events without End DateTimes
517  tempList.append( *eit );
518  }
519  eventListSorted.insert( sortIt, *eit );
520  }
521  if ( sortDirection == SortDirectionAscending ) {
522  // Prepend the list of Events without End DateTimes
523  tempList += eventListSorted;
524  eventListSorted = tempList;
525  } else {
526  // Append the list of Events without End DateTimes
527  eventListSorted += tempList;
528  }
529  break;
530 
531  default:
532  eventListSorted = sortEvents( eventList, sortField, sortDirection );
533  break;
534  }
535 
536  return eventListSorted;
537 }
538 
539 Event::List Calendar::events( const QDate &date,
540  const KDateTime::Spec &timeSpec,
541  EventSortField sortField,
542  SortDirection sortDirection )
543 {
544  Event::List el = rawEventsForDate( date, timeSpec, sortField, sortDirection );
545  d->mFilter->apply( &el );
546  return el;
547 }
548 
549 Event::List Calendar::events( const KDateTime &dt )
550 {
551  Event::List el = rawEventsForDate( dt );
552  d->mFilter->apply( &el );
553  return el;
554 }
555 
556 Event::List Calendar::events( const QDate &start, const QDate &end,
557  const KDateTime::Spec &timeSpec,
558  bool inclusive )
559 {
560  Event::List el = rawEvents( start, end, timeSpec, inclusive );
561  d->mFilter->apply( &el );
562  return el;
563 }
564 
565 Event::List Calendar::events( EventSortField sortField,
566  SortDirection sortDirection )
567 {
568  Event::List el = rawEvents( sortField, sortDirection );
569  d->mFilter->apply( &el );
570  return el;
571 }
572 
573 bool Calendar::addIncidence( Incidence *incidence )
574 {
575  Incidence::AddVisitor<Calendar> v( this );
576 
577  return incidence->accept( v );
578 }
579 
580 bool Calendar::deleteIncidence( Incidence *incidence )
581 {
582  if ( beginChange( incidence ) ) {
583  Incidence::DeleteVisitor<Calendar> v( this );
584  bool result = incidence->accept( v );
585  endChange( incidence );
586  return result;
587  } else {
588  return false;
589  }
590 }
591 
592 // Dissociate a single occurrence or all future occurrences from a recurring
593 // sequence. The new incidence is returned, but not automatically inserted
594 // into the calendar, which is left to the calling application.
595 Incidence *Calendar::dissociateOccurrence( Incidence *incidence,
596  const QDate &date,
597  const KDateTime::Spec &spec,
598  bool single )
599 {
600  if ( !incidence || !incidence->recurs() ) {
601  return 0;
602  }
603 
604  Incidence *newInc = incidence->clone();
605  newInc->recreate();
606  // Do not call setRelatedTo() when dissociating recurring to-dos, otherwise the new to-do
607  // will appear as a child. Originally, we planned to set a relation with reltype SIBLING
608  // when dissociating to-dos, but currently kcal only supports reltype PARENT.
609  // We can uncomment the following line when we support the PARENT reltype.
610  //newInc->setRelatedTo( incidence );
611  Recurrence *recur = newInc->recurrence();
612  if ( single ) {
613  recur->clear();
614  } else {
615  // Adjust the recurrence for the future incidences. In particular adjust
616  // the "end after n occurrences" rules! "No end date" and "end by ..."
617  // don't need to be modified.
618  int duration = recur->duration();
619  if ( duration > 0 ) {
620  int doneduration = recur->durationTo( date.addDays( -1 ) );
621  if ( doneduration >= duration ) {
622  kDebug() << "The dissociated event already occurred more often"
623  << "than it was supposed to ever occur. ERROR!";
624  recur->clear();
625  } else {
626  recur->setDuration( duration - doneduration );
627  }
628  }
629  }
630  // Adjust the date of the incidence
631  if ( incidence->type() == "Event" ) {
632  Event *ev = static_cast<Event *>( newInc );
633  KDateTime start( ev->dtStart() );
634  int daysTo = start.toTimeSpec( spec ).date().daysTo( date );
635  ev->setDtStart( start.addDays( daysTo ) );
636  ev->setDtEnd( ev->dtEnd().addDays( daysTo ) );
637  } else if ( incidence->type() == "Todo" ) {
638  Todo *td = static_cast<Todo *>( newInc );
639  bool haveOffset = false;
640  int daysTo = 0;
641  if ( td->hasDueDate() ) {
642  KDateTime due( td->dtDue() );
643  daysTo = due.toTimeSpec( spec ).date().daysTo( date );
644  td->setDtDue( due.addDays( daysTo ), true );
645  haveOffset = true;
646  }
647  if ( td->hasStartDate() ) {
648  KDateTime start( td->dtStart() );
649  if ( !haveOffset ) {
650  daysTo = start.toTimeSpec( spec ).date().daysTo( date );
651  }
652  td->setDtStart( start.addDays( daysTo ) );
653  haveOffset = true;
654  }
655  }
656  recur = incidence->recurrence();
657  if ( recur ) {
658  if ( single ) {
659  recur->addExDate( date );
660  } else {
661  // Make sure the recurrence of the past events ends
662  // at the corresponding day
663  recur->setEndDate( date.addDays(-1) );
664  }
665  }
666  return newInc;
667 }
668 
669 Incidence *Calendar::incidence( const QString &uid )
670 {
671  Incidence *i = event( uid );
672  if ( i ) {
673  return i;
674  }
675 
676  i = todo( uid );
677  if ( i ) {
678  return i;
679  }
680 
681  i = journal( uid );
682  return i;
683 }
684 
685 Incidence::List Calendar::incidencesFromSchedulingID( const QString &sid )
686 {
687  Incidence::List result;
688  const Incidence::List incidences = rawIncidences();
689  Incidence::List::const_iterator it = incidences.begin();
690  for ( ; it != incidences.end(); ++it ) {
691  if ( (*it)->schedulingID() == sid ) {
692  result.append( *it );
693  }
694  }
695  return result;
696 }
697 
698 Incidence *Calendar::incidenceFromSchedulingID( const QString &UID )
699 {
700  const Incidence::List incidences = rawIncidences();
701  Incidence::List::const_iterator it = incidences.begin();
702  for ( ; it != incidences.end(); ++it ) {
703  if ( (*it)->schedulingID() == UID ) {
704  // Touchdown, and the crowd goes wild
705  return *it;
706  }
707  }
708  // Not found
709  return 0;
710 }
711 
712 Todo::List Calendar::sortTodos( Todo::List *todoList,
713  TodoSortField sortField,
714  SortDirection sortDirection )
715 {
716  Todo::List todoListSorted;
717  Todo::List tempList, t;
718  Todo::List alphaList;
719  Todo::List::Iterator sortIt;
720  Todo::List::Iterator eit;
721 
722  // Notice we alphabetically presort Summaries first.
723  // We do this so comparison "ties" stay in a nice order.
724 
725  // Note that To-dos may not have Start DateTimes nor due DateTimes.
726 
727  switch( sortField ) {
728  case TodoSortUnsorted:
729  todoListSorted = *todoList;
730  break;
731 
732  case TodoSortStartDate:
733  alphaList = sortTodos( todoList, TodoSortSummary, sortDirection );
734  for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
735  if ( (*eit)->hasStartDate() ) {
736  sortIt = todoListSorted.begin();
737  if ( sortDirection == SortDirectionAscending ) {
738  while ( sortIt != todoListSorted.end() &&
739  (*eit)->dtStart() >= (*sortIt)->dtStart() ) {
740  ++sortIt;
741  }
742  } else {
743  while ( sortIt != todoListSorted.end() &&
744  (*eit)->dtStart() < (*sortIt)->dtStart() ) {
745  ++sortIt;
746  }
747  }
748  todoListSorted.insert( sortIt, *eit );
749  } else {
750  // Keep a list of the To-dos without Start DateTimes
751  tempList.append( *eit );
752  }
753  }
754  if ( sortDirection == SortDirectionAscending ) {
755  // Append the list of To-dos without Start DateTimes
756  todoListSorted += tempList;
757  } else {
758  // Prepend the list of To-dos without Start DateTimes
759  tempList += todoListSorted;
760  todoListSorted = tempList;
761  }
762  break;
763 
764  case TodoSortDueDate:
765  alphaList = sortTodos( todoList, TodoSortSummary, sortDirection );
766  for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
767  if ( (*eit)->hasDueDate() ) {
768  sortIt = todoListSorted.begin();
769  if ( sortDirection == SortDirectionAscending ) {
770  while ( sortIt != todoListSorted.end() &&
771  (*eit)->dtDue() >= (*sortIt)->dtDue() ) {
772  ++sortIt;
773  }
774  } else {
775  while ( sortIt != todoListSorted.end() &&
776  (*eit)->dtDue() < (*sortIt)->dtDue() ) {
777  ++sortIt;
778  }
779  }
780  todoListSorted.insert( sortIt, *eit );
781  } else {
782  // Keep a list of the To-dos without Due DateTimes
783  tempList.append( *eit );
784  }
785  }
786  if ( sortDirection == SortDirectionAscending ) {
787  // Append the list of To-dos without Due DateTimes
788  todoListSorted += tempList;
789  } else {
790  // Prepend the list of To-dos without Due DateTimes
791  tempList += todoListSorted;
792  todoListSorted = tempList;
793  }
794  break;
795 
796  case TodoSortPriority:
797  alphaList = sortTodos( todoList, TodoSortSummary, sortDirection );
798  for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
799  sortIt = todoListSorted.begin();
800  if ( sortDirection == SortDirectionAscending ) {
801  while ( sortIt != todoListSorted.end() &&
802  (*eit)->priority() >= (*sortIt)->priority() ) {
803  ++sortIt;
804  }
805  } else {
806  while ( sortIt != todoListSorted.end() &&
807  (*eit)->priority() < (*sortIt)->priority() ) {
808  ++sortIt;
809  }
810  }
811  todoListSorted.insert( sortIt, *eit );
812  }
813  break;
814 
815  case TodoSortPercentComplete:
816  alphaList = sortTodos( todoList, TodoSortSummary, sortDirection );
817  for ( eit = alphaList.begin(); eit != alphaList.end(); ++eit ) {
818  sortIt = todoListSorted.begin();
819  if ( sortDirection == SortDirectionAscending ) {
820  while ( sortIt != todoListSorted.end() &&
821  (*eit)->percentComplete() >= (*sortIt)->percentComplete() ) {
822  ++sortIt;
823  }
824  } else {
825  while ( sortIt != todoListSorted.end() &&
826  (*eit)->percentComplete() < (*sortIt)->percentComplete() ) {
827  ++sortIt;
828  }
829  }
830  todoListSorted.insert( sortIt, *eit );
831  }
832  break;
833 
834  case TodoSortSummary:
835  for ( eit = todoList->begin(); eit != todoList->end(); ++eit ) {
836  sortIt = todoListSorted.begin();
837  if ( sortDirection == SortDirectionAscending ) {
838  while ( sortIt != todoListSorted.end() &&
839  (*eit)->summary() >= (*sortIt)->summary() ) {
840  ++sortIt;
841  }
842  } else {
843  while ( sortIt != todoListSorted.end() &&
844  (*eit)->summary() < (*sortIt)->summary() ) {
845  ++sortIt;
846  }
847  }
848  todoListSorted.insert( sortIt, *eit );
849  }
850  break;
851  }
852 
853  return todoListSorted;
854 }
855 
856 Todo::List Calendar::todos( TodoSortField sortField,
857  SortDirection sortDirection )
858 {
859  Todo::List tl = rawTodos( sortField, sortDirection );
860  d->mFilter->apply( &tl );
861  return tl;
862 }
863 
864 Todo::List Calendar::todos( const QDate &date )
865 {
866  Todo::List el = rawTodosForDate( date );
867  d->mFilter->apply( &el );
868  return el;
869 }
870 
871 Journal::List Calendar::sortJournals( Journal::List *journalList,
872  JournalSortField sortField,
873  SortDirection sortDirection )
874 {
875  Journal::List journalListSorted;
876  Journal::List::Iterator sortIt;
877  Journal::List::Iterator eit;
878 
879  switch( sortField ) {
880  case JournalSortUnsorted:
881  journalListSorted = *journalList;
882  break;
883 
884  case JournalSortDate:
885  for ( eit = journalList->begin(); eit != journalList->end(); ++eit ) {
886  sortIt = journalListSorted.begin();
887  if ( sortDirection == SortDirectionAscending ) {
888  while ( sortIt != journalListSorted.end() &&
889  (*eit)->dtStart() >= (*sortIt)->dtStart() ) {
890  ++sortIt;
891  }
892  } else {
893  while ( sortIt != journalListSorted.end() &&
894  (*eit)->dtStart() < (*sortIt)->dtStart() ) {
895  ++sortIt;
896  }
897  }
898  journalListSorted.insert( sortIt, *eit );
899  }
900  break;
901 
902  case JournalSortSummary:
903  for ( eit = journalList->begin(); eit != journalList->end(); ++eit ) {
904  sortIt = journalListSorted.begin();
905  if ( sortDirection == SortDirectionAscending ) {
906  while ( sortIt != journalListSorted.end() &&
907  (*eit)->summary() >= (*sortIt)->summary() ) {
908  ++sortIt;
909  }
910  } else {
911  while ( sortIt != journalListSorted.end() &&
912  (*eit)->summary() < (*sortIt)->summary() ) {
913  ++sortIt;
914  }
915  }
916  journalListSorted.insert( sortIt, *eit );
917  }
918  break;
919  }
920 
921  return journalListSorted;
922 }
923 
924 Journal::List Calendar::journals( JournalSortField sortField,
925  SortDirection sortDirection )
926 {
927  Journal::List jl = rawJournals( sortField, sortDirection );
928  d->mFilter->apply( &jl );
929  return jl;
930 }
931 
932 Journal::List Calendar::journals( const QDate &date )
933 {
934  Journal::List el = rawJournalsForDate( date );
935  d->mFilter->apply( &el );
936  return el;
937 }
938 
939 void Calendar::beginBatchAdding()
940 {
941  emit batchAddingBegins();
942 }
943 
944 void Calendar::endBatchAdding()
945 {
946  emit batchAddingEnds();
947 }
948 
949 // When this is called, the to-dos have already been added to the calendar.
950 // This method is only about linking related to-dos.
951 void Calendar::setupRelations( Incidence *forincidence )
952 {
953  if ( !forincidence ) {
954  return;
955  }
956 
957  QString uid = forincidence->uid();
958 
959  // First, go over the list of orphans and see if this is their parent
960  QList<Incidence*> l = d->mOrphans.values( uid );
961  d->mOrphans.remove( uid );
962  for ( int i = 0, end = l.count(); i < end; ++i ) {
963  l[i]->setRelatedTo( forincidence );
964  forincidence->addRelation( l[i] );
965  d->mOrphanUids.remove( l[i]->uid() );
966  }
967 
968  // Now see about this incidences parent
969  if ( !forincidence->relatedTo() && !forincidence->relatedToUid().isEmpty() ) {
970  // Incidence has a uid it is related to but is not registered to it yet.
971  // Try to find it
972  Incidence *parent = incidence( forincidence->relatedToUid() );
973  if ( parent ) {
974  // Found it
975 
976  // look for hierarchy loops
977  if ( isAncestorOf( forincidence, parent ) ) {
978  forincidence->setRelatedToUid( QString() );
979  kWarning() << "hierarchy loop beetween " << forincidence->uid() << " and " << parent->uid();
980  } else {
981  forincidence->setRelatedTo( parent );
982  parent->addRelation( forincidence );
983  }
984 
985  } else {
986  // Not found, put this in the mOrphans list
987  // Note that the mOrphans dict might contain multiple entries with the
988  // same key! which are multiple children that wait for the parent
989  // incidence to be inserted.
990  d->mOrphans.insert( forincidence->relatedToUid(), forincidence );
991  d->mOrphanUids.insert( forincidence->uid(), forincidence );
992  }
993  }
994 }
995 
996 // If a to-do with sub-to-dos is deleted, move it's sub-to-dos to the orphan list
997 void Calendar::removeRelations( Incidence *incidence )
998 {
999  if ( !incidence ) {
1000  kDebug() << "Warning: incidence is 0";
1001  return;
1002  }
1003 
1004  QString uid = incidence->uid();
1005  foreach ( Incidence *i, incidence->relations() ) {
1006  if ( !d->mOrphanUids.contains( i->uid() ) ) {
1007  d->mOrphans.insert( uid, i );
1008  d->mOrphanUids.insert( i->uid(), i );
1009  i->setRelatedTo( 0 );
1010  i->setRelatedToUid( uid );
1011  }
1012  }
1013 
1014  // If this incidence is related to something else, tell that about it
1015  if ( incidence->relatedTo() ) {
1016  incidence->relatedTo()->removeRelation( incidence );
1017  }
1018 
1019  // Remove this one from the orphans list
1020  if ( d->mOrphanUids.remove( uid ) ) {
1021  // This incidence is located in the orphans list - it should be removed
1022  // Since the mOrphans dict might contain the same key (with different
1023  // child incidence pointers!) multiple times, take care that we remove
1024  // the correct one. So we need to remove all items with the given
1025  // parent UID, and readd those that are not for this item. Also, there
1026  // might be other entries with differnet UID that point to this
1027  // incidence (this might happen when the relatedTo of the item is
1028  // changed before its parent is inserted. This might happen with
1029  // groupware servers....). Remove them, too
1030  QStringList relatedToUids;
1031 
1032  // First, create a list of all keys in the mOrphans list which point
1033  // to the removed item
1034  relatedToUids << incidence->relatedToUid();
1035  for ( QMultiHash<QString, Incidence*>::Iterator it = d->mOrphans.begin();
1036  it != d->mOrphans.end(); ++it ) {
1037  if ( it.value()->uid() == uid ) {
1038  relatedToUids << it.key();
1039  }
1040  }
1041 
1042  // now go through all uids that have one entry that point to the incidence
1043  for ( QStringList::const_iterator uidit = relatedToUids.constBegin();
1044  uidit != relatedToUids.constEnd(); ++uidit ) {
1045  Incidence::List tempList;
1046  // Remove all to get access to the remaining entries
1047  QList<Incidence*> l = d->mOrphans.values( *uidit );
1048  d->mOrphans.remove( *uidit );
1049  foreach ( Incidence *i, l ) {
1050  if ( i != incidence ) {
1051  tempList.append( i );
1052  }
1053  }
1054  // Readd those that point to a different orphan incidence
1055  for ( Incidence::List::Iterator incit = tempList.begin();
1056  incit != tempList.end(); ++incit ) {
1057  d->mOrphans.insert( *uidit, *incit );
1058  }
1059  }
1060  }
1061 
1062  // Make sure the deleted incidence doesn't relate to a non-deleted incidence,
1063  // since that would cause trouble in CalendarLocal::close(), as the deleted
1064  // incidences are destroyed after the non-deleted incidences. The destructor
1065  // of the deleted incidences would then try to access the already destroyed
1066  // non-deleted incidence, which would segfault.
1067  //
1068  // So in short: Make sure dead incidences don't point to alive incidences
1069  // via the relation.
1070  //
1071  // This crash is tested in CalendarLocalTest::testRelationsCrash().
1072  incidence->setRelatedTo( 0 );
1073 }
1074 
1075 bool Calendar::isAncestorOf( Incidence *ancestor, Incidence *incidence )
1076 {
1077  if ( !incidence || incidence->relatedToUid().isEmpty() ) {
1078  return false;
1079  } else if ( incidence->relatedToUid() == ancestor->uid() ) {
1080  return true;
1081  } else {
1082  return isAncestorOf( ancestor, this->incidence( incidence->relatedToUid() ) );
1083  }
1084 }
1085 
1086 void Calendar::CalendarObserver::calendarModified( bool modified, Calendar *calendar )
1087 {
1088  Q_UNUSED( modified );
1089  Q_UNUSED( calendar );
1090 }
1091 
1092 void Calendar::CalendarObserver::calendarIncidenceAdded( Incidence *incidence )
1093 {
1094  Q_UNUSED( incidence );
1095 }
1096 
1097 void Calendar::CalendarObserver::calendarIncidenceChanged( Incidence *incidence )
1098 {
1099  Q_UNUSED( incidence );
1100 }
1101 
1102 void Calendar::CalendarObserver::calendarIncidenceDeleted( Incidence *incidence )
1103 {
1104  Q_UNUSED( incidence );
1105 }
1106 
1107 void Calendar::registerObserver( CalendarObserver *observer )
1108 {
1109  if ( !d->mObservers.contains( observer ) ) {
1110  d->mObservers.append( observer );
1111  }
1112  d->mNewObserver = true;
1113 }
1114 
1115 void Calendar::unregisterObserver( CalendarObserver *observer )
1116 {
1117  d->mObservers.removeAll( observer );
1118 }
1119 
1120 bool Calendar::isSaving()
1121 {
1122  return false;
1123 }
1124 
1125 void Calendar::setModified( bool modified )
1126 {
1127  if ( modified != d->mModified || d->mNewObserver ) {
1128  d->mNewObserver = false;
1129  foreach ( CalendarObserver *observer, d->mObservers ) {
1130  observer->calendarModified( modified, this );
1131  }
1132  d->mModified = modified;
1133  }
1134 }
1135 
1136 bool Calendar::isModified() const
1137 {
1138  return d->mModified;
1139 }
1140 
1141 void Calendar::incidenceUpdated( IncidenceBase *incidence )
1142 {
1143  incidence->setLastModified( KDateTime::currentUtcDateTime() );
1144  // we should probably update the revision number here,
1145  // or internally in the Event itself when certain things change.
1146  // need to verify with ical documentation.
1147 
1148  // The static_cast is ok as the CalendarLocal only observes Incidence objects
1149  notifyIncidenceChanged( static_cast<Incidence *>( incidence ) );
1150 
1151  setModified( true );
1152 }
1153 
1154 void Calendar::doSetTimeSpec( const KDateTime::Spec &timeSpec )
1155 {
1156  Q_UNUSED( timeSpec );
1157 }
1158 
1159 void Calendar::notifyIncidenceAdded( Incidence *i )
1160 {
1161  if ( !d->mObserversEnabled ) {
1162  return;
1163  }
1164 
1165  foreach ( CalendarObserver *observer, d->mObservers ) {
1166  observer->calendarIncidenceAdded( i );
1167  }
1168 }
1169 
1170 void Calendar::notifyIncidenceChanged( Incidence *i )
1171 {
1172  if ( !d->mObserversEnabled ) {
1173  return;
1174  }
1175 
1176  foreach ( CalendarObserver *observer, d->mObservers ) {
1177  observer->calendarIncidenceChanged( i );
1178  }
1179 }
1180 
1181 void Calendar::notifyIncidenceDeleted( Incidence *i )
1182 {
1183  if ( !d->mObserversEnabled ) {
1184  return;
1185  }
1186 
1187  foreach ( CalendarObserver *observer, d->mObservers ) {
1188  observer->calendarIncidenceDeleted( i );
1189  }
1190 }
1191 
1192 void Calendar::customPropertyUpdated()
1193 {
1194  setModified( true );
1195 }
1196 
1197 void Calendar::setProductId( const QString &id )
1198 {
1199  d->mProductId = id;
1200 }
1201 
1202 QString Calendar::productId() const
1203 {
1204  return d->mProductId;
1205 }
1206 
1207 Incidence::List Calendar::mergeIncidenceList( const Event::List &events,
1208  const Todo::List &todos,
1209  const Journal::List &journals )
1210 {
1211  Incidence::List incidences;
1212 
1213  int i, end;
1214  for ( i = 0, end = events.count(); i < end; ++i ) {
1215  incidences.append( events[i] );
1216  }
1217 
1218  for ( i = 0, end = todos.count(); i < end; ++i ) {
1219  incidences.append( todos[i] );
1220  }
1221 
1222  for ( i = 0, end = journals.count(); i < end; ++i ) {
1223  incidences.append( journals[i] );
1224  }
1225 
1226  return incidences;
1227 }
1228 
1229 bool Calendar::beginChange( Incidence *incidence )
1230 {
1231  Q_UNUSED( incidence );
1232  return true;
1233 }
1234 
1235 bool Calendar::endChange( Incidence *incidence )
1236 {
1237  Q_UNUSED( incidence );
1238  return true;
1239 }
1240 
1241 void Calendar::setObserversEnabled( bool enabled )
1242 {
1243  d->mObserversEnabled = enabled;
1244 }
1245 
1246 void Calendar::appendAlarms( Alarm::List &alarms, Incidence *incidence,
1247  const KDateTime &from, const KDateTime &to )
1248 {
1249  KDateTime preTime = from.addSecs(-1);
1250 
1251  Alarm::List alarmlist = incidence->alarms();
1252  for ( int i = 0, iend = alarmlist.count(); i < iend; ++i ) {
1253  if ( alarmlist[i]->enabled() ) {
1254  KDateTime dt = alarmlist[i]->nextRepetition( preTime );
1255  if ( dt.isValid() && dt <= to ) {
1256  kDebug() << incidence->summary() << "':" << dt.toString();
1257  alarms.append( alarmlist[i] );
1258  }
1259  }
1260  }
1261 }
1262 
1263 void Calendar::appendRecurringAlarms( Alarm::List &alarms,
1264  Incidence *incidence,
1265  const KDateTime &from,
1266  const KDateTime &to )
1267 {
1268  KDateTime dt;
1269  Duration endOffset( 0 );
1270  bool endOffsetValid = false;
1271  Duration period( from, to );
1272 
1273  Event *e = static_cast<Event *>( incidence );
1274  Todo *t = static_cast<Todo *>( incidence );
1275 
1276  Alarm::List alarmlist = incidence->alarms();
1277  for ( int i = 0, iend = alarmlist.count(); i < iend; ++i ) {
1278  Alarm *a = alarmlist[i];
1279  if ( a->enabled() ) {
1280  if ( a->hasTime() ) {
1281  // The alarm time is defined as an absolute date/time
1282  dt = a->nextRepetition( from.addSecs( -1 ) );
1283  if ( !dt.isValid() || dt > to ) {
1284  continue;
1285  }
1286  } else {
1287  // Alarm time is defined by an offset from the event start or end time.
1288  // Find the offset from the event start time, which is also used as the
1289  // offset from the recurrence time.
1290  Duration offset( 0 );
1291  if ( a->hasStartOffset() ) {
1292  offset = a->startOffset();
1293  } else if ( a->hasEndOffset() ) {
1294  offset = a->endOffset();
1295  if ( !endOffsetValid ) {
1296  if ( incidence->type() == "Event" ) {
1297  endOffset = Duration( e->dtStart(), e->dtEnd() );
1298  endOffsetValid = true;
1299  } else if ( incidence->type() == "Todo" &&
1300  t->hasStartDate() && t->hasDueDate() ) {
1301  endOffset = Duration( t->dtStart(), t->dtEnd() );
1302  endOffsetValid = true;
1303  }
1304  }
1305  }
1306 
1307  // Find the incidence's earliest alarm
1308  KDateTime alarmStart;
1309  if ( incidence->type() == "Event" ) {
1310  alarmStart =
1311  offset.end( a->hasEndOffset() ? e->dtEnd() : e->dtStart() );
1312  } else if ( incidence->type() == "Todo" ) {
1313  alarmStart =
1314  offset.end( a->hasEndOffset() ? t->dtDue() : t->dtStart() );
1315  }
1316 
1317  if ( alarmStart.isValid() && alarmStart > to ) {
1318  continue;
1319  }
1320 
1321  KDateTime baseStart;
1322  if ( incidence->type() == "Event" ) {
1323  baseStart = e->dtStart();
1324  } else if ( incidence->type() == "Todo" ) {
1325  baseStart = t->dtDue();
1326  }
1327  if ( alarmStart.isValid() && from > alarmStart ) {
1328  alarmStart = from; // don't look earlier than the earliest alarm
1329  baseStart = (-offset).end( (-endOffset).end( alarmStart ) );
1330  }
1331 
1332  // Adjust the 'alarmStart' date/time and find the next recurrence
1333  // at or after it. Treat the two offsets separately in case one
1334  // is daily and the other not.
1335  dt = incidence->recurrence()->getNextDateTime( baseStart.addSecs( -1 ) );
1336  if ( !dt.isValid() ||
1337  ( dt = endOffset.end( offset.end( dt ) ) ) > to ) // adjust 'dt' to get the alarm time
1338  {
1339  // The next recurrence is too late.
1340  if ( !a->repeatCount() ) {
1341  continue;
1342  }
1343 
1344  // The alarm has repetitions, so check whether repetitions of
1345  // previous recurrences fall within the time period.
1346  bool found = false;
1347  Duration alarmDuration = a->duration();
1348  for ( KDateTime base = baseStart;
1349  ( dt = incidence->recurrence()->getPreviousDateTime( base ) ).isValid();
1350  base = dt ) {
1351  if ( a->duration().end( dt ) < base ) {
1352  break; // this recurrence's last repetition is too early, so give up
1353  }
1354 
1355  // The last repetition of this recurrence is at or after
1356  // 'alarmStart' time. Check if a repetition occurs between
1357  // 'alarmStart' and 'to'.
1358  int snooze = a->snoozeTime().value(); // in seconds or days
1359  if ( a->snoozeTime().isDaily() ) {
1360  Duration toFromDuration( dt, base );
1361  int toFrom = toFromDuration.asDays();
1362  if ( a->snoozeTime().end( from ) <= to ||
1363  ( toFromDuration.isDaily() && toFrom % snooze == 0 ) ||
1364  ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asDays() ) {
1365  found = true;
1366 #ifndef NDEBUG
1367  // for debug output
1368  dt = offset.end( dt ).addDays( ( ( toFrom - 1 ) / snooze + 1 ) * snooze );
1369 #endif
1370  break;
1371  }
1372  } else {
1373  int toFrom = dt.secsTo( base );
1374  if ( period.asSeconds() >= snooze ||
1375  toFrom % snooze == 0 ||
1376  ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asSeconds() )
1377  {
1378  found = true;
1379 #ifndef NDEBUG
1380  // for debug output
1381  dt = offset.end( dt ).addSecs( ( ( toFrom - 1 ) / snooze + 1 ) * snooze );
1382 #endif
1383  break;
1384  }
1385  }
1386  }
1387  if ( !found ) {
1388  continue;
1389  }
1390  }
1391  }
1392  kDebug() << incidence->summary() << "':" << dt.toString();
1393  alarms.append( a );
1394  }
1395  }
1396 }
1397 
KCal::Calendar::rawEventsForDate
virtual Event::List rawEventsForDate(const KDateTime &dt)=0
Returns an unfiltered list of all Events which occur on the given timestamp.
KCal::Calendar::mergeIncidenceList
static Incidence::List mergeIncidenceList(const Event::List &events, const Todo::List &todos, const Journal::List &journals)
Create a merged list of Events, Todos, and Journals.
Definition: calendar.cpp:1207
KCal::Calendar::rawTodos
virtual Todo::List rawTodos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Returns a sorted, unfiltered list of all Todos for this Calendar.
KCal::IncidenceBase::setLastModified
void setLastModified(const KDateTime &lm)
Sets the time the incidence was last modified to lm.
Definition: incidencebase.cpp:189
KCal::Calendar::rawJournalsForDate
virtual Journal::List rawJournalsForDate(const QDate &date)=0
Returns an unfiltered list of all Journals for on the specified date.
KCal::Calendar::incidenceFromSchedulingID
Incidence * incidenceFromSchedulingID(const QString &sid)
Returns the Incidence associated with the given scheduling identifier.
Definition: calendar.cpp:698
KCal::Calendar::shiftTimes
void shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec)
Shifts the times of all incidences so that they appear at the same clock time as before but in a new ...
Definition: calendar.cpp:222
KCal::Calendar::setTimeSpec
void setTimeSpec(const KDateTime::Spec &timeSpec)
Sets the default time specification (time zone, etc.) used for creating or modifying incidences in th...
Definition: calendar.cpp:136
KCal::Calendar::~Calendar
virtual ~Calendar()
Destroys the calendar.
Definition: calendar.cpp:119
KCal::Incidence::relatedTo
Incidence * relatedTo() const
Returns a pointer for the incidence that is related to this one.
Definition: incidence.cpp:516
KCal::Calendar::sortJournals
static Journal::List sortJournals(Journal::List *journalList, JournalSortField sortField, SortDirection sortDirection)
Sort a list of Journals.
Definition: calendar.cpp:871
KCal::Calendar::categories
QStringList categories()
Returns a list of all categories used by Incidences in this Calendar.
Definition: calendar.cpp:258
KCal::Calendar::beginBatchAdding
void beginBatchAdding()
Emits the beginBatchAdding() signal.
Definition: calendar.cpp:939
KCal::Calendar::alarms
virtual Alarm::List alarms(const KDateTime &from, const KDateTime &to)=0
Returns a list of Alarms within a time range for this Calendar.
KCal::Calendar::registerObserver
void registerObserver(CalendarObserver *observer)
Registers an Observer for this Calendar.
Definition: calendar.cpp:1107
KCal::Calendar::customPropertyUpdated
virtual void customPropertyUpdated()
Definition: calendar.cpp:1192
KCal::Calendar::timeZoneId
QString timeZoneId() const
Returns the time zone ID used for creating or modifying incidences in the calendar.
Definition: calendar.cpp:189
KCal::Calendar::setObserversEnabled
void setObserversEnabled(bool enabled)
Let Calendar subclasses notify that they enabled an Observer.
Definition: calendar.cpp:1241
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::Incidence::relatedToUid
QString relatedToUid() const
Returns a UID string for the incidence that is related to this one.
Definition: incidence.cpp:492
KCal::Calendar::isSaving
virtual bool isSaving()
Determine if the calendar is currently being saved.
Definition: calendar.cpp:1120
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::Calendar::timeZones
ICalTimeZones * timeZones() const
Returns the time zone collection used by the calendar.
Definition: calendar.cpp:217
KCal::IncidenceBase
An abstract class that provides a common base for all calendar incidence classes. ...
Definition: incidencebase.h:102
KCal::Incidence::recreate
void recreate()
Recreate event.
Definition: incidence.cpp:284
KCal::Calendar::setViewTimeZoneId
void setViewTimeZoneId(const QString &timeZoneId) const
Notes the time zone Id which the client application intends to use for viewing the incidences in this...
Definition: calendar.cpp:201
KCal::Calendar::setModified
void setModified(bool modified)
Sets if the calendar has been modified.
Definition: calendar.cpp:1125
KCal::Calendar::CalendarObserver::calendarIncidenceDeleted
virtual void calendarIncidenceDeleted(Incidence *incidence)
Notify the Observer that an Incidence has been removed.
Definition: calendar.cpp:1102
KCal::Duration::asDays
int asDays() const
Returns the length of the duration in days.
Definition: duration.cpp:204
KCal::CalFilter
Provides a filter for calendars.
Definition: calfilter.h:57
KCal::IncidenceBase::dtStart
virtual KDateTime dtStart() const
Returns an incidence's starting date/time as a KDateTime.
Definition: incidencebase.cpp:248
KCal::Alarm::repeatCount
int repeatCount() const
Returns how many times an alarm may repeats after its initial occurrence.
Definition: alarm.cpp:488
KCal::Calendar::incidence
Incidence * incidence(const QString &uid)
Returns the Incidence associated with the given unique identifier.
Definition: calendar.cpp:669
KCal::Event
This class provides an Event in the sense of RFC2445.
Definition: event.h:41
KCal::ICalTimeZoneSource::parse
ICalTimeZone parse(icalcomponent *vtimezone)
Creates an ICalTimeZone instance containing the detailed information parsed from a VTIMEZONE componen...
Definition: icaltimezones.cpp:754
KCal::Recurrence::getPreviousDateTime
KDateTime getPreviousDateTime(const KDateTime &afterDateTime) const
Returns the date and time of the last previous recurrence, before the specified date/time.
Definition: recurrence.cpp:1087
KCal::Calendar::setOwner
void setOwner(const Person &owner)
Sets the owner of the calendar to owner.
Definition: calendar.cpp:129
KCal::IncidenceBase::uid
QString uid() const
Returns the unique id (uid) for the incidence.
Definition: incidencebase.cpp:184
KCal::Calendar::beginChange
virtual bool beginChange(Incidence *incidence)
Flag that a change to a Calendar Incidence is starting.
Definition: calendar.cpp:1229
KCal::Calendar::dissociateOccurrence
Incidence * dissociateOccurrence(Incidence *incidence, const QDate &date, const KDateTime::Spec &spec, bool single=true)
Dissociate an Incidence from a recurring Incidence.
Definition: calendar.cpp:595
KCal::Calendar::batchAddingEnds
void batchAddingEnds()
KCal::Calendar::rawEvents
virtual Event::List rawEvents(EventSortField sortField=EventSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Returns a sorted, unfiltered list of all Events for this Calendar.
KCal::Calendar::timeSpec
KDateTime::Spec timeSpec() const
Get the time specification (time zone etc.) used for creating or modifying incidences in the Calendar...
Definition: calendar.cpp:145
KCal::Incidence::addRelation
void addRelation(Incidence *incidence)
Adds an incidence that is related to this one.
Definition: incidence.cpp:526
KCal::Calendar::filter
CalFilter * filter()
Returns the calendar filter.
Definition: calendar.cpp:253
KCal::Todo::dtStart
virtual KDateTime dtStart() const
Definition: todo.cpp:289
KCal::Duration::asSeconds
int asSeconds() const
Returns the length of the duration in seconds.
Definition: duration.cpp:199
KCal::Calendar::CalendarObserver::calendarModified
virtual void calendarModified(bool modified, Calendar *calendar)
Notify the Observer that a Calendar has been modified.
Definition: calendar.cpp:1086
KCal::Todo::dtDue
KDateTime dtDue(bool first=false) const
Returns due date and time.
Definition: todo.cpp:181
KCal::Recurrence::clear
void clear()
Removes all recurrence and exception rules and dates.
Definition: recurrence.cpp:552
KCal::Calendar::appendAlarms
void appendAlarms(Alarm::List &alarms, Incidence *incidence, const KDateTime &from, const KDateTime &to)
Appends alarms of incidence in interval to list of alarms.
Definition: calendar.cpp:1246
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::Calendar::isAncestorOf
bool isAncestorOf(Incidence *ancestor, Incidence *incidence)
Checks if ancestor is an ancestor of incidence.
Definition: calendar.cpp:1075
KCal::Calendar::Calendar
Calendar(const KDateTime::Spec &timeSpec)
Constructs a calendar with a specified time zone timeZoneid.
Definition: calendar.cpp:106
KCal::Incidence::setRelatedToUid
void setRelatedToUid(const QString &uid)
Relates another incidence to this one, by UID.
Definition: incidence.cpp:483
KCal::Calendar::CalendarObserver
The CalendarObserver class.
Definition: calendar.h:966
KCal::Calendar::isModified
bool isModified() const
Determine the calendar's modification status.
Definition: calendar.cpp:1136
KCal::Calendar::rawJournals
virtual Journal::List rawJournals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending)=0
Returns a sorted, unfiltered list of all Journals for this Calendar.
KCal::Alarm::hasTime
bool hasTime() const
Returns true if the alarm has a trigger date/time.
Definition: alarm.cpp:450
KCal::Calendar::notifyIncidenceChanged
void notifyIncidenceChanged(Incidence *incidence)
Let Calendar subclasses notify that they modified an Incidence.
Definition: calendar.cpp:1170
KCal::Calendar::incidenceUpdated
void incidenceUpdated(IncidenceBase *incidenceBase)
The Observer interface.
Definition: calendar.cpp:1141
KCal::Calendar::notifyIncidenceAdded
void notifyIncidenceAdded(Incidence *incidence)
Let Calendar subclasses notify that they inserted an Incidence.
Definition: calendar.cpp:1159
KCal::Calendar::notifyIncidenceDeleted
void notifyIncidenceDeleted(Incidence *incidence)
Let Calendar subclasses notify that they removed an Incidence.
Definition: calendar.cpp:1181
KCal::Incidence::recurs
bool recurs() const
Definition: incidence.cpp:573
KCal::Calendar::setupRelations
virtual void setupRelations(Incidence *incidence)
Setup Relations for an Incidence.
Definition: calendar.cpp:951
KCal::Alarm::nextRepetition
KDateTime nextRepetition(const KDateTime &preTime) const
Returns the date/time of the alarm's initial occurrence or its next repetition after a given time...
Definition: alarm.cpp:499
KCal::Todo::setDtStart
void setDtStart(const KDateTime &dtStart)
Sets the start date of the todo.
Definition: todo.cpp:308
KCal::Event::setDtEnd
void setDtEnd(const KDateTime &dtEnd)
Sets the event end date and time.
Definition: event.cpp:119
KCal::Duration::isDaily
bool isDaily() const
Returns whether the duration is specified in terms of days rather than seconds.
Definition: duration.cpp:194
KCal::IncidenceBase::type
virtual QByteArray type() const =0
Prints the type of Incidence as a string.
KCal::Person
Represents a person, by name ane email address.
Definition: person.h:48
KCal::Calendar::event
virtual Event * event(const QString &uid)=0
Returns the Event associated with the given unique identifier.
KCal::Calendar::appendRecurringAlarms
void appendRecurringAlarms(Alarm::List &alarms, Incidence *incidence, const KDateTime &from, const KDateTime &to)
Appends alarms of recurring events in interval to list of alarms.
Definition: calendar.cpp:1263
calendar.h
This file is part of the API for handling calendar data and defines the Calendar class.
KCal::Alarm::hasStartOffset
bool hasStartOffset() const
Returns whether the alarm is defined in terms of an offset relative to the start of the parent Incide...
Definition: alarm.cpp:606
KCal::Incidence
Provides the abstract base class common to non-FreeBusy (Events, To-dos, Journals) calendar component...
Definition: incidence.h:68
KCal::ListBase
This class provides a template for lists of pointers.
Definition: listbase.h:44
exceptions.h
This file is part of the API for handling calendar data and defines the Exception and ErrorFormat cla...
KCal::Alarm::hasEndOffset
bool hasEndOffset() const
Returns whether the alarm is defined in terms of an offset relative to the end of the event...
Definition: alarm.cpp:611
KCal::Todo::hasDueDate
bool hasDueDate() const
Returns true if the todo has a due date, otherwise return false.
Definition: todo.cpp:252
KCal::Recurrence::setEndDate
void setEndDate(const QDate &endDate)
Sets the date of the last recurrence.
Definition: recurrence.cpp:463
KCal::Incidence::dtEnd
virtual KDateTime dtEnd() const
Returns the incidence ending date/time.
Definition: incidence.cpp:358
KCal::Alarm::endOffset
Duration endOffset() const
Returns offset of alarm in time relative to the end of the event.
Definition: alarm.cpp:626
KCal::Calendar::unregisterObserver
void unregisterObserver(CalendarObserver *observer)
Unregisters an Observer for this Calendar.
Definition: calendar.cpp:1115
KCal::Alarm::duration
Duration duration() const
Returns the interval between the alarm's initial occurrence and its final repetition.
Definition: alarm.cpp:493
KCal::Calendar::sortTodos
static Todo::List sortTodos(Todo::List *todoList, TodoSortField sortField, SortDirection sortDirection)
Sort a list of Todos.
Definition: calendar.cpp:712
KCal::Calendar::endChange
virtual bool endChange(Incidence *incidence)
Flag that a change to a Calendar Incidence has completed.
Definition: calendar.cpp:1235
KCal::Alarm::startOffset
Duration startOffset() const
Returns offset of alarm in time relative to the start of the parent Incidence.
Definition: alarm.cpp:601
KCal::Incidence::alarms
const Alarm::List & alarms() const
Returns a list of all incidence alarms.
Definition: incidence.cpp:906
KCal::Calendar::endBatchAdding
void endBatchAdding()
Emits the endBatchAdding() signal.
Definition: calendar.cpp:944
KCal::IncidenceBase::accept
virtual bool accept(Visitor &v)
Accept IncidenceVisitor.
Definition: incidencebase.h:228
KCal::Incidence::setRelatedTo
void setRelatedTo(Incidence *incidence)
Relates another incidence to this one.
Definition: incidence.cpp:497
KCal::Calendar::setFilter
void setFilter(CalFilter *filter)
Sets the calendar filter.
Definition: calendar.cpp:244
KCal::Calendar::journal
virtual Journal * journal(const QString &uid)=0
Returns the Journal associated with the given unique identifier.
KCal::Calendar::deleteIncidence
virtual bool deleteIncidence(Incidence *incidence)
Removes an Incidence from the calendar.
Definition: calendar.cpp:580
KCal::Calendar::rawTodosForDate
virtual Todo::List rawTodosForDate(const QDate &date)=0
Returns an unfiltered list of all Todos which due on the specified date.
KCal::Calendar::owner
Person owner() const
Returns the owner of the calendar.
Definition: calendar.cpp:124
KCal::Recurrence::getNextDateTime
KDateTime getNextDateTime(const KDateTime &preDateTime) const
Returns the date and time of the next recurrence, after the specified date/time.
Definition: recurrence.cpp:1012
KCal::ICalTimeZones
The ICalTimeZones class represents a time zone database which consists of a collection of individual ...
Definition: icaltimezones.h:64
KCal::Calendar::sortEventsForDate
static Event::List sortEventsForDate(Event::List *eventList, const QDate &date, const KDateTime::Spec &timeSpec, EventSortField sortField, SortDirection sortDirection)
Sort a list of Events that occur on a specified date.
Definition: calendar.cpp:395
KCal::Calendar::setProductId
void setProductId(const QString &id)
Sets the calendar Product ID to id.
Definition: calendar.cpp:1197
KCal::Duration::value
int value() const
Returns the length of the duration in seconds or days.
Definition: duration.cpp:209
KCal::Alarm::snoozeTime
Duration snoozeTime() const
Returns the snooze time interval.
Definition: alarm.cpp:475
KCal::Calendar::addIncidence
virtual bool addIncidence(Incidence *incidence)
Inserts an Incidence into the calendar.
Definition: calendar.cpp:573
KCal::ICalTimeZoneSource
A class which reads and parses iCalendar VTIMEZONE components, and accesses libical time zone data...
Definition: icaltimezones.h:328
KCal::Calendar::CalendarObserver::calendarIncidenceChanged
virtual void calendarIncidenceChanged(Incidence *incidence)
Notify the Observer that an Incidence has been modified.
Definition: calendar.cpp:1097
KCal::Calendar::batchAddingBegins
void batchAddingBegins()
KCal::Todo::hasStartDate
bool hasStartDate() const
Returns true if the todo has a start date, otherwise return false.
Definition: todo.cpp:266
KCal::Calendar::todo
virtual Todo * todo(const QString &uid)=0
Returns the Todo associated with the given unique identifier.
KCal::Duration
Represents a span of time measured in seconds or days.
Definition: duration.h:52
KCal::Calendar::setTimeZoneId
void setTimeZoneId(const QString &timeZoneId)
Sets the time zone ID used for creating or modifying incidences in the Calendar.
Definition: calendar.cpp:150
KCal::Calendar::journals
virtual Journal::List journals(JournalSortField sortField=JournalSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Returns a sorted, filtered list of all Journals for this Calendar.
Definition: calendar.cpp:924
KCal::Alarm::enabled
bool enabled() const
Returns the alarm enabled status: true (enabled) or false (disabled).
Definition: alarm.cpp:586
KCal::Calendar::rawIncidences
virtual Incidence::List rawIncidences()
Returns an unfiltered list of all Incidences for this Calendar.
Definition: calendar.cpp:287
KCal::Incidence::recurrence
Recurrence * recurrence() const
Returns the recurrence rule associated with this incidence.
Definition: incidence.cpp:545
KCal::Recurrence::durationTo
int durationTo(const KDateTime &dt) const
Returns the number of recurrences up to and including the date/time specified.
Definition: recurrence.cpp:491
KCal::Calendar::todos
virtual Todo::List todos(TodoSortField sortField=TodoSortUnsorted, SortDirection sortDirection=SortDirectionAscending)
Returns a sorted, filtered list of all Todos for this Calendar.
Definition: calendar.cpp:856
KCal::Calendar::viewTimeZoneId
QString viewTimeZoneId() const
Returns the time zone Id used for viewing the incidences in this calendar.
Definition: calendar.cpp:211
KCal::Calendar::doSetTimeSpec
virtual void doSetTimeSpec(const KDateTime::Spec &timeSpec)
Let Calendar subclasses set the time specification.
Definition: calendar.cpp:1154
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::Calendar::incidencesFromSchedulingID
Incidence::List incidencesFromSchedulingID(const QString &sid)
Searches all events and todos for an incidence with this scheduling identifiere.
Definition: calendar.cpp:685
calfilter.h
This file is part of the API for handling calendar data and defines the CalFilter class...
KCal::Calendar::incidences
virtual Incidence::List incidences()
Returns a filtered list of all Incidences for this Calendar.
Definition: calendar.cpp:282
KCal::Calendar::setViewTimeSpec
void setViewTimeSpec(const KDateTime::Spec &timeSpec) const
Notes the time specification which the client application intends to use for viewing the incidences i...
Definition: calendar.cpp:195
KCal::Calendar::sortEvents
static Event::List sortEvents(Event::List *eventList, EventSortField sortField, SortDirection sortDirection)
Sort a list of Events.
Definition: calendar.cpp:292
KCal::Incidence::removeRelation
void removeRelation(Incidence *incidence)
Removes an incidence that is related to this one.
Definition: incidence.cpp:533
KCal::Duration::end
KDateTime end(const KDateTime &start) const
Computes a duration end time by adding the number of seconds or days in the duration to the specified...
Definition: duration.cpp:183
KCal::Calendar::CalendarObserver::calendarIncidenceAdded
virtual void calendarIncidenceAdded(Incidence *incidence)
Notify the Observer that an Incidence has been inserted.
Definition: calendar.cpp:1092
KCal::Alarm
Represents an alarm notification.
Definition: alarm.h:66
KCal::Calendar::productId
QString productId() const
Returns the calendar's Product ID.
Definition: calendar.cpp:1202
KCal::Incidence::relations
Incidence::List relations() const
Returns a list of all incidences related to this one.
Definition: incidence.cpp:521
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::clone
virtual Incidence * clone()=0
Returns an exact copy of this incidence.
KCal::ICalTimeZone
The ICalTimeZone class represents an iCalendar VTIMEZONE component.
Definition: icaltimezones.h:142
KCal::Incidence::summary
QString summary() const
Returns the incidence summary.
Definition: incidence.cpp:424
KCal::Calendar::viewTimeSpec
KDateTime::Spec viewTimeSpec() const
Returns the time specification used for viewing the incidences in this calendar.
Definition: calendar.cpp:206
KCal::Todo::setDtDue
void setDtDue(const KDateTime &dtDue, bool first=false)
Sets due date and time.
KCal::Calendar::removeRelations
virtual void removeRelations(Incidence *incidence)
Removes all Relations from an Incidence.
Definition: calendar.cpp:997
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:57 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