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 // TODO: Add shortfmt param!!! 00123 QString Todo::dtDueStr() const 00124 { 00125 return KGlobal::locale()->formatDateTime( dtDue( !doesRecur() ) ); 00126 } 00127 00128 bool Todo::hasDueDate() const 00129 { 00130 return mHasDueDate; 00131 } 00132 00133 void Todo::setHasDueDate(bool f) 00134 { 00135 if (mReadOnly) return; 00136 mHasDueDate = f; 00137 updated(); 00138 } 00139 00140 00141 bool Todo::hasStartDate() const 00142 { 00143 return mHasStartDate; 00144 } 00145 00146 void Todo::setHasStartDate(bool f) 00147 { 00148 if (mReadOnly) return; 00149 00150 if ( doesRecur() && !f ) { 00151 if ( !comments().grep("NoStartDate").count() ) 00152 addComment("NoStartDate"); //TODO: --> custom flag? 00153 } else { 00154 QString s("NoStartDate"); 00155 removeComment(s); 00156 } 00157 mHasStartDate = f; 00158 updated(); 00159 } 00160 00161 QDateTime Todo::dtStart( bool first ) const 00162 { 00163 if ( doesRecur() && !first ) 00164 return mDtRecurrence.addDays( dtDue( true ).daysTo( IncidenceBase::dtStart() ) ); 00165 else 00166 return IncidenceBase::dtStart(); 00167 } 00168 00169 void Todo::setDtStart( const QDateTime &dtStart ) 00170 { 00171 // TODO: This doesn't seem right (rfc 2445/6 says, recurrence is calculated from the dtstart...) 00172 if ( doesRecur() ) { 00173 recurrence()->setStartDateTime( mDtDue ); 00174 recurrence()->setFloats( doesFloat() ); 00175 } 00176 IncidenceBase::setDtStart( dtStart ); 00177 } 00178 00179 QString Todo::dtStartTimeStr( bool first ) const 00180 { 00181 return KGlobal::locale()->formatTime(dtStart(first).time()); 00182 } 00183 00184 QString Todo::dtStartDateStr(bool shortfmt, bool first) const 00185 { 00186 return KGlobal::locale()->formatDate(dtStart(first).date(),shortfmt); 00187 } 00188 00189 QString Todo::dtStartStr(bool first) const 00190 { 00191 return KGlobal::locale()->formatDateTime(dtStart(first)); 00192 } 00193 00194 bool Todo::isCompleted() const 00195 { 00196 if (mPercentComplete == 100) return true; 00197 else return false; 00198 } 00199 00200 void Todo::setCompleted(bool completed) 00201 { 00202 if (completed) 00203 mPercentComplete = 100; 00204 else { 00205 mPercentComplete = 0; 00206 mHasCompletedDate = false; 00207 mCompleted = QDateTime(); 00208 } 00209 updated(); 00210 } 00211 00212 QDateTime Todo::completed() const 00213 { 00214 if ( hasCompletedDate() ) 00215 return mCompleted; 00216 else 00217 return QDateTime(); 00218 } 00219 00220 QString Todo::completedStr() const 00221 { 00222 return KGlobal::locale()->formatDateTime(mCompleted); 00223 } 00224 00225 void Todo::setCompleted(const QDateTime &completed) 00226 { 00227 if( !recurTodo() ) { 00228 mHasCompletedDate = true; 00229 mPercentComplete = 100; 00230 mCompleted = completed; 00231 } 00232 updated(); 00233 } 00234 00235 bool Todo::hasCompletedDate() const 00236 { 00237 return mHasCompletedDate; 00238 } 00239 00240 int Todo::percentComplete() const 00241 { 00242 return mPercentComplete; 00243 } 00244 00245 void Todo::setPercentComplete(int v) 00246 { 00247 mPercentComplete = v; 00248 if ( v != 100 ) mHasCompletedDate = false; 00249 updated(); 00250 } 00251 00252 void Todo::setDtRecurrence( const QDateTime &dt ) 00253 { 00254 mDtRecurrence = dt; 00255 } 00256 00257 QDateTime Todo::dtRecurrence() const 00258 { 00259 return mDtRecurrence.isValid() ? mDtRecurrence : mDtDue; 00260 } 00261 00262 bool Todo::recursOn( const QDate &date ) const 00263 { 00264 QDate today = QDate::currentDate(); 00265 return ( Incidence::recursOn(date) && 00266 !( date < today && mDtRecurrence.date() < today && 00267 mDtRecurrence > recurrence()->startDateTime() ) ); 00268 } 00269 00270 bool Todo::recurTodo() 00271 { 00272 if ( doesRecur() ) { 00273 Recurrence *r = recurrence(); 00274 QDateTime endDateTime = r->endDateTime(); 00275 QDateTime nextDate = r->getNextDateTime( dtDue() ); 00276 00277 if ( ( r->duration() == -1 || ( nextDate.isValid() && endDateTime.isValid() 00278 && nextDate <= endDateTime ) ) ) { 00279 00280 while ( !recursAt( nextDate ) || nextDate <= QDateTime::currentDateTime() ) { 00281 00282 if ( !nextDate.isValid() || nextDate > endDateTime ) { 00283 return false; 00284 } 00285 00286 nextDate = r->getNextDateTime( nextDate ); 00287 } 00288 00289 setDtDue( nextDate ); 00290 setCompleted( false ); 00291 setRevision( revision() + 1 ); 00292 00293 return true; 00294 } 00295 } 00296 00297 return false; 00298 } 00299 00300 bool Todo::isOverdue() const 00301 { 00302 bool inPast = doesFloat() ? dtDue().date() < QDate::currentDate() 00303 : dtDue() < QDateTime::currentDateTime(); 00304 return ( inPast && !isCompleted() ); 00305 }