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