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

KCal Library

  • 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
37using namespace KCal;
38
39//@cond PRIVATE
40class 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
84bool 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
121Recurrence::Recurrence()
122 : d( new KCal::Recurrence::Private() )
123{
124}
125
126Recurrence::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
143Recurrence::~Recurrence()
144{
145 delete d;
146}
147
148bool Recurrence::operator==( const Recurrence &r2 ) const
149{
150 return *d == *r2.d;
151}
152
153Recurrence &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
162void Recurrence::addObserver( RecurrenceObserver *observer )
163{
164 if ( !d->mObservers.contains( observer ) ) {
165 d->mObservers.append( observer );
166 }
167}
168
169void Recurrence::removeObserver( RecurrenceObserver *observer )
170{
171 if ( d->mObservers.contains( observer ) ) {
172 d->mObservers.removeAll( observer );
173 }
174}
175
176KDateTime Recurrence::startDateTime() const
177{
178 return d->mStartDateTime;
179}
180
181bool Recurrence::allDay() const
182{
183 return d->mAllDay;
184}
185
186void 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
202RecurrenceRule *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
217RecurrenceRule *Recurrence::defaultRRuleConst() const
218{
219 return d->mRRules.isEmpty() ? 0 : d->mRRules[0];
220}
221
222void 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
233bool Recurrence::recurs() const
234{
235 return !d->mRRules.isEmpty() || !d->mRDates.isEmpty() || !d->mRDateTimes.isEmpty();
236}
237
238ushort Recurrence::recurrenceType() const
239{
240 if ( d->mCachedType == rMax ) {
241 d->mCachedType = recurrenceType( defaultRRuleConst() );
242 }
243 return d->mCachedType;
244}
245
246ushort 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
334bool 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
399bool 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
432KDateTime 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
457QDate Recurrence::endDate() const
458{
459 KDateTime end( endDateTime() );
460 return end.isValid() ? end.date() : QDate();
461}
462
463void 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
472void 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
485int Recurrence::duration() const
486{
487 RecurrenceRule *rrule = defaultRRuleConst();
488 return rrule ? rrule->duration() : 0;
489}
490
491int 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
498int Recurrence::durationTo( const QDate &date ) const
499{
500 return durationTo( KDateTime( date, QTime( 23, 59, 59 ), d->mStartDateTime.timeSpec() ) );
501}
502
503void 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
517void 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
543void Recurrence::unsetRecurs()
544{
545 if ( d->mRecurReadOnly ) {
546 return;
547 }
548 d->mRRules.clear();
549 updated();
550}
551
552void 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
567void Recurrence::setRecurReadOnly( bool readOnly )
568{
569 d->mRecurReadOnly = readOnly;
570}
571
572bool Recurrence::recurReadOnly() const
573{
574 return d->mRecurReadOnly;
575}
576
577QDate Recurrence::startDate() const
578{
579 return d->mStartDateTime.date();
580}
581
582void 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
600int 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
608void 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
623int Recurrence::weekStart() const
624{
625 RecurrenceRule *rrule = defaultRRuleConst();
626 return rrule ? rrule->weekStart() : 1;
627}
628
629// Emulate the old behavior
630QBitArray 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
649QList<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
660QList<RecurrenceRule::WDayPos> Recurrence::monthPositions() const
661{
662 RecurrenceRule *rrule = defaultRRuleConst();
663 return rrule ? rrule->byDays() : QList<RecurrenceRule::WDayPos>();
664}
665
666// YEARLY
667
668QList<int> Recurrence::yearDays() const
669{
670 RecurrenceRule *rrule = defaultRRuleConst();
671 return rrule ? rrule->byYearDays() : QList<int>();
672}
673
674QList<int> Recurrence::yearDates() const
675{
676 return monthDays();
677}
678
679QList<int> Recurrence::yearMonths() const
680{
681 RecurrenceRule *rrule = defaultRRuleConst();
682 return rrule ? rrule->byMonths() : QList<int>();
683}
684
685QList<RecurrenceRule::WDayPos> Recurrence::yearPositions() const
686{
687 return monthPositions();
688}
689
690RecurrenceRule *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
708void Recurrence::setMinutely( int _rFreq )
709{
710 if ( setNewRecurrenceType( RecurrenceRule::rMinutely, _rFreq ) ) {
711 updated();
712 }
713}
714
715void Recurrence::setHourly( int _rFreq )
716{
717 if ( setNewRecurrenceType( RecurrenceRule::rHourly, _rFreq ) ) {
718 updated();
719 }
720}
721
722void Recurrence::setDaily( int _rFreq )
723{
724 if ( setNewRecurrenceType( RecurrenceRule::rDaily, _rFreq ) ) {
725 updated();
726 }
727}
728
729void 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
739void Recurrence::setWeekly( int freq, const QBitArray &days, int weekStart )
740{
741 setWeekly( freq, weekStart );
742 addMonthlyPos( 0, days );
743}
744
745void Recurrence::addWeeklyDays( const QBitArray &days )
746{
747 addMonthlyPos( 0, days );
748}
749
750void Recurrence::setMonthly( int freq )
751{
752 if ( setNewRecurrenceType( RecurrenceRule::rMonthly, freq ) ) {
753 updated();
754 }
755}
756
757void 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
786void 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
807void 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
826void Recurrence::setYearly( int freq )
827{
828 if ( setNewRecurrenceType( RecurrenceRule::rYearly, freq ) ) {
829 updated();
830 }
831}
832
833// Daynumber within year
834void 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
850void Recurrence::addYearlyDate( int day )
851{
852 addMonthlyDate( day );
853}
854
855// day part of date within year, given as position (n-th weekday)
856void Recurrence::addYearlyPos( short pos, const QBitArray &days )
857{
858 addMonthlyPos( pos, days );
859}
860
861// month part of date within year
862void 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
881TimeList 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
946DateTimeList 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
1012KDateTime 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
1087KDateTime 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
1160RecurrenceRule::List Recurrence::rRules() const
1161{
1162 return d->mRRules;
1163}
1164
1165void 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
1177void 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
1188void 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
1199RecurrenceRule::List Recurrence::exRules() const
1200{
1201 return d->mExRules;
1202}
1203
1204void 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
1216void 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
1227void 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
1238DateTimeList Recurrence::rDateTimes() const
1239{
1240 return d->mRDateTimes;
1241}
1242
1243void 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
1254void Recurrence::addRDateTime( const KDateTime &rdate )
1255{
1256 if ( d->mRecurReadOnly ) {
1257 return;
1258 }
1259
1260 d->mRDateTimes.insertSorted( rdate );
1261 updated();
1262}
1263
1264DateList Recurrence::rDates() const
1265{
1266 return d->mRDates;
1267}
1268
1269void 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
1280void Recurrence::addRDate( const QDate &rdate )
1281{
1282 if ( d->mRecurReadOnly ) {
1283 return;
1284 }
1285
1286 d->mRDates.insertSorted( rdate );
1287 updated();
1288}
1289
1290DateTimeList Recurrence::exDateTimes() const
1291{
1292 return d->mExDateTimes;
1293}
1294
1295void Recurrence::setExDateTimes( const DateTimeList &exdates )
1296{
1297 if ( d->mRecurReadOnly ) {
1298 return;
1299 }
1300
1301 d->mExDateTimes = exdates;
1302 d->mExDateTimes.sortUnique();
1303}
1304
1305void Recurrence::addExDateTime( const KDateTime &exdate )
1306{
1307 if ( d->mRecurReadOnly ) {
1308 return;
1309 }
1310
1311 d->mExDateTimes.insertSorted( exdate );
1312 updated();
1313}
1314
1315DateList Recurrence::exDates() const
1316{
1317 return d->mExDates;
1318}
1319
1320void 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
1331void Recurrence::addExDate( const QDate &exdate )
1332{
1333 if ( d->mRecurReadOnly ) {
1334 return;
1335 }
1336
1337 d->mExDates.insertSorted( exdate );
1338 updated();
1339}
1340
1341void Recurrence::recurrenceChanged( RecurrenceRule * )
1342{
1343 updated();
1344}
1345
1346// %%%%%%%%%%%%%%%%%% end:Recurrencerule %%%%%%%%%%%%%%%%%%
1347
1348void 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::ListBase
This class provides a template for lists of pointers.
Definition: listbase.h:45
KCal::RecurrenceRule::WDayPos
structure for describing the n-th weekday of the month/year.
Definition: recurrencerule.h:72
KCal::RecurrenceRule
This class represents a recurrence rule for a calendar incidence.
Definition: recurrencerule.h:47
KCal::RecurrenceRule::setAllDay
void setAllDay(bool allDay)
Sets whether the dtstart is all-day (i.e.
Definition: recurrencerule.cpp:987
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::RecurrenceRule::setFrequency
void setFrequency(int freq)
Sets the recurrence frequency, in terms of the recurrence time period type.
Definition: recurrencerule.cpp:1015
KCal::RecurrenceRule::frequency
uint frequency() const
Returns the recurrence frequency, in terms of the recurrence time period type.
Definition: recurrencerule.cpp:2119
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::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::RecurrenceRule::setEndDt
void setEndDt(const KDateTime &endDateTime)
Sets the date and time of the last recurrence.
Definition: recurrencerule.cpp:968
KCal::RecurrenceRule::PeriodType
PeriodType
enum for describing the frequency how an event recurs, if at all.
Definition: recurrencerule.h:59
KCal::RecurrenceRule::addObserver
void addObserver(RuleObserver *observer)
Installs an observer.
Definition: recurrencerule.cpp:914
KCal::RecurrenceRule::setStartDt
void setStartDt(const KDateTime &start)
Sets the recurrence start date/time.
Definition: recurrencerule.cpp:1006
KCal::RecurrenceRule::removeObserver
void removeObserver(RuleObserver *observer)
Removes an observer that was added with addObserver.
Definition: recurrencerule.cpp:921
KCal::Recurrence
This class represents a recurrence rule for a calendar incidence.
Definition: recurrence.h:92
KCal::Recurrence::recurrenceType
ushort recurrenceType() const
Returns the event's recurrence status.
Definition: recurrence.cpp:238
KCal::Recurrence::removeRRule
void removeRRule(RecurrenceRule *rrule)
Remove a recurrence rule from the recurrence.
Definition: recurrence.cpp:1177
KCal::Recurrence::setEndDateTime
void setEndDateTime(const KDateTime &endDateTime)
Sets the date and time of the last recurrence.
Definition: recurrence.cpp:472
KCal::Recurrence::yearPositions
QList< RecurrenceRule::WDayPos > yearPositions() const
Returns the positions within a yearly recurrence.
Definition: recurrence.cpp:685
KCal::Recurrence::setRecurReadOnly
void setRecurReadOnly(bool readOnly)
Set if recurrence is read-only or can be changed.
Definition: recurrence.cpp:567
KCal::Recurrence::yearDates
QList< int > yearDates() const
Returns the dates within a yearly recurrence.
Definition: recurrence.cpp:674
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::frequency
int frequency() const
Returns frequency of recurrence, in terms of the recurrence time period type.
Definition: recurrence.cpp:600
KCal::Recurrence::addYearlyDay
void addYearlyDay(int day)
Adds day number of year within a yearly recurrence.
Definition: recurrence.cpp:834
KCal::Recurrence::setYearly
void setYearly(int freq)
Sets an event to recur yearly.
Definition: recurrence.cpp:826
KCal::Recurrence::setWeekly
void setWeekly(int freq, int weekStart=1)
Sets an event to recur weekly.
Definition: recurrence.cpp:729
KCal::Recurrence::recurs
bool recurs() const
Returns whether the event recurs at all.
Definition: recurrence.cpp:233
KCal::Recurrence::setStartDateTime
void setStartDateTime(const KDateTime &start)
Set start of recurrence.
Definition: recurrence.cpp:582
KCal::Recurrence::operator=
Recurrence & operator=(const Recurrence &r)
Assignment operator.
Definition: recurrence.cpp:153
KCal::Recurrence::~Recurrence
virtual ~Recurrence()
Destructor.
Definition: recurrence.cpp:143
KCal::Recurrence::setMinutely
void setMinutely(int freq)
Sets an event to recur minutely.
Definition: recurrence.cpp:708
KCal::Recurrence::setMonthly
void setMonthly(int freq)
Sets an event to recur monthly.
Definition: recurrence.cpp:750
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::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::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::Recurrence::setFrequency
void setFrequency(int freq)
Sets the frequency of recurrence, in terms of the recurrence time period type.
Definition: recurrence.cpp:608
KCal::Recurrence::monthDays
QList< int > monthDays() const
Returns list of day numbers of a month.
Definition: recurrence.cpp:649
KCal::Recurrence::endDateTime
KDateTime endDateTime() const
Returns the date/time of the last recurrence.
Definition: recurrence.cpp:432
KCal::Recurrence::deleteExRule
void deleteExRule(RecurrenceRule *exrule)
Remove an exception rule from the recurrence and delete it.
Definition: recurrence.cpp:1227
KCal::Recurrence::addYearlyMonth
void addYearlyMonth(short _rNum)
Adds month in yearly recurrence.
Definition: recurrence.cpp:862
KCal::Recurrence::deleteRRule
void deleteRRule(RecurrenceRule *rrule)
Remove a recurrence rule from the recurrence and delete it.
Definition: recurrence.cpp:1188
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::removeObserver
void removeObserver(RecurrenceObserver *observer)
Removes an observer that was added with addObserver.
Definition: recurrence.cpp:169
KCal::Recurrence::allDay
bool allDay() const
Set whether the recurrence has no time, just a date.
Definition: recurrence.cpp:181
KCal::Recurrence::startDate
QDate startDate() const
Return the start date/time of the recurrence.
Definition: recurrence.cpp:577
KCal::Recurrence::addMonthlyPos
void addMonthlyPos(short pos, const QBitArray &days)
Adds a position (e.g.
Definition: recurrence.cpp:757
KCal::Recurrence::addObserver
void addObserver(RecurrenceObserver *observer)
Installs an observer.
Definition: recurrence.cpp:162
KCal::Recurrence::addYearlyDate
void addYearlyDate(int date)
Adds date within a yearly recurrence.
Definition: recurrence.cpp:850
KCal::Recurrence::days
QBitArray days() const
Returns week day mask (bit 0 = Monday).
Definition: recurrence.cpp:630
KCal::Recurrence::removeExRule
void removeExRule(RecurrenceRule *exrule)
Remove an exception rule from the recurrence.
Definition: recurrence.cpp:1216
KCal::Recurrence::addYearlyPos
void addYearlyPos(short pos, const QBitArray &days)
Adds position within month/year within a yearly recurrence.
Definition: recurrence.cpp:856
KCal::Recurrence::setAllDay
void setAllDay(bool allDay)
Sets whether the dtstart is a all-day (i.e.
Definition: recurrence.cpp:186
KCal::Recurrence::addRRule
void addRRule(RecurrenceRule *rrule)
Add a recurrence rule to the recurrence.
Definition: recurrence.cpp:1165
KCal::Recurrence::setDaily
void setDaily(int freq)
Sets an event to recur daily.
Definition: recurrence.cpp:722
KCal::Recurrence::unsetRecurs
void unsetRecurs()
Removes all recurrence rules.
Definition: recurrence.cpp:543
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::Recurrence::dump
void dump() const
Debug output.
Definition: recurrence.cpp:1348
KCal::Recurrence::addExRule
void addExRule(RecurrenceRule *exrule)
Add an exception rule to the recurrence.
Definition: recurrence.cpp:1204
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::yearMonths
QList< int > yearMonths() const
Returns the months within a yearly recurrence.
Definition: recurrence.cpp:679
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::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::setHourly
void setHourly(int freq)
Sets an event to recur hourly.
Definition: recurrence.cpp:715
KCal::Recurrence::clear
void clear()
Removes all recurrence and exception rules and dates.
Definition: recurrence.cpp:552
KCal::Recurrence::addMonthlyDate
void addMonthlyDate(short day)
Adds a date (e.g.
Definition: recurrence.cpp:807
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::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::yearDays
QList< int > yearDays() const
Returns the day numbers within a yearly recurrence.
Definition: recurrence.cpp:668
KCal::Recurrence::operator==
bool operator==(const Recurrence &r) const
Comparison operator for equality.
Definition: recurrence.cpp:148
KCal::Recurrence::addWeeklyDays
void addWeeklyDays(const QBitArray &days)
Adds days to the weekly day recurrence list.
Definition: recurrence.cpp:745
KCal::Recurrence::monthPositions
QList< RecurrenceRule::WDayPos > monthPositions() const
Returns list of day positions in months.
Definition: recurrence.cpp:660
KCal::Recurrence::endDate
QDate endDate() const
Returns the date of the last recurrence.
Definition: recurrence.cpp:457
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::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::Recurrence
Recurrence()
Constructs an empty recurrence.
Definition: recurrence.cpp:121
KCal::SortableList
A QList which can be sorted.
Definition: sortablelist.h:87
KCal::SortableList::removeSorted
int removeSorted(const T &value, int start=0)
Remove value value from the list.
Definition: sortablelist.h:292
KCal::SortableList::sortUnique
void sortUnique()
Sort the list.
Definition: sortablelist.h:191
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Thu Jul 21 2022 00:00:00 by doxygen 1.9.5 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-4.14.10 API Reference

Skip menu "kdepimlibs-4.14.10 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