summaryrefslogtreecommitdiffstats
path: root/libkcal/calendarlocal.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libkcal/calendarlocal.cpp')
-rw-r--r--libkcal/calendarlocal.cpp145
1 files changed, 107 insertions, 38 deletions
diff --git a/libkcal/calendarlocal.cpp b/libkcal/calendarlocal.cpp
index 27b27e0e2..2f2d7739b 100644
--- a/libkcal/calendarlocal.cpp
+++ b/libkcal/calendarlocal.cpp
@@ -327,7 +327,12 @@ Alarm::List CalendarLocal::alarms( const TQDateTime &from, const TQDateTime &to
Todo::List::ConstIterator it2;
for( it2 = mTodoList.begin(); it2 != mTodoList.end(); ++it2 ) {
- if (! (*it2)->isCompleted() ) appendAlarms( alarms, *it2, from, to );
+ Todo *t = *it2;
+ if ( t->isCompleted() ) {
+ continue;
+ }
+ if ( t->doesRecur() ) appendRecurringAlarms( alarms, t, from, to );
+ else appendAlarms( alarms, t, from, to );
}
return alarms;
@@ -340,13 +345,14 @@ void CalendarLocal::appendAlarms( Alarm::List &alarms, Incidence *incidence,
Alarm::List::ConstIterator it;
for( it = incidence->alarms().begin(); it != incidence->alarms().end();
++it ) {
- if ( (*it)->enabled() ) {
- TQDateTime dt = (*it)->nextRepetition(preTime);
+ Alarm *alarm = *it;
+ if ( alarm->enabled() ) {
+ TQDateTime dt = alarm->nextRepetition( preTime );
if ( dt.isValid() && dt <= to ) {
kdDebug(5800) << "CalendarLocal::appendAlarms() '"
<< incidence->summary() << "': "
<< dt.toString() << endl;
- alarms.append( *it );
+ alarms.append( alarm );
}
}
}
@@ -357,10 +363,14 @@ void CalendarLocal::appendRecurringAlarms( Alarm::List &alarms,
const TQDateTime &from,
const TQDateTime &to )
{
- TQDateTime qdt;
- int endOffset = 0;
+ TQDateTime dt;
+ Duration endOffset( 0 );
bool endOffsetValid = false;
- int period = from.secsTo(to);
+ Duration period( from, to );
+
+ Event *e = static_cast<Event *>( incidence );
+ Todo *t = static_cast<Todo *>( incidence );
+
Alarm::List::ConstIterator it;
for( it = incidence->alarms().begin(); it != incidence->alarms().end();
++it ) {
@@ -368,59 +378,118 @@ void CalendarLocal::appendRecurringAlarms( Alarm::List &alarms,
if ( alarm->enabled() ) {
if ( alarm->hasTime() ) {
// The alarm time is defined as an absolute date/time
- qdt = alarm->nextRepetition( from.addSecs(-1) );
- if ( !qdt.isValid() || qdt > to )
+ dt = alarm->nextRepetition( from.addSecs(-1) );
+ if ( !dt.isValid() || dt > to ) {
continue;
+ }
} else {
- // The alarm time is defined by an offset from the event start or end time.
+ // Alarm time is defined by an offset from the event start or end time.
// Find the offset from the event start time, which is also used as the
// offset from the recurrence time.
- int offset = 0;
+ Duration offset( 0 );
if ( alarm->hasStartOffset() ) {
offset = alarm->startOffset().asSeconds();
} else if ( alarm->hasEndOffset() ) {
+ offset = alarm->endOffset().asSeconds();
if ( !endOffsetValid ) {
- endOffset = incidence->dtStart().secsTo( incidence->dtEnd() );
- endOffsetValid = true;
+ if ( incidence->type() == "Event" ) {
+ endOffset = Duration( e->dtStart(), e->dtEnd() );
+ endOffsetValid = true;
+ } else if ( incidence->type() == "Todo" &&
+ t->hasStartDate() && t->hasDueDate() ) {
+ endOffset = Duration( t->dtStart(), t->dtDue() );
+ endOffsetValid = true;
+ }
}
- offset = alarm->endOffset().asSeconds() + endOffset;
}
- // Adjust the 'from' date/time and find the next recurrence at or after it
- qdt = incidence->recurrence()->getNextDateTime( from.addSecs(-offset - 1) );
- if ( !qdt.isValid()
- || (qdt = qdt.addSecs( offset )) > to ) // remove the adjustment to get the alarm time
+ // Find the incidence's earliest alarm
+ TQDateTime alarmStart;
+ if ( incidence->type() == "Event" ) {
+ alarmStart =
+ offset.end( alarm->hasEndOffset() ? e->dtEnd() : e->dtStart() );
+ } else if ( incidence->type() == "Todo" ) {
+ alarmStart =
+ offset.end( alarm->hasEndOffset() ? t->dtDue() : t->dtStart() );
+ }
+
+ if ( alarmStart.isValid() && alarmStart > to ) {
+ continue;
+ }
+
+ TQDateTime baseStart;
+ if ( incidence->type() == "Event" ) {
+ baseStart = e->dtStart();
+ } else if ( incidence->type() == "Todo" ) {
+ baseStart = t->dtDue();
+ }
+ if ( alarmStart.isValid() && from > alarmStart ) {
+ alarmStart = from; // don't look earlier than the earliest alarm
+ baseStart = (-offset).end( (-endOffset).end( alarmStart ) );
+ }
+
+ // Adjust the 'alarmStart' date/time and find the next recurrence
+ // at or after it. Treat the two offsets separately in case one
+ // is daily and the other not.
+ dt = incidence->recurrence()->getNextDateTime( baseStart.addSecs(-1) );
+ if ( !dt.isValid() ||
+ ( dt = endOffset.end( offset.end( dt ) ) ) > to ) // adjust 'dt' to get the alarm time
{
// The next recurrence is too late.
- if ( !alarm->repeatCount() )
+ if ( !alarm->repeatCount() ) {
continue;
- // The alarm has repetitions, so check whether repetitions of previous
- // recurrences fall within the time period.
+ }
+
+ // The alarm has repetitions, so check whether repetitions of
+ // previous recurrences fall within the time period.
bool found = false;
- qdt = from.addSecs( -offset );
- while ( (qdt = incidence->recurrence()->getPreviousDateTime( qdt )).isValid() ) {
- int toFrom = qdt.secsTo( from ) - offset;
- if ( toFrom > alarm->duration() )
- break; // this recurrence's last repetition is too early, so give up
- // The last repetition of this recurrence is at or after 'from' time.
- // Check if a repetition occurs between 'from' and 'to'.
- int snooze = alarm->snoozeTime() * 60; // in seconds
- if ( period >= snooze
- || toFrom % snooze == 0
- || (toFrom / snooze + 1) * snooze <= toFrom + period ) {
- found = true;
+ Duration alarmDuration = alarm->duration();
+ for ( TQDateTime base = baseStart;
+ ( dt = incidence->recurrence()->getPreviousDateTime( base ) ).isValid();
+ base = dt ) {
+ if ( alarm->duration().end( dt ) < base ) {
+ break; // recurrence's last repetition is too early, so give up
+ }
+
+ // The last repetition of this recurrence is on or after
+ // 'alarmStart' time. Check if a repetition occurs between
+ // 'alarmStart' and 'to'.
+ int snooze = alarm->snoozeTime().value(); // in seconds or days
+ if ( alarm->snoozeTime().isDaily() ) {
+ Duration toFromDuration( dt, base );
+ int toFrom = toFromDuration.asDays();
+ if ( alarm->snoozeTime().end( from ) <= to ||
+ ( toFromDuration.isDaily() && toFrom % snooze == 0 ) ||
+ ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asDays() ) {
+ found = true;
+#ifndef NDEBUG
+ // for debug output
+ dt = offset.end( dt ).addDays( ( ( toFrom - 1 ) / snooze + 1 ) * snooze );
+#endif
+ break;
+ }
+ } else {
+ int toFrom = dt.secsTo( base );
+ if ( period.asSeconds() >= snooze ||
+ toFrom % snooze == 0 ||
+ ( toFrom / snooze + 1 ) * snooze <= toFrom + period.asSeconds() )
+ {
+ found = true;
#ifndef NDEBUG
- qdt = qdt.addSecs( offset + ((toFrom-1) / snooze + 1) * snooze ); // for debug output
+ // for debug output
+ dt = offset.end( dt ).addSecs( ( ( toFrom - 1 ) / snooze + 1 ) * snooze );
#endif
- break;
+ break;
+ }
}
}
- if ( !found )
+ if ( !found ) {
continue;
+ }
}
}
kdDebug(5800) << "CalendarLocal::appendAlarms() '" << incidence->summary()
- << "': " << qdt.toString() << endl;
+ << "': " << dt.toString() << endl;
alarms.append( alarm );
}
}
@@ -485,7 +554,7 @@ Event::List CalendarLocal::rawEventsForDate( const TQDate &qd,
}
}
- return sortEvents( &eventList, sortField, sortDirection );
+ return sortEventsForDate( &eventList, qd, sortField, sortDirection );
}
Event::List CalendarLocal::rawEvents( const TQDate &start, const TQDate &end,