karm

task.cpp
1#include <tqcstring.h>
2#include <tqdatetime.h>
3#include <tqstring.h>
4#include <tqtimer.h>
5
6#include <kiconloader.h>
7
8#include "tdeapplication.h" // tdeApp
9#include "kdebug.h"
10
11#include "event.h"
12
13#include "karmutility.h"
14#include "task.h"
15#include "taskview.h"
16#include "preferences.h"
17
18
19const int gSecondsPerMinute = 60;
20
21
22TQPtrVector<TQPixmap> *Task::icons = 0;
23
24Task::Task( const TQString& taskName, long minutes, long sessionTime,
25 DesktopList desktops, TaskView *parent)
26 : TQObject(), TQListViewItem(parent)
27{
28 init(taskName, minutes, sessionTime, desktops, 0);
29}
30
31Task::Task( const TQString& taskName, long minutes, long sessionTime,
32 DesktopList desktops, Task *parent)
33 : TQObject(), TQListViewItem(parent)
34{
35 init(taskName, minutes, sessionTime, desktops, 0);
36}
37
38Task::Task( KCal::Todo* todo, TaskView* parent )
39 : TQObject(), TQListViewItem( parent )
40{
41 long minutes = 0;
42 TQString name;
43 long sessionTime = 0;
44 int percent_complete = 0;
45 DesktopList desktops;
46
47 parseIncidence(todo, minutes, sessionTime, name, desktops, percent_complete);
48 init(name, minutes, sessionTime, desktops, percent_complete);
49}
50
51void Task::init( const TQString& taskName, long minutes, long sessionTime,
52 DesktopList desktops, int percent_complete)
53{
54 // If our parent is the taskview then connect our totalTimesChanged
55 // signal to its receiver
56 if ( ! parent() )
57 connect( this, TQ_SIGNAL( totalTimesChanged ( long, long ) ),
58 listView(), TQ_SLOT( taskTotalTimesChanged( long, long) ));
59
60 connect( this, TQ_SIGNAL( deletingTask( Task* ) ),
61 listView(), TQ_SLOT( deletingTask( Task* ) ));
62
63 if (icons == 0) {
64 icons = new TQPtrVector<TQPixmap>(8);
65 TDEIconLoader kil("karm"); // always load icons from the KArm application
66 for (int i=0; i<8; i++)
67 {
68 TQPixmap *icon = new TQPixmap();
69 TQString name;
70 name.sprintf("watch-%d.xpm",i);
71 *icon = kil.loadIcon( name, TDEIcon::User );
72 icons->insert(i,icon);
73 }
74 }
75
76 _removing = false;
77 _name = taskName.stripWhiteSpace();
78 _lastStart = TQDateTime::currentDateTime();
79 _totalTime = _time = minutes;
80 _totalSessionTime = _sessionTime = sessionTime;
81 _timer = new TQTimer(this);
82 _desktops = desktops;
83 connect(_timer, TQ_SIGNAL(timeout()), this, TQ_SLOT(updateActiveIcon()));
84 setPixmap(1, UserIcon(TQString::fromLatin1("empty-watch.xpm")));
85 _currentPic = 0;
86 _percentcomplete = percent_complete;
87
88 update();
89 changeParentTotalTimes( _sessionTime, _time);
90}
91
92Task::~Task() {
93 emit deletingTask(this);
94 delete _timer;
95}
96
97void Task::setRunning( bool on, KarmStorage* storage, TQDateTime whenStarted, TQDateTime whenStopped )
98// Sets a task running or stopped. If the task is to be stopped, whenStarted is not evaluated.
99// on=true if the task shall be started on=false if the task shall be stopped
100// This is the back-end, the front-end is StartTimerFor()
101{
102 kdDebug(5970) << "Entering Task::setRunning " << "on=" << on << "whenStarted=" << whenStarted << " whenStopped=" << whenStopped << endl;
103 if ( on )
104 {
105 if (!_timer->isActive())
106 {
107 _timer->start(1000);
108 storage->startTimer(this);
109 _currentPic=7;
110 _lastStart = whenStarted;
112 }
113 }
114 else
115 {
116 if (_timer->isActive())
117 {
118 _timer->stop();
119 if ( ! _removing )
120 {
121 storage->stopTimer(this, whenStopped);
122 setPixmap(1, UserIcon(TQString::fromLatin1("empty-watch.xpm")));
123 }
124 }
125 }
126}
127
128void Task::setUid(TQString uid) {
129 _uid = uid;
130}
131
132bool Task::isRunning() const
133{
134 return _timer->isActive();
135}
136
137void Task::setName( const TQString& name, KarmStorage* storage )
138{
139 kdDebug(5970) << "Task:setName: " << name << endl;
140
141 TQString oldname = _name;
142 if ( oldname != name ) {
143 _name = name;
144 storage->setName(this, oldname);
145 update();
146 }
147}
148
149void Task::setPercentComplete(const int percent, KarmStorage *storage)
150{
151 kdDebug(5970) << "Task::setPercentComplete(" << percent << ", storage): "
152 << _uid << endl;
153
154 if (!percent)
155 _percentcomplete = 0;
156 else if (percent > 100)
157 _percentcomplete = 100;
158 else if (percent < 0)
159 _percentcomplete = 0;
160 else
161 _percentcomplete = percent;
162
163 if (isRunning() && _percentcomplete==100) taskView()->stopTimerFor(this);
164
166
167 // When parent marked as complete, mark all children as complete as well.
168 // Complete tasks are not displayed in the task view, so if a parent is
169 // marked as complete and some of the children are not, then we get an error
170 // message. KArm actually keep chugging along in this case and displays the
171 // child tasks just fine, so an alternative solution is to remove that error
172 // message (from KarmStorage::load). But I think it makes more sense that
173 // if you mark a parent task as complete, then all children should be
174 // complete as well.
175 //
176 // This behavior is consistent with KOrganizer (as of 2003-09-24).
177 if (_percentcomplete == 100)
178 {
179 for (Task* child= this->firstChild(); child; child = child->nextSibling())
180 child->setPercentComplete(_percentcomplete, storage);
181 }
182}
183
185{
186 TQPixmap icon ;
187 if (_percentcomplete >= 100)
188 icon = UserIcon("task-complete.xpm");
189 else
190 icon = UserIcon("task-incomplete.xpm");
191 setPixmap(0, icon);
192}
193
194bool Task::isComplete() { return _percentcomplete == 100; }
195
197{
198 while ( Task* child = firstChild() )
199 child->removeFromView();
200 delete this;
201}
202
203void Task::setDesktopList ( DesktopList desktopList )
204{
205 _desktops = desktopList;
206}
207
208void Task::changeTime( long minutes, KarmStorage* storage )
209{
210 changeTimes( minutes, minutes, storage);
211}
212
213void Task::changeTimes( long minutesSession, long minutes, KarmStorage* storage)
214{
215 if( minutesSession != 0 || minutes != 0)
216 {
217 _sessionTime += minutesSession;
218 _time += minutes;
219 if ( storage ) storage->changeTime(this, minutes * gSecondsPerMinute);
220 changeTotalTimes( minutesSession, minutes );
221 }
222}
223
224void Task::changeTotalTimes( long minutesSession, long minutes )
225{
226 kdDebug(5970)
227 << "Task::changeTotalTimes(" << minutesSession << ", "
228 << minutes << ") for " << name() << endl;
229
230 _totalSessionTime += minutesSession;
231 _totalTime += minutes;
232 update();
233 changeParentTotalTimes( minutesSession, minutes );
234}
235
237{
238 _totalSessionTime -= _sessionTime;
239 _totalTime -= _time;
240 changeParentTotalTimes( -_sessionTime, -_time);
241 _sessionTime = 0;
242 _time = 0;
243 update();
244}
245
246void Task::changeParentTotalTimes( long minutesSession, long minutes )
247{
248 //kdDebug(5970)
249 // << "Task::changeParentTotalTimes(" << minutesSession << ", "
250 // << minutes << ") for " << name() << endl;
251
252 if ( isRoot() )
253 emit totalTimesChanged( minutesSession, minutes );
254 else
255 parent()->changeTotalTimes( minutesSession, minutes );
256}
257
258bool Task::remove( TQPtrList<Task>& activeTasks, KarmStorage* storage)
259{
260 kdDebug(5970) << "Task::remove: " << _name << endl;
261
262 bool ok = true;
263
264 _removing = true;
265 storage->removeTask(this);
266 if( isRunning() ) setRunning( false, storage );
267
268 for (Task* child = this->firstChild(); child; child = child->nextSibling())
269 {
270 if (child->isRunning())
271 child->setRunning(false, storage);
272 child->remove(activeTasks, storage);
273 }
274
275 changeParentTotalTimes( -_sessionTime, -_time);
276
277 _removing = false;
278
279 return ok;
280}
281
283{
284 _currentPic = (_currentPic+1) % 8;
285 setPixmap(1, *(*icons)[_currentPic]);
286}
287
288TQString Task::fullName() const
289{
290 if (isRoot())
291 return name();
292 else
293 return parent()->fullName() + TQString::fromLatin1("/") + name();
294}
295
296KCal::Todo* Task::asTodo(KCal::Todo* todo) const
297{
298
299 Q_ASSERT( todo != NULL );
300
301 kdDebug(5970) << "Task::asTodo: name() = '" << name() << "'" << endl;
302 todo->setSummary( name() );
303
304 // Note: if the date start is empty, the KOrganizer GUI will have the
305 // checkbox blank, but will prefill the todo's starting datetime to the
306 // time the file is opened.
307 // todo->setDtStart( current );
308
309 todo->setCustomProperty( tdeApp->instanceName(),
310 TQCString( "totalTaskTime" ), TQString::number( _time ) );
311 todo->setCustomProperty( tdeApp->instanceName(),
312 TQCString( "totalSessionTime" ), TQString::number( _sessionTime) );
313
314 if (getDesktopStr().isEmpty())
315 todo->removeCustomProperty(tdeApp->instanceName(), TQCString("desktopList"));
316 else
317 todo->setCustomProperty( tdeApp->instanceName(),
318 TQCString( "desktopList" ), getDesktopStr() );
319
320 todo->setOrganizer( Preferences::instance()->userRealName() );
321
322 todo->setPercentComplete(_percentcomplete);
323
324 return todo;
325}
326
327bool Task::parseIncidence( KCal::Incidence* incident, long& minutes,
328 long& sessionMinutes, TQString& name, DesktopList& desktops,
329 int& percent_complete )
330{
331 bool ok;
332
333 name = incident->summary();
334 _uid = incident->uid();
335
336 _comment = incident->description();
337
338 ok = false;
339 minutes = incident->customProperty( tdeApp->instanceName(),
340 TQCString( "totalTaskTime" )).toInt( &ok );
341 if ( !ok )
342 minutes = 0;
343
344 ok = false;
345 sessionMinutes = incident->customProperty( tdeApp->instanceName(),
346 TQCString( "totalSessionTime" )).toInt( &ok );
347 if ( !ok )
348 sessionMinutes = 0;
349
350 TQString desktopList = incident->customProperty( tdeApp->instanceName(),
351 TQCString( "desktopList" ) );
352 TQStringList desktopStrList = TQStringList::split( TQString::fromLatin1(","),
353 desktopList );
354 desktops.clear();
355
356 for ( TQStringList::iterator iter = desktopStrList.begin();
357 iter != desktopStrList.end();
358 ++iter ) {
359 int desktopInt = (*iter).toInt( &ok );
360 if ( ok ) {
361 desktops.push_back( desktopInt );
362 }
363 }
364
365 percent_complete = static_cast<KCal::Todo*>(incident)->percentComplete();
366
367 //kdDebug(5970) << "Task::parseIncidence: "
368 // << name << ", Minutes: " << minutes
369 // << ", desktop: " << desktopList << endl;
370
371 return true;
372}
373
374TQString Task::getDesktopStr() const
375{
376 if ( _desktops.empty() )
377 return TQString();
378
379 TQString desktopstr;
380 for ( DesktopList::const_iterator iter = _desktops.begin();
381 iter != _desktops.end();
382 ++iter ) {
383 desktopstr += TQString::number( *iter ) + TQString::fromLatin1( "," );
384 }
385 desktopstr.remove( desktopstr.length() - 1, 1 );
386 return desktopstr;
387}
388
390{
391 //kdDebug(5970) << "Task::cut - " << name() << endl;
392 changeParentTotalTimes( -_totalSessionTime, -_totalTime);
393 if ( ! parent())
394 listView()->takeItem(this);
395 else
396 parent()->takeItem(this);
397}
398
399void Task::move(Task* destination)
400{
401 cut();
402 paste(destination);
403}
404
405void Task::paste(Task* destination)
406{
407 destination->insertItem(this);
408 changeParentTotalTimes( _totalSessionTime, _totalTime);
409}
410
412{
413 setText(0, _name);
414 setText(1, formatTime(_sessionTime));
415 setText(2, formatTime(_time));
416 setText(3, formatTime(_totalSessionTime));
417 setText(4, formatTime(_totalTime));
418}
419
420void Task::addComment( TQString comment, KarmStorage* storage )
421{
422 _comment = _comment + TQString::fromLatin1("\n") + comment;
423 storage->addComment(this, comment);
424}
425
426TQString Task::comment() const
427{
428 return _comment;
429}
430
431int Task::compare ( TQListViewItem * i, int col, bool ascending ) const
432{
433 long thistime = 0;
434 long thattime = 0;
435 Task *task = static_cast<Task*>(i);
436
437 switch ( col )
438 {
439 case 1:
440 thistime = _sessionTime;
441 thattime = task->sessionTime();
442 break;
443 case 2:
444 thistime = _time;
445 thattime = task->time();
446 break;
447 case 3:
448 thistime = _totalSessionTime;
449 thattime = task->totalSessionTime();
450 break;
451 case 4:
452 thistime = _totalTime;
453 thattime = task->totalTime();
454 break;
455 default:
456 return key(col, ascending).localeAwareCompare( i->key(col, ascending) );
457 }
458
459 if ( thistime < thattime ) return -1;
460 if ( thistime > thattime ) return 1;
461 return 0;
462
463}
464
465#include "task.moc"
Singleton to store/retrieve KArm data to/from persistent storage.
Definition: karmstorage.h:68
void setName(const Task *task, const TQString &oldname)
Log a change to a task name.
Definition: karmstorage.h:219
bool removeTask(Task *task)
Remove this task from iCalendar file.
void startTimer(const Task *task)
Log the event that a timer has started for a task.
Definition: karmstorage.h:230
void stopTimer(const Task *task, TQDateTime when=TQDateTime::currentDateTime())
Log the event that the timer has stopped for this task.
void changeTime(const Task *task, const long deltaSeconds)
Log the change in a task's time.
void addComment(const Task *task, const TQString &comment)
Log a new comment for this task.
Container and interface for the tasks.
Definition: taskview.h:43
A class representing a task.
Definition: task.h:42
void addComment(TQString comment, KarmStorage *storage)
Add a comment to this task.
Definition: task.cpp:420
void changeTimes(long minutesSession, long minutes, KarmStorage *storage=0)
Add minutes to time and session time, and write to storage.
Definition: task.cpp:213
TaskView * taskView() const
Return task view for this task.
Definition: task.h:65
void resetTimes()
Reset all times to 0.
Definition: task.cpp:236
void setRunning(bool on, KarmStorage *storage, TQDateTime whenStarted=TQDateTime::currentDateTime(), TQDateTime whenStopped=TQDateTime::currentDateTime())
starts or stops a task
Definition: task.cpp:97
bool isComplete()
Return true if task is complete (percent complete equals 100).
Definition: task.cpp:194
void changeTime(long minutes, KarmStorage *storage)
Change task time.
Definition: task.cpp:208
void update()
Update the display of the task (all columns) in the UI.
Definition: task.cpp:411
void removeFromView()
Remove current task and all it's children from the view.
Definition: task.cpp:196
TQString name() const
returns the name of this task.
Definition: task.h:162
KCal::Todo * asTodo(KCal::Todo *calendar) const
Load the todo passed in with this tasks info.
Definition: task.cpp:296
void updateActiveIcon()
animate the active icon
Definition: task.cpp:282
void setName(const TQString &name, KarmStorage *storage)
sets the name of the task
Definition: task.cpp:137
TQString fullName() const
Returns that task name, prefixed by parent tree up to root.
Definition: task.cpp:288
void setPixmapProgress()
Sets an appropriate icon for this task based on its level of completion.
Definition: task.cpp:184
bool isRoot() const
tells you whether this task is the root of the task tree
Definition: task.h:209
void changeTotalTimes(long minutesSession, long minutes)
adds minutes to total and session time
Definition: task.cpp:224
TQString uid() const
Return unique iCalendar Todo ID for this task.
Definition: task.h:70
void setPercentComplete(const int percent, KarmStorage *storage)
Update percent complete for this task.
Definition: task.cpp:149
int compare(TQListViewItem *i, int col, bool ascending) const
Sort times numerically, not alphabetically.
Definition: task.cpp:431
void move(Task *destination)
cut Task out of parent Task or the TaskView and into the destination Task
Definition: task.cpp:399
void paste(Task *destination)
insert Task into the destination Task
Definition: task.cpp:405
bool isRunning() const
return the state of a task - if it's running or not
Definition: task.cpp:132
Task * firstChild() const
return parent Task or null in case of TaskView.
Definition: task.h:60
void cut()
cut Task out of parent Task or the TaskView
Definition: task.cpp:389
bool remove(TQPtrList< Task > &activeTasks, KarmStorage *storage)
remove Task with all it's children
Definition: task.cpp:258
TQString comment() const
Retrieve the entire comment for the task.
Definition: task.cpp:426
void deletingTask(Task *thisTask)
signal that we're about to delete a task
void setUid(const TQString uid)
Set unique id for the task.
Definition: task.cpp:128