00001 #include <qcstring.h>
00002 #include <qdatetime.h>
00003 #include <qstring.h>
00004 #include <qtimer.h>
00005
00006 #include <kiconloader.h>
00007
00008 #include "kapplication.h"
00009 #include "kdebug.h"
00010
00011 #include "event.h"
00012
00013 #include "karmutility.h"
00014 #include "task.h"
00015 #include "taskview.h"
00016 #include "preferences.h"
00017
00018
00019 const int gSecondsPerMinute = 60;
00020
00021
00022 QPtrVector<QPixmap> *Task::icons = 0;
00023
00024 Task::Task( const QString& taskName, long minutes, long sessionTime,
00025 DesktopList desktops, TaskView *parent)
00026 : QObject(), QListViewItem(parent)
00027 {
00028 init(taskName, minutes, sessionTime, desktops, 0);
00029 }
00030
00031 Task::Task( const QString& taskName, long minutes, long sessionTime,
00032 DesktopList desktops, Task *parent)
00033 : QObject(), QListViewItem(parent)
00034 {
00035 init(taskName, minutes, sessionTime, desktops, 0);
00036 }
00037
00038 Task::Task( KCal::Todo* todo, TaskView* parent )
00039 : QObject(), QListViewItem( parent )
00040 {
00041 long minutes = 0;
00042 QString name;
00043 long sessionTime = 0;
00044 int percent_complete = 0;
00045 DesktopList desktops;
00046
00047 parseIncidence(todo, minutes, sessionTime, name, desktops, percent_complete);
00048 init(name, minutes, sessionTime, desktops, percent_complete);
00049 }
00050
00051 void Task::init( const QString& taskName, long minutes, long sessionTime,
00052 DesktopList desktops, int percent_complete)
00053 {
00054
00055
00056 if ( ! parent() )
00057 connect( this, SIGNAL( totalTimesChanged ( long, long ) ),
00058 listView(), SLOT( taskTotalTimesChanged( long, long) ));
00059
00060 connect( this, SIGNAL( deletingTask( Task* ) ),
00061 listView(), SLOT( deletingTask( Task* ) ));
00062
00063 if (icons == 0) {
00064 icons = new QPtrVector<QPixmap>(8);
00065 KIconLoader* kil = new KIconLoader("karm");
00066 for (int i=0; i<8; i++)
00067 {
00068 QPixmap *icon = new QPixmap();
00069 QString name;
00070 name.sprintf("watch-%d.xpm",i);
00071 *icon = kil->loadIcon( name, KIcon::User );
00072 icons->insert(i,icon);
00073 }
00074 }
00075
00076 _removing = false;
00077 _name = taskName.stripWhiteSpace();
00078 _lastStart = QDateTime::currentDateTime();
00079 _totalTime = _time = minutes;
00080 _totalSessionTime = _sessionTime = sessionTime;
00081 _timer = new QTimer(this);
00082 _desktops = desktops;
00083 connect(_timer, SIGNAL(timeout()), this, SLOT(updateActiveIcon()));
00084 setPixmap(1, UserIcon(QString::fromLatin1("empty-watch.xpm")));
00085 _currentPic = 0;
00086 _percentcomplete = percent_complete;
00087
00088 update();
00089 changeParentTotalTimes( _sessionTime, _time);
00090 }
00091
00092 Task::~Task() {
00093 emit deletingTask(this);
00094 delete _timer;
00095 }
00096
00097 void Task::setRunning( bool on, KarmStorage* storage, QDateTime whenStarted, QDateTime whenStopped )
00098
00099 {
00100 kdDebug(5970) << "Entering Task::setRunning" << endl;
00101 if ( on ) {
00102 if (isComplete()) return;
00103 if (!_timer->isActive()) {
00104 _timer->start(1000);
00105 storage->startTimer(this);
00106 _currentPic=7;
00107 _lastStart = whenStarted;
00108 updateActiveIcon();
00109 }
00110 }
00111 else {
00112 if (_timer->isActive()) {
00113 _timer->stop();
00114 if ( ! _removing ) {
00115 storage->stopTimer(this, whenStopped);
00116 setPixmap(1, UserIcon(QString::fromLatin1("empty-watch.xpm")));
00117 }
00118 }
00119 }
00120 }
00121
00122 void Task::setUid(QString uid) {
00123 _uid = uid;
00124 }
00125
00126 bool Task::isRunning() const
00127 {
00128 return _timer->isActive();
00129 }
00130
00131 void Task::setName( const QString& name, KarmStorage* storage )
00132 {
00133 kdDebug(5970) << "Task:setName: " << name << endl;
00134
00135 QString oldname = _name;
00136 if ( oldname != name ) {
00137 _name = name;
00138 storage->setName(this, oldname);
00139 update();
00140 }
00141 }
00142
00143 void Task::setPercentComplete(const int percent, KarmStorage *storage)
00144 {
00145 kdDebug(5970) << "Task::setPercentComplete(" << percent << ", storage): "
00146 << _uid << endl;
00147
00148 if (!percent)
00149 _percentcomplete = 0;
00150 else if (percent > 100)
00151 _percentcomplete = 100;
00152 else if (percent < 0)
00153 _percentcomplete = 0;
00154 else
00155 _percentcomplete = percent;
00156
00157 if (isRunning() && _percentcomplete==100) setRunning(false, storage);
00158
00159 setPixmapProgress();
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 if (_percentcomplete == 100)
00172 {
00173 for (Task* child= this->firstChild(); child; child = child->nextSibling())
00174 child->setPercentComplete(_percentcomplete, storage);
00175 }
00176 }
00177
00178 void Task::setPixmapProgress()
00179 {
00180 QPixmap* icon = new QPixmap();
00181 if (_percentcomplete >= 100)
00182 *icon = UserIcon("task-complete.xpm");
00183 else
00184 *icon = UserIcon("task-incomplete.xpm");
00185 setPixmap(0, *icon);
00186 }
00187
00188 bool Task::isComplete() { return _percentcomplete == 100; }
00189
00190 void Task::removeFromView()
00191 {
00192 while ( Task* child = firstChild() )
00193 child->removeFromView();
00194 delete this;
00195 }
00196
00197 void Task::setDesktopList ( DesktopList desktopList )
00198 {
00199 _desktops = desktopList;
00200 }
00201
00202 void Task::changeTime( long minutes, KarmStorage* storage )
00203 {
00204 changeTimes( minutes, minutes, storage);
00205 }
00206
00207 void Task::changeTimes( long minutesSession, long minutes, KarmStorage* storage)
00208 {
00209 if( minutesSession != 0 || minutes != 0)
00210 {
00211 _sessionTime += minutesSession;
00212 _time += minutes;
00213 if ( storage ) storage->changeTime(this, minutes * gSecondsPerMinute);
00214 changeTotalTimes( minutesSession, minutes );
00215 }
00216 }
00217
00218 void Task::changeTotalTimes( long minutesSession, long minutes )
00219 {
00220 kdDebug(5970)
00221 << "Task::changeTotalTimes(" << minutesSession << ", "
00222 << minutes << ") for " << name() << endl;
00223
00224 _totalSessionTime += minutesSession;
00225 _totalTime += minutes;
00226 update();
00227 changeParentTotalTimes( minutesSession, minutes );
00228 }
00229
00230 void Task::resetTimes()
00231 {
00232 _totalSessionTime -= _sessionTime;
00233 _totalTime -= _time;
00234 changeParentTotalTimes( -_sessionTime, -_time);
00235 _sessionTime = 0;
00236 _time = 0;
00237 update();
00238 }
00239
00240 void Task::changeParentTotalTimes( long minutesSession, long minutes )
00241 {
00242
00243
00244
00245
00246 if ( isRoot() )
00247 emit totalTimesChanged( minutesSession, minutes );
00248 else
00249 parent()->changeTotalTimes( minutesSession, minutes );
00250 }
00251
00252 bool Task::remove( QPtrList<Task>& activeTasks, KarmStorage* storage)
00253 {
00254 kdDebug(5970) << "Task::remove: " << _name << endl;
00255
00256 bool ok = true;
00257
00258 _removing = true;
00259 storage->removeTask(this);
00260 if( isRunning() ) setRunning( false, storage );
00261
00262 for (Task* child = this->firstChild(); child; child = child->nextSibling())
00263 {
00264 if (child->isRunning())
00265 child->setRunning(false, storage);
00266 child->remove(activeTasks, storage);
00267 }
00268
00269 changeParentTotalTimes( -_sessionTime, -_time);
00270
00271 _removing = false;
00272
00273 return ok;
00274 }
00275
00276 void Task::updateActiveIcon()
00277 {
00278 _currentPic = (_currentPic+1) % 8;
00279 setPixmap(1, *(*icons)[_currentPic]);
00280 }
00281
00282 QString Task::fullName() const
00283 {
00284 if (isRoot())
00285 return name();
00286 else
00287 return parent()->fullName() + QString::fromLatin1("/") + name();
00288 }
00289
00290 KCal::Todo* Task::asTodo(KCal::Todo* todo) const
00291 {
00292
00293 Q_ASSERT( todo != NULL );
00294
00295 kdDebug(5970) << "Task::asTodo: name() = '" << name() << "'" << endl;
00296 todo->setSummary( name() );
00297
00298
00299
00300
00301
00302
00303 todo->setCustomProperty( kapp->instanceName(),
00304 QCString( "totalTaskTime" ), QString::number( _time ) );
00305 todo->setCustomProperty( kapp->instanceName(),
00306 QCString( "totalSessionTime" ), QString::number( _sessionTime) );
00307
00308 if (getDesktopStr().isEmpty())
00309 todo->removeCustomProperty(kapp->instanceName(), QCString("desktopList"));
00310 else
00311 todo->setCustomProperty( kapp->instanceName(),
00312 QCString( "desktopList" ), getDesktopStr() );
00313
00314 todo->setOrganizer( Preferences::instance()->userRealName() );
00315
00316 todo->setPercentComplete(_percentcomplete);
00317
00318 return todo;
00319 }
00320
00321 bool Task::parseIncidence( KCal::Incidence* incident, long& minutes,
00322 long& sessionMinutes, QString& name, DesktopList& desktops,
00323 int& percent_complete )
00324 {
00325 bool ok;
00326
00327 name = incident->summary();
00328 _uid = incident->uid();
00329
00330 _comment = incident->description();
00331
00332 ok = false;
00333 minutes = incident->customProperty( kapp->instanceName(),
00334 QCString( "totalTaskTime" )).toInt( &ok );
00335 if ( !ok )
00336 minutes = 0;
00337
00338 ok = false;
00339 sessionMinutes = incident->customProperty( kapp->instanceName(),
00340 QCString( "totalSessionTime" )).toInt( &ok );
00341 if ( !ok )
00342 sessionMinutes = 0;
00343
00344 QString desktopList = incident->customProperty( kapp->instanceName(),
00345 QCString( "desktopList" ) );
00346 QStringList desktopStrList = QStringList::split( QString::fromLatin1(","),
00347 desktopList );
00348 desktops.clear();
00349
00350 for ( QStringList::iterator iter = desktopStrList.begin();
00351 iter != desktopStrList.end();
00352 ++iter ) {
00353 int desktopInt = (*iter).toInt( &ok );
00354 if ( ok ) {
00355 desktops.push_back( desktopInt );
00356 }
00357 }
00358
00359 percent_complete = static_cast<KCal::Todo*>(incident)->percentComplete();
00360
00361
00362
00363
00364
00365 return true;
00366 }
00367
00368 QString Task::getDesktopStr() const
00369 {
00370 if ( _desktops.empty() )
00371 return QString();
00372
00373 QString desktopstr;
00374 for ( DesktopList::const_iterator iter = _desktops.begin();
00375 iter != _desktops.end();
00376 ++iter ) {
00377 desktopstr += QString::number( *iter ) + QString::fromLatin1( "," );
00378 }
00379 desktopstr.remove( desktopstr.length() - 1, 1 );
00380 return desktopstr;
00381 }
00382
00383 void Task::cut()
00384 {
00385
00386 changeParentTotalTimes( -_totalSessionTime, -_totalTime);
00387 if ( ! parent())
00388 listView()->takeItem(this);
00389 else
00390 parent()->takeItem(this);
00391 }
00392
00393 void Task::move(Task* destination)
00394 {
00395 cut();
00396 paste(destination);
00397 }
00398
00399 void Task::paste(Task* destination)
00400 {
00401 destination->insertItem(this);
00402 changeParentTotalTimes( _totalSessionTime, _totalTime);
00403 }
00404
00405 void Task::update()
00406 {
00407 setText(0, _name);
00408 setText(1, formatTime(_sessionTime));
00409 setText(2, formatTime(_time));
00410 setText(3, formatTime(_totalSessionTime));
00411 setText(4, formatTime(_totalTime));
00412 }
00413
00414 void Task::addComment( QString comment, KarmStorage* storage )
00415 {
00416 _comment = _comment + QString::fromLatin1("\n") + comment;
00417 storage->addComment(this, comment);
00418 }
00419
00420 QString Task::comment() const
00421 {
00422 return _comment;
00423 }
00424
00425 int Task::compare ( QListViewItem * i, int col, bool ascending ) const
00426 {
00427 long thistime = 0;
00428 long thattime = 0;
00429 Task *task = static_cast<Task*>(i);
00430
00431 switch ( col )
00432 {
00433 case 1:
00434 thistime = _sessionTime;
00435 thattime = task->sessionTime();
00436 break;
00437 case 2:
00438 thistime = _time;
00439 thattime = task->time();
00440 break;
00441 case 3:
00442 thistime = _totalSessionTime;
00443 thattime = task->totalSessionTime();
00444 break;
00445 case 4:
00446 thistime = _totalTime;
00447 thattime = task->totalTime();
00448 break;
00449 default:
00450 return key(col, ascending).localeAwareCompare( i->key(col, ascending) );
00451 }
00452
00453 if ( thistime < thattime ) return -1;
00454 if ( thistime > thattime ) return 1;
00455 return 0;
00456
00457 }
00458
00459 #include "task.moc"