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

KCal Library

  • sources
  • kde-4.12
  • kdepimlibs
  • kcal
recurrence.cpp
1 /*
2  This file is part of libkcal.
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 
25 #include "recurrence.h"
26 #include "recurrencerule.h"
27 
28 #include <kglobal.h>
29 #include <klocalizedstring.h>
30 #include <kdebug.h>
31 
32 #include <QtCore/QList>
33 #include <QtCore/QBitArray>
34 
35 #include <limits.h>
36 
37 using namespace KCal;
38 
39 //@cond PRIVATE
40 class KCal::Recurrence::Private
41 {
42  public:
43  Private()
44  : mCachedType( rMax ),
45  mAllDay( false ),
46  mRecurReadOnly( false )
47  {
48  mExRules.setAutoDelete( true );
49  mRRules.setAutoDelete( true );
50  }
51 
52  Private( const Private &p )
53  : mRDateTimes( p.mRDateTimes ),
54  mRDates( p.mRDates ),
55  mExDateTimes( p.mExDateTimes ),
56  mExDates( p.mExDates ),
57  mStartDateTime( p.mStartDateTime ),
58  mCachedType( p.mCachedType ),
59  mAllDay( p.mAllDay ),
60  mRecurReadOnly( p.mRecurReadOnly )
61  {
62  mExRules.setAutoDelete( true );
63  mRRules.setAutoDelete( true );
64  }
65 
66  bool operator==( const Private &p ) const;
67 
68  RecurrenceRule::List mExRules;
69  RecurrenceRule::List mRRules;
70  DateTimeList mRDateTimes;
71  DateList mRDates;
72  DateTimeList mExDateTimes;
73  DateList mExDates;
74  KDateTime mStartDateTime; // date/time of first recurrence
75  QList<RecurrenceObserver*> mObservers;
76 
77  // Cache the type of the recurrence with the old system (e.g. MonthlyPos)
78  mutable ushort mCachedType;
79 
80  bool mAllDay; // the recurrence has no time, just a date
81  bool mRecurReadOnly;
82 };
83 
84 bool Recurrence::Private::operator==( const Recurrence::Private &p ) const
85 {
86  if ( mStartDateTime != p.mStartDateTime ||
87  mAllDay != p.mAllDay ||
88  mRecurReadOnly != p.mRecurReadOnly ||
89  mExDates != p.mExDates ||
90  mExDateTimes != p.mExDateTimes ||
91  mRDates != p.mRDates ||
92  mRDateTimes != p.mRDateTimes ) {
93  return false;
94  }
95 
96 // Compare the rrules, exrules! Assume they have the same order... This only
97 // matters if we have more than one rule (which shouldn't be the default anyway)
98  int i;
99  int end = mRRules.count();
100  if ( end != p.mRRules.count() ) {
101  return false;
102  }
103  for ( i = 0; i < end; ++i ) {
104  if ( *mRRules[i] != *p.mRRules[i] ) {
105  return false;
106  }
107  }
108  end = mExRules.count();
109  if ( end != p.mExRules.count() ) {
110  return false;
111  }
112  for ( i = 0; i < end; ++i ) {
113  if ( *mExRules[i] != *p.mExRules[i] ) {
114  return false;
115  }
116  }
117  return true;
118 }
119 //@endcond
120 
121 Recurrence::Recurrence()
122  : d( new KCal::Recurrence::Private() )
123 {
124 }
125 
126 Recurrence::Recurrence( const Recurrence &r )
127  : RecurrenceRule::RuleObserver(),
128  d( new KCal::Recurrence::Private( *r.d ) )
129 {
130  int i, end;
131  for ( i = 0, end = r.d->mRRules.count(); i < end; ++i ) {
132  RecurrenceRule *rule = new RecurrenceRule( *r.d->mRRules[i] );
133  d->mRRules.append( rule );
134  rule->addObserver( this );
135  }
136  for ( i = 0, end = r.d->mExRules.count(); i < end; ++i ) {
137  RecurrenceRule *rule = new RecurrenceRule( *r.d->mExRules[i] );
138  d->mExRules.append( rule );
139  rule->addObserver( this );
140  }
141 }
142 
143 Recurrence::~Recurrence()
144 {
145  delete d;
146 }
147 
148 bool Recurrence::operator==( const Recurrence &r2 ) const
149 {
150  return *d == *r2.d;
151 }
152 
153 Recurrence &Recurrence::operator=( const Recurrence &other )
154 {
155  if ( &other == this ) // Check for self assignment
156  return *this;
157 
158  *d = *other.d;
159  return *this;
160 }
161 
162 void Recurrence::addObserver( RecurrenceObserver *observer )
163 {
164  if ( !d->mObservers.contains( observer ) ) {
165  d->mObservers.append( observer );
166  }
167 }
168 
169 void Recurrence::removeObserver( RecurrenceObserver *observer )
170 {
171  if ( d->mObservers.contains( observer ) ) {
172  d->mObservers.removeAll( observer );
173  }
174 }
175 
176 KDateTime Recurrence::startDateTime() const
177 {
178  return d->mStartDateTime;
179 }
180 
181 bool Recurrence::allDay() const
182 {
183  return d->mAllDay;
184 }
185 
186 void Recurrence::setAllDay( bool allDay )
187 {
188  if ( d->mRecurReadOnly || allDay == d->mAllDay ) {
189  return;
190  }
191 
192  d->mAllDay = allDay;
193  for ( int i = 0, end = d->mRRules.count(); i < end; ++i ) {
194  d->mRRules[i]->setAllDay( allDay );
195  }
196  for ( int i = 0, end = d->mExRules.count(); i < end; ++i ) {
197  d->mExRules[i]->setAllDay( allDay );
198  }
199  updated();
200 }
201 
202 RecurrenceRule *Recurrence::defaultRRule( bool create ) const
203 {
204  if ( d->mRRules.isEmpty() ) {
205  if ( !create || d->mRecurReadOnly ) {
206  return 0;
207  }
208  RecurrenceRule *rrule = new RecurrenceRule();
209  rrule->setStartDt( startDateTime() );
210  const_cast<KCal::Recurrence*>(this)->addRRule( rrule );
211  return rrule;
212  } else {
213  return d->mRRules[0];
214  }
215 }
216 
217 RecurrenceRule *Recurrence::defaultRRuleConst() const
218 {
219  return d->mRRules.isEmpty() ? 0 : d->mRRules[0];
220 }
221 
222 void Recurrence::updated()
223 {
224  // recurrenceType() re-calculates the type if it's rMax
225  d->mCachedType = rMax;
226  for ( int i = 0, end = d->mObservers.count(); i < end; ++i ) {
227  if ( d->mObservers[i] ) {
228  d->mObservers[i]->recurrenceUpdated( this );
229  }
230  }
231 }
232 
233 bool Recurrence::recurs() const
234 {
235  return !d->mRRules.isEmpty() || !d->mRDates.isEmpty() || !d->mRDateTimes.isEmpty();
236 }
237 
238 ushort Recurrence::recurrenceType() const
239 {
240  if ( d->mCachedType == rMax ) {
241  d->mCachedType = recurrenceType( defaultRRuleConst() );
242  }
243  return d->mCachedType;
244 }
245 
246 ushort Recurrence::recurrenceType( const RecurrenceRule *rrule )
247 {
248  if ( !rrule ) {
249  return rNone;
250  }
251  RecurrenceRule::PeriodType type = rrule->recurrenceType();
252 
253  // BYSETPOS, BYWEEKNUMBER and BYSECOND were not supported in old versions
254  if ( !rrule->bySetPos().isEmpty() ||
255  !rrule->bySeconds().isEmpty() ||
256  !rrule->byWeekNumbers().isEmpty() ) {
257  return rOther;
258  }
259 
260  // It wasn't possible to set BYMINUTES, BYHOUR etc. by the old code. So if
261  // it's set, it's none of the old types
262  if ( !rrule->byMinutes().isEmpty() || !rrule->byHours().isEmpty() ) {
263  return rOther;
264  }
265 
266  // Possible combinations were:
267  // BYDAY: with WEEKLY, MONTHLY, YEARLY
268  // BYMONTHDAY: with MONTHLY, YEARLY
269  // BYMONTH: with YEARLY
270  // BYYEARDAY: with YEARLY
271  if ( ( !rrule->byYearDays().isEmpty() && type != RecurrenceRule::rYearly ) ||
272  ( !rrule->byMonths().isEmpty() && type != RecurrenceRule::rYearly ) ) {
273  return rOther;
274  }
275  if ( !rrule->byDays().isEmpty() ) {
276  if ( type != RecurrenceRule::rYearly &&
277  type != RecurrenceRule::rMonthly &&
278  type != RecurrenceRule::rWeekly ) {
279  return rOther;
280  }
281  }
282 
283  switch ( type ) {
284  case RecurrenceRule::rNone:
285  return rNone;
286  case RecurrenceRule::rMinutely:
287  return rMinutely;
288  case RecurrenceRule::rHourly:
289  return rHourly;
290  case RecurrenceRule::rDaily:
291  return rDaily;
292  case RecurrenceRule::rWeekly:
293  return rWeekly;
294  case RecurrenceRule::rMonthly:
295  {
296  if ( rrule->byDays().isEmpty() ) {
297  return rMonthlyDay;
298  } else if ( rrule->byMonthDays().isEmpty() ) {
299  return rMonthlyPos;
300  } else {
301  return rOther; // both position and date specified
302  }
303  }
304  case RecurrenceRule::rYearly:
305  {
306  // Possible combinations:
307  // rYearlyMonth: [BYMONTH &] BYMONTHDAY
308  // rYearlyDay: BYYEARDAY
309  // rYearlyPos: [BYMONTH &] BYDAY
310  if ( !rrule->byDays().isEmpty() ) {
311  // can only by rYearlyPos
312  if ( rrule->byMonthDays().isEmpty() && rrule->byYearDays().isEmpty() ) {
313  return rYearlyPos;
314  } else {
315  return rOther;
316  }
317  } else if ( !rrule->byYearDays().isEmpty() ) {
318  // Can only be rYearlyDay
319  if ( rrule->byMonths().isEmpty() && rrule->byMonthDays().isEmpty() ) {
320  return rYearlyDay;
321  } else {
322  return rOther;
323  }
324  } else {
325  return rYearlyMonth;
326  }
327  break;
328  }
329  default: return rOther;
330  }
331  return rOther;
332 }
333 
334 bool Recurrence::recursOn( const QDate &qd, const KDateTime::Spec &timeSpec ) const
335 {
336  // Don't waste time if date is before the start of the recurrence
337  if ( KDateTime( qd, QTime( 23, 59, 59 ), timeSpec ) < d->mStartDateTime ) {
338  return false;
339  }
340 
341  // First handle dates. Exrules override
342  if ( d->mExDates.containsSorted( qd ) ) {
343  return false;
344  }
345 
346  int i, end;
347  TimeList tms;
348  // For all-day events a matching exrule excludes the whole day
349  // since exclusions take precedence over inclusions, we know it can't occur on that day.
350  if ( allDay() ) {
351  for ( i = 0, end = d->mExRules.count(); i < end; ++i ) {
352  if ( d->mExRules[i]->recursOn( qd, timeSpec ) ) {
353  return false;
354  }
355  }
356  }
357 
358  if ( d->mRDates.containsSorted( qd ) ) {
359  return true;
360  }
361 
362  // Check if it might recur today at all.
363  bool recurs = ( startDate() == qd );
364  for ( i = 0, end = d->mRDateTimes.count(); i < end && !recurs; ++i ) {
365  recurs = ( d->mRDateTimes[i].toTimeSpec( timeSpec ).date() == qd );
366  }
367  for ( i = 0, end = d->mRRules.count(); i < end && !recurs; ++i ) {
368  recurs = d->mRRules[i]->recursOn( qd, timeSpec );
369  }
370  // If the event wouldn't recur at all, simply return false, don't check ex*
371  if ( !recurs ) {
372  return false;
373  }
374 
375  // Check if there are any times for this day excluded, either by exdate or exrule:
376  bool exon = false;
377  for ( i = 0, end = d->mExDateTimes.count(); i < end && !exon; ++i ) {
378  exon = ( d->mExDateTimes[i].toTimeSpec( timeSpec ).date() == qd );
379  }
380  if ( !allDay() ) { // we have already checked all-day times above
381  for ( i = 0, end = d->mExRules.count(); i < end && !exon; ++i ) {
382  exon = d->mExRules[i]->recursOn( qd, timeSpec );
383  }
384  }
385 
386  if ( !exon ) {
387  // Simple case, nothing on that day excluded, return the value from before
388  return recurs;
389  } else {
390  // Harder part: I don't think there is any way other than to calculate the
391  // whole list of items for that day.
392 //TODO: consider whether it would be more efficient to call
393 // Rule::recurTimesOn() instead of Rule::recursOn() from the start
394  TimeList timesForDay( recurTimesOn( qd, timeSpec ) );
395  return !timesForDay.isEmpty();
396  }
397 }
398 
399 bool Recurrence::recursAt( const KDateTime &dt ) const
400 {
401  // Convert to recurrence's time zone for date comparisons, and for more efficient time comparisons
402  KDateTime dtrecur = dt.toTimeSpec( d->mStartDateTime.timeSpec() );
403 
404  // if it's excluded anyway, don't bother to check if it recurs at all.
405  if ( d->mExDateTimes.containsSorted( dtrecur ) ||
406  d->mExDates.containsSorted( dtrecur.date() ) ) {
407  return false;
408  }
409  int i, end;
410  for ( i = 0, end = d->mExRules.count(); i < end; ++i ) {
411  if ( d->mExRules[i]->recursAt( dtrecur ) ) {
412  return false;
413  }
414  }
415 
416  // Check explicit recurrences, then rrules.
417  if ( startDateTime() == dtrecur || d->mRDateTimes.containsSorted( dtrecur ) ) {
418  return true;
419  }
420  for ( i = 0, end = d->mRRules.count(); i < end; ++i ) {
421  if ( d->mRRules[i]->recursAt( dtrecur ) ) {
422  return true;
423  }
424  }
425 
426  return false;
427 }
428 
432 KDateTime Recurrence::endDateTime() const
433 {
434  DateTimeList dts;
435  dts << startDateTime();
436  if ( !d->mRDates.isEmpty() ) {
437  dts << KDateTime( d->mRDates.last(), QTime( 0, 0, 0 ), d->mStartDateTime.timeSpec() );
438  }
439  if ( !d->mRDateTimes.isEmpty() ) {
440  dts << d->mRDateTimes.last();
441  }
442  for ( int i = 0, end = d->mRRules.count(); i < end; ++i ) {
443  KDateTime rl( d->mRRules[i]->endDt() );
444  // if any of the rules is infinite, the whole recurrence is
445  if ( !rl.isValid() ) {
446  return KDateTime();
447  }
448  dts << rl;
449  }
450  dts.sortUnique();
451  return dts.isEmpty() ? KDateTime() : dts.last();
452 }
453 
457 QDate Recurrence::endDate() const
458 {
459  KDateTime end( endDateTime() );
460  return end.isValid() ? end.date() : QDate();
461 }
462 
463 void Recurrence::setEndDate( const QDate &date )
464 {
465  KDateTime dt( date, d->mStartDateTime.time(), d->mStartDateTime.timeSpec() );
466  if ( allDay() ) {
467  dt.setTime( QTime( 23, 59, 59 ) );
468  }
469  setEndDateTime( dt );
470 }
471 
472 void Recurrence::setEndDateTime( const KDateTime &dateTime )
473 {
474  if ( d->mRecurReadOnly ) {
475  return;
476  }
477  RecurrenceRule *rrule = defaultRRule( true );
478  if ( !rrule ) {
479  return;
480  }
481  rrule->setEndDt( dateTime );
482  updated();
483 }
484 
485 int Recurrence::duration() const
486 {
487  RecurrenceRule *rrule = defaultRRuleConst();
488  return rrule ? rrule->duration() : 0;
489 }
490 
491 int Recurrence::durationTo( const KDateTime &datetime ) const
492 {
493  // Emulate old behavior: This is just an interface to the first rule!
494  RecurrenceRule *rrule = defaultRRuleConst();
495  return rrule ? rrule->durationTo( datetime ) : 0;
496 }
497 
498 int Recurrence::durationTo( const QDate &date ) const
499 {
500  return durationTo( KDateTime( date, QTime( 23, 59, 59 ), d->mStartDateTime.timeSpec() ) );
501 }
502 
503 void Recurrence::setDuration( int duration )
504 {
505  if ( d->mRecurReadOnly ) {
506  return;
507  }
508 
509  RecurrenceRule *rrule = defaultRRule( true );
510  if ( !rrule ) {
511  return;
512  }
513  rrule->setDuration( duration );
514  updated();
515 }
516 
517 void Recurrence::shiftTimes( const KDateTime::Spec &oldSpec, const KDateTime::Spec &newSpec )
518 {
519  if ( d->mRecurReadOnly ) {
520  return;
521  }
522 
523  d->mStartDateTime = d->mStartDateTime.toTimeSpec( oldSpec );
524  d->mStartDateTime.setTimeSpec( newSpec );
525 
526  int i, end;
527  for ( i = 0, end = d->mRDateTimes.count(); i < end; ++i ) {
528  d->mRDateTimes[i] = d->mRDateTimes[i].toTimeSpec( oldSpec );
529  d->mRDateTimes[i].setTimeSpec( newSpec );
530  }
531  for ( i = 0, end = d->mExDateTimes.count(); i < end; ++i ) {
532  d->mExDateTimes[i] = d->mExDateTimes[i].toTimeSpec( oldSpec );
533  d->mExDateTimes[i].setTimeSpec( newSpec );
534  }
535  for ( i = 0, end = d->mRRules.count(); i < end; ++i ) {
536  d->mRRules[i]->shiftTimes( oldSpec, newSpec );
537  }
538  for ( i = 0, end = d->mExRules.count(); i < end; ++i ) {
539  d->mExRules[i]->shiftTimes( oldSpec, newSpec );
540  }
541 }
542 
543 void Recurrence::unsetRecurs()
544 {
545  if ( d->mRecurReadOnly ) {
546  return;
547  }
548  d->mRRules.clear();
549  updated();
550 }
551 
552 void Recurrence::clear()
553 {
554  if ( d->mRecurReadOnly ) {
555  return;
556  }
557  d->mRRules.clearAll();
558  d->mExRules.clearAll();
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  d->mRRules.clearAll();
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) break; // <= Assume that the rdatetime list is sorted
914  }
915  for ( i = 0, end = d->mRRules.count(); i < end; ++i ) {
916  times += d->mRRules[i]->recurTimesOn( date, timeSpec );
917  }
918  times.sortUnique();
919 
920  foundDate = false;
921  TimeList extimes;
922  for ( i = 0, end = d->mExDateTimes.count(); i < end; ++i ) {
923  dt = d->mExDateTimes[i].toTimeSpec( timeSpec );
924  if ( dt.date() == date ) {
925  extimes << dt.time();
926  foundDate = true;
927  } else if (foundDate) break;
928  }
929  if ( !allDay() ) { // we have already checked all-day times above
930  for ( i = 0, end = d->mExRules.count(); i < end; ++i ) {
931  extimes += d->mExRules[i]->recurTimesOn( date, timeSpec );
932  }
933  }
934  extimes.sortUnique();
935 
936  int st = 0;
937  for ( i = 0, end = extimes.count(); i < end; ++i ) {
938  int j = times.removeSorted( extimes[i], st );
939  if ( j >= 0 ) {
940  st = j;
941  }
942  }
943  return times;
944 }
945 
946 DateTimeList Recurrence::timesInInterval( const KDateTime &start, const KDateTime &end ) const
947 {
948  int i, count;
949  DateTimeList times;
950  for ( i = 0, count = d->mRRules.count(); i < count; ++i ) {
951  times += d->mRRules[i]->timesInInterval( start, end );
952  }
953 
954  // add rdatetimes that fit in the interval
955  for ( i = 0, count = d->mRDateTimes.count(); i < count; ++i ) {
956  if ( d->mRDateTimes[i] >= start && d->mRDateTimes[i] <= end ) {
957  times += d->mRDateTimes[i];
958  }
959  }
960 
961  // add rdates that fit in the interval
962  KDateTime kdt( d->mStartDateTime );
963  for ( i = 0, count = d->mRDates.count(); i < count; ++i ) {
964  kdt.setDate( d->mRDates[i] );
965  if ( kdt >= start && kdt <= end ) {
966  times += kdt;
967  }
968  }
969 
970  // Recurrence::timesInInterval(...) doesn't explicitly add mStartDateTime to the list
971  // of times to be returned. It calls mRRules[i]->timesInInterval(...) which include
972  // mStartDateTime.
973  // So, If we have rdates/rdatetimes but don't have any rrule we must explicitly
974  // add mStartDateTime to the list, otherwise we won't see the first occurrence.
975  if ( ( !d->mRDates.isEmpty() || !d->mRDateTimes.isEmpty() ) &&
976  d->mRRules.isEmpty() &&
977  start <= d->mStartDateTime &&
978  end >= d->mStartDateTime ) {
979  times += d->mStartDateTime;
980  }
981 
982  times.sortUnique();
983 
984  // Remove excluded times
985  int idt = 0;
986  int enddt = times.count();
987  for ( i = 0, count = d->mExDates.count(); i < count && idt < enddt; ++i ) {
988  while ( idt < enddt && times[idt].date() < d->mExDates[i] ) ++idt;
989  while ( idt < enddt && times[idt].date() == d->mExDates[i] ) {
990  times.removeAt(idt);
991  --enddt;
992  }
993  }
994  DateTimeList extimes;
995  for ( i = 0, count = d->mExRules.count(); i < count; ++i ) {
996  extimes += d->mExRules[i]->timesInInterval( start, end );
997  }
998  extimes += d->mExDateTimes;
999  extimes.sortUnique();
1000 
1001  int st = 0;
1002  for ( i = 0, count = extimes.count(); i < count; ++i ) {
1003  int j = times.removeSorted( extimes[i], st );
1004  if ( j >= 0 ) {
1005  st = j;
1006  }
1007  }
1008 
1009  return times;
1010 }
1011 
1012 KDateTime Recurrence::getNextDateTime( const KDateTime &preDateTime ) const
1013 {
1014  KDateTime nextDT = preDateTime;
1015  // prevent infinite loops, e.g. when an exrule extinguishes an rrule (e.g.
1016  // the exrule is identical to the rrule). If an occurrence is found, break
1017  // out of the loop by returning that KDateTime
1018 // TODO_Recurrence: Is a loop counter of 1000 really okay? I mean for secondly
1019 // recurrence, an exdate might exclude more than 1000 intervals!
1020  int loop = 0;
1021  while ( loop < 1000 ) {
1022  // Outline of the algo:
1023  // 1) Find the next date/time after preDateTime when the event could recur
1024  // 1.0) Add the start date if it's after preDateTime
1025  // 1.1) Use the next occurrence from the explicit RDATE lists
1026  // 1.2) Add the next recurrence for each of the RRULEs
1027  // 2) Take the earliest recurrence of these = KDateTime nextDT
1028  // 3) If that date/time is not excluded, either explicitly by an EXDATE or
1029  // by an EXRULE, return nextDT as the next date/time of the recurrence
1030  // 4) If it's excluded, start all at 1), but starting at nextDT (instead
1031  // of preDateTime). Loop at most 1000 times.
1032  ++loop;
1033  // First, get the next recurrence from the RDate lists
1034  DateTimeList dates;
1035  if ( nextDT < startDateTime() ) {
1036  dates << startDateTime();
1037  }
1038 
1039  int end;
1040  // Assume that the rdatetime list is sorted
1041  int i = d->mRDateTimes.findGT( nextDT );
1042  if ( i >= 0 ) {
1043  dates << d->mRDateTimes[i];
1044  }
1045 
1046  KDateTime kdt( startDateTime() );
1047  for ( i = 0, end = d->mRDates.count(); i < end; ++i ) {
1048  kdt.setDate( d->mRDates[i] );
1049  if ( kdt > nextDT ) {
1050  dates << kdt;
1051  break;
1052  }
1053  }
1054 
1055  // Add the next occurrences from all RRULEs.
1056  for ( i = 0, end = d->mRRules.count(); i < end; ++i ) {
1057  KDateTime dt = d->mRRules[i]->getNextDate( nextDT );
1058  if ( dt.isValid() ) {
1059  dates << dt;
1060  }
1061  }
1062 
1063  // Take the first of these (all others can't be used later on)
1064  dates.sortUnique();
1065  if ( dates.isEmpty() ) {
1066  return KDateTime();
1067  }
1068  nextDT = dates.first();
1069 
1070  // Check if that date/time is excluded explicitly or by an exrule:
1071  if ( !d->mExDates.containsSorted( nextDT.date() ) &&
1072  !d->mExDateTimes.containsSorted( nextDT ) ) {
1073  bool allowed = true;
1074  for ( i = 0, end = d->mExRules.count(); i < end; ++i ) {
1075  allowed = allowed && !( d->mExRules[i]->recursAt( nextDT ) );
1076  }
1077  if ( allowed ) {
1078  return nextDT;
1079  }
1080  }
1081  }
1082 
1083  // Couldn't find a valid occurrences in 1000 loops, something is wrong!
1084  return KDateTime();
1085 }
1086 
1087 KDateTime Recurrence::getPreviousDateTime( const KDateTime &afterDateTime ) const
1088 {
1089  KDateTime prevDT = afterDateTime;
1090  // prevent infinite loops, e.g. when an exrule extinguishes an rrule (e.g.
1091  // the exrule is identical to the rrule). If an occurrence is found, break
1092  // out of the loop by returning that KDateTime
1093  int loop = 0;
1094  while ( loop < 1000 ) {
1095  // Outline of the algo:
1096  // 1) Find the next date/time after preDateTime when the event could recur
1097  // 1.1) Use the next occurrence from the explicit RDATE lists
1098  // 1.2) Add the next recurrence for each of the RRULEs
1099  // 2) Take the earliest recurrence of these = KDateTime nextDT
1100  // 3) If that date/time is not excluded, either explicitly by an EXDATE or
1101  // by an EXRULE, return nextDT as the next date/time of the recurrence
1102  // 4) If it's excluded, start all at 1), but starting at nextDT (instead
1103  // of preDateTime). Loop at most 1000 times.
1104  ++loop;
1105  // First, get the next recurrence from the RDate lists
1106  DateTimeList dates;
1107  if ( prevDT > startDateTime() ) {
1108  dates << startDateTime();
1109  }
1110 
1111  int i = d->mRDateTimes.findLT( prevDT );
1112  if ( i >= 0 ) {
1113  dates << d->mRDateTimes[i];
1114  }
1115 
1116  KDateTime kdt( startDateTime() );
1117  for ( i = d->mRDates.count(); --i >= 0; ) {
1118  kdt.setDate( d->mRDates[i] );
1119  if ( kdt < prevDT ) {
1120  dates << kdt;
1121  break;
1122  }
1123  }
1124 
1125  // Add the previous occurrences from all RRULEs.
1126  int end;
1127  for ( i = 0, end = d->mRRules.count(); i < end; ++i ) {
1128  KDateTime dt = d->mRRules[i]->getPreviousDate( prevDT );
1129  if ( dt.isValid() ) {
1130  dates << dt;
1131  }
1132  }
1133 
1134  // Take the last of these (all others can't be used later on)
1135  dates.sortUnique();
1136  if ( dates.isEmpty() ) {
1137  return KDateTime();
1138  }
1139  prevDT = dates.last();
1140 
1141  // Check if that date/time is excluded explicitly or by an exrule:
1142  if ( !d->mExDates.containsSorted( prevDT.date() ) &&
1143  !d->mExDateTimes.containsSorted( prevDT ) ) {
1144  bool allowed = true;
1145  for ( i = 0, end = d->mExRules.count(); i < end; ++i ) {
1146  allowed = allowed && !( d->mExRules[i]->recursAt( prevDT ) );
1147  }
1148  if ( allowed ) {
1149  return prevDT;
1150  }
1151  }
1152  }
1153 
1154  // Couldn't find a valid occurrences in 1000 loops, something is wrong!
1155  return KDateTime();
1156 }
1157 
1158 /***************************** PROTECTED FUNCTIONS ***************************/
1159 
1160 RecurrenceRule::List Recurrence::rRules() const
1161 {
1162  return d->mRRules;
1163 }
1164 
1165 void Recurrence::addRRule( RecurrenceRule *rrule )
1166 {
1167  if ( d->mRecurReadOnly || !rrule ) {
1168  return;
1169  }
1170 
1171  rrule->setAllDay( d->mAllDay );
1172  d->mRRules.append( rrule );
1173  rrule->addObserver( this );
1174  updated();
1175 }
1176 
1177 void Recurrence::removeRRule( RecurrenceRule *rrule )
1178 {
1179  if (d->mRecurReadOnly) {
1180  return;
1181  }
1182 
1183  d->mRRules.removeAll( rrule );
1184  rrule->removeObserver( this );
1185  updated();
1186 }
1187 
1188 void Recurrence::deleteRRule( RecurrenceRule *rrule )
1189 {
1190  if (d->mRecurReadOnly) {
1191  return;
1192  }
1193 
1194  d->mRRules.removeAll( rrule );
1195  delete rrule;
1196  updated();
1197 }
1198 
1199 RecurrenceRule::List Recurrence::exRules() const
1200 {
1201  return d->mExRules;
1202 }
1203 
1204 void Recurrence::addExRule( RecurrenceRule *exrule )
1205 {
1206  if ( d->mRecurReadOnly || !exrule ) {
1207  return;
1208  }
1209 
1210  exrule->setAllDay( d->mAllDay );
1211  d->mExRules.append( exrule );
1212  exrule->addObserver( this );
1213  updated();
1214 }
1215 
1216 void Recurrence::removeExRule( RecurrenceRule *exrule )
1217 {
1218  if ( d->mRecurReadOnly ) {
1219  return;
1220  }
1221 
1222  d->mExRules.removeAll( exrule );
1223  exrule->removeObserver( this );
1224  updated();
1225 }
1226 
1227 void Recurrence::deleteExRule( RecurrenceRule *exrule )
1228 {
1229  if ( d->mRecurReadOnly ) {
1230  return;
1231  }
1232 
1233  d->mExRules.removeAll( exrule );
1234  delete exrule;
1235  updated();
1236 }
1237 
1238 DateTimeList Recurrence::rDateTimes() const
1239 {
1240  return d->mRDateTimes;
1241 }
1242 
1243 void Recurrence::setRDateTimes( const DateTimeList &rdates )
1244 {
1245  if ( d->mRecurReadOnly ) {
1246  return;
1247  }
1248 
1249  d->mRDateTimes = rdates;
1250  d->mRDateTimes.sortUnique();
1251  updated();
1252 }
1253 
1254 void Recurrence::addRDateTime( const KDateTime &rdate )
1255 {
1256  if ( d->mRecurReadOnly ) {
1257  return;
1258  }
1259 
1260  d->mRDateTimes.insertSorted( rdate );
1261  updated();
1262 }
1263 
1264 DateList Recurrence::rDates() const
1265 {
1266  return d->mRDates;
1267 }
1268 
1269 void Recurrence::setRDates( const DateList &rdates )
1270 {
1271  if ( d->mRecurReadOnly ) {
1272  return;
1273  }
1274 
1275  d->mRDates = rdates;
1276  d->mRDates.sortUnique();
1277  updated();
1278 }
1279 
1280 void Recurrence::addRDate( const QDate &rdate )
1281 {
1282  if ( d->mRecurReadOnly ) {
1283  return;
1284  }
1285 
1286  d->mRDates.insertSorted( rdate );
1287  updated();
1288 }
1289 
1290 DateTimeList Recurrence::exDateTimes() const
1291 {
1292  return d->mExDateTimes;
1293 }
1294 
1295 void Recurrence::setExDateTimes( const DateTimeList &exdates )
1296 {
1297  if ( d->mRecurReadOnly ) {
1298  return;
1299  }
1300 
1301  d->mExDateTimes = exdates;
1302  d->mExDateTimes.sortUnique();
1303 }
1304 
1305 void Recurrence::addExDateTime( const KDateTime &exdate )
1306 {
1307  if ( d->mRecurReadOnly ) {
1308  return;
1309  }
1310 
1311  d->mExDateTimes.insertSorted( exdate );
1312  updated();
1313 }
1314 
1315 DateList Recurrence::exDates() const
1316 {
1317  return d->mExDates;
1318 }
1319 
1320 void Recurrence::setExDates( const DateList &exdates )
1321 {
1322  if ( d->mRecurReadOnly ) {
1323  return;
1324  }
1325 
1326  d->mExDates = exdates;
1327  d->mExDates.sortUnique();
1328  updated();
1329 }
1330 
1331 void Recurrence::addExDate( const QDate &exdate )
1332 {
1333  if ( d->mRecurReadOnly ) {
1334  return;
1335  }
1336 
1337  d->mExDates.insertSorted( exdate );
1338  updated();
1339 }
1340 
1341 void Recurrence::recurrenceChanged( RecurrenceRule * )
1342 {
1343  updated();
1344 }
1345 
1346 // %%%%%%%%%%%%%%%%%% end:Recurrencerule %%%%%%%%%%%%%%%%%%
1347 
1348 void Recurrence::dump() const
1349 {
1350  kDebug();
1351 
1352  int i;
1353  int count = d->mRRules.count();
1354  kDebug() << " -)" << count << "RRULEs:";
1355  for ( i = 0; i < count; ++i ) {
1356  kDebug() << " -) RecurrenceRule: ";
1357  d->mRRules[i]->dump();
1358  }
1359  count = d->mExRules.count();
1360  kDebug() << " -)" << count << "EXRULEs:";
1361  for ( i = 0; i < count; ++i ) {
1362  kDebug() << " -) ExceptionRule :";
1363  d->mExRules[i]->dump();
1364  }
1365 
1366  count = d->mRDates.count();
1367  kDebug() << endl << " -)" << count << "Recurrence Dates:";
1368  for ( i = 0; i < count; ++i ) {
1369  kDebug() << " " << d->mRDates[i];
1370  }
1371  count = d->mRDateTimes.count();
1372  kDebug() << endl << " -)" << count << "Recurrence Date/Times:";
1373  for ( i = 0; i < count; ++i ) {
1374  kDebug() << " " << d->mRDateTimes[i].dateTime();
1375  }
1376  count = d->mExDates.count();
1377  kDebug() << endl << " -)" << count << "Exceptions Dates:";
1378  for ( i = 0; i < count; ++i ) {
1379  kDebug() << " " << d->mExDates[i];
1380  }
1381  count = d->mExDateTimes.count();
1382  kDebug() << endl << " -)" << count << "Exception Date/Times:";
1383  for ( i = 0; i < count; ++i ) {
1384  kDebug() << " " << d->mExDateTimes[i].dateTime();
1385  }
1386 }
KCal::Recurrence::removeExRule
void removeExRule(RecurrenceRule *exrule)
Remove an exception rule from the recurrence.
Definition: recurrence.cpp:1216
KCal::Recurrence::addMonthlyPos
void addMonthlyPos(short pos, const QBitArray &days)
Adds a position (e.g.
Definition: recurrence.cpp:757
KCal::Recurrence::addYearlyDate
void addYearlyDate(int date)
Adds date within a yearly recurrence.
Definition: recurrence.cpp:850
KCal::Recurrence::Recurrence
Recurrence()
Constructs an empty recurrence.
Definition: recurrence.cpp:121
KCal::Recurrence::addYearlyPos
void addYearlyPos(short pos, const QBitArray &days)
Adds position within month/year within a yearly recurrence.
Definition: recurrence.cpp:856
KCal::RecurrenceRule::setAllDay
void setAllDay(bool allDay)
Sets whether the dtstart is all-day (i.e.
Definition: recurrencerule.cpp:987
KCal::Recurrence::yearMonths
QList< int > yearMonths() const
Returns the months within a yearly recurrence.
Definition: recurrence.cpp:679
KCal::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:978
KCal::Recurrence::setEndDateTime
void setEndDateTime(const KDateTime &endDateTime)
Sets the date and time of the last recurrence.
Definition: recurrence.cpp:472
KCal::Recurrence::duration
int duration() const
Returns -1 if the event recurs infinitely, 0 if the end date is set, otherwise the total number of re...
Definition: recurrence.cpp:485
KCal::Recurrence::addObserver
void addObserver(RecurrenceObserver *observer)
Installs an observer.
Definition: recurrence.cpp:162
KCal::Recurrence::addWeeklyDays
void addWeeklyDays(const QBitArray &days)
Adds days to the weekly day recurrence list.
Definition: recurrence.cpp:745
KCal::RecurrenceRule::removeObserver
void removeObserver(RuleObserver *observer)
Removes an observer that was added with addObserver.
Definition: recurrencerule.cpp:921
KCal::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:334
KCal::RecurrenceRule::setFrequency
void setFrequency(int freq)
Sets the recurrence frequency, in terms of the recurrence time period type.
Definition: recurrencerule.cpp:1015
KCal::Recurrence::yearDays
QList< int > yearDays() const
Returns the day numbers within a yearly recurrence.
Definition: recurrence.cpp:668
KCal::Recurrence::setRecurReadOnly
void setRecurReadOnly(bool readOnly)
Set if recurrence is read-only or can be changed.
Definition: recurrence.cpp:567
KCal::Recurrence::setYearly
void setYearly(int freq)
Sets an event to recur yearly.
Definition: recurrence.cpp:826
KCal::Recurrence::setAllDay
void setAllDay(bool allDay)
Sets whether the dtstart is a all-day (i.e.
Definition: recurrence.cpp:186
KCal::RecurrenceRule::addObserver
void addObserver(RuleObserver *observer)
Installs an observer.
Definition: recurrencerule.cpp:914
KCal::Recurrence::monthPositions
QList< RecurrenceRule::WDayPos > monthPositions() const
Returns list of day positions in months.
Definition: recurrence.cpp:660
KCal::Recurrence::deleteExRule
void deleteExRule(RecurrenceRule *exrule)
Remove an exception rule from the recurrence and delete it.
Definition: recurrence.cpp:1227
KCal::Recurrence::getPreviousDateTime
KDateTime getPreviousDateTime(const KDateTime &afterDateTime) const
Returns the date and time of the last previous recurrence, before the specified date/time.
Definition: recurrence.cpp:1087
KCal::Recurrence::operator=
Recurrence & operator=(const Recurrence &r)
Assignment operator.
Definition: recurrence.cpp:153
KCal::Recurrence::removeObserver
void removeObserver(RecurrenceObserver *observer)
Removes an observer that was added with addObserver.
Definition: recurrence.cpp:169
KCal::Recurrence::frequency
int frequency() const
Returns frequency of recurrence, in terms of the recurrence time period type.
Definition: recurrence.cpp:600
KCal::Recurrence::addMonthlyDate
void addMonthlyDate(short day)
Adds a date (e.g.
Definition: recurrence.cpp:807
KCal::Recurrence::days
QBitArray days() const
Returns week day mask (bit 0 = Monday).
Definition: recurrence.cpp:630
KCal::Recurrence::unsetRecurs
void unsetRecurs()
Removes all recurrence rules.
Definition: recurrence.cpp:543
KCal::Recurrence::clear
void clear()
Removes all recurrence and exception rules and dates.
Definition: recurrence.cpp:552
KCal::RecurrenceRule::durationTo
int durationTo(const KDateTime &dt) const
Returns the number of recurrences up to and including the date/time specified.
Definition: recurrencerule.cpp:1561
KCal::Recurrence::operator==
bool operator==(const Recurrence &r) const
Comparison operator for equality.
Definition: recurrence.cpp:148
KCal::Recurrence::setDuration
void setDuration(int duration)
Sets the total number of times the event is to occur, including both the first and last...
Definition: recurrence.cpp:503
KCal::Recurrence::recurs
bool recurs() const
Returns whether the event recurs at all.
Definition: recurrence.cpp:233
KCal::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
KCal::Recurrence::setMonthly
void setMonthly(int freq)
Sets an event to recur monthly.
Definition: recurrence.cpp:750
KCal::Recurrence::setMinutely
void setMinutely(int freq)
Sets an event to recur minutely.
Definition: recurrence.cpp:708
KCal::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:946
KCal::Recurrence::setHourly
void setHourly(int freq)
Sets an event to recur hourly.
Definition: recurrence.cpp:715
KCal::RecurrenceRule::WDayPos
structure for describing the n-th weekday of the month/year.
Definition: recurrencerule.h:71
KCal::Recurrence::startDate
QDate startDate() const
Return the start date/time of the recurrence.
Definition: recurrence.cpp:577
KCal::Recurrence::setWeekly
void setWeekly(int freq, int weekStart=1)
Sets an event to recur weekly.
Definition: recurrence.cpp:729
KCal::Recurrence::addRRule
void addRRule(RecurrenceRule *rrule)
Add a recurrence rule to the recurrence.
Definition: recurrence.cpp:1165
KCal::Recurrence::addYearlyMonth
void addYearlyMonth(short _rNum)
Adds month in yearly recurrence.
Definition: recurrence.cpp:862
KCal::ListBase
This class provides a template for lists of pointers.
Definition: listbase.h:44
KCal::Recurrence::setEndDate
void setEndDate(const QDate &endDate)
Sets the date of the last recurrence.
Definition: recurrence.cpp:463
KCal::Recurrence::weekStart
int weekStart() const
Returns the first day of the week.
Definition: recurrence.cpp:623
KCal::Recurrence::recurReadOnly
bool recurReadOnly() const
Returns true if the recurrence is read-only, or false if it can be changed.
Definition: recurrence.cpp:572
KCal::Recurrence::deleteRRule
void deleteRRule(RecurrenceRule *rrule)
Remove a recurrence rule from the recurrence and delete it.
Definition: recurrence.cpp:1188
KCal::Recurrence::endDateTime
KDateTime endDateTime() const
Returns the date/time of the last recurrence.
Definition: recurrence.cpp:432
KCal::Recurrence::yearDates
QList< int > yearDates() const
Returns the dates within a yearly recurrence.
Definition: recurrence.cpp:674
KCal::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:399
KCal::Recurrence::setFrequency
void setFrequency(int freq)
Sets the frequency of recurrence, in terms of the recurrence time period type.
Definition: recurrence.cpp:608
KCal::RecurrenceRule::frequency
uint frequency() const
Returns the recurrence frequency, in terms of the recurrence time period type.
Definition: recurrencerule.cpp:2119
KCal::SortableList::sortUnique
void sortUnique()
Sort the list.
Definition: sortablelist.h:191
KCal::Recurrence::getNextDateTime
KDateTime getNextDateTime(const KDateTime &preDateTime) const
Returns the date and time of the next recurrence, after the specified date/time.
Definition: recurrence.cpp:1012
KCal::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:176
KCal::SortableList
A QList which can be sorted.
Definition: sortablelist.h:86
KCal::Recurrence::endDate
QDate endDate() const
Returns the date of the last recurrence.
Definition: recurrence.cpp:457
KCal::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:517
KCal::Recurrence::~Recurrence
virtual ~Recurrence()
Destructor.
Definition: recurrence.cpp:143
KCal::Recurrence::yearPositions
QList< RecurrenceRule::WDayPos > yearPositions() const
Returns the positions within a yearly recurrence.
Definition: recurrence.cpp:685
KCal::Recurrence::setDaily
void setDaily(int freq)
Sets an event to recur daily.
Definition: recurrence.cpp:722
KCal::Recurrence::durationTo
int durationTo(const KDateTime &dt) const
Returns the number of recurrences up to and including the date/time specified.
Definition: recurrence.cpp:491
KCal::Recurrence::addYearlyDay
void addYearlyDay(int day)
Adds day number of year within a yearly recurrence.
Definition: recurrence.cpp:834
KCal::RecurrenceRule::setEndDt
void setEndDt(const KDateTime &endDateTime)
Sets the date and time of the last recurrence.
Definition: recurrencerule.cpp:968
KCal::Recurrence::recurrenceType
ushort recurrenceType() const
Returns the event's recurrence status.
Definition: recurrence.cpp:238
KCal::Recurrence::setStartDateTime
void setStartDateTime(const KDateTime &start)
Set start of recurrence.
Definition: recurrence.cpp:582
KCal::SortableList::removeSorted
int removeSorted(const T &value, int start=0)
Remove value value from the list.
Definition: sortablelist.h:292
KCal::Recurrence::removeRRule
void removeRRule(RecurrenceRule *rrule)
Remove a recurrence rule from the recurrence.
Definition: recurrence.cpp:1177
KCal::Recurrence::allDay
bool allDay() const
Set whether the recurrence has no time, just a date.
Definition: recurrence.cpp:181
KCal::Recurrence::addExRule
void addExRule(RecurrenceRule *exrule)
Add an exception rule to the recurrence.
Definition: recurrence.cpp:1204
KCal::RecurrenceRule::PeriodType
PeriodType
enum for describing the frequency how an event recurs, if at all.
Definition: recurrencerule.h:59
KCal::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:2124
KCal::Recurrence::monthDays
QList< int > monthDays() const
Returns list of day numbers of a month.
Definition: recurrence.cpp:649
KCal::Recurrence::dump
void dump() const
Debug output.
Definition: recurrence.cpp:1348
KCal::Recurrence
This class represents a recurrence rule for a calendar incidence.
Definition: recurrence.h:91
KCal::RecurrenceRule::setStartDt
void setStartDt(const KDateTime &start)
Sets the recurrence start date/time.
Definition: recurrencerule.cpp:1006
KCal::RecurrenceRule
This class represents a recurrence rule for a calendar incidence.
Definition: recurrencerule.h:46
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 23:00:58 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KCal Library

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

kdepimlibs API Reference

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

Search



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

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