You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/libkcal/todo.cpp

334 lines
7.5 KiB

/*
This file is part of libkcal.
Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org>
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 <kglobal.h>
#include <klocale.h>
#include <kdebug.h>
#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<const Incidence&>(*this) == static_cast<const Incidence&>(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 KGlobal::locale()->formatTime( dtDue(!doesRecur()).time() );
}
TQString Todo::dtDueDateStr(bool shortfmt) const
{
return KGlobal::locale()->formatDate(dtDue( !doesRecur() ).date(),shortfmt);
}
// TODO: Add shortfmt param!!!
TQString Todo::dtDueStr() const
{
return KGlobal::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 KGlobal::locale()->formatTime(dtStart(first).time());
}
TQString Todo::dtStartDateStr(bool shortfmt, bool first) const
{
return KGlobal::locale()->formatDate(dtStart(first).date(),shortfmt);
}
TQString Todo::dtStartStr(bool first) const
{
return KGlobal::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 KGlobal::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::tqcurrentDate();
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::tqcurrentDateTime() ) {
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::tqcurrentDate()
: dtDue() < TQDateTime::tqcurrentDateTime();
return ( inPast && !isCompleted() );
}