summaryrefslogtreecommitdiffabout
path: root/libkcal/todo.cpp
Unidiff
Diffstat (limited to 'libkcal/todo.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r--libkcal/todo.cpp31
1 files changed, 29 insertions, 2 deletions
diff --git a/libkcal/todo.cpp b/libkcal/todo.cpp
index 48d37d5..de07496 100644
--- a/libkcal/todo.cpp
+++ b/libkcal/todo.cpp
@@ -1,235 +1,262 @@
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#define SAVETIMER_TIMEOUT_SECONDS 300
33//#define SAVETIMER_TIMEOUT_SECONDS 8
34#define SAVETIMER_TIMEOUT_RETRY_SECONDS 5
35
32using namespace KCal; 36using namespace KCal;
33 37
34Todo::Todo(): QObject(), Incidence() 38Todo::Todo(): QObject(), Incidence()
35{ 39{
36// mStatus = TENTATIVE; 40// mStatus = TENTATIVE;
37 41
38 mHasDueDate = false; 42 mHasDueDate = false;
39 setHasStartDate( false ); 43 setHasStartDate( false );
40 mCompleted = getEvenTime(QDateTime::currentDateTime()); 44 mCompleted = getEvenTime(QDateTime::currentDateTime());
41 mHasCompletedDate = false; 45 mHasCompletedDate = false;
42 mPercentComplete = 0; 46 mPercentComplete = 0;
43 mRunning = false; 47 mRunning = false;
44 mRunSaveTimer = 0; 48 mRunSaveTimer = 0;
45 setFloats( true ); 49 setFloats( true );
50 mCurrentTimerDelay = 0;
46} 51}
47 52
48Todo::Todo(const Todo &t) : QObject(),Incidence(t) 53Todo::Todo(const Todo &t) : QObject(),Incidence(t)
49{ 54{
50 mDtDue = t.mDtDue; 55 mDtDue = t.mDtDue;
51 mHasDueDate = t.mHasDueDate; 56 mHasDueDate = t.mHasDueDate;
52 mCompleted = t.mCompleted; 57 mCompleted = t.mCompleted;
53 mHasCompletedDate = t.mHasCompletedDate; 58 mHasCompletedDate = t.mHasCompletedDate;
54 mPercentComplete = t.mPercentComplete; 59 mPercentComplete = t.mPercentComplete;
55 mRunning = false; 60 mRunning = false;
56 mRunSaveTimer = 0; 61 mRunSaveTimer = 0;
62 mCurrentTimerDelay = 0;
57} 63}
58 64
59Todo::~Todo() 65Todo::~Todo()
60{ 66{
61 setRunning( false ); 67 setRunning( false );
62 //qDebug("Todo::~Todo() "); 68 //qDebug("Todo::~Todo() ");
63} 69}
64 70
65void Todo::setRunningFalse( QString s ) 71void Todo::setRunningFalse( QString s )
66{ 72{
67 if ( ! mRunning ) 73 if ( ! mRunning )
68 return; 74 return;
69 mRunning = false; 75 mRunning = false;
70 if ( mRunSaveTimer ) 76 if ( mRunSaveTimer )
71 mRunSaveTimer->stop(); 77 mRunSaveTimer->stop();
72 saveRunningInfoToFile( s ); 78 saveRunningInfoToFile( s );
73} 79}
74void Todo::stopRunning() 80void Todo::stopRunning()
75{ 81{
76 if ( !mRunning ) 82 if ( !mRunning )
77 return; 83 return;
78 if ( mRunSaveTimer ) 84 if ( mRunSaveTimer )
79 mRunSaveTimer->stop(); 85 mRunSaveTimer->stop();
80 mRunning = false; 86 mRunning = false;
81} 87}
82void Todo::setRunning( bool run ) 88void Todo::setRunning( bool run )
83{ 89{
84 if ( run == mRunning ) 90 if ( run == mRunning )
85 return; 91 return;
86 //qDebug("Todo::setRunning %d ", run); 92 //qDebug("Todo::setRunning %d ", run);
87 if ( !mRunSaveTimer ) { 93 if ( !mRunSaveTimer ) {
88 mRunSaveTimer = new QTimer ( this ); 94 mRunSaveTimer = new QTimer ( this );
89 connect ( mRunSaveTimer, SIGNAL( timeout() ), this , SLOT ( saveRunningInfoToFile() ) ); 95 connect ( mRunSaveTimer, SIGNAL( timeout() ), this , SLOT ( timerSlotSaveRunningInfoToFile() ) );
90 } 96 }
91 mRunning = run; 97 mRunning = run;
98 mRunLastSave = QDateTime::currentDateTime();
92 if ( mRunning ) { 99 if ( mRunning ) {
93 mRunSaveTimer->start( 1000 * 60 * 5 ); // 5 min 100 mRunSaveTimer->start( SAVETIMER_TIMEOUT_SECONDS * 1000 ); // 5 min
94 mRunStart = QDateTime::currentDateTime(); 101 mRunStart = QDateTime::currentDateTime();
102 mRunLastSave = QDateTime::currentDateTime();
103 mCurrentTimerDelay = SAVETIMER_TIMEOUT_SECONDS;
95 } else { 104 } else {
96 mRunSaveTimer->stop(); 105 mRunSaveTimer->stop();
97 saveRunningInfoToFile(); 106 saveRunningInfoToFile();
98 } 107 }
99} 108}
100void Todo::saveRunningInfo( QString comment, QDateTime start, QDateTime end ) 109void Todo::saveRunningInfo( QString comment, QDateTime start, QDateTime end )
101{ 110{
102 if ( !mRunning) return; 111 if ( !mRunning) return;
103 mRunning = false; 112 mRunning = false;
104 mRunStart = start; 113 mRunStart = start;
105 mRunEnd = end; 114 mRunEnd = end;
106 saveRunningInfoToFile( comment ); 115 saveRunningInfoToFile( comment );
107} 116}
117void Todo::timerSlotSaveRunningInfoToFile()
118{
119 mRunEnd = QDateTime::currentDateTime();
120 int secsTo = mRunLastSave.secsTo( mRunEnd );
121 if( secsTo == 8 ) ++secsTo;
122 qDebug("KO Todo::saveTimerTimeout %d %d", secsTo, mCurrentTimerDelay );
123 if ( secsTo > mCurrentTimerDelay ) {
124 qDebug("KO Todo::saveTimerTimeout restart %d ", SAVETIMER_TIMEOUT_RETRY_SECONDS );
125 mRunSaveTimer->start( SAVETIMER_TIMEOUT_RETRY_SECONDS * 1000 );
126 mRunLastSave = QDateTime::currentDateTime();
127 mCurrentTimerDelay = SAVETIMER_TIMEOUT_RETRY_SECONDS;
128 return;
129 }
130 mRunSaveTimer->start( SAVETIMER_TIMEOUT_SECONDS * 1000 ); // 5 min
131 mRunLastSave = QDateTime::currentDateTime();
132 mCurrentTimerDelay = SAVETIMER_TIMEOUT_SECONDS;
133 saveRunningInfoToFile( QString::null );
134}
108void Todo::saveRunningInfoToFile() 135void Todo::saveRunningInfoToFile()
109{ 136{
110 mRunEnd = QDateTime::currentDateTime(); 137 mRunEnd = QDateTime::currentDateTime();
111 saveRunningInfoToFile( QString::null ); 138 saveRunningInfoToFile( QString::null );
112} 139}
113void Todo::saveRunningInfoToFile( QString comment ) 140void Todo::saveRunningInfoToFile( QString comment )
114{ 141{
115 //qDebug("Todo::saveRunningInfoToFile() %s", summary().latin1()); 142 //qDebug("Todo::saveRunningInfoToFile() %s", summary().latin1());
116 if ( mRunStart.secsTo ( mRunEnd) < 15 ) { 143 if ( mRunStart.secsTo ( mRunEnd) < 15 ) {
117 qDebug("Running time < 15 seconds. Skipped. "); 144 qDebug("Running time < 15 seconds. Skipped. ");
118 return; 145 return;
119 } 146 }
120 QString dir = KGlobalSettings::timeTrackerDir(); 147 QString dir = KGlobalSettings::timeTrackerDir();
121 //qDebug("%s ", dir.latin1()); 148 //qDebug("%s ", dir.latin1());
122 QString file = "%1%2%3-%4%5%6-"; 149 QString file = "%1%2%3-%4%5%6-";
123 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 ); 150 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 );
124 file.replace ( QRegExp (" "), "0" ); 151 file.replace ( QRegExp (" "), "0" );
125 file += uid(); 152 file += uid();
126 //qDebug("File %s ",file.latin1() ); 153 //qDebug("File %s ",file.latin1() );
127 CalendarLocal cal; 154 CalendarLocal cal;
128 cal.setLocalTime(); 155 cal.setLocalTime();
129 Todo * to = (Todo*) clone(); 156 Todo * to = (Todo*) clone();
130 to->setFloats( false ); 157 to->setFloats( false );
131 to->setDtStart( mRunStart ); 158 to->setDtStart( mRunStart );
132 to->setHasStartDate( true ); 159 to->setHasStartDate( true );
133 to->setDtDue( mRunEnd ); 160 to->setDtDue( mRunEnd );
134 to->setHasDueDate( true ); 161 to->setHasDueDate( true );
135 to->setUid( file ); 162 to->setUid( file );
136 if ( !comment.isEmpty() ) { 163 if ( !comment.isEmpty() ) {
137 QString des = to->description(); 164 QString des = to->description();
138 if ( des.isEmpty () ) 165 if ( des.isEmpty () )
139 to->setDescription( "TT-Note: " + comment ); 166 to->setDescription( "TT-Note: " + comment );
140 else 167 else
141 to->setDescription( "TT-Note: " + comment +"\n" + des ); 168 to->setDescription( "TT-Note: " + comment +"\n" + des );
142 } 169 }
143 cal.addIncidence( to ); 170 cal.addIncidence( to );
144 ICalFormat format( false ); 171 ICalFormat format( false );
145 file = dir +"/" +file +".ics"; 172 file = dir +"/" +file +".ics";
146 format.save( &cal, file ); 173 format.save( &cal, file );
147 saveParents(); 174 saveParents();
148 175
149} 176}
150void Todo::saveParents() 177void Todo::saveParents()
151{ 178{
152 if (!relatedTo() ) 179 if (!relatedTo() )
153 return; 180 return;
154 Incidence * inc = relatedTo(); 181 Incidence * inc = relatedTo();
155 if ( inc->typeID() != todoID ) 182 if ( inc->typeID() != todoID )
156 return; 183 return;
157 Todo* to = (Todo*)inc; 184 Todo* to = (Todo*)inc;
158 bool saveTodo = false; 185 bool saveTodo = false;
159 QString file = KGlobalSettings::timeTrackerDir() + "/"+ to->uid() + ".ics"; 186 QString file = KGlobalSettings::timeTrackerDir() + "/"+ to->uid() + ".ics";
160 QFileInfo fi ( file ); 187 QFileInfo fi ( file );
161 if ( fi.exists() ) { 188 if ( fi.exists() ) {
162 if ( fi.lastModified () < to->lastModified ()) 189 if ( fi.lastModified () < to->lastModified ())
163 saveTodo = true; 190 saveTodo = true;
164 } else { 191 } else {
165 saveTodo = true; 192 saveTodo = true;
166 } 193 }
167 if ( saveTodo ) { 194 if ( saveTodo ) {
168 CalendarLocal cal; 195 CalendarLocal cal;
169 cal.setLocalTime(); 196 cal.setLocalTime();
170 Todo * par = (Todo *) to->clone(); 197 Todo * par = (Todo *) to->clone();
171 cal.addIncidence( par ); 198 cal.addIncidence( par );
172 ICalFormat format( false ); 199 ICalFormat format( false );
173 format.save( &cal, file ); 200 format.save( &cal, file );
174 } 201 }
175 to->saveParents(); 202 to->saveParents();
176} 203}
177 204
178int Todo::runTime() 205int Todo::runTime()
179{ 206{
180 if ( !mRunning ) 207 if ( !mRunning )
181 return 0; 208 return 0;
182 return mRunStart.secsTo( QDateTime::currentDateTime() ); 209 return mRunStart.secsTo( QDateTime::currentDateTime() );
183} 210}
184bool Todo::hasRunningSub() 211bool Todo::hasRunningSub()
185{ 212{
186 if ( mRunning ) 213 if ( mRunning )
187 return true; 214 return true;
188 Incidence *aTodo; 215 Incidence *aTodo;
189 for (aTodo = mRelations.first(); aTodo; aTodo = mRelations.next()) { 216 for (aTodo = mRelations.first(); aTodo; aTodo = mRelations.next()) {
190 if ( ((Todo*)aTodo)->hasRunningSub() ) 217 if ( ((Todo*)aTodo)->hasRunningSub() )
191 return true; 218 return true;
192 } 219 }
193 return false; 220 return false;
194} 221}
195Incidence *Todo::clone() 222Incidence *Todo::clone()
196{ 223{
197 return new Todo(*this); 224 return new Todo(*this);
198} 225}
199 226
200bool Todo::contains ( Todo* from ) 227bool Todo::contains ( Todo* from )
201{ 228{
202 229
203 if ( !from->summary().isEmpty() ) 230 if ( !from->summary().isEmpty() )
204 if ( !summary().startsWith( from->summary() )) 231 if ( !summary().startsWith( from->summary() ))
205 return false; 232 return false;
206 if ( from->hasStartDate() ) { 233 if ( from->hasStartDate() ) {
207 if ( !hasStartDate() ) 234 if ( !hasStartDate() )
208 return false; 235 return false;
209 if ( from->dtStart() != dtStart()) 236 if ( from->dtStart() != dtStart())
210 return false; 237 return false;
211 } 238 }
212 if ( from->hasDueDate() ){ 239 if ( from->hasDueDate() ){
213 if ( !hasDueDate() ) 240 if ( !hasDueDate() )
214 return false; 241 return false;
215 if ( from->dtDue() != dtDue()) 242 if ( from->dtDue() != dtDue())
216 return false; 243 return false;
217 } 244 }
218 if ( !from->location().isEmpty() ) 245 if ( !from->location().isEmpty() )
219 if ( !location().startsWith( from->location() ) ) 246 if ( !location().startsWith( from->location() ) )
220 return false; 247 return false;
221 if ( !from->description().isEmpty() ) 248 if ( !from->description().isEmpty() )
222 if ( !description().startsWith( from->description() )) 249 if ( !description().startsWith( from->description() ))
223 return false; 250 return false;
224 if ( from->alarms().count() ) { 251 if ( from->alarms().count() ) {
225 Alarm *a = from->alarms().first(); 252 Alarm *a = from->alarms().first();
226 if ( a->enabled() ){ 253 if ( a->enabled() ){
227 if ( !alarms().count() ) 254 if ( !alarms().count() )
228 return false; 255 return false;
229 Alarm *b = alarms().first(); 256 Alarm *b = alarms().first();
230 if( ! b->enabled() ) 257 if( ! b->enabled() )
231 return false; 258 return false;
232 if ( ! (a->offset() == b->offset() )) 259 if ( ! (a->offset() == b->offset() ))
233 return false; 260 return false;
234 } 261 }
235 } 262 }