libkcal
todo.cpp
00001 /* 00002 This file is part of libkcal. 00003 00004 Copyright (c) 2001-2003 Cornelius Schumacher <schumacher@kde.org> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #include <kglobal.h> 00023 #include <klocale.h> 00024 #include <kdebug.h> 00025 00026 #include "todo.h" 00027 00028 using namespace KCal; 00029 00030 Todo::Todo() 00031 { 00032 mHasDueDate = false; 00033 mHasStartDate = false; 00034 00035 mHasCompletedDate = false; 00036 mPercentComplete = 0; 00037 } 00038 00039 Todo::Todo(const Todo &t) : Incidence(t) 00040 { 00041 mDtDue = t.mDtDue; 00042 mHasDueDate = t.mHasDueDate; 00043 mHasStartDate = t.mHasStartDate; 00044 mCompleted = t.mCompleted; 00045 mHasCompletedDate = t.mHasCompletedDate; 00046 mPercentComplete = t.mPercentComplete; 00047 mDtRecurrence = t.mDtRecurrence; 00048 } 00049 00050 Todo::~Todo() 00051 { 00052 } 00053 00054 Todo *Todo::clone() 00055 { 00056 return new Todo( *this ); 00057 } 00058 00059 00060 bool Todo::operator==( const Todo& t2 ) const 00061 { 00062 return 00063 static_cast<const Incidence&>(*this) == static_cast<const Incidence&>(t2) && 00064 dtDue() == t2.dtDue() && 00065 hasDueDate() == t2.hasDueDate() && 00066 hasStartDate() == t2.hasStartDate() && 00067 completed() == t2.completed() && 00068 hasCompletedDate() == t2.hasCompletedDate() && 00069 percentComplete() == t2.percentComplete(); 00070 } 00071 00072 void Todo::setDtDue(const QDateTime &dtDue, bool first ) 00073 { 00074 //int diffsecs = mDtDue.secsTo(dtDue); 00075 00076 /*if (mReadOnly) return; 00077 const Alarm::List& alarms = alarms(); 00078 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) { 00079 if (alarm->enabled()) { 00080 alarm->setTime(alarm->time().addSecs(diffsecs)); 00081 } 00082 }*/ 00083 if( doesRecur() && !first ) { 00084 mDtRecurrence = dtDue; 00085 } else { 00086 mDtDue = dtDue; 00087 // TODO: This doesn't seem right... 00088 recurrence()->setStartDateTime( dtDue ); 00089 recurrence()->setFloats( doesFloat() ); 00090 } 00091 00092 if ( doesRecur() && dtDue < recurrence()->startDateTime() ) 00093 setDtStart( dtDue ); 00094 00095 //kdDebug(5800) << "setDtDue says date is " << mDtDue.toString() << endl; 00096 00097 /*const Alarm::List& alarms = alarms(); 00098 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) 00099 alarm->setAlarmStart(mDtDue);*/ 00100 00101 updated(); 00102 } 00103 00104 QDateTime Todo::dtDue( bool first ) const 00105 { 00106 if ( doesRecur() && !first && mDtRecurrence.isValid() ) 00107 return mDtRecurrence; 00108 00109 return mDtDue; 00110 } 00111 00112 QString Todo::dtDueTimeStr() const 00113 { 00114 return KGlobal::locale()->formatTime( dtDue(!doesRecur()).time() ); 00115 } 00116 00117 QString Todo::dtDueDateStr(bool shortfmt) const 00118 { 00119 return KGlobal::locale()->formatDate(dtDue( !doesRecur() ).date(),shortfmt); 00120 } 00121 00122 QString Todo::dtDueStr() const 00123 { 00124 return KGlobal::locale()->formatDateTime( dtDue( !doesRecur() ) ); 00125 } 00126 00127 bool Todo::hasDueDate() const 00128 { 00129 return mHasDueDate; 00130 } 00131 00132 void Todo::setHasDueDate(bool f) 00133 { 00134 if (mReadOnly) return; 00135 mHasDueDate = f; 00136 updated(); 00137 } 00138 00139 00140 bool Todo::hasStartDate() const 00141 { 00142 return mHasStartDate; 00143 } 00144 00145 void Todo::setHasStartDate(bool f) 00146 { 00147 if (mReadOnly) return; 00148 00149 if ( doesRecur() && !f ) { 00150 if ( !comments().grep("NoStartDate").count() ) 00151 addComment("NoStartDate"); //TODO: --> custom flag? 00152 } else { 00153 QString s("NoStartDate"); 00154 removeComment(s); 00155 } 00156 mHasStartDate = f; 00157 updated(); 00158 } 00159 00160 QDateTime Todo::dtStart( bool first ) const 00161 { 00162 if ( doesRecur() && !first ) 00163 return mDtRecurrence.addDays( dtDue( true ).daysTo( IncidenceBase::dtStart() ) ); 00164 else 00165 return IncidenceBase::dtStart(); 00166 } 00167 00168 void Todo::setDtStart( const QDateTime &dtStart ) 00169 { 00170 // TODO: This doesn't seem right (rfc 2445/6 says, recurrence is calculated from the dtstart...) 00171 if ( doesRecur() ) { 00172 recurrence()->setStartDateTime( mDtDue ); 00173 recurrence()->setFloats( doesFloat() ); 00174 } 00175 IncidenceBase::setDtStart( dtStart ); 00176 } 00177 00178 QString Todo::dtStartTimeStr( bool first ) const 00179 { 00180 return KGlobal::locale()->formatTime(dtStart(first).time()); 00181 } 00182 00183 QString Todo::dtStartDateStr(bool shortfmt, bool first) const 00184 { 00185 return KGlobal::locale()->formatDate(dtStart(first).date(),shortfmt); 00186 } 00187 00188 QString Todo::dtStartStr(bool first) const 00189 { 00190 return KGlobal::locale()->formatDateTime(dtStart(first)); 00191 } 00192 00193 bool Todo::isCompleted() const 00194 { 00195 if (mPercentComplete == 100) return true; 00196 else return false; 00197 } 00198 00199 void Todo::setCompleted(bool completed) 00200 { 00201 if (completed) 00202 mPercentComplete = 100; 00203 else { 00204 mPercentComplete = 0; 00205 mHasCompletedDate = false; 00206 mCompleted = QDateTime(); 00207 } 00208 updated(); 00209 } 00210 00211 QDateTime Todo::completed() const 00212 { 00213 if ( hasCompletedDate() ) 00214 return mCompleted; 00215 else 00216 return QDateTime(); 00217 } 00218 00219 QString Todo::completedStr() const 00220 { 00221 return KGlobal::locale()->formatDateTime(mCompleted); 00222 } 00223 00224 void Todo::setCompleted(const QDateTime &completed) 00225 { 00226 if( !recurTodo() ) { 00227 mHasCompletedDate = true; 00228 mPercentComplete = 100; 00229 mCompleted = completed; 00230 } 00231 updated(); 00232 } 00233 00234 bool Todo::hasCompletedDate() const 00235 { 00236 return mHasCompletedDate; 00237 } 00238 00239 int Todo::percentComplete() const 00240 { 00241 return mPercentComplete; 00242 } 00243 00244 void Todo::setPercentComplete(int v) 00245 { 00246 mPercentComplete = v; 00247 if ( v != 100 ) mHasCompletedDate = false; 00248 updated(); 00249 } 00250 00251 void Todo::setDtRecurrence( const QDateTime &dt ) 00252 { 00253 mDtRecurrence = dt; 00254 } 00255 00256 QDateTime Todo::dtRecurrence() const 00257 { 00258 return mDtRecurrence.isValid() ? mDtRecurrence : mDtDue; 00259 } 00260 00261 bool Todo::recursOn( const QDate &date ) const 00262 { 00263 QDate today = QDate::currentDate(); 00264 return ( Incidence::recursOn(date) && 00265 !( date < today && mDtRecurrence.date() < today && 00266 mDtRecurrence > recurrence()->startDateTime() ) ); 00267 } 00268 00269 bool Todo::recurTodo() 00270 { 00271 if ( doesRecur() ) { 00272 Recurrence *r = recurrence(); 00273 QDateTime endDateTime = r->endDateTime(); 00274 QDateTime nextDate = r->getNextDateTime( dtDue() ); 00275 00276 if ( ( r->duration() == -1 || ( nextDate.isValid() && endDateTime.isValid() 00277 && nextDate <= endDateTime ) ) ) { 00278 setDtDue( nextDate ); 00279 while ( !recursAt( dtDue() ) || dtDue() <= QDateTime::currentDateTime() ) { 00280 setDtDue( r->getNextDateTime( dtDue() ) ); 00281 } 00282 00283 setCompleted( false ); 00284 setRevision( revision() + 1 ); 00285 00286 return true; 00287 } 00288 } 00289 00290 return false; 00291 } 00292 00293 bool Todo::isOverdue() const 00294 { 00295 bool inPast = doesFloat() ? mDtDue.date() < QDate::currentDate() 00296 : mDtDue < QDateTime::currentDateTime(); 00297 return ( inPast && !isCompleted() ); 00298 }