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

KCalCore Library

  • sources
  • kde-4.12
  • kdepimlibs
  • kcalcore
recurrence.cpp
1 /*
2  This file is part of kcalcore library.
3 
4  Copyright (c) 1998 Preston Brown <pbrown@kde.org>
5  Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
6  Copyright (c) 2002,2006 David Jarvie <software@astrojar.org.uk>
7  Copyright (C) 2005 Reinhold Kainhofer <kainhofer@kde.org>
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 */
24 #include "recurrence.h"
25 
26 #include <KDebug>
27 
28 #include <QtCore/QBitArray>
29 #include <QtCore/QTime>
30 
31 using namespace KCalCore;
32 
33 //@cond PRIVATE
34 class KCalCore::Recurrence::Private
35 {
36 public:
37  Private()
38  : mCachedType(rMax),
39  mAllDay(false),
40  mRecurReadOnly(false)
41  {
42  }
43 
44  Private(const Private &p)
45  : mRDateTimes(p.mRDateTimes),
46  mRDates(p.mRDates),
47  mExDateTimes(p.mExDateTimes),
48  mExDates(p.mExDates),
49  mStartDateTime(p.mStartDateTime),
50  mCachedType(p.mCachedType),
51  mAllDay(p.mAllDay),
52  mRecurReadOnly(p.mRecurReadOnly)
53  {
54  }
55 
56  bool operator==(const Private &p) const;
57 
58  RecurrenceRule::List mExRules;
59  RecurrenceRule::List mRRules;
60  DateTimeList mRDateTimes;
61  DateList mRDates;
62  DateTimeList mExDateTimes;
63  DateList mExDates;
64  KDateTime mStartDateTime; // date/time of first recurrence
65  QList<RecurrenceObserver*> mObservers;
66 
67  // Cache the type of the recurrence with the old system (e.g. MonthlyPos)
68  mutable ushort mCachedType;
69 
70  bool mAllDay; // the recurrence has no time, just a date
71  bool mRecurReadOnly;
72 };
73 
74 bool Recurrence::Private::operator==(const Recurrence::Private &p) const
75 {
76  if ((mStartDateTime != p.mStartDateTime &&
77  (mStartDateTime.isValid() || p.mStartDateTime.isValid())) ||
78  mAllDay != p.mAllDay ||
79  mRecurReadOnly != p.mRecurReadOnly ||
80  mExDates != p.mExDates ||
81  mExDateTimes != p.mExDateTimes ||
82  mRDates != p.mRDates ||
83  mRDateTimes != p.mRDateTimes) {
84  return false;
85  }
86 
87 // Compare the rrules, exrules! Assume they have the same order... This only
88 // matters if we have more than one rule (which shouldn't be the default anyway)
89  int i;
90  int end = mRRules.count();
91  if (end != p.mRRules.count()) {
92  return false;
93  }
94  for (i = 0; i < end; ++i) {
95  if (*mRRules[i] != *p.mRRules[i]) {
96  return false;
97  }
98  }
99  end = mExRules.count();
100  if (end != p.mExRules.count()) {
101  return false;
102  }
103  for (i = 0; i < end; ++i) {
104  if (*mExRules[i] != *p.mExRules[i]) {
105  return false;
106  }
107  }
108  return true;
109 }
110 //@endcond
111 
112 Recurrence::Recurrence()
113  : d(new KCalCore::Recurrence::Private())
114 {
115 }
116 
117 Recurrence::Recurrence(const Recurrence &r)
118  : RecurrenceRule::RuleObserver(),
119  d(new KCalCore::Recurrence::Private(*r.d))
120 {
121  int i, end;
122  for (i = 0, end = r.d->mRRules.count(); i < end; ++i) {
123  RecurrenceRule *rule = new RecurrenceRule(*r.d->mRRules[i]);
124  d->mRRules.append(rule);
125  rule->addObserver(this);
126  }
127  for (i = 0, end = r.d->mExRules.count(); i < end; ++i) {
128  RecurrenceRule *rule = new RecurrenceRule(*r.d->mExRules[i]);
129  d->mExRules.append(rule);
130  rule->addObserver(this);
131  }
132 }
133 
134 Recurrence::~Recurrence()
135 {
136  qDeleteAll(d->mExRules);
137  qDeleteAll(d->mRRules);
138  delete d;
139 }
140 
141 bool Recurrence::operator==(const Recurrence &recurrence) const
142 {
143  return *d == *recurrence.d;
144 }
145 
146 Recurrence &Recurrence::operator=(const Recurrence &recurrence)
147 {
148  // check for self assignment
149  if (&recurrence == this) {
150  return *this;
151  }
152 
153  *d = *recurrence.d;
154  return *this;
155 }
156 
157 void Recurrence::addObserver(RecurrenceObserver *observer)
158 {
159  if (!d->mObservers.contains(observer)) {
160  d->mObservers.append(observer);
161  }
162 }
163 
164 void Recurrence::removeObserver(RecurrenceObserver *observer)
165 {
166  if (d->mObservers.contains(observer)) {
167  d->mObservers.removeAll(observer);
168  }
169 }
170 
171 KDateTime Recurrence::startDateTime() const
172 {
173  return d->mStartDateTime;
174 }
175 
176 bool Recurrence::allDay() const
177 {
178  return d->mAllDay;
179 }
180 
181 void Recurrence::setAllDay(bool allDay)
182 {
183  if (d->mRecurReadOnly || allDay == d->mAllDay) {
184  return;
185  }
186 
187  d->mAllDay = allDay;
188  for (int i = 0, end = d->mRRules.count(); i < end; ++i) {
189  d->mRRules[i]->setAllDay(allDay);
190  }
191  for (int i = 0, end = d->mExRules.count(); i < end; ++i) {
192  d->mExRules[i]->setAllDay(allDay);
193  }
194  updated();
195 }
196 
197 RecurrenceRule *Recurrence::defaultRRule(bool create) const
198 {
199  if (d->mRRules.isEmpty()) {
200  if (!create || d->mRecurReadOnly) {
201  return 0;
202  }
203  RecurrenceRule *rrule = new RecurrenceRule();
204  rrule->setStartDt(startDateTime());
205  const_cast<KCalCore::Recurrence*>(this)->addRRule(rrule);
206  return rrule;
207  } else {
208  return d->mRRules[0];
209  }
210 }
211 
212 RecurrenceRule *Recurrence::defaultRRuleConst() const
213 {
214  return d->mRRules.isEmpty() ? 0 : d->mRRules[0];
215 }
216 
217 void Recurrence::updated()
218 {
219  // recurrenceType() re-calculates the type if it's rMax
220  d->mCachedType = rMax;
221  for (int i = 0, end = d->mObservers.count(); i < end; ++i) {
222  if (d->mObservers[i]) {
223  d->mObservers[i]->recurrenceUpdated(this);
224  }
225  }
226 }
227 
228 bool Recurrence::recurs() const
229 {
230  return !d->mRRules.isEmpty() || !d->mRDates.isEmpty() || !d->mRDateTimes.isEmpty();
231 }
232 
233 ushort Recurrence::recurrenceType() const
234 {
235  if (d->mCachedType == rMax) {
236  d->mCachedType = recurrenceType(defaultRRuleConst());
237  }
238  return d->mCachedType;
239 }
240 
241 ushort Recurrence::recurrenceType(const RecurrenceRule *rrule)
242 {
243  if (!rrule) {
244  return rNone;
245  }
246  RecurrenceRule::PeriodType type = rrule->recurrenceType();
247 
248  // BYSETPOS, BYWEEKNUMBER and BYSECOND were not supported in old versions
249  if (!rrule->bySetPos().isEmpty() ||
250  !rrule->bySeconds().isEmpty() ||
251  !rrule->byWeekNumbers().isEmpty()) {
252  return rOther;
253  }
254 
255  // It wasn't possible to set BYMINUTES, BYHOUR etc. by the old code. So if
256  // it's set, it's none of the old types
257  if (!rrule->byMinutes().isEmpty() || !rrule->byHours().isEmpty()) {
258  return rOther;
259  }
260 
261  // Possible combinations were:
262  // BYDAY: with WEEKLY, MONTHLY, YEARLY
263  // BYMONTHDAY: with MONTHLY, YEARLY
264  // BYMONTH: with YEARLY
265  // BYYEARDAY: with YEARLY
266  if ((!rrule->byYearDays().isEmpty() && type != RecurrenceRule::rYearly) ||
267  (!rrule->byMonths().isEmpty() && type != RecurrenceRule::rYearly)) {
268  return rOther;
269  }
270  if (!rrule->byDays().isEmpty()) {
271  if (type != RecurrenceRule::rYearly &&
272  type != RecurrenceRule::rMonthly &&
273  type != RecurrenceRule::rWeekly) {
274  return rOther;
275  }
276  }
277 
278  switch (type) {
279  case RecurrenceRule::rNone:
280  return rNone;
281  case RecurrenceRule::rMinutely:
282  return rMinutely;
283  case RecurrenceRule::rHourly:
284  return rHourly;
285  case RecurrenceRule::rDaily:
286  return rDaily;
287  case RecurrenceRule::rWeekly:
288  return rWeekly;
289  case RecurrenceRule::rMonthly:
290  {
291  if (rrule->byDays().isEmpty()) {
292  return rMonthlyDay;
293  } else if (rrule->byMonthDays().isEmpty()) {
294  return rMonthlyPos;
295  } else {
296  return rOther; // both position and date specified
297  }
298  }
299  case RecurrenceRule::rYearly:
300  {
301  // Possible combinations:
302  // rYearlyMonth: [BYMONTH &] BYMONTHDAY
303  // rYearlyDay: BYYEARDAY
304  // rYearlyPos: [BYMONTH &] BYDAY
305  if (!rrule->byDays().isEmpty()) {
306  // can only by rYearlyPos
307  if (rrule->byMonthDays().isEmpty() && rrule->byYearDays().isEmpty()) {
308  return rYearlyPos;
309  } else {
310  return rOther;
311  }
312  } else if (!rrule->byYearDays().isEmpty()) {
313  // Can only be rYearlyDay
314  if (rrule->byMonths().isEmpty() && rrule->byMonthDays().isEmpty()) {
315  return rYearlyDay;
316  } else {
317  return rOther;
318  }
319  } else {
320  return rYearlyMonth;
321  }
322  break;
323  }
324  default:
325  return rOther;
326  }
327  return rOther;
328 }
329 
330 bool Recurrence::recursOn(const QDate &qd, const KDateTime::Spec &timeSpec) const
331 {
332  // Don't waste time if date is before the start of the recurrence
333  if (KDateTime(qd, QTime(23, 59, 59), timeSpec) < d->mStartDateTime) {
334  return false;
335  }
336 
337  // First handle dates. Exrules override
338  if (d->mExDates.containsSorted(qd)) {
339  return false;
340  }
341 
342  int i, end;
343  TimeList tms;
344  // For all-day events a matching exrule excludes the whole day
345  // since exclusions take precedence over inclusions, we know it can't occur on that day.
346  if (allDay()) {
347  for (i = 0, end = d->mExRules.count(); i < end; ++i) {
348  if (d->mExRules[i]->recursOn(qd, timeSpec)) {
349  return false;
350  }
351  }
352  }
353 
354  if (d->mRDates.containsSorted(qd)) {
355  return true;
356  }
357 
358  // Check if it might recur today at all.
359  bool recurs = (startDate() == qd);
360  for (i = 0, end = d->mRDateTimes.count(); i < end && !recurs; ++i) {
361  recurs = (d->mRDateTimes[i].toTimeSpec(timeSpec).date() == qd);
362  }
363  for (i = 0, end = d->mRRules.count(); i < end && !recurs; ++i) {
364  recurs = d->mRRules[i]->recursOn(qd, timeSpec);
365  }
366  // If the event wouldn't recur at all, simply return false, don't check ex*
367  if (!recurs) {
368  return false;
369  }
370 
371  // Check if there are any times for this day excluded, either by exdate or exrule:
372  bool exon = false;
373  for (i = 0, end = d->mExDateTimes.count(); i < end && !exon; ++i) {
374  exon = (d->mExDateTimes[i].toTimeSpec(timeSpec).date() == qd);
375  }
376  if (!allDay()) { // we have already checked all-day times above
377  for (i = 0, end = d->mExRules.count(); i < end && !exon; ++i) {
378  exon = d->mExRules[i]->recursOn(qd, timeSpec);
379  }
380  }
381 
382  if (!exon) {
383  // Simple case, nothing on that day excluded, return the value from before
384  return recurs;
385  } else {
386  // Harder part: I don't think there is any way other than to calculate the
387  // whole list of items for that day.
388 //TODO: consider whether it would be more efficient to call
389 // Rule::recurTimesOn() instead of Rule::recursOn() from the start
390  TimeList timesForDay(recurTimesOn(qd, timeSpec));
391  return !timesForDay.isEmpty();
392  }
393 }
394 
395 bool Recurrence::recursAt(const KDateTime &dt) const
396 {
397  // Convert to recurrence's time zone for date comparisons, and for more efficient time comparisons
398  KDateTime dtrecur = dt.toTimeSpec(d->mStartDateTime.timeSpec());
399 
400  // if it's excluded anyway, don't bother to check if it recurs at all.
401  if (d->mExDateTimes.containsSorted(dtrecur) ||
402  d->mExDates.containsSorted(dtrecur.date())) {
403  return false;
404  }
405  int i, end;
406  for (i = 0, end = d->mExRules.count(); i < end; ++i) {
407  if (d->mExRules[i]->recursAt(dtrecur)) {
408  return false;
409  }
410  }
411 
412  // Check explicit recurrences, then rrules.
413  if (startDateTime() == dtrecur || d->mRDateTimes.containsSorted(dtrecur)) {
414  return true;
415  }
416  for (i = 0, end = d->mRRules.count(); i < end; ++i) {
417  if (d->mRRules[i]->recursAt(dtrecur)) {
418  return true;
419  }
420  }
421 
422  return false;
423 }
424 
428 KDateTime Recurrence::endDateTime() const
429 {
430  DateTimeList dts;
431  dts << startDateTime();
432  if (!d->mRDates.isEmpty()) {
433  dts << KDateTime(d->mRDates.last(), QTime(0, 0, 0), d->mStartDateTime.timeSpec());
434  }
435  if (!d->mRDateTimes.isEmpty()) {
436  dts << d->mRDateTimes.last();
437  }
438  for (int i = 0, end = d->mRRules.count(); i < end; ++i) {
439  KDateTime rl(d->mRRules[i]->endDt());
440  // if any of the rules is infinite, the whole recurrence is
441  if (!rl.isValid()) {
442  return KDateTime();
443  }
444  dts << rl;
445  }
446  dts.sortUnique();
447  return dts.isEmpty() ? KDateTime() : dts.last();
448 }
449 
453 QDate Recurrence::endDate() const
454 {
455  KDateTime end(endDateTime());
456  return end.isValid() ? end.date() : QDate();
457 }
458 
459 void Recurrence::setEndDate(const QDate &date)
460 {
461  KDateTime dt(date, d->mStartDateTime.time(), d->mStartDateTime.timeSpec());
462  if (allDay()) {
463  dt.setTime(QTime(23, 59, 59));
464  }
465  setEndDateTime(dt);
466 }
467 
468 void Recurrence::setEndDateTime(const KDateTime &dateTime)
469 {
470  if (d->mRecurReadOnly) {
471  return;
472  }
473  RecurrenceRule *rrule = defaultRRule(true);
474  if (!rrule) {
475  return;
476  }
477  rrule->setEndDt(dateTime);
478  updated();
479 }
480 
481 int Recurrence::duration() const
482 {
483  RecurrenceRule *rrule = defaultRRuleConst();
484  return rrule ? rrule->duration() : 0;
485 }
486 
487 int Recurrence::durationTo(const KDateTime &datetime) const
488 {
489  // Emulate old behavior: This is just an interface to the first rule!
490  RecurrenceRule *rrule = defaultRRuleConst();
491  return rrule ? rrule->durationTo(datetime) : 0;
492 }
493 
494 int Recurrence::durationTo(const QDate &date) const
495 {
496  return durationTo(KDateTime(date, QTime(23, 59, 59), d->mStartDateTime.timeSpec()));
497 }
498 
499 void Recurrence::setDuration(int duration)
500 {
501  if (d->mRecurReadOnly) {
502  return;
503  }
504 
505  RecurrenceRule *rrule = defaultRRule(true);
506  if (!rrule) {
507  return;
508  }
509  rrule->setDuration(duration);
510  updated();
511 }
512 
513 void Recurrence::shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec)
514 {
515  if (d->mRecurReadOnly) {
516  return;
517  }
518 
519  d->mStartDateTime = d->mStartDateTime.toTimeSpec(oldSpec);
520  d->mStartDateTime.setTimeSpec(newSpec);
521 
522  int i, end;
523  for (i = 0, end = d->mRDateTimes.count(); i < end; ++i) {
524  d->mRDateTimes[i] = d->mRDateTimes[i].toTimeSpec(oldSpec);
525  d->mRDateTimes[i].setTimeSpec(newSpec);
526  }
527  for (i = 0, end = d->mExDateTimes.count(); i < end; ++i) {
528  d->mExDateTimes[i] = d->mExDateTimes[i].toTimeSpec(oldSpec);
529  d->mExDateTimes[i].setTimeSpec(newSpec);
530  }
531  for (i = 0, end = d->mRRules.count(); i < end; ++i) {
532  d->mRRules[i]->shiftTimes(oldSpec, newSpec);
533  }
534  for (i = 0, end = d->mExRules.count(); i < end; ++i) {
535  d->mExRules[i]->shiftTimes(oldSpec, newSpec);
536  }
537 }
538 
539 void Recurrence::unsetRecurs()
540 {
541  if (d->mRecurReadOnly) {
542  return;
543  }
544  qDeleteAll(d->mRRules);
545  d->mRRules.clear();
546  updated();
547 }
548 
549 void Recurrence::clear()
550 {
551  if (d->mRecurReadOnly) {
552  return;
553  }
554  qDeleteAll(d->mRRules);
555  d->mRRules.clear();
556  qDeleteAll(d->mExRules);
557  d->mExRules.clear();
558  d->mRDates.clear();
559  d->mRDateTimes.clear();
560  d->mExDates.clear();
561  d->mExDateTimes.clear();
562  d->mCachedType = rMax;
563  updated();
564 }
565 
566 void Recurrence::setRecurReadOnly(bool readOnly)
567 {
568  d->mRecurReadOnly = readOnly;
569 }
570 
571 bool Recurrence::recurReadOnly() const
572 {
573  return d->mRecurReadOnly;
574 }
575 
576 QDate Recurrence::startDate() const
577 {
578  return d->mStartDateTime.date();
579 }
580 
581 void Recurrence::setStartDateTime(const KDateTime &start)
582 {
583  if (d->mRecurReadOnly) {
584  return;
585  }
586  d->mStartDateTime = start;
587  setAllDay(start.isDateOnly()); // set all RRULEs and EXRULEs
588 
589  int i, end;
590  for (i = 0, end = d->mRRules.count(); i < end; ++i) {
591  d->mRRules[i]->setStartDt(start);
592  }
593  for (i = 0, end = d->mExRules.count(); i < end; ++i) {
594  d->mExRules[i]->setStartDt(start);
595  }
596  updated();
597 }
598 
599 int Recurrence::frequency() const
600 {
601  RecurrenceRule *rrule = defaultRRuleConst();
602  return rrule ? rrule->frequency() : 0;
603 }
604 
605 // Emulate the old behaviour. Make this methods just an interface to the
606 // first rrule
607 void Recurrence::setFrequency(int freq)
608 {
609  if (d->mRecurReadOnly || freq <= 0) {
610  return;
611  }
612 
613  RecurrenceRule *rrule = defaultRRule(true);
614  if (rrule) {
615  rrule->setFrequency(freq);
616  }
617  updated();
618 }
619 
620 // WEEKLY
621 
622 int Recurrence::weekStart() const
623 {
624  RecurrenceRule *rrule = defaultRRuleConst();
625  return rrule ? rrule->weekStart() : 1;
626 }
627 
628 // Emulate the old behavior
629 QBitArray Recurrence::days() const
630 {
631  QBitArray days(7);
632  days.fill(0);
633  RecurrenceRule *rrule = defaultRRuleConst();
634  if (rrule) {
635  QList<RecurrenceRule::WDayPos> bydays = rrule->byDays();
636  for (int i = 0; i < bydays.size(); ++i) {
637  if (bydays.at(i).pos() == 0) {
638  days.setBit(bydays.at(i).day() - 1);
639  }
640  }
641  }
642  return days;
643 }
644 
645 // MONTHLY
646 
647 // Emulate the old behavior
648 QList<int> Recurrence::monthDays() const
649 {
650  RecurrenceRule *rrule = defaultRRuleConst();
651  if (rrule) {
652  return rrule->byMonthDays();
653  } else {
654  return QList<int>();
655  }
656 }
657 
658 // Emulate the old behavior
659 QList<RecurrenceRule::WDayPos> Recurrence::monthPositions() const
660 {
661  RecurrenceRule *rrule = defaultRRuleConst();
662  return rrule ? rrule->byDays() : QList<RecurrenceRule::WDayPos>();
663 }
664 
665 // YEARLY
666 
667 QList<int> Recurrence::yearDays() const
668 {
669  RecurrenceRule *rrule = defaultRRuleConst();
670  return rrule ? rrule->byYearDays() : QList<int>();
671 }
672 
673 QList<int> Recurrence::yearDates() const
674 {
675  return monthDays();
676 }
677 
678 QList<int> Recurrence::yearMonths() const
679 {
680  RecurrenceRule *rrule = defaultRRuleConst();
681  return rrule ? rrule->byMonths() : QList<int>();
682 }
683 
684 QList<RecurrenceRule::WDayPos> Recurrence::yearPositions() const
685 {
686  return monthPositions();
687 }
688 
689 RecurrenceRule *Recurrence::setNewRecurrenceType(RecurrenceRule::PeriodType type, int freq)
690 {
691  if (d->mRecurReadOnly || freq <= 0) {
692  return 0;
693  }
694 
695  qDeleteAll(d->mRRules);
696  d->mRRules.clear();
697  updated();
698  RecurrenceRule *rrule = defaultRRule(true);
699  if (!rrule) {
700  return 0;
701  }
702  rrule->setRecurrenceType(type);
703  rrule->setFrequency(freq);
704  rrule->setDuration(-1);
705  return rrule;
706 }
707 
708 void Recurrence::setMinutely(int _rFreq)
709 {
710  if (setNewRecurrenceType(RecurrenceRule::rMinutely, _rFreq)) {
711  updated();
712  }
713 }
714 
715 void Recurrence::setHourly(int _rFreq)
716 {
717  if (setNewRecurrenceType(RecurrenceRule::rHourly, _rFreq)) {
718  updated();
719  }
720 }
721 
722 void Recurrence::setDaily(int _rFreq)
723 {
724  if (setNewRecurrenceType(RecurrenceRule::rDaily, _rFreq)) {
725  updated();
726  }
727 }
728 
729 void Recurrence::setWeekly(int freq, int weekStart)
730 {
731  RecurrenceRule *rrule = setNewRecurrenceType(RecurrenceRule::rWeekly, freq);
732  if (!rrule) {
733  return;
734  }
735  rrule->setWeekStart(weekStart);
736  updated();
737 }
738 
739 void Recurrence::setWeekly(int freq, const QBitArray &days, int weekStart)
740 {
741  setWeekly(freq, weekStart);
742  addMonthlyPos(0, days);
743 }
744 
745 void Recurrence::addWeeklyDays(const QBitArray &days)
746 {
747  addMonthlyPos(0, days);
748 }
749 
750 void Recurrence::setMonthly(int freq)
751 {
752  if (setNewRecurrenceType(RecurrenceRule::rMonthly, freq)) {
753  updated();
754  }
755 }
756 
757 void Recurrence::addMonthlyPos(short pos, const QBitArray &days)
758 {
759  // Allow 53 for yearly!
760  if (d->mRecurReadOnly || pos > 53 || pos < -53) {
761  return;
762  }
763 
764  RecurrenceRule *rrule = defaultRRule(false);
765  if (!rrule) {
766  return;
767  }
768  bool changed = false;
769  QList<RecurrenceRule::WDayPos> positions = rrule->byDays();
770 
771  for (int i = 0; i < 7; ++i) {
772  if (days.testBit(i)) {
773  RecurrenceRule::WDayPos p(pos, i + 1);
774  if (!positions.contains(p)) {
775  changed = true;
776  positions.append(p);
777  }
778  }
779  }
780  if (changed) {
781  rrule->setByDays(positions);
782  updated();
783  }
784 }
785 
786 void Recurrence::addMonthlyPos(short pos, ushort day)
787 {
788  // Allow 53 for yearly!
789  if (d->mRecurReadOnly || pos > 53 || pos < -53) {
790  return;
791  }
792 
793  RecurrenceRule *rrule = defaultRRule(false);
794  if (!rrule) {
795  return;
796  }
797  QList<RecurrenceRule::WDayPos> positions = rrule->byDays();
798 
799  RecurrenceRule::WDayPos p(pos, day);
800  if (!positions.contains(p)) {
801  positions.append(p);
802  rrule->setByDays(positions);
803  updated();
804  }
805 }
806 
807 void Recurrence::addMonthlyDate(short day)
808 {
809  if (d->mRecurReadOnly || day > 31 || day < -31) {
810  return;
811  }
812 
813  RecurrenceRule *rrule = defaultRRule(true);
814  if (!rrule) {
815  return;
816  }
817 
818  QList<int> monthDays = rrule->byMonthDays();
819  if (!monthDays.contains(day)) {
820  monthDays.append(day);
821  rrule->setByMonthDays(monthDays);
822  updated();
823  }
824 }
825 
826 void Recurrence::setYearly(int freq)
827 {
828  if (setNewRecurrenceType(RecurrenceRule::rYearly, freq)) {
829  updated();
830  }
831 }
832 
833 // Daynumber within year
834 void Recurrence::addYearlyDay(int day)
835 {
836  RecurrenceRule *rrule = defaultRRule(false); // It must already exist!
837  if (!rrule) {
838  return;
839  }
840 
841  QList<int> days = rrule->byYearDays();
842  if (!days.contains(day)) {
843  days << day;
844  rrule->setByYearDays(days);
845  updated();
846  }
847 }
848 
849 // day part of date within year
850 void Recurrence::addYearlyDate(int day)
851 {
852  addMonthlyDate(day);
853 }
854 
855 // day part of date within year, given as position (n-th weekday)
856 void Recurrence::addYearlyPos(short pos, const QBitArray &days)
857 {
858  addMonthlyPos(pos, days);
859 }
860 
861 // month part of date within year
862 void Recurrence::addYearlyMonth(short month)
863 {
864  if (d->mRecurReadOnly || month < 1 || month > 12) {
865  return;
866  }
867 
868  RecurrenceRule *rrule = defaultRRule(false);
869  if (!rrule) {
870  return;
871  }
872 
873  QList<int> months = rrule->byMonths();
874  if (!months.contains(month)) {
875  months << month;
876  rrule->setByMonths(months);
877  updated();
878  }
879 }
880 
881 TimeList Recurrence::recurTimesOn(const QDate &date, const KDateTime::Spec &timeSpec) const
882 {
883 // kDebug() << "recurTimesOn(" << date << ")";
884  int i, end;
885  TimeList times;
886 
887  // The whole day is excepted
888  if (d->mExDates.containsSorted(date)) {
889  return times;
890  }
891 
892  // EXRULE takes precedence over RDATE entries, so for all-day events,
893  // a matching excule also excludes the whole day automatically
894  if (allDay()) {
895  for (i = 0, end = d->mExRules.count(); i < end; ++i) {
896  if (d->mExRules[i]->recursOn(date, timeSpec)) {
897  return times;
898  }
899  }
900  }
901 
902  KDateTime dt = startDateTime().toTimeSpec(timeSpec);
903  if (dt.date() == date) {
904  times << dt.time();
905  }
906 
907  bool foundDate = false;
908  for (i = 0, end = d->mRDateTimes.count(); i < end; ++i) {
909  dt = d->mRDateTimes[i].toTimeSpec(timeSpec);
910  if (dt.date() == date) {
911  times << dt.time();
912  foundDate = true;
913  } else if (foundDate) {
914  break; // <= Assume that the rdatetime list is sorted
915  }
916  }
917  for (i = 0, end = d->mRRules.count(); i < end; ++i) {
918  times += d->mRRules[i]->recurTimesOn(date, timeSpec);
919  }
920  times.sortUnique();
921 
922  foundDate = false;
923  TimeList extimes;
924  for (i = 0, end = d->mExDateTimes.count(); i < end; ++i) {
925  dt = d->mExDateTimes[i].toTimeSpec(timeSpec);
926  if (dt.date() == date) {
927  extimes << dt.time();
928  foundDate = true;
929  } else if (foundDate) {
930  break;
931  }
932  }
933  if (!allDay()) { // we have already checked all-day times above
934  for (i = 0, end = d->mExRules.count(); i < end; ++i) {
935  extimes += d->mExRules[i]->recurTimesOn(date, timeSpec);
936  }
937  }
938  extimes.sortUnique();
939 
940  int st = 0;
941  for (i = 0, end = extimes.count(); i < end; ++i) {
942  int j = times.removeSorted(extimes[i], st);
943  if (j >= 0) {
944  st = j;
945  }
946  }
947  return times;
948 }
949 
950 DateTimeList Recurrence::timesInInterval(const KDateTime &start, const KDateTime &end) const
951 {
952  int i, count;
953  DateTimeList times;
954  for (i = 0, count = d->mRRules.count(); i < count; ++i) {
955  times += d->mRRules[i]->timesInInterval(start, end);
956  }
957 
958  // add rdatetimes that fit in the interval
959  for (i = 0, count = d->mRDateTimes.count(); i < count; ++i) {
960  if (d->mRDateTimes[i] >= start && d->mRDateTimes[i] <= end) {
961  times += d->mRDateTimes[i];
962  }
963  }
964 
965  // add rdates that fit in the interval
966  KDateTime kdt(d->mStartDateTime);
967  for (i = 0, count = d->mRDates.count(); i < count; ++i) {
968  kdt.setDate(d->mRDates[i]);
969  if (kdt >= start && kdt <= end) {
970  times += kdt;
971  }
972  }
973 
974  // Recurrence::timesInInterval(...) doesn't explicitly add mStartDateTime to the list
975  // of times to be returned. It calls mRRules[i]->timesInInterval(...) which include
976  // mStartDateTime.
977  // So, If we have rdates/rdatetimes but don't have any rrule we must explicitly
978  // add mStartDateTime to the list, otherwise we won't see the first occurrence.
979  if ((!d->mRDates.isEmpty() || !d->mRDateTimes.isEmpty()) &&
980  d->mRRules.isEmpty() &&
981  start <= d->mStartDateTime &&
982  end >= d->mStartDateTime) {
983  times += d->mStartDateTime;
984  }
985 
986  times.sortUnique();
987 
988  // Remove excluded times
989  int idt = 0;
990  int enddt = times.count();
991  for (i = 0, count = d->mExDates.count(); i < count && idt < enddt; ++i) {
992  while (idt < enddt && times[idt].date() < d->mExDates[i]) {
993  ++idt;
994  }
995  while (idt < enddt && times[idt].date() == d->mExDates[i]) {
996  times.removeAt(idt);
997  --enddt;
998  }
999  }
1000  DateTimeList extimes;
1001  for (i = 0, count = d->mExRules.count(); i < count; ++i) {
1002  extimes += d->mExRules[i]->timesInInterval(start, end);
1003  }
1004  extimes += d->mExDateTimes;
1005  extimes.sortUnique();
1006 
1007  int st = 0;
1008  for (i = 0, count = extimes.count(); i < count; ++i) {
1009  int j = times.removeSorted(extimes[i], st);
1010  if (j >= 0) {
1011  st = j;
1012  }
1013  }
1014 
1015  return times;
1016 }
1017 
1018 KDateTime Recurrence::getNextDateTime(const KDateTime &preDateTime) const
1019 {
1020  KDateTime nextDT = preDateTime;
1021  // prevent infinite loops, e.g. when an exrule extinguishes an rrule (e.g.
1022  // the exrule is identical to the rrule). If an occurrence is found, break
1023  // out of the loop by returning that KDateTime
1024 // TODO_Recurrence: Is a loop counter of 1000 really okay? I mean for secondly
1025 // recurrence, an exdate might exclude more than 1000 intervals!
1026  int loop = 0;
1027  while (loop < 1000) {
1028  // Outline of the algo:
1029  // 1) Find the next date/time after preDateTime when the event could recur
1030  // 1.0) Add the start date if it's after preDateTime
1031  // 1.1) Use the next occurrence from the explicit RDATE lists
1032  // 1.2) Add the next recurrence for each of the RRULEs
1033  // 2) Take the earliest recurrence of these = KDateTime nextDT
1034  // 3) If that date/time is not excluded, either explicitly by an EXDATE or
1035  // by an EXRULE, return nextDT as the next date/time of the recurrence
1036  // 4) If it's excluded, start all at 1), but starting at nextDT (instead
1037  // of preDateTime). Loop at most 1000 times.
1038  ++loop;
1039  // First, get the next recurrence from the RDate lists
1040  DateTimeList dates;
1041  if (nextDT < startDateTime()) {
1042  dates << startDateTime();
1043  }
1044 
1045  int end;
1046  // Assume that the rdatetime list is sorted
1047  int i = d->mRDateTimes.findGT(nextDT);
1048  if (i >= 0) {
1049  dates << d->mRDateTimes[i];
1050  }
1051 
1052  KDateTime kdt(startDateTime());
1053  for (i = 0, end = d->mRDates.count(); i < end; ++i) {
1054  kdt.setDate(d->mRDates[i]);
1055  if (kdt > nextDT) {
1056  dates << kdt;
1057  break;
1058  }
1059  }
1060 
1061  // Add the next occurrences from all RRULEs.
1062  for (i = 0, end = d->mRRules.count(); i < end; ++i) {
1063  KDateTime dt = d->mRRules[i]->getNextDate(nextDT);
1064  if (dt.isValid()) {
1065  dates << dt;
1066  }
1067  }
1068 
1069  // Take the first of these (all others can't be used later on)
1070  dates.sortUnique();
1071  if (dates.isEmpty()) {
1072  return KDateTime();
1073  }
1074  nextDT = dates.first();
1075 
1076  // Check if that date/time is excluded explicitly or by an exrule:
1077  if (!d->mExDates.containsSorted(nextDT.date()) &&
1078  !d->mExDateTimes.containsSorted(nextDT)) {
1079  bool allowed = true;
1080  for (i = 0, end = d->mExRules.count(); i < end; ++i) {
1081  allowed = allowed && !(d->mExRules[i]->recursAt(nextDT));
1082  }
1083  if (allowed) {
1084  return nextDT;
1085  }
1086  }
1087  }
1088 
1089  // Couldn't find a valid occurrences in 1000 loops, something is wrong!
1090  return KDateTime();
1091 }
1092 
1093 KDateTime Recurrence::getPreviousDateTime(const KDateTime &afterDateTime) const
1094 {
1095  KDateTime prevDT = afterDateTime;
1096  // prevent infinite loops, e.g. when an exrule extinguishes an rrule (e.g.
1097  // the exrule is identical to the rrule). If an occurrence is found, break
1098  // out of the loop by returning that KDateTime
1099  int loop = 0;
1100  while (loop < 1000) {
1101  // Outline of the algo:
1102  // 1) Find the next date/time after preDateTime when the event could recur
1103  // 1.1) Use the next occurrence from the explicit RDATE lists
1104  // 1.2) Add the next recurrence for each of the RRULEs
1105  // 2) Take the earliest recurrence of these = KDateTime nextDT
1106  // 3) If that date/time is not excluded, either explicitly by an EXDATE or
1107  // by an EXRULE, return nextDT as the next date/time of the recurrence
1108  // 4) If it's excluded, start all at 1), but starting at nextDT (instead
1109  // of preDateTime). Loop at most 1000 times.
1110  ++loop;
1111  // First, get the next recurrence from the RDate lists
1112  DateTimeList dates;
1113  if (prevDT > startDateTime()) {
1114  dates << startDateTime();
1115  }
1116 
1117  int i = d->mRDateTimes.findLT(prevDT);
1118  if (i >= 0) {
1119  dates << d->mRDateTimes[i];
1120  }
1121 
1122  KDateTime kdt(startDateTime());
1123  for (i = d->mRDates.count(); --i >= 0;) {
1124  kdt.setDate(d->mRDates[i]);
1125  if (kdt < prevDT) {
1126  dates << kdt;
1127  break;
1128  }
1129  }
1130 
1131  // Add the previous occurrences from all RRULEs.
1132  int end;
1133  for (i = 0, end = d->mRRules.count(); i < end; ++i) {
1134  KDateTime dt = d->mRRules[i]->getPreviousDate(prevDT);
1135  if (dt.isValid()) {
1136  dates << dt;
1137  }
1138  }
1139 
1140  // Take the last of these (all others can't be used later on)
1141  dates.sortUnique();
1142  if (dates.isEmpty()) {
1143  return KDateTime();
1144  }
1145  prevDT = dates.last();
1146 
1147  // Check if that date/time is excluded explicitly or by an exrule:
1148  if (!d->mExDates.containsSorted(prevDT.date()) &&
1149  !d->mExDateTimes.containsSorted(prevDT)) {
1150  bool allowed = true;
1151  for (i = 0, end = d->mExRules.count(); i < end; ++i) {
1152  allowed = allowed && !(d->mExRules[i]->recursAt(prevDT));
1153  }
1154  if (allowed) {
1155  return prevDT;
1156  }
1157  }
1158  }
1159 
1160  // Couldn't find a valid occurrences in 1000 loops, something is wrong!
1161  return KDateTime();
1162 }
1163 
1164 /***************************** PROTECTED FUNCTIONS ***************************/
1165 
1166 RecurrenceRule::List Recurrence::rRules() const
1167 {
1168  return d->mRRules;
1169 }
1170 
1171 void Recurrence::addRRule(RecurrenceRule *rrule)
1172 {
1173  if (d->mRecurReadOnly || !rrule) {
1174  return;
1175  }
1176 
1177  rrule->setAllDay(d->mAllDay);
1178  d->mRRules.append(rrule);
1179  rrule->addObserver(this);
1180  updated();
1181 }
1182 
1183 void Recurrence::removeRRule(RecurrenceRule *rrule)
1184 {
1185  if (d->mRecurReadOnly) {
1186  return;
1187  }
1188 
1189  d->mRRules.removeAll(rrule);
1190  rrule->removeObserver(this);
1191  updated();
1192 }
1193 
1194 void Recurrence::deleteRRule(RecurrenceRule *rrule)
1195 {
1196  if (d->mRecurReadOnly) {
1197  return;
1198  }
1199 
1200  d->mRRules.removeAll(rrule);
1201  delete rrule;
1202  updated();
1203 }
1204 
1205 RecurrenceRule::List Recurrence::exRules() const
1206 {
1207  return d->mExRules;
1208 }
1209 
1210 void Recurrence::addExRule(RecurrenceRule *exrule)
1211 {
1212  if (d->mRecurReadOnly || !exrule) {
1213  return;
1214  }
1215 
1216  exrule->setAllDay(d->mAllDay);
1217  d->mExRules.append(exrule);
1218  exrule->addObserver(this);
1219  updated();
1220 }
1221 
1222 void Recurrence::removeExRule(RecurrenceRule *exrule)
1223 {
1224  if (d->mRecurReadOnly) {
1225  return;
1226  }
1227 
1228  d->mExRules.removeAll(exrule);
1229  exrule->removeObserver(this);
1230  updated();
1231 }
1232 
1233 void Recurrence::deleteExRule(RecurrenceRule *exrule)
1234 {
1235  if (d->mRecurReadOnly) {
1236  return;
1237  }
1238 
1239  d->mExRules.removeAll(exrule);
1240  delete exrule;
1241  updated();
1242 }
1243 
1244 DateTimeList Recurrence::rDateTimes() const
1245 {
1246  return d->mRDateTimes;
1247 }
1248 
1249 void Recurrence::setRDateTimes(const DateTimeList &rdates)
1250 {
1251  if (d->mRecurReadOnly) {
1252  return;
1253  }
1254 
1255  d->mRDateTimes = rdates;
1256  d->mRDateTimes.sortUnique();
1257  updated();
1258 }
1259 
1260 void Recurrence::addRDateTime(const KDateTime &rdate)
1261 {
1262  if (d->mRecurReadOnly) {
1263  return;
1264  }
1265 
1266  d->mRDateTimes.insertSorted(rdate);
1267  updated();
1268 }
1269 
1270 DateList Recurrence::rDates() const
1271 {
1272  return d->mRDates;
1273 }
1274 
1275 void Recurrence::setRDates(const DateList &rdates)
1276 {
1277  if (d->mRecurReadOnly) {
1278  return;
1279  }
1280 
1281  d->mRDates = rdates;
1282  d->mRDates.sortUnique();
1283  updated();
1284 }
1285 
1286 void Recurrence::addRDate(const QDate &rdate)
1287 {
1288  if (d->mRecurReadOnly) {
1289  return;
1290  }
1291 
1292  d->mRDates.insertSorted(rdate);
1293  updated();
1294 }
1295 
1296 DateTimeList Recurrence::exDateTimes() const
1297 {
1298  return d->mExDateTimes;
1299 }
1300 
1301 void Recurrence::setExDateTimes(const DateTimeList &exdates)
1302 {
1303  if (d->mRecurReadOnly) {
1304  return;
1305  }
1306 
1307  d->mExDateTimes = exdates;
1308  d->mExDateTimes.sortUnique();
1309 }
1310 
1311 void Recurrence::addExDateTime(const KDateTime &exdate)
1312 {
1313  if (d->mRecurReadOnly) {
1314  return;
1315  }
1316 
1317  d->mExDateTimes.insertSorted(exdate);
1318  updated();
1319 }
1320 
1321 DateList Recurrence::exDates() const
1322 {
1323  return d->mExDates;
1324 }
1325 
1326 void Recurrence::setExDates(const DateList &exdates)
1327 {
1328  if (d->mRecurReadOnly) {
1329  return;
1330  }
1331 
1332  d->mExDates = exdates;
1333  d->mExDates.sortUnique();
1334  updated();
1335 }
1336 
1337 void Recurrence::addExDate(const QDate &exdate)
1338 {
1339  if (d->mRecurReadOnly) {
1340  return;
1341  }
1342 
1343  d->mExDates.insertSorted(exdate);
1344  updated();
1345 }
1346 
1347 void Recurrence::recurrenceChanged(RecurrenceRule *)
1348 {
1349  updated();
1350 }
1351 
1352 // %%%%%%%%%%%%%%%%%% end:Recurrencerule %%%%%%%%%%%%%%%%%%
1353 
1354 void Recurrence::dump() const
1355 {
1356  kDebug();
1357 
1358  int i;
1359  int count = d->mRRules.count();
1360  kDebug() << " -)" << count << "RRULEs:";
1361  for (i = 0; i < count; ++i) {
1362  kDebug() << " -) RecurrenceRule: ";
1363  d->mRRules[i]->dump();
1364  }
1365  count = d->mExRules.count();
1366  kDebug() << " -)" << count << "EXRULEs:";
1367  for (i = 0; i < count; ++i) {
1368  kDebug() << " -) ExceptionRule :";
1369  d->mExRules[i]->dump();
1370  }
1371 
1372  count = d->mRDates.count();
1373  kDebug() << endl << " -)" << count << "Recurrence Dates:";
1374  for (i = 0; i < count; ++i) {
1375  kDebug() << " " << d->mRDates[i];
1376  }
1377  count = d->mRDateTimes.count();
1378  kDebug() << endl << " -)" << count << "Recurrence Date/Times:";
1379  for (i = 0; i < count; ++i) {
1380  kDebug() << " " << d->mRDateTimes[i].dateTime();
1381  }
1382  count = d->mExDates.count();
1383  kDebug() << endl << " -)" << count << "Exceptions Dates:";
1384  for (i = 0; i < count; ++i) {
1385  kDebug() << " " << d->mExDates[i];
1386  }
1387  count = d->mExDateTimes.count();
1388  kDebug() << endl << " -)" << count << "Exception Date/Times:";
1389  for (i = 0; i < count; ++i) {
1390  kDebug() << " " << d->mExDateTimes[i].dateTime();
1391  }
1392 }
1393 
1394 Recurrence::RecurrenceObserver::~RecurrenceObserver()
1395 {
1396 }
1397 
1398 KCALCORE_EXPORT QDataStream& KCalCore::operator<<(QDataStream &out, KCalCore::Recurrence *r)
1399 {
1400  if (!r)
1401  return out;
1402 
1403  out << r->d->mRDateTimes << r->d->mExDateTimes
1404  << r->d->mRDates << r->d->mStartDateTime << r->d->mCachedType
1405  << r->d->mAllDay << r->d->mRecurReadOnly << r->d->mExDates
1406  << r->d->mExRules.count() << r->d->mRRules.count();
1407 
1408  foreach(RecurrenceRule *rule, r->d->mExRules) {
1409  out << rule;
1410  }
1411 
1412  foreach(RecurrenceRule *rule, r->d->mRRules) {
1413  out << rule;
1414  }
1415 
1416  return out;
1417 }
1418 
1419 
1420 KCALCORE_EXPORT QDataStream& KCalCore::operator>>(QDataStream &in, KCalCore::Recurrence *r)
1421 {
1422  if (!r)
1423  return in;
1424 
1425  int rruleCount, exruleCount;
1426 
1427  in >> r->d->mRDateTimes >> r->d->mExDateTimes
1428  >> r->d->mRDates >> r->d->mStartDateTime >> r->d->mCachedType
1429  >> r->d->mAllDay >> r->d->mRecurReadOnly >> r->d->mExDates
1430  >> exruleCount >> rruleCount;
1431 
1432  r->d->mExRules.clear();
1433  r->d->mRRules.clear();
1434 
1435  for (int i=0; i<exruleCount; ++i) {
1436  RecurrenceRule *rule = new RecurrenceRule();
1437  rule->addObserver(r);
1438  in >> rule;
1439  r->d->mExRules.append(rule);
1440  }
1441 
1442  for (int i=0; i<rruleCount; ++i) {
1443  RecurrenceRule *rule = new RecurrenceRule();
1444  rule->addObserver(r);
1445  in >> rule;
1446  r->d->mRRules.append(rule);
1447  }
1448 
1449  return in;
1450 }
KCalCore::Recurrence::addWeeklyDays
void addWeeklyDays(const QBitArray &days)
Adds days to the weekly day recurrence list.
Definition: recurrence.cpp:745
KCalCore::RecurrenceRule::setFrequency
void setFrequency(int freq)
Sets the recurrence frequency, in terms of the recurrence time period type.
Definition: recurrencerule.cpp:1033
KCalCore::RecurrenceRule::WDayPos
structure for describing the n-th weekday of the month/year.
Definition: recurrencerule.h:68
KCalCore::Recurrence::addYearlyDay
void addYearlyDay(int day)
Adds day number of year within a yearly recurrence.
Definition: recurrence.cpp:834
KCalCore::Recurrence::Recurrence
Recurrence()
Constructs an empty recurrence.
Definition: recurrence.cpp:112
KCalCore::Recurrence::operator==
bool operator==(const Recurrence &r) const
Comparison operator for equality.
Definition: recurrence.cpp:141
KCalCore::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:499
KCalCore::Recurrence::setStartDateTime
void setStartDateTime(const KDateTime &start)
Set start of recurrence.
Definition: recurrence.cpp:581
KCalCore::Recurrence::startDate
QDate startDate() const
Return the start date/time of the recurrence.
Definition: recurrence.cpp:576
KCalCore::Recurrence::removeObserver
void removeObserver(RecurrenceObserver *observer)
Removes an observer that was added with addObserver.
Definition: recurrence.cpp:164
KCalCore::Recurrence::~Recurrence
~Recurrence()
Destructor.
Definition: recurrence.cpp:134
KCalCore::RecurrenceRule::setDuration
void setDuration(int duration)
Sets the total number of times the event is to occur, including both the first and last...
Definition: recurrencerule.cpp:996
KCalCore::SortableList::sortUnique
void sortUnique()
Sort the list.
Definition: sortablelist.h:193
KCalCore::Recurrence::yearDays
QList< int > yearDays() const
Returns the day numbers within a yearly recurrence.
Definition: recurrence.cpp:667
KCalCore::Recurrence::recurReadOnly
bool recurReadOnly() const
Returns true if the recurrence is read-only, or false if it can be changed.
Definition: recurrence.cpp:571
KCalCore::Recurrence::shiftTimes
void shiftTimes(const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec)
Shift the times of the recurrence so that they appear at the same clock time as before but in a new t...
Definition: recurrence.cpp:513
KCalCore::Recurrence::yearDates
QList< int > yearDates() const
Returns the dates within a yearly recurrence.
Definition: recurrence.cpp:673
KCalCore::Recurrence::setEndDateTime
void setEndDateTime(const KDateTime &endDateTime)
Sets the date and time of the last recurrence.
Definition: recurrence.cpp:468
KCalCore::Recurrence::durationTo
int durationTo(const KDateTime &dt) const
Returns the number of recurrences up to and including the date/time specified.
Definition: recurrence.cpp:487
KCalCore::Recurrence::weekStart
int weekStart() const
Returns the first day of the week.
Definition: recurrence.cpp:622
KCalCore::Recurrence::setYearly
void setYearly(int freq)
Sets an event to recur yearly.
Definition: recurrence.cpp:826
KCalCore::Recurrence::endDate
QDate endDate() const
Returns the date of the last recurrence.
Definition: recurrence.cpp:453
KCalCore::Recurrence::frequency
int frequency() const
Returns frequency of recurrence, in terms of the recurrence time period type.
Definition: recurrence.cpp:599
KCalCore::Recurrence::dump
void dump() const
Debug output.
Definition: recurrence.cpp:1354
KCalCore::RecurrenceRule::setEndDt
void setEndDt(const KDateTime &endDateTime)
Sets the date and time of the last recurrence.
Definition: recurrencerule.cpp:986
KCalCore::Recurrence::addObserver
void addObserver(RecurrenceObserver *observer)
Installs an observer.
Definition: recurrence.cpp:157
KCalCore::Recurrence
This class represents a recurrence rule for a calendar incidence.
Definition: recurrence.h:87
KCalCore::SortableList::removeSorted
int removeSorted(const T &value, int start=0)
Remove value value from the list.
Definition: sortablelist.h:296
KCalCore::Recurrence::recursOn
bool recursOn(const QDate &date, const KDateTime::Spec &timeSpec) const
Returns true if the date specified is one on which the event will recur.
Definition: recurrence.cpp:330
KCalCore::Recurrence::setRecurReadOnly
void setRecurReadOnly(bool readOnly)
Set if recurrence is read-only or can be changed.
Definition: recurrence.cpp:566
KCalCore::Recurrence::setEndDate
void setEndDate(const QDate &endDate)
Sets the date of the last recurrence.
Definition: recurrence.cpp:459
KCalCore::Recurrence::addMonthlyPos
void addMonthlyPos(short pos, const QBitArray &days)
Adds a position (e.g.
Definition: recurrence.cpp:757
KCalCore::SortableList
A QList which can be sorted.
Definition: sortablelist.h:86
KCalCore::Recurrence::allDay
bool allDay() const
Set whether the recurrence has no time, just a date.
Definition: recurrence.cpp:176
KCalCore::Recurrence::setFrequency
void setFrequency(int freq)
Sets the frequency of recurrence, in terms of the recurrence time period type.
Definition: recurrence.cpp:607
KCalCore::Recurrence::monthDays
QList< int > monthDays() const
Returns list of day numbers of a month.
Definition: recurrence.cpp:648
KCalCore::Recurrence::deleteRRule
void deleteRRule(RecurrenceRule *rrule)
Remove a recurrence rule from the recurrence and delete it.
Definition: recurrence.cpp:1194
KCalCore::Recurrence::setHourly
void setHourly(int freq)
Sets an event to recur hourly.
Definition: recurrence.cpp:715
KCalCore::RecurrenceRule::frequency
uint frequency() const
Returns the recurrence frequency, in terms of the recurrence time period type.
Definition: recurrencerule.cpp:2152
KCalCore::Recurrence::removeExRule
void removeExRule(RecurrenceRule *exrule)
Remove an exception rule from the recurrence.
Definition: recurrence.cpp:1222
KCalCore::Recurrence::clear
void clear()
Removes all recurrence and exception rules and dates.
Definition: recurrence.cpp:549
KCalCore::Recurrence::recursAt
bool recursAt(const KDateTime &dt) const
Returns true if the date/time specified is one at which the event will recur.
Definition: recurrence.cpp:395
KCalCore::operator>>
KCALCORE_EXPORT QDataStream & operator>>(QDataStream &in, const KCalCore::Alarm::Ptr &)
Alarm deserializer.
Definition: alarm.cpp:863
KCalCore::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:481
KCalCore::Recurrence::yearMonths
QList< int > yearMonths() const
Returns the months within a yearly recurrence.
Definition: recurrence.cpp:678
KCalCore::RecurrenceRule::removeObserver
void removeObserver(RuleObserver *observer)
Removes an observer that was added with addObserver.
Definition: recurrencerule.cpp:939
KCalCore::Recurrence::addMonthlyDate
void addMonthlyDate(short day)
Adds a date (e.g.
Definition: recurrence.cpp:807
KCalCore::RecurrenceRule::PeriodType
PeriodType
enum for describing the frequency how an event recurs, if at all.
Definition: recurrencerule.h:56
KCalCore::RecurrenceRule::addObserver
void addObserver(RuleObserver *observer)
Installs an observer.
Definition: recurrencerule.cpp:932
KCalCore::Recurrence::unsetRecurs
void unsetRecurs()
Removes all recurrence rules.
Definition: recurrence.cpp:539
KCalCore::Recurrence::addRRule
void addRRule(RecurrenceRule *rrule)
Add a recurrence rule to the recurrence.
Definition: recurrence.cpp:1171
KCalCore::Recurrence::addYearlyDate
void addYearlyDate(int date)
Adds date within a yearly recurrence.
Definition: recurrence.cpp:850
KCalCore::Recurrence::setMinutely
void setMinutely(int freq)
Sets an event to recur minutely.
Definition: recurrence.cpp:708
KCalCore::Recurrence::operator=
Recurrence & operator=(const Recurrence &r)
Assignment operator.
Definition: recurrence.cpp:146
KCalCore::RecurrenceRule::durationTo
int durationTo(const KDateTime &dt) const
Returns the number of recurrences up to and including the date/time specified.
Definition: recurrencerule.cpp:1582
KCalCore::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:1018
KCalCore::RecurrenceRule::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: recurrencerule.cpp:2157
KCalCore::Recurrence::setAllDay
void setAllDay(bool allDay)
Sets whether the dtstart is a all-day (i.e.
Definition: recurrence.cpp:181
KCalCore::Recurrence::addYearlyMonth
void addYearlyMonth(short _rNum)
Adds month in yearly recurrence.
Definition: recurrence.cpp:862
KCalCore::RecurrenceRule::setAllDay
void setAllDay(bool allDay)
Sets whether the dtstart is all-day (i.e.
Definition: recurrencerule.cpp:1005
KCalCore::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:1093
KCalCore::Recurrence::timesInInterval
DateTimeList timesInInterval(const KDateTime &start, const KDateTime &end) const
Returns a list of all the times at which the recurrence will occur between two specified times...
Definition: recurrence.cpp:950
KCalCore::Recurrence::recurrenceType
ushort recurrenceType() const
Returns the event's recurrence status.
Definition: recurrence.cpp:233
KCalCore::RecurrenceRule::setStartDt
void setStartDt(const KDateTime &start)
Sets the recurrence start date/time.
Definition: recurrencerule.cpp:1024
KCalCore::Recurrence::deleteExRule
void deleteExRule(RecurrenceRule *exrule)
Remove an exception rule from the recurrence and delete it.
Definition: recurrence.cpp:1233
KCalCore::Recurrence::setMonthly
void setMonthly(int freq)
Sets an event to recur monthly.
Definition: recurrence.cpp:750
KCalCore::Recurrence::addYearlyPos
void addYearlyPos(short pos, const QBitArray &days)
Adds position within month/year within a yearly recurrence.
Definition: recurrence.cpp:856
KCalCore::Recurrence::days
QBitArray days() const
Returns week day mask (bit 0 = Monday).
Definition: recurrence.cpp:629
KCalCore::Recurrence::removeRRule
void removeRRule(RecurrenceRule *rrule)
Remove a recurrence rule from the recurrence.
Definition: recurrence.cpp:1183
KCalCore::Recurrence::startDateTime
KDateTime startDateTime() const
Return the start date/time of the recurrence (Time for all-day recurrences will be 0:00)...
Definition: recurrence.cpp:171
KCalCore::operator<<
KCALCORE_EXPORT QDataStream & operator<<(QDataStream &out, const KCalCore::Alarm::Ptr &)
Alarm serializer.
Definition: alarm.cpp:853
KCalCore::Recurrence::endDateTime
KDateTime endDateTime() const
Returns the date/time of the last recurrence.
Definition: recurrence.cpp:428
KCalCore::Recurrence::recurs
bool recurs() const
Returns whether the event recurs at all.
Definition: recurrence.cpp:228
KCalCore::Recurrence::recurTimesOn
TimeList recurTimesOn(const QDate &date, const KDateTime::Spec &timeSpec) const
Returns a list of the times on the specified date at which the recurrence will occur.
Definition: recurrence.cpp:881
KCalCore::Recurrence::addExRule
void addExRule(RecurrenceRule *exrule)
Add an exception rule to the recurrence.
Definition: recurrence.cpp:1210
KCalCore::Recurrence::monthPositions
QList< RecurrenceRule::WDayPos > monthPositions() const
Returns list of day positions in months.
Definition: recurrence.cpp:659
KCalCore::Recurrence::yearPositions
QList< RecurrenceRule::WDayPos > yearPositions() const
Returns the positions within a yearly recurrence.
Definition: recurrence.cpp:684
KCalCore::Recurrence::setWeekly
void setWeekly(int freq, int weekStart=1)
Sets an event to recur weekly.
Definition: recurrence.cpp:729
KCalCore::Recurrence::setDaily
void setDaily(int freq)
Sets an event to recur daily.
Definition: recurrence.cpp:722
KCalCore::RecurrenceRule
This class represents a recurrence rule for a calendar incidence.
Definition: recurrencerule.h:43
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:59:57 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCalCore Library

Skip menu "KCalCore 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