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

KCalCore Library

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

Skip menu "kdepimlibs-4.11.3 API Reference"
  • akonadi
  •   contact
  •   kmime
  •   socialutils
  • kabc
  • kalarmcal
  • kblog
  • kcal
  • kcalcore
  • kcalutils
  • kholidays
  • kimap
  • kioslave
  •   imap4
  •   mbox
  •   nntp
  • kldap
  • kmbox
  • kmime
  • kontactinterface
  • kpimidentities
  • kpimtextedit
  • kpimutils
  • kresources
  • ktnef
  • kxmlrpcclient
  • mailtransport
  • microblog
  • qgpgme
  • syndication
  •   atom
  •   rdf
  •   rss2
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