28 #include <tdeglobal.h>
29 #include <tdelocale.h>
30 #include <tqbitarray.h>
32 #include "recurrence.h"
33 #include "recurrencerule.h"
37 Recurrence::Recurrence()
39 mRecurReadOnly(false),
42 mExRules.setAutoDelete(
true );
43 mRRules.setAutoDelete(
true );
48 mRDateTimes( r.mRDateTimes ), mRDates( r.mRDates ),
49 mExDateTimes( r.mExDateTimes ), mExDates( r.mExDates ),
50 mStartDateTime( r.mStartDateTime ),
51 mFloating( r.mFloating ),
52 mRecurReadOnly(r.mRecurReadOnly),
53 mCachedType( r.mCachedType )
55 mExRules.setAutoDelete(
true );
56 mRRules.setAutoDelete(
true );
57 RecurrenceRule::List::ConstIterator rr;
58 for ( rr = r.mRRules.begin(); rr != r.mRRules.end(); ++rr ) {
60 mRRules.append( rule );
63 for ( rr = r.mExRules.begin(); rr != r.mExRules.end(); ++rr ) {
65 mExRules.append( rule );
70 Recurrence::~Recurrence()
76 bool Recurrence::operator==(
const Recurrence& r2 )
const
78 if ( mStartDateTime != r2.mStartDateTime
79 || mFloating != r2.mFloating
80 || mRecurReadOnly != r2.mRecurReadOnly )
82 if ( mExDates != r2.mExDates )
return false;
83 if ( mExDateTimes != r2.mExDateTimes )
return false;
84 if ( mRDates != r2.mRDates )
return false;
85 if ( mRDateTimes != r2.mRDateTimes )
return false;
89 if ( mRRules.count() != r2.mRRules.count() )
return false;
90 RecurrenceRule::List::ConstIterator rit1 = mRRules.begin();
91 RecurrenceRule::List::ConstIterator rit2 = r2.mRRules.begin();
93 while ( rit1 != mRRules.end() && rit2 != r2.mRRules.end() ) {
96 if ( *(*rit1) != *(*rit2) )
return false;
100 RecurrenceRule::List::ConstIterator exit1 = mExRules.begin();
101 RecurrenceRule::List::ConstIterator exit2 = r2.mExRules.begin();
103 while ( exit1 != mExRules.end() && exit2 != r2.mExRules.end() ) {
106 if ( *(*exit1) != *(*exit2) )
return false;
115 if ( !mObservers.contains( observer ) )
116 mObservers.append( observer );
121 if ( mObservers.contains( observer ) )
122 mObservers.remove( observer );
129 return TQDateTime( mStartDateTime.date(), TQTime( 0, 0, 0 ) );
130 else return mStartDateTime;
135 if ( mRecurReadOnly )
return;
136 if ( floats == mFloating )
return;
140 RecurrenceRule::List::ConstIterator it;
141 for ( it = mRRules.begin(); it != mRRules.end(); ++it ) {
142 (*it)->setFloats( floats );
145 RecurrenceRule::List::ConstIterator it1;
146 for ( it1 = mExRules.begin(); it1 != mExRules.end(); ++it1 ) {
147 (*it1)->setFloats( floats );
154 if ( mRRules.isEmpty() ) {
155 if ( !create || mRecurReadOnly )
return 0;
161 return mRRules.first();
167 if ( mRRules.isEmpty() ) {
170 return mRRules.first();
174 void Recurrence::updated()
178 for ( TQValueList<Observer*>::ConstIterator it = mObservers.begin();
179 it != mObservers.end(); ++it ) {
180 if ( (*it) ) (*it)->recurrenceUpdated(
this );
186 return !mRRules.isEmpty() || !mRDates.isEmpty() || !mRDateTimes.isEmpty();
191 if ( mCachedType == rMax ) {
199 if ( !rrule )
return rNone;
203 if ( !rrule->bySetPos().isEmpty() )
205 if ( !rrule->bySeconds().isEmpty() )
207 if ( !rrule->byWeekNumbers().isEmpty() )
212 if ( !rrule->byMinutes().isEmpty() )
214 if ( !rrule->byHours().isEmpty() )
222 if ( !rrule->byYearDays().isEmpty() && type != RecurrenceRule::rYearly )
224 if ( !rrule->byMonths().isEmpty() && type != RecurrenceRule::rYearly )
226 if ( !rrule->byDays().isEmpty() ) {
227 if ( type != RecurrenceRule::rYearly && type != RecurrenceRule::rMonthly &&
228 type != RecurrenceRule::rWeekly )
233 case RecurrenceRule::rNone:
return rNone;
234 case RecurrenceRule::rMinutely:
return rMinutely;
235 case RecurrenceRule::rHourly:
return rHourly;
236 case RecurrenceRule::rDaily:
return rDaily;
237 case RecurrenceRule::rWeekly:
return rWeekly;
238 case RecurrenceRule::rMonthly: {
239 if ( rrule->byDays().isEmpty() )
return rMonthlyDay;
240 else if ( rrule->byMonthDays().isEmpty() )
return rMonthlyPos;
243 case RecurrenceRule::rYearly: {
248 if ( !rrule->byDays().isEmpty() ) {
250 if ( rrule->byMonthDays().isEmpty() && rrule->byYearDays().isEmpty() )
253 }
else if ( !rrule->byYearDays().isEmpty() ) {
255 if ( rrule->byMonths().isEmpty() && rrule->byMonthDays().isEmpty() )
263 default:
return rOther;
272 if ( mExDates.contains( qd ) )
return false;
276 for ( RecurrenceRule::List::ConstIterator rr = mExRules.begin(); rr != mExRules.end(); ++rr ) {
277 if ( (*rr)->recursOn( qd ) )
282 if ( mRDates.contains( qd ) )
return true;
286 for ( RecurrenceRule::List::ConstIterator rr = mRRules.begin(); rr != mRRules.end(); ++rr ) {
287 recurs = recurs || (*rr)->recursOn( qd );
291 for ( DateTimeList::ConstIterator rit = mRDateTimes.begin();
292 rit != mRDateTimes.end(); ++rit ) {
293 if ( (*rit).date() == qd ) {
300 if ( !recurs )
return false;
304 for ( DateTimeList::ConstIterator exit = mExDateTimes.begin();
305 exit != mExDateTimes.end(); ++exit ) {
306 if ( (*exit).date() == qd ) {
312 for ( RecurrenceRule::List::ConstIterator rr = mExRules.begin(); rr != mExRules.end(); ++rr ) {
313 exon = exon || (*rr)->recursOn( qd );
324 return !timesForDay.isEmpty();
331 if ( mExDateTimes.contains( dt ))
return false;
332 if ( mExDates.contains( dt.date() ))
return false;
333 for ( RecurrenceRule::List::ConstIterator rr = mExRules.begin(); rr != mExRules.end(); ++rr ) {
334 if ( (*rr)->recursAt( dt ) )
return false;
338 bool occurs = (
startDateTime() == dt ) || mRDateTimes.contains( dt );
341 for ( RecurrenceRule::List::ConstIterator rr = mRRules.begin(); rr != mRRules.end(); ++rr ) {
342 if ( (*rr)->recursAt( dt ) )
return true;
355 if ( !mRDates.isEmpty() ) dts << TQDateTime( mRDates.last(), TQTime( 0, 0, 0 ) );
356 if ( !mRDateTimes.isEmpty() ) dts << mRDateTimes.last();
357 for ( RecurrenceRule::List::ConstIterator rr = mRRules.begin(); rr != mRRules.end(); ++rr ) {
358 TQDateTime rl( (*rr)->endDt() );
360 if ( !rl.isValid() )
return TQDateTime();
364 if ( dts.isEmpty() )
return TQDateTime();
365 else return dts.last();
374 if ( end.isValid() ) {
return end.date(); }
375 else return TQDate();
388 if ( mRecurReadOnly )
return;
390 if ( !rrule )
return;
398 if ( rrule )
return rrule->
duration();
411 if ( !rrule )
return 0;
417 if ( mRecurReadOnly )
return;
419 if ( !rrule )
return;
426 if ( mRecurReadOnly )
return;
433 if ( mRecurReadOnly )
return;
439 mExDateTimes.clear();
446 if ( mRecurReadOnly )
return;
447 mStartDateTime = start;
450 for ( RecurrenceRule::List::ConstIterator rr = mRRules.begin(); rr != mRRules.end(); ++rr ) {
451 (*rr)->setStartDt( start );
453 for ( RecurrenceRule::List::ConstIterator rr = mExRules.begin(); rr != mExRules.end(); ++rr ) {
454 (*rr)->setStartDt( start );
476 if ( mRecurReadOnly || freq <= 0 )
return;
489 if ( rrule )
return rrule->weekStart();
496 TQBitArray
days( 7 );
500 TQValueList<RecurrenceRule::WDayPos> bydays = rrule->byDays();
501 for ( TQValueListConstIterator<RecurrenceRule::WDayPos> it = bydays.begin();
502 it != bydays.end(); ++it ) {
503 if ( (*it).pos() == 0 ) {
504 days.setBit( (*it).day() - 1 );
518 if ( rrule )
return rrule->byMonthDays();
519 else return TQValueList<int>();
526 if ( rrule )
return rrule->byDays();
527 else return TQValueList<RecurrenceRule::WDayPos>();
536 if ( rrule )
return rrule->byYearDays();
537 else return TQValueList<int>();
548 if ( rrule )
return rrule->byMonths();
549 else return TQValueList<int>();
561 if ( mRecurReadOnly || freq <= 0 )
return 0;
565 if ( !rrule )
return 0;
566 rrule->setRecurrenceType( type );
574 if ( setNewRecurrenceType( RecurrenceRule::rMinutely, _rFreq ) )
580 if ( setNewRecurrenceType( RecurrenceRule::rHourly, _rFreq ) )
586 if ( setNewRecurrenceType( RecurrenceRule::rDaily, _rFreq ) )
592 RecurrenceRule *rrule = setNewRecurrenceType( RecurrenceRule::rWeekly, freq );
593 if ( !rrule )
return;
611 if ( setNewRecurrenceType( RecurrenceRule::rMonthly, freq ) )
618 if ( mRecurReadOnly || pos > 53 || pos < -53 )
return;
620 if ( !rrule )
return;
621 bool changed =
false;
622 TQValueList<RecurrenceRule::WDayPos> positions = rrule->byDays();
624 for (
int i = 0; i < 7; ++i ) {
625 if (
days.testBit(i) ) {
627 if ( !positions.contains( p ) ) {
629 positions.append( p );
634 rrule->setByDays( positions );
643 if ( mRecurReadOnly || pos > 53 || pos < -53 )
return;
645 if ( !rrule )
return;
646 TQValueList<RecurrenceRule::WDayPos> positions = rrule->byDays();
649 if ( !positions.contains( p ) ) {
650 positions.append( p );
651 rrule->setByDays( positions );
659 if ( mRecurReadOnly || day > 31 || day < -31 )
return;
661 if ( !rrule )
return;
663 TQValueList<int>
monthDays = rrule->byMonthDays();
673 if ( setNewRecurrenceType( RecurrenceRule::rYearly, freq ) )
682 if ( !rrule )
return;
684 TQValueList<int>
days = rrule->byYearDays();
685 if ( !
days.contains( day ) ) {
687 rrule->setByYearDays(
days );
708 if ( mRecurReadOnly || month < 1 || month > 12 )
return;
710 if ( !rrule )
return;
712 TQValueList<int> months = rrule->byMonths();
713 if ( !months.contains(month) ) {
715 rrule->setByMonths( months );
725 if ( mExDates.contains( date ) )
return times;
729 for ( RecurrenceRule::List::ConstIterator rr = mExRules.begin(); rr != mExRules.end(); ++rr ) {
730 if ( (*rr)->recursOn( date ) )
736 bool foundDate =
false;
737 for ( DateTimeList::ConstIterator it = mRDateTimes.begin();
738 it != mRDateTimes.end(); ++it ) {
739 if ( (*it).date() == date ) {
740 times << (*it).time();
742 }
else if (foundDate)
break;
744 for ( RecurrenceRule::List::ConstIterator rr = mRRules.begin(); rr != mRRules.end(); ++rr ) {
745 times += (*rr)->recurTimesOn( date );
747 qSortUnique( times );
751 for ( DateTimeList::ConstIterator it = mExDateTimes.begin();
752 it != mExDateTimes.end(); ++it ) {
753 if ( (*it).date() == date ) {
754 extimes << (*it).time();
756 }
else if (foundDate)
break;
759 for ( RecurrenceRule::List::ConstIterator rr = mExRules.begin(); rr != mExRules.end(); ++rr ) {
760 extimes += (*rr)->recurTimesOn( date );
763 qSortUnique( extimes );
765 for ( TimeList::Iterator it = extimes.begin(); it != extimes.end(); ++it ) {
766 times.remove( (*it) );
775 for ( i = 0, count = mRRules.count(); i < count; ++i ) {
776 times += mRRules[i]->timesInInterval( start, end );
780 for ( i = 0, count = mRDateTimes.count(); i < count; ++i ) {
781 if ( mRDateTimes[i] >= start && mRDateTimes[i] <= end ) {
782 times += mRDateTimes[i];
787 TQDateTime qdt( mStartDateTime );
788 for ( i = 0, count = mRDates.count(); i < count; ++i ) {
789 qdt.setDate( mRDates[i] );
790 if ( qdt >= start && qdt <= end ) {
800 if ( ( !mRDates.isEmpty() || !mRDateTimes.isEmpty() ) &&
802 start <= mStartDateTime &&
803 end >= mStartDateTime ) {
804 times += mStartDateTime;
807 qSortUnique( times );
811 int enddt = times.count();
812 for ( i = 0, count = mExDates.count(); i < count && idt < enddt; ++i ) {
813 while ( idt < enddt && times[idt].date() < mExDates[i] ) ++idt;
814 while ( idt < enddt && times[idt].date() == mExDates[i] ) {
815 times.remove( times.at( idt ) );
819 DateTimeList extimes;
820 for ( i = 0, count = mExRules.count(); i < count; ++i ) {
821 extimes += mExRules[i]->timesInInterval( start, end );
823 extimes += mExDateTimes;
824 qSortUnique( extimes );
827 for ( i = 0, count = extimes.count(); i < count; ++i ) {
828 int j = removeSorted( times, extimes[i], st );
839 TQDateTime nextDT = preDateTime;
846 while ( loop < 1000 ) {
866 int i = findGT( mRDateTimes, nextDT, 0 );
868 dates << mRDateTimes[i];
872 for ( i = 0, end = mRDates.count(); i < end; ++i ) {
873 qdt.setDate( mRDates[i] );
874 if ( qdt > nextDT ) {
881 for ( i = 0, end = mRRules.count(); i < end; ++i ) {
882 TQDateTime dt = mRRules[i]->getNextDate( nextDT );
883 if ( dt.isValid() ) {
889 qSortUnique( dates );
890 if ( dates.isEmpty() ) {
893 nextDT = dates.first();
896 if ( !containsSorted( mExDates, nextDT.date() ) &&
897 !containsSorted( mExDateTimes, nextDT ) ) {
899 for ( i = 0, end = mExRules.count(); i < end; ++i ) {
900 allowed = allowed && !( mExRules[i]->recursAt( nextDT ) );
914 TQDateTime prevDT = afterDateTime;
919 while ( loop < 1000 ) {
936 int i = findLT( mRDateTimes, prevDT, 0 );
938 dates << mRDateTimes[i];
942 for ( i = mRDates.count(); --i >= 0; ) {
943 qdt.setDate( mRDates[i] );
944 if ( qdt < prevDT ) {
952 for ( i = 0, end = mRRules.count(); i < end; ++i ) {
953 TQDateTime dt = mRRules[i]->getPreviousDate( prevDT );
954 if ( dt.isValid() ) {
960 qSortUnique( dates );
961 if ( dates.isEmpty() ) {
964 prevDT = dates.last();
967 if ( !containsSorted( mExDates, prevDT.date() ) &&
968 !containsSorted( mExDateTimes, prevDT ) ) {
970 for ( i = 0, end = mExRules.count(); i < end; ++i ) {
971 allowed = allowed && !( mExRules[i]->recursAt( prevDT ) );
994 if ( mRecurReadOnly || !rrule )
return;
996 mRRules.append( rrule );
1003 if (mRecurReadOnly)
return;
1004 mRRules.remove( rrule );
1016 if ( mRecurReadOnly || !exrule )
return;
1018 mExRules.append( exrule );
1025 if (mRecurReadOnly)
return;
1026 mExRules.remove( exrule );
1032 DateTimeList Recurrence::rDateTimes()
const
1037 void Recurrence::setRDateTimes(
const DateTimeList &rdates )
1039 if ( mRecurReadOnly )
return;
1040 mRDateTimes = rdates;
1041 qSortUnique( mRDateTimes );
1045 void Recurrence::addRDateTime(
const TQDateTime &rdate )
1047 if ( mRecurReadOnly )
return;
1048 mRDateTimes.append( rdate );
1049 qSortUnique( mRDateTimes );
1054 DateList Recurrence::rDates()
const
1059 void Recurrence::setRDates(
const DateList &rdates )
1061 if ( mRecurReadOnly )
return;
1063 qSortUnique( mRDates );
1067 void Recurrence::addRDate(
const TQDate &rdate )
1069 if ( mRecurReadOnly )
return;
1070 mRDates.append( rdate );
1071 qSortUnique( mRDates );
1076 DateTimeList Recurrence::exDateTimes()
const
1078 return mExDateTimes;
1081 void Recurrence::setExDateTimes(
const DateTimeList &exdates )
1083 if ( mRecurReadOnly )
return;
1084 mExDateTimes = exdates;
1085 qSortUnique( mExDateTimes );
1088 void Recurrence::addExDateTime(
const TQDateTime &exdate )
1090 if ( mRecurReadOnly )
return;
1091 mExDateTimes.append( exdate );
1092 qSortUnique( mExDateTimes );
1097 DateList Recurrence::exDates()
const
1102 void Recurrence::setExDates(
const DateList &exdates )
1104 if ( mRecurReadOnly )
return;
1106 qSortUnique( mExDates );
1110 void Recurrence::addExDate(
const TQDate &exdate )
1112 if ( mRecurReadOnly )
return;
1113 mExDates.append( exdate );
1114 qSortUnique( mExDates );
1128 kdDebug(5800) <<
"Recurrence::dump():" << endl;
1130 kdDebug(5800) <<
" -) " << mRRules.count() <<
" RRULEs: " << endl;
1131 for ( RecurrenceRule::List::ConstIterator rr = mRRules.begin(); rr != mRRules.end(); ++rr ) {
1132 kdDebug(5800) <<
" -) RecurrenceRule : " << endl;
1135 kdDebug(5800) <<
" -) " << mExRules.count() <<
" EXRULEs: " << endl;
1136 for ( RecurrenceRule::List::ConstIterator rr = mExRules.begin(); rr != mExRules.end(); ++rr ) {
1137 kdDebug(5800) <<
" -) ExceptionRule : " << endl;
1142 kdDebug(5800) << endl <<
" -) " << mRDates.count() <<
" Recurrence Dates: " << endl;
1143 for ( DateList::ConstIterator it = mRDates.begin(); it != mRDates.end(); ++it ) {
1144 kdDebug(5800) <<
" " << (*it) << endl;
1146 kdDebug(5800) << endl <<
" -) " << mRDateTimes.count() <<
" Recurrence Date/Times: " << endl;
1147 for ( DateTimeList::ConstIterator it = mRDateTimes.begin(); it != mRDateTimes.end(); ++it ) {
1148 kdDebug(5800) <<
" " << (*it) << endl;
1150 kdDebug(5800) << endl <<
" -) " << mExDates.count() <<
" Exceptions Dates: " << endl;
1151 for ( DateList::ConstIterator it = mExDates.begin(); it != mExDates.end(); ++it ) {
1152 kdDebug(5800) <<
" " << (*it) << endl;
1154 kdDebug(5800) << endl <<
" -) " << mExDateTimes.count() <<
" Exception Date/Times: " << endl;
1155 for ( DateTimeList::ConstIterator it = mExDateTimes.begin(); it != mExDateTimes.end(); ++it ) {
1156 kdDebug(5800) <<
" " << (*it) << endl;