/* This file is part of libkcal. Copyright (c) 2001-2003 Cornelius Schumacher This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include "todo.h" using namespace KCal; Todo::Todo() { mHasDueDate = false; mHasStartDate = false; mHasCompletedDate = false; mPercentComplete = 0; } Todo::Todo(const Todo &t) : Incidence(t) { mDtDue = t.mDtDue; mHasDueDate = t.mHasDueDate; mHasStartDate = t.mHasStartDate; mCompleted = t.mCompleted; mHasCompletedDate = t.mHasCompletedDate; mPercentComplete = t.mPercentComplete; mDtRecurrence = t.mDtRecurrence; } Todo::~Todo() { } Todo *Todo::clone() { return new Todo( *this ); } Todo& Todo::operator=( const Todo &t ) { Incidence::operator=( t ); mDtDue = t.mDtDue; mHasDueDate = t.mHasDueDate; mHasStartDate = t.mHasStartDate; mCompleted = t.mCompleted; mHasCompletedDate = t.mHasCompletedDate; mPercentComplete = t.mPercentComplete; mDtRecurrence = t.mDtRecurrence; return *this; } bool Todo::operator==( const Todo& t2 ) const { return static_cast(*this) == static_cast(t2) && dtDue() == t2.dtDue() && hasDueDate() == t2.hasDueDate() && hasStartDate() == t2.hasStartDate() && completed() == t2.completed() && hasCompletedDate() == t2.hasCompletedDate() && percentComplete() == t2.percentComplete(); } void Todo::setDtDue(const TQDateTime &dtDue, bool first ) { //int diffsecs = mDtDue.secsTo(dtDue); /*if (mReadOnly) return; const Alarm::List& alarms = alarms(); for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) { if (alarm->enabled()) { alarm->setTime(alarm->time().addSecs(diffsecs)); } }*/ if( doesRecur() && !first ) { mDtRecurrence = dtDue; } else { mDtDue = dtDue; // TODO: This doesn't seem right... recurrence()->setStartDateTime( dtDue ); recurrence()->setFloats( doesFloat() ); } if ( doesRecur() && dtDue < recurrence()->startDateTime() ) setDtStart( dtDue ); //kdDebug(5800) << "setDtDue says date is " << mDtDue.toString() << endl; /*const Alarm::List& alarms = alarms(); for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) alarm->setAlarmStart(mDtDue);*/ updated(); } TQDateTime Todo::dtDue( bool first ) const { if ( doesRecur() && !first && mDtRecurrence.isValid() ) { return mDtRecurrence; } else if ( hasDueDate() ) { return mDtDue; } else { return TQDateTime(); } } TQString Todo::dtDueTimeStr() const { return TDEGlobal::locale()->formatTime( dtDue(!doesRecur()).time() ); } TQString Todo::dtDueDateStr(bool shortfmt) const { return TDEGlobal::locale()->formatDate(dtDue( !doesRecur() ).date(),shortfmt); } // TODO: Add shortfmt param!!! TQString Todo::dtDueStr() const { return TDEGlobal::locale()->formatDateTime( dtDue( !doesRecur() ) ); } bool Todo::hasDueDate() const { return mHasDueDate; } void Todo::setHasDueDate(bool f) { if (mReadOnly) return; mHasDueDate = f; updated(); } bool Todo::hasStartDate() const { return mHasStartDate; } void Todo::setHasStartDate(bool f) { if (mReadOnly) return; if ( doesRecur() && !f ) { if ( !comments().grep("NoStartDate").count() ) addComment("NoStartDate"); //TODO: --> custom flag? } else { TQString s("NoStartDate"); removeComment(s); } mHasStartDate = f; updated(); } TQDateTime Todo::dtStart( bool first ) const { if ( doesRecur() && !first ) { TQDateTime dt = mDtRecurrence.addDays( dtDue( true ).daysTo( IncidenceBase::dtStart() ) ); // We want the dtStart's time, not dtDue's dt.setTime( IncidenceBase::dtStart().time() ); return dt; } else if ( hasStartDate() ) { return IncidenceBase::dtStart(); } else { return TQDateTime(); } } void Todo::setDtStart( const TQDateTime &dtStart ) { // TODO: This doesn't seem right (rfc 2445/6 says, recurrence is calculated from the dtstart...) if ( doesRecur() ) { recurrence()->setStartDateTime( mDtDue ); recurrence()->setFloats( doesFloat() ); } IncidenceBase::setDtStart( dtStart ); } TQString Todo::dtStartTimeStr( bool first ) const { return TDEGlobal::locale()->formatTime(dtStart(first).time()); } TQString Todo::dtStartDateStr(bool shortfmt, bool first) const { return TDEGlobal::locale()->formatDate(dtStart(first).date(),shortfmt); } TQString Todo::dtStartStr(bool first) const { return TDEGlobal::locale()->formatDateTime(dtStart(first)); } bool Todo::isCompleted() const { if (mPercentComplete == 100) return true; else return false; } void Todo::setCompleted(bool completed) { if (completed) mPercentComplete = 100; else { mPercentComplete = 0; mHasCompletedDate = false; mCompleted = TQDateTime(); } updated(); } TQDateTime Todo::completed() const { if ( hasCompletedDate() ) return mCompleted; else return TQDateTime(); } TQString Todo::completedStr() const { return TDEGlobal::locale()->formatDateTime(mCompleted); } void Todo::setCompleted(const TQDateTime &completed) { if( !recurTodo() ) { mHasCompletedDate = true; mPercentComplete = 100; mCompleted = completed; } updated(); } bool Todo::hasCompletedDate() const { return mHasCompletedDate; } int Todo::percentComplete() const { return mPercentComplete; } void Todo::setPercentComplete( int v ) { mPercentComplete = v; if ( v != 100 ) { mHasCompletedDate = false; mCompleted = TQDateTime(); } updated(); } void Todo::setDtRecurrence( const TQDateTime &dt ) { mDtRecurrence = dt; } TQDateTime Todo::dtRecurrence() const { return mDtRecurrence.isValid() ? mDtRecurrence : mDtDue; } bool Todo::recursOn( const TQDate &date ) const { TQDate today = TQDate::currentDate(); return ( Incidence::recursOn(date) && !( date < today && mDtRecurrence.date() < today && mDtRecurrence > recurrence()->startDateTime() ) ); } bool Todo::recurTodo() { if ( doesRecur() ) { Recurrence *r = recurrence(); TQDateTime endDateTime = r->endDateTime(); TQDateTime nextDate = r->getNextDateTime( dtDue() ); if ( ( r->duration() == -1 || ( nextDate.isValid() && endDateTime.isValid() && nextDate <= endDateTime ) ) ) { while ( !recursAt( nextDate ) || nextDate <= TQDateTime::currentDateTime() ) { if ( !nextDate.isValid() || ( nextDate > endDateTime && r->duration() != -1 ) ) { return false; } nextDate = r->getNextDateTime( nextDate ); } setDtDue( nextDate ); setCompleted( false ); setRevision( revision() + 1 ); return true; } } return false; } bool Todo::isOverdue() const { bool inPast = doesFloat() ? dtDue().date() < TQDate::currentDate() : dtDue() < TQDateTime::currentDateTime(); return ( inPast && !isCompleted() ); }