39 using namespace KCalCore;
46 class KCalCore::Todo::Private
50 : mPercentComplete( 0 ),
52 mHasStartDate( false ),
53 mHasCompletedDate( false )
55 Private(
const KCalCore::Todo::Private &other )
58 void init(
const KCalCore::Todo::Private &other );
62 KDateTime mDtRecurrence;
67 bool mHasCompletedDate;
72 bool recurTodo(
Todo *todo );
75 void KCalCore::Todo::Private::init(
const KCalCore::Todo::Private &other )
77 mDtDue = other.mDtDue;
78 mDtRecurrence = other.mDtRecurrence;
79 mCompleted = other.mCompleted;
80 mPercentComplete = other.mPercentComplete;
81 mHasDueDate = other.mHasDueDate;
82 mHasStartDate = other.mHasStartDate;
83 mHasCompletedDate = other.mHasCompletedDate;
89 : d( new KCalCore::
Todo::Private )
95 d( new KCalCore::
Todo::Private( *other.d ) )
106 return new Todo( *
this );
111 if ( &other !=
this ) {
113 const Todo *t =
static_cast<const Todo*
>( &other );
114 d->init( *( t->d ) );
125 const Todo *t =
static_cast<const Todo*
>( &todo );
127 ( !
dtDue().isValid() && !t->
dtDue().isValid() ) ) &&
159 d->mHasDueDate = dtDue.isValid();
161 if (
recurs() && !first ) {
162 d->mDtRecurrence =
dtDue;
186 if (
recurs() && !first && d->mDtRecurrence.isValid() ) {
187 return d->mDtRecurrence;
195 return d->mHasDueDate;
211 return d->mHasStartDate;
222 if ( !
comments().filter(
"NoStartDate" ).count() ) {
226 QString s(
"NoStartDate" );
229 d->mHasStartDate = f;
244 if (
recurs() && !first ) {
257 d->mHasStartDate = dtStart.isValid();
268 return d->mPercentComplete == 100;
275 d->mPercentComplete = 100;
277 d->mPercentComplete = 0;
278 d->mHasCompletedDate =
false;
279 d->mCompleted = KDateTime();
288 return d->mCompleted;
297 if ( !d->recurTodo(
this ) ) {
298 d->mHasCompletedDate =
true;
299 d->mPercentComplete = 100;
300 d->mCompleted = completed.toUtc();
308 return d->mHasCompletedDate;
313 return d->mPercentComplete;
318 if ( percent > 100 ) {
320 }
else if ( percent < 0 ) {
325 d->mPercentComplete = percent;
326 if ( percent != 100 ) {
327 d->mHasCompletedDate =
false;
339 if ( d->mPercentComplete > 0 ) {
343 if ( d->mHasStartDate && d->mHasDueDate ) {
345 QDate currDate = QDate::currentDate();
346 if (
dtStart( first ).date() <= currDate && currDate <
dtDue( first ).date() ) {
350 KDateTime currDate = KDateTime::currentUtcDateTime();
351 if (
dtStart( first ) <= currDate && currDate <
dtDue( first ) ) {
371 if ( d->mPercentComplete > 0 ) {
375 if ( !d->mHasStartDate ) {
380 if (
dtStart( first ).date() >= QDate::currentDate() ) {
384 if (
dtStart( first ) >= KDateTime::currentUtcDateTime() ) {
392 const KDateTime::Spec &newSpec )
395 d->mDtDue = d->mDtDue.toTimeSpec( oldSpec );
396 d->mDtDue.setTimeSpec( newSpec );
398 d->mDtRecurrence = d->mDtRecurrence.toTimeSpec( oldSpec );
399 d->mDtRecurrence.setTimeSpec( newSpec );
401 if ( d->mHasCompletedDate ) {
402 d->mCompleted = d->mCompleted.toTimeSpec( oldSpec );
403 d->mCompleted.setTimeSpec( newSpec );
409 d->mDtRecurrence = dt;
415 return d->mDtRecurrence.isValid() ? d->mDtRecurrence : d->mDtDue;
420 QDate today = QDate::currentDate();
423 !( date < today && d->mDtRecurrence.date() < today &&
429 if ( !
dtDue().isValid() ) {
433 const bool inPast =
allDay() ?
434 dtDue().date() < QDate::currentDate() :
435 dtDue() < KDateTime::currentUtcDateTime();
450 bool Todo::Private::recurTodo(
Todo *todo )
452 if ( todo && todo->
recurs() ) {
454 const KDateTime recurrenceEndDateTime = r->
endDateTime();
458 ( nextOccurrenceDateTime.isValid() && recurrenceEndDateTime.isValid() &&
459 nextOccurrenceDateTime <= recurrenceEndDateTime ) ) ) {
461 const KDateTime rightNow =
462 KDateTime::currentUtcDateTime().toTimeSpec( nextOccurrenceDateTime.timeSpec() );
463 const bool isDateOnly = todo->
allDay();
471 while ( !todo->
recursAt( nextOccurrenceDateTime ) ||
472 ( !isDateOnly && nextOccurrenceDateTime <= rightNow ) ||
473 ( isDateOnly && nextOccurrenceDateTime.date() < rightNow.date() ) ) {
475 if ( !nextOccurrenceDateTime.isValid() ||
476 ( nextOccurrenceDateTime > recurrenceEndDateTime && r->
duration() != -1 ) ) {
482 todo->
setDtDue( nextOccurrenceDateTime );
496 return v.
visit( incidence.staticCast<
Todo>() );
516 case RoleEndRecurrenceBase:
522 if (
alarms().isEmpty() ) {
528 }
else if ( alarm->hasEndOffset() &&
hasDueDate() ) {
552 kDebug() <<
"Unhandled role" << role;
570 return QLatin1String(
"application/x-vnd.akonadi.calendar.todo" );
577 if (
recurs() && occurrenceDT.isDateOnly() ) {
578 occurrenceDT.setTime( QTime( 0, 0 ) );
581 const bool usesCompletedTaskPixmap =
isCompleted() ||
582 (
recurs() && occurrenceDT.isValid() &&
583 occurrenceDT <
dtDue(
false ) );
585 if ( usesCompletedTaskPixmap ) {
586 return QLatin1String(
"task-complete" );
588 return QLatin1String(
"view-calendar-tasks" );