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 )
00098 {
00099 if ( on ) {
00100 if (isComplete()) return;
00101 if (!_timer->isActive()) {
00102 _timer->start(1000);
00103 storage->startTimer(this);
00104 _currentPic=7;
00105 _lastStart = whenStarted;
00106 updateActiveIcon();
00107 }
00108 }
00109 else {
00110 if (_timer->isActive()) {
00111 _timer->stop();
00112 if ( ! _removing ) {
00113 storage->stopTimer(this);
00114 setPixmap(1, UserIcon(QString::fromLatin1("empty-watch.xpm")));
00115 }
00116 }
00117 }
00118 }
00119
00120 void Task::setUid(QString uid) {
00121 _uid = uid;
00122 }
00123
00124 bool Task::isRunning() const
00125 {
00126 return _timer->isActive();
00127 }
00128
00129 void Task::setName( const QString& name, KarmStorage* storage )
00130 {
00131 kdDebug(5970) << "Task:setName: " << name << endl;
00132
00133 QString oldname = _name;
00134 if ( oldname != name ) {
00135 _name = name;
00136 storage->setName(this, oldname);
00137 update();
00138 }
00139 }
00140
00141 void Task::setPercentComplete(const int percent, KarmStorage *storage)
00142 {
00143 kdDebug(5970) << "Task::setPercentComplete(" << percent << ", storage): "
00144 << _uid << endl;
00145
00146 if (!percent)
00147 _percentcomplete = 0;
00148 else if (percent > 100)
00149 _percentcomplete = 100;
00150 else if (percent < 0)
00151 _percentcomplete = 0;
00152 else
00153 _percentcomplete = percent;
00154
00155 if (isRunning() && _percentcomplete==100) setRunning(false, storage);
00156
00157 setPixmapProgress();
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 if (_percentcomplete == 100)
00170 {
00171 for (Task* child= this->firstChild(); child; child = child->nextSibling())
00172 child->setPercentComplete(_percentcomplete, storage);
00173 }
00174 }
00175
00176 void Task::setPixmapProgress()
00177 {
00178 QPixmap* icon = new QPixmap();
00179 if (_percentcomplete >= 100)
00180 *icon = UserIcon("task-complete.xpm");
00181 else
00182 *icon = UserIcon("task-incomplete.xpm");
00183 setPixmap(0, *icon);
00184 }
00185
00186 bool Task::isComplete() { return _percentcomplete == 100; }
00187
00188 void Task::removeFromView()
00189 {
00190 while ( Task* child = firstChild() )
00191 child->removeFromView();
00192 delete this;
00193 }
00194
00195 void Task::setDesktopList ( DesktopList desktopList )
00196 {
00197 _desktops = desktopList;
00198 }
00199
00200 void Task::changeTime( long minutes, KarmStorage* storage )
00201 {
00202 changeTimes( minutes, minutes, storage);
00203 }
00204
00205 void Task::changeTimes( long minutesSession, long minutes, KarmStorage* storage)
00206 {
00207 if( minutesSession != 0 || minutes != 0)
00208 {
00209 _sessionTime += minutesSession;
00210 _time += minutes;
00211 if ( storage ) storage->changeTime(this, minutes * gSecondsPerMinute);
00212 changeTotalTimes( minutesSession, minutes );
00213 }
00214 }
00215
00216 void Task::changeTotalTimes( long minutesSession, long minutes )
00217 {
00218 kdDebug(5970)
00219 << "Task::changeTotalTimes(" << minutesSession << ", "
00220 << minutes << ") for " << name() << endl;
00221
00222 _totalSessionTime += minutesSession;
00223 _totalTime += minutes;
00224 update();
00225 changeParentTotalTimes( minutesSession, minutes );
00226 }
00227
00228 void Task::resetTimes()
00229 {
00230 _totalSessionTime -= _sessionTime;
00231 _totalTime -= _time;
00232 changeParentTotalTimes( -_sessionTime, -_time);
00233 _sessionTime = 0;
00234 _time = 0;
00235 update();
00236 }
00237
00238 void Task::changeParentTotalTimes( long minutesSession, long minutes )
00239 {
00240
00241
00242
00243
00244 if ( isRoot() )
00245 emit totalTimesChanged( minutesSession, minutes );
00246 else
00247 parent()->changeTotalTimes( minutesSession, minutes );
00248 }
00249
00250 bool Task::remove( QPtrList<Task>& activeTasks, KarmStorage* storage)
00251 {
00252 kdDebug(5970) << "Task::remove: " << _name << endl;
00253
00254 bool ok = true;
00255
00256 _removing = true;
00257 storage->removeTask(this);
00258 if( isRunning() ) setRunning( false, storage );
00259
00260 for (Task* child = this->firstChild(); child; child = child->nextSibling())
00261 {
00262 if (child->isRunning())
00263 child->setRunning(false, storage);
00264 child->remove(activeTasks, storage);
00265 }
00266
00267 changeParentTotalTimes( -_sessionTime, -_time);
00268
00269 _removing = false;
00270
00271 return ok;
00272 }
00273
00274 void Task::updateActiveIcon()
00275 {
00276 _currentPic = (_currentPic+1) % 8;
00277 setPixmap(1, *(*icons)[_currentPic]);
00278 }
00279
00280 QString Task::fullName() const
00281 {
00282 if (isRoot())
00283 return name();
00284 else
00285 return parent()->fullName() + QString::fromLatin1("/") + name();
00286 }
00287
00288 KCal::Todo* Task::asTodo(KCal::Todo* todo) const
00289 {
00290
00291 Q_ASSERT( todo != NULL );
00292
00293 kdDebug(5970) << "Task::asTodo: name() = '" << name() << "'" << endl;
00294 todo->setSummary( name() );
00295
00296
00297
00298
00299
00300
00301 todo->setCustomProperty( kapp->instanceName(),
00302 QCString( "totalTaskTime" ), QString::number( _time ) );
00303 todo->setCustomProperty( kapp->instanceName(),
00304 QCString( "totalSessionTime" ), QString::number( _sessionTime) );
00305
00306 if (getDesktopStr().isEmpty())
00307 todo->removeCustomProperty(kapp->instanceName(), QCString("desktopList"));
00308 else
00309 todo->setCustomProperty( kapp->instanceName(),
00310 QCString( "desktopList" ), getDesktopStr() );
00311
00312 todo->setOrganizer( Preferences::instance()->userRealName() );
00313
00314 todo->setPercentComplete(_percentcomplete);
00315
00316 return todo;
00317 }
00318
00319 bool Task::parseIncidence( KCal::Incidence* incident, long& minutes,
00320 long& sessionMinutes, QString& name, DesktopList& desktops,
00321 int& percent_complete )
00322 {
00323 bool ok;
00324
00325 name = incident->summary();
00326 _uid = incident->uid();
00327
00328 _comment = incident->description();
00329
00330 ok = false;
00331 minutes = incident->customProperty( kapp->instanceName(),
00332 QCString( "totalTaskTime" )).toInt( &ok );
00333 if ( !ok )
00334 minutes = 0;
00335
00336 ok = false;
00337 sessionMinutes = incident->customProperty( kapp->instanceName(),
00338 QCString( "totalSessionTime" )).toInt( &ok );
00339 if ( !ok )
00340 sessionMinutes = 0;
00341
00342 QString desktopList = incident->customProperty( kapp->instanceName(),
00343 QCString( "desktopList" ) );
00344 QStringList desktopStrList = QStringList::split( QString::fromLatin1(","),
00345 desktopList );
00346 desktops.clear();
00347
00348 for ( QStringList::iterator iter = desktopStrList.begin();
00349 iter != desktopStrList.end();
00350 ++iter ) {
00351 int desktopInt = (*iter).toInt( &ok );
00352 if ( ok ) {
00353 desktops.push_back( desktopInt );
00354 }
00355 }
00356
00357 percent_complete = static_cast<KCal::Todo*>(incident)->percentComplete();
00358
00359
00360
00361
00362
00363 return true;
00364 }
00365
00366 QString Task::getDesktopStr() const
00367 {
00368 if ( _desktops.empty() )
00369 return QString();
00370
00371 QString desktopstr;
00372 for ( DesktopList::const_iterator iter = _desktops.begin();
00373 iter != _desktops.end();
00374 ++iter ) {
00375 desktopstr += QString::number( *iter ) + QString::fromLatin1( "," );
00376 }
00377 desktopstr.remove( desktopstr.length() - 1, 1 );
00378 return desktopstr;
00379 }
00380
00381 void Task::cut()
00382 {
00383
00384 changeParentTotalTimes( -_totalSessionTime, -_totalTime);
00385 if ( ! parent())
00386 listView()->takeItem(this);
00387 else
00388 parent()->takeItem(this);
00389 }
00390
00391 void Task::move(Task* destination)
00392 {
00393 cut();
00394 paste(destination);
00395 }
00396
00397 void Task::paste(Task* destination)
00398 {
00399 destination->insertItem(this);
00400 changeParentTotalTimes( _totalSessionTime, _totalTime);
00401 }
00402
00403 void Task::update()
00404 {
00405 setText(0, _name);
00406 setText(1, formatTime(_sessionTime));
00407 setText(2, formatTime(_time));
00408 setText(3, formatTime(_totalSessionTime));
00409 setText(4, formatTime(_totalTime));
00410 }
00411
00412 void Task::addComment( QString comment, KarmStorage* storage )
00413 {
00414 _comment = _comment + QString::fromLatin1("\n") + comment;
00415 storage->addComment(this, comment);
00416 }
00417
00418 QString Task::comment() const
00419 {
00420 return _comment;
00421 }
00422
00423 int Task::compare ( QListViewItem * i, int col, bool ascending ) const
00424 {
00425 long thistime = 0;
00426 long thattime = 0;
00427 Task *task = static_cast<Task*>(i);
00428
00429 switch ( col )
00430 {
00431 case 1:
00432 thistime = _sessionTime;
00433 thattime = task->sessionTime();
00434 break;
00435 case 2:
00436 thistime = _time;
00437 thattime = task->time();
00438 break;
00439 case 3:
00440 thistime = _totalSessionTime;
00441 thattime = task->totalSessionTime();
00442 break;
00443 case 4:
00444 thistime = _totalTime;
00445 thattime = task->totalTime();
00446 break;
00447 default:
00448 return key(col, ascending).localeAwareCompare( i->key(col, ascending) );
00449 }
00450
00451 if ( thistime < thattime ) return -1;
00452 if ( thistime > thattime ) return 1;
00453 return 0;
00454
00455 }
00456
00457 #include "task.moc"