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 Todo& Todo::operator=( const Todo &t ) 00061 { 00062 Incidence::operator=( t ); 00063 mDtDue = t.mDtDue; 00064 mHasDueDate = t.mHasDueDate; 00065 mHasStartDate = t.mHasStartDate; 00066 mCompleted = t.mCompleted; 00067 mHasCompletedDate = t.mHasCompletedDate; 00068 mPercentComplete = t.mPercentComplete; 00069 mDtRecurrence = t.mDtRecurrence; 00070 return *this; 00071 } 00072 00073 bool Todo::operator==( const Todo& t2 ) const 00074 { 00075 return 00076 static_cast<const Incidence&>(*this) == static_cast<const Incidence&>(t2) && 00077 dtDue() == t2.dtDue() && 00078 hasDueDate() == t2.hasDueDate() && 00079 hasStartDate() == t2.hasStartDate() && 00080 completed() == t2.completed() && 00081 hasCompletedDate() == t2.hasCompletedDate() && 00082 percentComplete() == t2.percentComplete(); 00083 } 00084 00085 void Todo::setDtDue(const QDateTime &dtDue, bool first ) 00086 { 00087 //int diffsecs = mDtDue.secsTo(dtDue); 00088 00089 /*if (mReadOnly) return; 00090 const Alarm::List& alarms = alarms(); 00091 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) { 00092 if (alarm->enabled()) { 00093 alarm->setTime(alarm->time().addSecs(diffsecs)); 00094 } 00095 }*/ 00096 if( doesRecur() && !first ) { 00097 mDtRecurrence = dtDue; 00098 } else { 00099 mDtDue = dtDue; 00100 // TODO: This doesn't seem right... 00101 recurrence()->setStartDateTime( dtDue ); 00102 recurrence()->setFloats( doesFloat() ); 00103 } 00104 00105 if ( doesRecur() && dtDue < recurrence()->startDateTime() ) 00106 setDtStart( dtDue ); 00107 00108 //kdDebug(5800) << "setDtDue says date is " << mDtDue.toString() << endl; 00109 00110 /*const Alarm::List& alarms = alarms(); 00111 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) 00112 alarm->setAlarmStart(mDtDue);*/ 00113 00114 updated(); 00115 } 00116 00117 QDateTime Todo::dtDue( bool first ) const 00118 { 00119 if ( doesRecur() && !first && mDtRecurrence.isValid() ) { 00120 return mDtRecurrence; 00121 } else if ( hasDueDate() ) { 00122 return mDtDue; 00123 } else { 00124 return QDateTime(); 00125 } 00126 } 00127 00128 QString Todo::dtDueTimeStr() const 00129 { 00130 return KGlobal::locale()->formatTime( dtDue(!doesRecur()).time() ); 00131 } 00132 00133 QString Todo::dtDueDateStr(bool shortfmt) const 00134 { 00135 return KGlobal::locale()->formatDate(dtDue( !doesRecur() ).date(),shortfmt); 00136 } 00137 00138 // TODO: Add shortfmt param!!! 00139 QString Todo::dtDueStr() const 00140 { 00141 return KGlobal::locale()->formatDateTime( dtDue( !doesRecur() ) ); 00142 } 00143 00144 bool Todo::hasDueDate() const 00145 { 00146 return mHasDueDate; 00147 } 00148 00149 void Todo::setHasDueDate(bool f) 00150 { 00151 if (mReadOnly) return; 00152 mHasDueDate = f; 00153 updated(); 00154 } 00155 00156 00157 bool Todo::hasStartDate() const 00158 { 00159 return mHasStartDate; 00160 } 00161 00162 void Todo::setHasStartDate(bool f) 00163 { 00164 if (mReadOnly) return; 00165 00166 if ( doesRecur() && !f ) { 00167 if ( !comments().grep("NoStartDate").count() ) 00168 addComment("NoStartDate"); //TODO: --> custom flag? 00169 } else { 00170 QString s("NoStartDate"); 00171 removeComment(s); 00172 } 00173 mHasStartDate = f; 00174 updated(); 00175 } 00176 00177 QDateTime Todo::dtStart( bool first ) const 00178 { 00179 if ( doesRecur() && !first ) { 00180 QDateTime dt = mDtRecurrence.addDays( dtDue( true ).daysTo( IncidenceBase::dtStart() ) ); 00181 00182 // We want the dtStart's time, not dtDue's 00183 dt.setTime( IncidenceBase::dtStart().time() ); 00184 return dt; 00185 } else if ( hasStartDate() ) { 00186 return IncidenceBase::dtStart(); 00187 } else { 00188 return QDateTime(); 00189 } 00190 } 00191 00192 void Todo::setDtStart( const QDateTime &dtStart ) 00193 { 00194 // TODO: This doesn't seem right (rfc 2445/6 says, recurrence is calculated from the dtstart...) 00195 if ( doesRecur() ) { 00196 recurrence()->setStartDateTime( mDtDue ); 00197 recurrence()->setFloats( doesFloat() ); 00198 } 00199 IncidenceBase::setDtStart( dtStart ); 00200 } 00201 00202 QString Todo::dtStartTimeStr( bool first ) const 00203 { 00204 return KGlobal::locale()->formatTime(dtStart(first).time()); 00205 } 00206 00207 QString Todo::dtStartDateStr(bool shortfmt, bool first) const 00208 { 00209 return KGlobal::locale()->formatDate(dtStart(first).date(),shortfmt); 00210 } 00211 00212 QString Todo::dtStartStr(bool first) const 00213 { 00214 return KGlobal::locale()->formatDateTime(dtStart(first)); 00215 } 00216 00217 bool Todo::isCompleted() const 00218 { 00219 if (mPercentComplete == 100) return true; 00220 else return false; 00221 } 00222 00223 void Todo::setCompleted(bool completed) 00224 { 00225 if (completed) 00226 mPercentComplete = 100; 00227 else { 00228 mPercentComplete = 0; 00229 mHasCompletedDate = false; 00230 mCompleted = QDateTime(); 00231 } 00232 updated(); 00233 } 00234 00235 QDateTime Todo::completed() const 00236 { 00237 if ( hasCompletedDate() ) 00238 return mCompleted; 00239 else 00240 return QDateTime(); 00241 } 00242 00243 QString Todo::completedStr() const 00244 { 00245 return KGlobal::locale()->formatDateTime(mCompleted); 00246 } 00247 00248 void Todo::setCompleted(const QDateTime &completed) 00249 { 00250 if( !recurTodo() ) { 00251 mHasCompletedDate = true; 00252 mPercentComplete = 100; 00253 mCompleted = completed; 00254 } 00255 updated(); 00256 } 00257 00258 bool Todo::hasCompletedDate() const 00259 { 00260 return mHasCompletedDate; 00261 } 00262 00263 int Todo::percentComplete() const 00264 { 00265 return mPercentComplete; 00266 } 00267 00268 void Todo::setPercentComplete(int v) 00269 { 00270 mPercentComplete = v; 00271 if ( v != 100 ) mHasCompletedDate = false; 00272 updated(); 00273 } 00274 00275 void Todo::setDtRecurrence( const QDateTime &dt ) 00276 { 00277 mDtRecurrence = dt; 00278 } 00279 00280 QDateTime Todo::dtRecurrence() const 00281 { 00282 return mDtRecurrence.isValid() ? mDtRecurrence : mDtDue; 00283 } 00284 00285 bool Todo::recursOn( const QDate &date ) const 00286 { 00287 QDate today = QDate::currentDate(); 00288 return ( Incidence::recursOn(date) && 00289 !( date < today && mDtRecurrence.date() < today && 00290 mDtRecurrence > recurrence()->startDateTime() ) ); 00291 } 00292 00293 bool Todo::recurTodo() 00294 { 00295 if ( doesRecur() ) { 00296 Recurrence *r = recurrence(); 00297 QDateTime endDateTime = r->endDateTime(); 00298 QDateTime nextDate = r->getNextDateTime( dtDue() ); 00299 00300 if ( ( r->duration() == -1 || ( nextDate.isValid() && endDateTime.isValid() 00301 && nextDate <= endDateTime ) ) ) { 00302 00303 while ( !recursAt( nextDate ) || nextDate <= QDateTime::currentDateTime() ) { 00304 00305 if ( !nextDate.isValid() || 00306 ( nextDate > endDateTime && r->duration() != -1 ) ) { 00307 return false; 00308 } 00309 00310 nextDate = r->getNextDateTime( nextDate ); 00311 } 00312 00313 setDtDue( nextDate ); 00314 setCompleted( false ); 00315 setRevision( revision() + 1 ); 00316 00317 return true; 00318 } 00319 } 00320 00321 return false; 00322 } 00323 00324 bool Todo::isOverdue() const 00325 { 00326 bool inPast = doesFloat() ? dtDue().date() < QDate::currentDate() 00327 : dtDue() < QDateTime::currentDateTime(); 00328 return ( inPast && !isCompleted() ); 00329 }