summaryrefslogtreecommitdiffabout
authorzautrix <zautrix>2005-09-28 00:42:41 (UTC)
committer zautrix <zautrix>2005-09-28 00:42:41 (UTC)
commit4fb9beb1ec26f37a18f98af9d3b6b59acf8c56d2 (patch) (unidiff)
treecbfbb81858c5ec08ba16e45b511ddbab539af864
parente6112c5497b334d6dc38108b37963c5e803413d3 (diff)
downloadkdepimpi-4fb9beb1ec26f37a18f98af9d3b6b59acf8c56d2.zip
kdepimpi-4fb9beb1ec26f37a18f98af9d3b6b59acf8c56d2.tar.gz
kdepimpi-4fb9beb1ec26f37a18f98af9d3b6b59acf8c56d2.tar.bz2
save tt fix
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/todo.cpp7
-rw-r--r--libkcal/todo.h1
2 files changed, 8 insertions, 0 deletions
diff --git a/libkcal/todo.cpp b/libkcal/todo.cpp
index 29f725f..2201814 100644
--- a/libkcal/todo.cpp
+++ b/libkcal/todo.cpp
@@ -1,576 +1,583 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20 20
21#include <kglobal.h> 21#include <kglobal.h>
22#include <kglobalsettings.h> 22#include <kglobalsettings.h>
23#include <klocale.h> 23#include <klocale.h>
24#include <kdebug.h> 24#include <kdebug.h>
25#include <qregexp.h> 25#include <qregexp.h>
26#include <qfileinfo.h> 26#include <qfileinfo.h>
27 27
28#include "calendarlocal.h" 28#include "calendarlocal.h"
29#include "icalformat.h" 29#include "icalformat.h"
30#include "todo.h" 30#include "todo.h"
31 31
32#ifndef DESKTOP_VERSION 32#ifndef DESKTOP_VERSION
33#include <qpe/qpeapplication.h> 33#include <qpe/qpeapplication.h>
34#endif 34#endif
35 35
36#define SAVETIMER_TIMEOUT_SECONDS 300 36#define SAVETIMER_TIMEOUT_SECONDS 300
37//#define SAVETIMER_TIMEOUT_SECONDS 8 37//#define SAVETIMER_TIMEOUT_SECONDS 8
38#define SAVETIMER_TIMEOUT_RETRY_SECONDS 5 38#define SAVETIMER_TIMEOUT_RETRY_SECONDS 5
39 39
40using namespace KCal; 40using namespace KCal;
41 41
42Todo::Todo(): QObject(), Incidence() 42Todo::Todo(): QObject(), Incidence()
43{ 43{
44// mStatus = TENTATIVE; 44// mStatus = TENTATIVE;
45 45
46 mHasDueDate = false; 46 mHasDueDate = false;
47 setHasStartDate( false ); 47 setHasStartDate( false );
48 mCompleted = getEvenTime(QDateTime::currentDateTime()); 48 mCompleted = getEvenTime(QDateTime::currentDateTime());
49 mHasCompletedDate = false; 49 mHasCompletedDate = false;
50 mPercentComplete = 0; 50 mPercentComplete = 0;
51 mRunning = false; 51 mRunning = false;
52 mRunSaveTimer = 0; 52 mRunSaveTimer = 0;
53 setFloats( true ); 53 setFloats( true );
54 mCurrentTimerDelay = 0; 54 mCurrentTimerDelay = 0;
55} 55}
56 56
57Todo::Todo(const Todo &t) : QObject(),Incidence(t) 57Todo::Todo(const Todo &t) : QObject(),Incidence(t)
58{ 58{
59 mDtDue = t.mDtDue; 59 mDtDue = t.mDtDue;
60 mHasDueDate = t.mHasDueDate; 60 mHasDueDate = t.mHasDueDate;
61 mCompleted = t.mCompleted; 61 mCompleted = t.mCompleted;
62 mHasCompletedDate = t.mHasCompletedDate; 62 mHasCompletedDate = t.mHasCompletedDate;
63 mPercentComplete = t.mPercentComplete; 63 mPercentComplete = t.mPercentComplete;
64 mRunning = false; 64 mRunning = false;
65 mRunSaveTimer = 0; 65 mRunSaveTimer = 0;
66 mCurrentTimerDelay = 0; 66 mCurrentTimerDelay = 0;
67} 67}
68 68
69Todo::~Todo() 69Todo::~Todo()
70{ 70{
71 setRunning( false ); 71 setRunning( false );
72 //qDebug("Todo::~Todo() "); 72 //qDebug("Todo::~Todo() ");
73} 73}
74 74
75void Todo::setRunningFalse( QString s ) 75void Todo::setRunningFalse( QString s )
76{ 76{
77 if ( ! mRunning ) 77 if ( ! mRunning )
78 return; 78 return;
79 mRunning = false; 79 mRunning = false;
80 if ( mRunSaveTimer ) 80 if ( mRunSaveTimer )
81 mRunSaveTimer->stop(); 81 mRunSaveTimer->stop();
82 saveRunningInfoToFile( s ); 82 saveRunningInfoToFile( s );
83} 83}
84void Todo::stopRunning() 84void Todo::stopRunning()
85{ 85{
86 if ( !mRunning ) 86 if ( !mRunning )
87 return; 87 return;
88 if ( mRunSaveTimer ) 88 if ( mRunSaveTimer )
89 mRunSaveTimer->stop(); 89 mRunSaveTimer->stop();
90 mRunning = false; 90 mRunning = false;
91} 91}
92void Todo::setRunning( bool run ) 92void Todo::setRunning( bool run )
93{ 93{
94 if ( run == mRunning ) 94 if ( run == mRunning )
95 return; 95 return;
96 //qDebug("Todo::setRunning %d ", run); 96 //qDebug("Todo::setRunning %d ", run);
97 if ( !mRunSaveTimer ) { 97 if ( !mRunSaveTimer ) {
98 mRunSaveTimer = new QTimer ( this ); 98 mRunSaveTimer = new QTimer ( this );
99 connect ( mRunSaveTimer, SIGNAL( timeout() ), this , SLOT ( timerSlotSaveRunningInfoToFile() ) ); 99 connect ( mRunSaveTimer, SIGNAL( timeout() ), this , SLOT ( timerSlotSaveRunningInfoToFile() ) );
100 } 100 }
101 mRunning = run; 101 mRunning = run;
102 mRunLastSave = QDateTime::currentDateTime(); 102 mRunLastSave = QDateTime::currentDateTime();
103 if ( mRunning ) { 103 if ( mRunning ) {
104 restartSaveTimer( SAVETIMER_TIMEOUT_SECONDS ); 104 restartSaveTimer( SAVETIMER_TIMEOUT_SECONDS );
105 mRunStart = QDateTime::currentDateTime(); 105 mRunStart = QDateTime::currentDateTime();
106 } else { 106 } else {
107 mRunSaveTimer->stop(); 107 mRunSaveTimer->stop();
108 saveRunningInfoToFile(); 108 saveRunningInfoToFile();
109 } 109 }
110 mLastSavedFileName = "";
110} 111}
111void Todo::saveRunningInfo( QString comment, QDateTime start, QDateTime end ) 112void Todo::saveRunningInfo( QString comment, QDateTime start, QDateTime end )
112{ 113{
113 if ( !mRunning) return; 114 if ( !mRunning) return;
114 mRunning = false; 115 mRunning = false;
115 mRunStart = start; 116 mRunStart = start;
116 mRunEnd = end; 117 mRunEnd = end;
117 saveRunningInfoToFile( comment ); 118 saveRunningInfoToFile( comment );
118} 119}
119void Todo::restartSaveTimer( int secs ) 120void Todo::restartSaveTimer( int secs )
120{ 121{
121 mRunSaveTimer->start( secs * 1000 ); 122 mRunSaveTimer->start( secs * 1000 );
122 mRunLastSave = QDateTime::currentDateTime(); 123 mRunLastSave = QDateTime::currentDateTime();
123 mCurrentTimerDelay = secs; 124 mCurrentTimerDelay = secs;
124} 125}
125void Todo::timerSlotSaveRunningInfoToFile() 126void Todo::timerSlotSaveRunningInfoToFile()
126{ 127{
127 mRunEnd = QDateTime::currentDateTime(); 128 mRunEnd = QDateTime::currentDateTime();
128 int secsTo = mRunLastSave.secsTo( mRunEnd ); 129 int secsTo = mRunLastSave.secsTo( mRunEnd );
129 //if( secsTo == 8 ) ++secsTo; 130 //if( secsTo == 8 ) ++secsTo;
130 qDebug("KO Todo::saveTimerTimeout %d %d", secsTo, mCurrentTimerDelay ); 131 qDebug("KO Todo::saveTimerTimeout %d %d", secsTo, mCurrentTimerDelay );
131 if ( secsTo > mCurrentTimerDelay ) { 132 if ( secsTo > mCurrentTimerDelay ) {
132 qDebug("KO Todo::saveTimerTimeout restart %d ", SAVETIMER_TIMEOUT_RETRY_SECONDS ); 133 qDebug("KO Todo::saveTimerTimeout restart %d ", SAVETIMER_TIMEOUT_RETRY_SECONDS );
133 restartSaveTimer( SAVETIMER_TIMEOUT_RETRY_SECONDS ); 134 restartSaveTimer( SAVETIMER_TIMEOUT_RETRY_SECONDS );
134 return; 135 return;
135 } 136 }
136 int msecs = mRunLastSave.time().msecsTo( mRunEnd.time()); 137 int msecs = mRunLastSave.time().msecsTo( mRunEnd.time());
137 if ( msecs < 0 ) { 138 if ( msecs < 0 ) {
138 restartSaveTimer( SAVETIMER_TIMEOUT_RETRY_SECONDS ); 139 restartSaveTimer( SAVETIMER_TIMEOUT_RETRY_SECONDS );
139 return; 140 return;
140 } 141 }
141 // qDebug("KO Todo::saveTimerTimeout restarting! millisecs %d", msecs - ( ( mCurrentTimerDelay * 1000 ) + 50 ) ); 142 // qDebug("KO Todo::saveTimerTimeout restarting! millisecs %d", msecs - ( ( mCurrentTimerDelay * 1000 ) + 50 ) );
142 if ( msecs > ( ( mCurrentTimerDelay * 1000 ) + 50 )) { 143 if ( msecs > ( ( mCurrentTimerDelay * 1000 ) + 50 )) {
143 qDebug("KO Todo::saveTimerTimeout restarting! millisecs %d", msecs - ( ( mCurrentTimerDelay * 1000 ) + 50 ) ); 144 qDebug("KO Todo::saveTimerTimeout restarting! millisecs %d", msecs - ( ( mCurrentTimerDelay * 1000 ) + 50 ) );
144 restartSaveTimer( SAVETIMER_TIMEOUT_RETRY_SECONDS ); 145 restartSaveTimer( SAVETIMER_TIMEOUT_RETRY_SECONDS );
145 return; 146 return;
146 } 147 }
147 restartSaveTimer( SAVETIMER_TIMEOUT_SECONDS ); 148 restartSaveTimer( SAVETIMER_TIMEOUT_SECONDS );
148 saveRunningInfoToFile( QString::null ); 149 saveRunningInfoToFile( QString::null );
149} 150}
150void Todo::saveRunningInfoToFile() 151void Todo::saveRunningInfoToFile()
151{ 152{
152 mRunEnd = QDateTime::currentDateTime(); 153 mRunEnd = QDateTime::currentDateTime();
153 saveRunningInfoToFile( QString::null ); 154 saveRunningInfoToFile( QString::null );
154} 155}
155void Todo::saveRunningInfoToFile( QString comment ) 156void Todo::saveRunningInfoToFile( QString comment )
156{ 157{
157#ifndef DESKTOP_VERSION 158#ifndef DESKTOP_VERSION
158 //QPEApplication::setTempScreenSaverMode ( QPEApplication::Disable ); 159 //QPEApplication::setTempScreenSaverMode ( QPEApplication::Disable );
159#endif 160#endif
160 //qDebug("Todo::saveRunningInfoToFile() %s", summary().latin1()); 161 //qDebug("Todo::saveRunningInfoToFile() %s", summary().latin1());
161 if ( mRunStart.secsTo ( mRunEnd) < 15 ) { 162 if ( mRunStart.secsTo ( mRunEnd) < 15 ) {
162 qDebug("Running time < 15 seconds. Skipped. "); 163 qDebug("Running time < 15 seconds. Skipped. ");
163 return; 164 return;
164 } 165 }
165 QString dir = KGlobalSettings::timeTrackerDir(); 166 QString dir = KGlobalSettings::timeTrackerDir();
166 //qDebug("%s ", dir.latin1()); 167 //qDebug("%s ", dir.latin1());
167 QString file = "%1%2%3-%4%5%6-"; 168 QString file = "%1%2%3-%4%5%6-";
168 file = file.arg( mRunStart.date().year(), 4).arg( mRunStart.date().month(),2 ).arg( mRunStart.date().day(), 2 ).arg( mRunStart.time().hour(),2 ).arg( mRunStart.time().minute(),2 ).arg( mRunStart.time().second(),2 ); 169 file = file.arg( mRunStart.date().year(), 4).arg( mRunStart.date().month(),2 ).arg( mRunStart.date().day(), 2 ).arg( mRunStart.time().hour(),2 ).arg( mRunStart.time().minute(),2 ).arg( mRunStart.time().second(),2 );
169 file.replace ( QRegExp (" "), "0" ); 170 file.replace ( QRegExp (" "), "0" );
170 file += uid(); 171 file += uid();
171 //qDebug("File %s ",file.latin1() ); 172 //qDebug("File %s ",file.latin1() );
172 CalendarLocal cal; 173 CalendarLocal cal;
173 cal.setLocalTime(); 174 cal.setLocalTime();
174 Todo * to = (Todo*) clone(); 175 Todo * to = (Todo*) clone();
175 to->setFloats( false ); 176 to->setFloats( false );
176 to->setDtStart( mRunStart ); 177 to->setDtStart( mRunStart );
177 to->setHasStartDate( true ); 178 to->setHasStartDate( true );
178 to->setDtDue( mRunEnd ); 179 to->setDtDue( mRunEnd );
179 to->setHasDueDate( true ); 180 to->setHasDueDate( true );
180 to->setUid( file ); 181 to->setUid( file );
181 if ( !comment.isEmpty() ) { 182 if ( !comment.isEmpty() ) {
182 QString des = to->description(); 183 QString des = to->description();
183 if ( des.isEmpty () ) 184 if ( des.isEmpty () )
184 to->setDescription( "TT-Note: " + comment ); 185 to->setDescription( "TT-Note: " + comment );
185 else 186 else
186 to->setDescription( "TT-Note: " + comment +"\n" + des ); 187 to->setDescription( "TT-Note: " + comment +"\n" + des );
187 } 188 }
188 cal.addIncidence( to ); 189 cal.addIncidence( to );
189 ICalFormat format( false ); 190 ICalFormat format( false );
190 file = dir +"/" +file +".ics"; 191 file = dir +"/" +file +".ics";
191 format.save( &cal, file ); 192 format.save( &cal, file );
192 saveParents(); 193 saveParents();
194 if ( !mLastSavedFileName.isEmpty() ) {
195 if ( mLastSavedFileName != file ) {
196 QFile::remove( mLastSavedFileName );
197 }
198 }
199 mLastSavedFileName = file;
193#ifndef DESKTOP_VERSION 200#ifndef DESKTOP_VERSION
194 //QPEApplication::setTempScreenSaverMode ( QPEApplication::Enable ); 201 //QPEApplication::setTempScreenSaverMode ( QPEApplication::Enable );
195#endif 202#endif
196} 203}
197void Todo::saveParents() 204void Todo::saveParents()
198{ 205{
199 if (!relatedTo() ) 206 if (!relatedTo() )
200 return; 207 return;
201 Incidence * inc = relatedTo(); 208 Incidence * inc = relatedTo();
202 if ( inc->typeID() != todoID ) 209 if ( inc->typeID() != todoID )
203 return; 210 return;
204 Todo* to = (Todo*)inc; 211 Todo* to = (Todo*)inc;
205 bool saveTodo = false; 212 bool saveTodo = false;
206 QString file = KGlobalSettings::timeTrackerDir() + "/"+ to->uid() + ".ics"; 213 QString file = KGlobalSettings::timeTrackerDir() + "/"+ to->uid() + ".ics";
207 QFileInfo fi ( file ); 214 QFileInfo fi ( file );
208 if ( fi.exists() ) { 215 if ( fi.exists() ) {
209 if ( fi.lastModified () < to->lastModified ()) 216 if ( fi.lastModified () < to->lastModified ())
210 saveTodo = true; 217 saveTodo = true;
211 } else { 218 } else {
212 saveTodo = true; 219 saveTodo = true;
213 } 220 }
214 if ( saveTodo ) { 221 if ( saveTodo ) {
215 CalendarLocal cal; 222 CalendarLocal cal;
216 cal.setLocalTime(); 223 cal.setLocalTime();
217 Todo * par = (Todo *) to->clone(); 224 Todo * par = (Todo *) to->clone();
218 cal.addIncidence( par ); 225 cal.addIncidence( par );
219 ICalFormat format( false ); 226 ICalFormat format( false );
220 format.save( &cal, file ); 227 format.save( &cal, file );
221 } 228 }
222 to->saveParents(); 229 to->saveParents();
223} 230}
224 231
225int Todo::runTime() 232int Todo::runTime()
226{ 233{
227 if ( !mRunning ) 234 if ( !mRunning )
228 return 0; 235 return 0;
229 return mRunStart.secsTo( QDateTime::currentDateTime() ); 236 return mRunStart.secsTo( QDateTime::currentDateTime() );
230} 237}
231bool Todo::hasRunningSub() 238bool Todo::hasRunningSub()
232{ 239{
233 if ( mRunning ) 240 if ( mRunning )
234 return true; 241 return true;
235 Incidence *aTodo; 242 Incidence *aTodo;
236 for (aTodo = mRelations.first(); aTodo; aTodo = mRelations.next()) { 243 for (aTodo = mRelations.first(); aTodo; aTodo = mRelations.next()) {
237 if ( ((Todo*)aTodo)->hasRunningSub() ) 244 if ( ((Todo*)aTodo)->hasRunningSub() )
238 return true; 245 return true;
239 } 246 }
240 return false; 247 return false;
241} 248}
242Incidence *Todo::clone() 249Incidence *Todo::clone()
243{ 250{
244 return new Todo(*this); 251 return new Todo(*this);
245} 252}
246 253
247bool Todo::contains ( Todo* from ) 254bool Todo::contains ( Todo* from )
248{ 255{
249 256
250 if ( !from->summary().isEmpty() ) 257 if ( !from->summary().isEmpty() )
251 if ( !summary().startsWith( from->summary() )) 258 if ( !summary().startsWith( from->summary() ))
252 return false; 259 return false;
253 if ( from->hasStartDate() ) { 260 if ( from->hasStartDate() ) {
254 if ( !hasStartDate() ) 261 if ( !hasStartDate() )
255 return false; 262 return false;
256 if ( from->dtStart() != dtStart()) 263 if ( from->dtStart() != dtStart())
257 return false; 264 return false;
258 } 265 }
259 if ( from->hasDueDate() ){ 266 if ( from->hasDueDate() ){
260 if ( !hasDueDate() ) 267 if ( !hasDueDate() )
261 return false; 268 return false;
262 if ( from->dtDue() != dtDue()) 269 if ( from->dtDue() != dtDue())
263 return false; 270 return false;
264 } 271 }
265 if ( !from->location().isEmpty() ) 272 if ( !from->location().isEmpty() )
266 if ( !location().startsWith( from->location() ) ) 273 if ( !location().startsWith( from->location() ) )
267 return false; 274 return false;
268 if ( !from->description().isEmpty() ) 275 if ( !from->description().isEmpty() )
269 if ( !description().startsWith( from->description() )) 276 if ( !description().startsWith( from->description() ))
270 return false; 277 return false;
271 if ( from->alarms().count() ) { 278 if ( from->alarms().count() ) {
272 Alarm *a = from->alarms().first(); 279 Alarm *a = from->alarms().first();
273 if ( a->enabled() ){ 280 if ( a->enabled() ){
274 if ( !alarms().count() ) 281 if ( !alarms().count() )
275 return false; 282 return false;
276 Alarm *b = alarms().first(); 283 Alarm *b = alarms().first();
277 if( ! b->enabled() ) 284 if( ! b->enabled() )
278 return false; 285 return false;
279 if ( ! (a->offset() == b->offset() )) 286 if ( ! (a->offset() == b->offset() ))
280 return false; 287 return false;
281 } 288 }
282 } 289 }
283 290
284 QStringList cat = categories(); 291 QStringList cat = categories();
285 QStringList catFrom = from->categories(); 292 QStringList catFrom = from->categories();
286 QString nCat; 293 QString nCat;
287 unsigned int iii; 294 unsigned int iii;
288 for ( iii = 0; iii < catFrom.count();++iii ) { 295 for ( iii = 0; iii < catFrom.count();++iii ) {
289 nCat = catFrom[iii]; 296 nCat = catFrom[iii];
290 if ( !nCat.isEmpty() ) 297 if ( !nCat.isEmpty() )
291 if ( !cat.contains( nCat )) { 298 if ( !cat.contains( nCat )) {
292 return false; 299 return false;
293 } 300 }
294 } 301 }
295 if ( from->isCompleted() ) { 302 if ( from->isCompleted() ) {
296 if ( !isCompleted() ) 303 if ( !isCompleted() )
297 return false; 304 return false;
298 } 305 }
299 if( priority() != from->priority() ) 306 if( priority() != from->priority() )
300 return false; 307 return false;
301 308
302 309
303 return true; 310 return true;
304 311
305} 312}
306bool KCal::operator==( const Todo& t1, const Todo& t2 ) 313bool KCal::operator==( const Todo& t1, const Todo& t2 )
307{ 314{
308 315
309 bool ret = operator==( (const Incidence&)t1, (const Incidence&)t2 ); 316 bool ret = operator==( (const Incidence&)t1, (const Incidence&)t2 );
310 if ( ! ret ) 317 if ( ! ret )
311 return false; 318 return false;
312 if ( t1.hasDueDate() == t2.hasDueDate() ) { 319 if ( t1.hasDueDate() == t2.hasDueDate() ) {
313 if ( t1.hasDueDate() ) { 320 if ( t1.hasDueDate() ) {
314 if ( t1.doesFloat() == t2.doesFloat() ) { 321 if ( t1.doesFloat() == t2.doesFloat() ) {
315 if ( t1.doesFloat() ) { 322 if ( t1.doesFloat() ) {
316 if ( t1.dtDue().date() != t2.dtDue().date() ) 323 if ( t1.dtDue().date() != t2.dtDue().date() )
317 return false; 324 return false;
318 } else 325 } else
319 if ( t1.dtDue() != t2.dtDue() ) 326 if ( t1.dtDue() != t2.dtDue() )
320 return false; 327 return false;
321 } else 328 } else
322 return false;// float != 329 return false;// float !=
323 } 330 }
324 331
325 } else 332 } else
326 return false; 333 return false;
327 if ( t1.percentComplete() != t2.percentComplete() ) 334 if ( t1.percentComplete() != t2.percentComplete() )
328 return false; 335 return false;
329 if ( t1.isCompleted() ) { 336 if ( t1.isCompleted() ) {
330 if ( t1.hasCompletedDate() == t2.hasCompletedDate() ) { 337 if ( t1.hasCompletedDate() == t2.hasCompletedDate() ) {
331 if ( t1.hasCompletedDate() ) { 338 if ( t1.hasCompletedDate() ) {
332 if ( t1.completed() != t2.completed() ) 339 if ( t1.completed() != t2.completed() )
333 return false; 340 return false;
334 } 341 }
335 342
336 } else 343 } else
337 return false; 344 return false;
338 } 345 }
339 return true; 346 return true;
340 347
341} 348}
342 349
343void Todo::setDtDue(const QDateTime &dtDue) 350void Todo::setDtDue(const QDateTime &dtDue)
344{ 351{
345 //int diffsecs = mDtDue.secsTo(dtDue); 352 //int diffsecs = mDtDue.secsTo(dtDue);
346 353
347 /*if (mReadOnly) return; 354 /*if (mReadOnly) return;
348 const QPtrList<Alarm>& alarms = alarms(); 355 const QPtrList<Alarm>& alarms = alarms();
349 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) { 356 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) {
350 if (alarm->enabled()) { 357 if (alarm->enabled()) {
351 alarm->setTime(alarm->time().addSecs(diffsecs)); 358 alarm->setTime(alarm->time().addSecs(diffsecs));
352 } 359 }
353 }*/ 360 }*/
354 mDtDue = getEvenTime(dtDue); 361 mDtDue = getEvenTime(dtDue);
355 362
356 //kdDebug(5800) << "setDtDue says date is " << mDtDue.toString() << endl; 363 //kdDebug(5800) << "setDtDue says date is " << mDtDue.toString() << endl;
357 364
358 /*const QPtrList<Alarm>& alarms = alarms(); 365 /*const QPtrList<Alarm>& alarms = alarms();
359 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next()) 366 for (Alarm* alarm = alarms.first(); alarm; alarm = alarms.next())
360 alarm->setAlarmStart(mDtDue);*/ 367 alarm->setAlarmStart(mDtDue);*/
361 updated(); 368 updated();
362} 369}
363 370
364QDateTime Todo::dtDue() const 371QDateTime Todo::dtDue() const
365{ 372{
366 return mDtDue; 373 return mDtDue;
367} 374}
368 375
369QString Todo::dtDueTimeStr() const 376QString Todo::dtDueTimeStr() const
370{ 377{
371 return KGlobal::locale()->formatTime(mDtDue.time()); 378 return KGlobal::locale()->formatTime(mDtDue.time());
372} 379}
373 380
374QString Todo::dtDueDateStr(bool shortfmt) const 381QString Todo::dtDueDateStr(bool shortfmt) const
375{ 382{
376 return KGlobal::locale()->formatDate(mDtDue.date(),shortfmt); 383 return KGlobal::locale()->formatDate(mDtDue.date(),shortfmt);
377} 384}
378 385
379QString Todo::dtDueStr(bool shortfmt) const 386QString Todo::dtDueStr(bool shortfmt) const
380{ 387{
381 if ( doesFloat() ) 388 if ( doesFloat() )
382 return KGlobal::locale()->formatDate(mDtDue.date(),shortfmt); 389 return KGlobal::locale()->formatDate(mDtDue.date(),shortfmt);
383 return KGlobal::locale()->formatDateTime(mDtDue, shortfmt); 390 return KGlobal::locale()->formatDateTime(mDtDue, shortfmt);
384} 391}
385// retval 0 : no found 392// retval 0 : no found
386// 1 : due for date found 393// 1 : due for date found
387// 2 : overdue for date found 394// 2 : overdue for date found
388int Todo::hasDueSubTodoForDate( const QDate & date, bool checkSubtodos ) 395int Todo::hasDueSubTodoForDate( const QDate & date, bool checkSubtodos )
389{ 396{
390 int retval = 0; 397 int retval = 0;
391 if ( isCompleted() ) 398 if ( isCompleted() )
392 return 0; 399 return 0;
393 if ( hasDueDate() ) { 400 if ( hasDueDate() ) {
394 if ( dtDue().date() < date ) 401 if ( dtDue().date() < date )
395 return 2; 402 return 2;
396 // we do not return, because we may find an overdue sub todo 403 // we do not return, because we may find an overdue sub todo
397 if ( dtDue().date() == date ) 404 if ( dtDue().date() == date )
398 retval = 1; 405 retval = 1;
399 } 406 }
400 if ( checkSubtodos ) { 407 if ( checkSubtodos ) {
401 Incidence *aTodo; 408 Incidence *aTodo;
402 for (aTodo = mRelations.first(); aTodo; aTodo = mRelations.next()) { 409 for (aTodo = mRelations.first(); aTodo; aTodo = mRelations.next()) {
403 int ret = ((Todo*)aTodo)->hasDueSubTodoForDate( date ,checkSubtodos ); 410 int ret = ((Todo*)aTodo)->hasDueSubTodoForDate( date ,checkSubtodos );
404 if ( ret == 2 ) 411 if ( ret == 2 )
405 return 2; 412 return 2;
406 if ( ret == 1) 413 if ( ret == 1)
407 retval = 1; 414 retval = 1;
408 } 415 }
409 } 416 }
410 return retval; 417 return retval;
411} 418}
412int Todo::hasDueSubTodo( bool checkSubtodos ) //= true 419int Todo::hasDueSubTodo( bool checkSubtodos ) //= true
413{ 420{
414 return hasDueSubTodoForDate(QDate::currentDate(), checkSubtodos ); 421 return hasDueSubTodoForDate(QDate::currentDate(), checkSubtodos );
415} 422}
416bool Todo::hasDueDate() const 423bool Todo::hasDueDate() const
417{ 424{
418 return mHasDueDate; 425 return mHasDueDate;
419} 426}
420 427
421void Todo::setHasDueDate(bool f) 428void Todo::setHasDueDate(bool f)
422{ 429{
423 if (mReadOnly) return; 430 if (mReadOnly) return;
424 mHasDueDate = f; 431 mHasDueDate = f;
425 updated(); 432 updated();
426} 433}
427 434
428 435
429#if 0 436#if 0
430void Todo::setStatus(const QString &statStr) 437void Todo::setStatus(const QString &statStr)
431{ 438{
432 if (mReadOnly) return; 439 if (mReadOnly) return;
433 QString ss(statStr.upper()); 440 QString ss(statStr.upper());
434 441
435 if (ss == "X-ACTION") 442 if (ss == "X-ACTION")
436 mStatus = NEEDS_ACTION; 443 mStatus = NEEDS_ACTION;
437 else if (ss == "NEEDS ACTION") 444 else if (ss == "NEEDS ACTION")
438 mStatus = NEEDS_ACTION; 445 mStatus = NEEDS_ACTION;
439 else if (ss == "ACCEPTED") 446 else if (ss == "ACCEPTED")
440 mStatus = ACCEPTED; 447 mStatus = ACCEPTED;
441 else if (ss == "SENT") 448 else if (ss == "SENT")
442 mStatus = SENT; 449 mStatus = SENT;
443 else if (ss == "TENTATIVE") 450 else if (ss == "TENTATIVE")
444 mStatus = TENTATIVE; 451 mStatus = TENTATIVE;
445 else if (ss == "CONFIRMED") 452 else if (ss == "CONFIRMED")
446 mStatus = CONFIRMED; 453 mStatus = CONFIRMED;
447 else if (ss == "DECLINED") 454 else if (ss == "DECLINED")
448 mStatus = DECLINED; 455 mStatus = DECLINED;
449 else if (ss == "COMPLETED") 456 else if (ss == "COMPLETED")
450 mStatus = COMPLETED; 457 mStatus = COMPLETED;
451 else if (ss == "DELEGATED") 458 else if (ss == "DELEGATED")
452 mStatus = DELEGATED; 459 mStatus = DELEGATED;
453 460
454 updated(); 461 updated();
455} 462}
456 463
457void Todo::setStatus(int status) 464void Todo::setStatus(int status)
458{ 465{
459 if (mReadOnly) return; 466 if (mReadOnly) return;
460 mStatus = status; 467 mStatus = status;
461 updated(); 468 updated();
462} 469}
463 470
464int Todo::status() const 471int Todo::status() const
465{ 472{
466 return mStatus; 473 return mStatus;
467} 474}
468 475
469QString Todo::statusStr() const 476QString Todo::statusStr() const
470{ 477{
471 switch(mStatus) { 478 switch(mStatus) {
472 case NEEDS_ACTION: 479 case NEEDS_ACTION:
473 return QString("NEEDS ACTION"); 480 return QString("NEEDS ACTION");
474 break; 481 break;
475 case ACCEPTED: 482 case ACCEPTED:
476 return QString("ACCEPTED"); 483 return QString("ACCEPTED");
477 break; 484 break;
478 case SENT: 485 case SENT:
479 return QString("SENT"); 486 return QString("SENT");
480 break; 487 break;
481 case TENTATIVE: 488 case TENTATIVE:
482 return QString("TENTATIVE"); 489 return QString("TENTATIVE");
483 break; 490 break;
484 case CONFIRMED: 491 case CONFIRMED:
485 return QString("CONFIRMED"); 492 return QString("CONFIRMED");
486 break; 493 break;
487 case DECLINED: 494 case DECLINED:
488 return QString("DECLINED"); 495 return QString("DECLINED");
489 break; 496 break;
490 case COMPLETED: 497 case COMPLETED:
491 return QString("COMPLETED"); 498 return QString("COMPLETED");
492 break; 499 break;
493 case DELEGATED: 500 case DELEGATED:
494 return QString("DELEGATED"); 501 return QString("DELEGATED");
495 break; 502 break;
496 } 503 }
497 return QString(""); 504 return QString("");
498} 505}
499#endif 506#endif
500 507
501bool Todo::isCompleted() const 508bool Todo::isCompleted() const
502{ 509{
503 if (mPercentComplete == 100) { 510 if (mPercentComplete == 100) {
504 return true; 511 return true;
505 } 512 }
506 else return false; 513 else return false;
507} 514}
508 515
509void Todo::setCompleted(bool completed) 516void Todo::setCompleted(bool completed)
510{ 517{
511 if ( mHasRecurrenceID && completed && mPercentComplete != 100 ) { 518 if ( mHasRecurrenceID && completed && mPercentComplete != 100 ) {
512 if ( !setRecurDates() ) 519 if ( !setRecurDates() )
513 completed = false; 520 completed = false;
514 } 521 }
515 if (completed) mPercentComplete = 100; 522 if (completed) mPercentComplete = 100;
516 else { 523 else {
517 mPercentComplete = 0; 524 mPercentComplete = 0;
518 mHasCompletedDate = false; 525 mHasCompletedDate = false;
519 } 526 }
520 updated(); 527 updated();
521} 528}
522 529
523QDateTime Todo::completed() const 530QDateTime Todo::completed() const
524{ 531{
525 return mCompleted; 532 return mCompleted;
526} 533}
527 534
528QString Todo::completedStr( bool shortF ) const 535QString Todo::completedStr( bool shortF ) const
529{ 536{
530 return KGlobal::locale()->formatDateTime(mCompleted, shortF); 537 return KGlobal::locale()->formatDateTime(mCompleted, shortF);
531} 538}
532 539
533void Todo::setCompleted(const QDateTime &completed) 540void Todo::setCompleted(const QDateTime &completed)
534{ 541{
535 //qDebug("Todo::setCompleted "); 542 //qDebug("Todo::setCompleted ");
536 if ( mHasCompletedDate ) { 543 if ( mHasCompletedDate ) {
537 // qDebug("has completed data - return "); 544 // qDebug("has completed data - return ");
538 return; 545 return;
539 } 546 }
540 mHasCompletedDate = true; 547 mHasCompletedDate = true;
541 mPercentComplete = 100; 548 mPercentComplete = 100;
542 mCompleted = getEvenTime(completed); 549 mCompleted = getEvenTime(completed);
543 updated(); 550 updated();
544} 551}
545 552
546bool Todo::hasCompletedDate() const 553bool Todo::hasCompletedDate() const
547{ 554{
548 return mHasCompletedDate; 555 return mHasCompletedDate;
549} 556}
550 557
551int Todo::percentComplete() const 558int Todo::percentComplete() const
552{ 559{
553 return mPercentComplete; 560 return mPercentComplete;
554} 561}
555bool Todo::setRecurDates() 562bool Todo::setRecurDates()
556{ 563{
557 if ( !mHasRecurrenceID ) 564 if ( !mHasRecurrenceID )
558 return true; 565 return true;
559 int secs = mDtStart.secsTo( dtDue() ); 566 int secs = mDtStart.secsTo( dtDue() );
560 bool ok; 567 bool ok;
561 qDebug("T:setRecurDates() "); 568 qDebug("T:setRecurDates() ");
562 //qDebug("%s %s %s ",mDtStart.toString().latin1(), dtDue().toString().latin1(),mRecurrenceID.toString().latin1() ); 569 //qDebug("%s %s %s ",mDtStart.toString().latin1(), dtDue().toString().latin1(),mRecurrenceID.toString().latin1() );
563 QDateTime next = getNextOccurence( mRecurrenceID, &ok ); 570 QDateTime next = getNextOccurence( mRecurrenceID, &ok );
564 if ( ok ) { 571 if ( ok ) {
565 mRecurrenceID = next; 572 mRecurrenceID = next;
566 mDtStart = next; 573 mDtStart = next;
567 setDtDue( next.addSecs( secs ) ); 574 setDtDue( next.addSecs( secs ) );
568 if ( QDateTime::currentDateTime() > next) 575 if ( QDateTime::currentDateTime() > next)
569 return false; 576 return false;
570 } else { 577 } else {
571 setHasRecurrenceID( false ); 578 setHasRecurrenceID( false );
572 recurrence()->unsetRecurs(); 579 recurrence()->unsetRecurs();
573 } 580 }
574 return true; 581 return true;
575} 582}
576void Todo::setPercentComplete(int v) 583void Todo::setPercentComplete(int v)
diff --git a/libkcal/todo.h b/libkcal/todo.h
index 71b7a4e..2131732 100644
--- a/libkcal/todo.h
+++ b/libkcal/todo.h
@@ -1,161 +1,162 @@
1/* 1/*
2 This file is part of libkcal. 2 This file is part of libkcal.
3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org> 3 Copyright (c) 2001 Cornelius Schumacher <schumacher@kde.org>
4 4
5 This library is free software; you can redistribute it and/or 5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public 6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either 7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version. 8 version 2 of the License, or (at your option) any later version.
9 9
10 This library is distributed in the hope that it will be useful, 10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details. 13 Library General Public License for more details.
14 14
15 You should have received a copy of the GNU Library General Public License 15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to 16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 17 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. 18 Boston, MA 02111-1307, USA.
19*/ 19*/
20#ifndef TODO_H 20#ifndef TODO_H
21#define TODO_H 21#define TODO_H
22// 22//
23// Todo component, representing a VTODO object 23// Todo component, representing a VTODO object
24// 24//
25 25
26#include "incidence.h" 26#include "incidence.h"
27 27
28#include <qtimer.h> 28#include <qtimer.h>
29 29
30namespace KCal { 30namespace KCal {
31 31
32/** 32/**
33 This class provides a Todo in the sense of RFC2445. 33 This class provides a Todo in the sense of RFC2445.
34*/ 34*/
35 class Todo : public QObject,public Incidence 35 class Todo : public QObject,public Incidence
36{ 36{
37 Q_OBJECT 37 Q_OBJECT
38 public: 38 public:
39 Todo(); 39 Todo();
40 Todo(const Todo &); 40 Todo(const Todo &);
41 ~Todo(); 41 ~Todo();
42 typedef ListBase<Todo> List; 42 typedef ListBase<Todo> List;
43 QCString type() const { return "Todo"; } 43 QCString type() const { return "Todo"; }
44 IncTypeID typeID() const { return todoID; } 44 IncTypeID typeID() const { return todoID; }
45 45
46 /** Return an exact copy of this todo. */ 46 /** Return an exact copy of this todo. */
47 Incidence *clone(); 47 Incidence *clone();
48 QDateTime getNextAlarmDateTime( bool * ok, int * offset, QDateTime start_dt ) const; 48 QDateTime getNextAlarmDateTime( bool * ok, int * offset, QDateTime start_dt ) const;
49 49
50 /** for setting the todo's due date/time with a QDateTime. */ 50 /** for setting the todo's due date/time with a QDateTime. */
51 void setDtDue(const QDateTime &dtDue); 51 void setDtDue(const QDateTime &dtDue);
52 /** returns an event's Due date/time as a QDateTime. */ 52 /** returns an event's Due date/time as a QDateTime. */
53 QDateTime dtDue() const; 53 QDateTime dtDue() const;
54 /** returns an event's due time as a string formatted according to the 54 /** returns an event's due time as a string formatted according to the
55 users locale settings */ 55 users locale settings */
56 QString dtDueTimeStr() const; 56 QString dtDueTimeStr() const;
57 /** returns an event's due date as a string formatted according to the 57 /** returns an event's due date as a string formatted according to the
58 users locale settings */ 58 users locale settings */
59 QString dtDueDateStr(bool shortfmt=true) const; 59 QString dtDueDateStr(bool shortfmt=true) const;
60 /** returns an event's due date and time as a string formatted according 60 /** returns an event's due date and time as a string formatted according
61 to the users locale settings */ 61 to the users locale settings */
62 QString dtDueStr(bool shortfmt=true) const; 62 QString dtDueStr(bool shortfmt=true) const;
63 63
64 /** returns TRUE or FALSE depending on whether the todo has a due date */ 64 /** returns TRUE or FALSE depending on whether the todo has a due date */
65 bool hasDueDate() const; 65 bool hasDueDate() const;
66 /** sets the event's hasDueDate value. */ 66 /** sets the event's hasDueDate value. */
67 void setHasDueDate(bool f); 67 void setHasDueDate(bool f);
68 68
69 /* 69 /*
70 Looks for a subtodo (including itself ) which is not complete and is 70 Looks for a subtodo (including itself ) which is not complete and is
71 - overdue, or 71 - overdue, or
72 - due today. 72 - due today.
73 It returns 0 for nothing found, 73 It returns 0 for nothing found,
74 1 for found a todo which is due today and no overdue found 74 1 for found a todo which is due today and no overdue found
75 2 for found a overdue todo 75 2 for found a overdue todo
76 */ 76 */
77 int hasDueSubTodo( bool checkSubtodos = true ); 77 int hasDueSubTodo( bool checkSubtodos = true );
78 /* same as above, but a specific date can be specified*/ 78 /* same as above, but a specific date can be specified*/
79 int hasDueSubTodoForDate( const QDate & date, bool checkSubtodos ); 79 int hasDueSubTodoForDate( const QDate & date, bool checkSubtodos );
80 80
81 81
82 /** sets the event's status to the string specified. The string 82 /** sets the event's status to the string specified. The string
83 * must be a recognized value for the status field, i.e. a string 83 * must be a recognized value for the status field, i.e. a string
84 * equivalent of the possible status enumerations previously described. */ 84 * equivalent of the possible status enumerations previously described. */
85// void setStatus(const QString &statStr); 85// void setStatus(const QString &statStr);
86 /** sets the event's status to the value specified. See the enumeration 86 /** sets the event's status to the value specified. See the enumeration
87 * above for possible values. */ 87 * above for possible values. */
88// void setStatus(int); 88// void setStatus(int);
89 /** return the event's status. */ 89 /** return the event's status. */
90// int status() const; 90// int status() const;
91 /** return the event's status in string format. */ 91 /** return the event's status in string format. */
92// QString statusStr() const; 92// QString statusStr() const;
93 93
94 /** return, if this todo is completed */ 94 /** return, if this todo is completed */
95 bool isCompleted() const; 95 bool isCompleted() const;
96 /** set completed state of this todo */ 96 /** set completed state of this todo */
97 void setCompleted(bool); 97 void setCompleted(bool);
98 98
99 /** 99 /**
100 Return how many percent of the task are completed. Returns a value 100 Return how many percent of the task are completed. Returns a value
101 between 0 and 100. 101 between 0 and 100.
102 */ 102 */
103 int percentComplete() const; 103 int percentComplete() const;
104 /** 104 /**
105 Set how many percent of the task are completed. Valid values are in the 105 Set how many percent of the task are completed. Valid values are in the
106 range from 0 to 100. 106 range from 0 to 100.
107 */ 107 */
108 void setPercentComplete(int); 108 void setPercentComplete(int);
109 109
110 /** return date and time when todo was completed */ 110 /** return date and time when todo was completed */
111 QDateTime completed() const; 111 QDateTime completed() const;
112 QString completedStr(bool shortF = true) const; 112 QString completedStr(bool shortF = true) const;
113 /** set date and time of completion */ 113 /** set date and time of completion */
114 void setCompleted(const QDateTime &completed); 114 void setCompleted(const QDateTime &completed);
115 115
116 /** Return true, if todo has a date associated with completion */ 116 /** Return true, if todo has a date associated with completion */
117 bool hasCompletedDate() const; 117 bool hasCompletedDate() const;
118 bool contains ( Todo*); 118 bool contains ( Todo*);
119 void checkSetCompletedFalse(); 119 void checkSetCompletedFalse();
120 bool setRecurDates(); 120 bool setRecurDates();
121 bool isRunning() {return mRunning;} 121 bool isRunning() {return mRunning;}
122 bool hasRunningSub(); 122 bool hasRunningSub();
123 void setRunning( bool ); 123 void setRunning( bool );
124 void setRunningFalse( QString ); 124 void setRunningFalse( QString );
125 void stopRunning(); 125 void stopRunning();
126 int runTime(); 126 int runTime();
127 QDateTime runStart () const { return mRunStart;} 127 QDateTime runStart () const { return mRunStart;}
128 void saveRunningInfo( QString comment, QDateTime start, QDateTime end ); 128 void saveRunningInfo( QString comment, QDateTime start, QDateTime end );
129 public slots: 129 public slots:
130 void saveRunningInfoToFile( QString st ); 130 void saveRunningInfoToFile( QString st );
131 void saveRunningInfoToFile( ); 131 void saveRunningInfoToFile( );
132 void saveParents(); 132 void saveParents();
133 QString durationText(); 133 QString durationText();
134 private slots: 134 private slots:
135 void timerSlotSaveRunningInfoToFile( ); 135 void timerSlotSaveRunningInfoToFile( );
136 private: 136 private:
137 QString mLastSavedFileName;
137 void restartSaveTimer( int secs ); 138 void restartSaveTimer( int secs );
138 int mCurrentTimerDelay; 139 int mCurrentTimerDelay;
139 bool mRunning; 140 bool mRunning;
140 QTimer * mRunSaveTimer; 141 QTimer * mRunSaveTimer;
141 QDateTime mRunStart; 142 QDateTime mRunStart;
142 QDateTime mRunLastSave; 143 QDateTime mRunLastSave;
143 QDateTime mRunEnd; 144 QDateTime mRunEnd;
144 bool accept(Visitor &v) { return v.visit(this); } 145 bool accept(Visitor &v) { return v.visit(this); }
145 146
146 QDateTime mDtDue; // due date of todo 147 QDateTime mDtDue; // due date of todo
147 148
148 bool mHasDueDate; // if todo has associated due date 149 bool mHasDueDate; // if todo has associated due date
149 150
150// int mStatus; // confirmed/delegated/tentative/etc 151// int mStatus; // confirmed/delegated/tentative/etc
151 152
152 QDateTime mCompleted; 153 QDateTime mCompleted;
153 bool mHasCompletedDate; 154 bool mHasCompletedDate;
154 155
155 int mPercentComplete; 156 int mPercentComplete;
156}; 157};
157 158
158 bool operator==( const Todo&, const Todo& ); 159 bool operator==( const Todo&, const Todo& );
159} 160}
160 161
161#endif 162#endif