You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdepim/karm/task.cpp

466 lines
12 KiB

#include <qcstring.h>
#include <qdatetime.h>
#include <qstring.h>
#include <qtimer.h>
#include <kiconloader.h>
#include "kapplication.h" // kapp
#include "kdebug.h"
#include "event.h"
#include "karmutility.h"
#include "task.h"
#include "taskview.h"
#include "preferences.h"
const int gSecondsPerMinute = 60;
QPtrVector<QPixmap> *Task::icons = 0;
Task::Task( const QString& taskName, long minutes, long sessionTime,
DesktopList desktops, TaskView *parent)
: QObject(), QListViewItem(parent)
{
init(taskName, minutes, sessionTime, desktops, 0);
}
Task::Task( const QString& taskName, long minutes, long sessionTime,
DesktopList desktops, Task *parent)
: QObject(), QListViewItem(parent)
{
init(taskName, minutes, sessionTime, desktops, 0);
}
Task::Task( KCal::Todo* todo, TaskView* parent )
: QObject(), QListViewItem( parent )
{
long minutes = 0;
QString name;
long sessionTime = 0;
int percent_complete = 0;
DesktopList desktops;
parseIncidence(todo, minutes, sessionTime, name, desktops, percent_complete);
init(name, minutes, sessionTime, desktops, percent_complete);
}
void Task::init( const QString& taskName, long minutes, long sessionTime,
DesktopList desktops, int percent_complete)
{
// If our parent is the taskview then connect our totalTimesChanged
// signal to its receiver
if ( ! parent() )
connect( this, SIGNAL( totalTimesChanged ( long, long ) ),
listView(), SLOT( taskTotalTimesChanged( long, long) ));
connect( this, SIGNAL( deletingTask( Task* ) ),
listView(), SLOT( deletingTask( Task* ) ));
if (icons == 0) {
icons = new QPtrVector<QPixmap>(8);
KIconLoader kil("karm"); // always load icons from the KArm application
for (int i=0; i<8; i++)
{
QPixmap *icon = new QPixmap();
QString name;
name.sprintf("watch-%d.xpm",i);
*icon = kil.loadIcon( name, KIcon::User );
icons->insert(i,icon);
}
}
_removing = false;
_name = taskName.stripWhiteSpace();
_lastStart = QDateTime::currentDateTime();
_totalTime = _time = minutes;
_totalSessionTime = _sessionTime = sessionTime;
_timer = new QTimer(this);
_desktops = desktops;
connect(_timer, SIGNAL(timeout()), this, SLOT(updateActiveIcon()));
setPixmap(1, UserIcon(QString::fromLatin1("empty-watch.xpm")));
_currentPic = 0;
_percentcomplete = percent_complete;
update();
changeParentTotalTimes( _sessionTime, _time);
}
Task::~Task() {
emit deletingTask(this);
delete _timer;
}
void Task::setRunning( bool on, KarmStorage* storage, QDateTime whenStarted, QDateTime whenStopped )
// Sets a task running or stopped. If the task is to be stopped, whenStarted is not evaluated.
// on=true if the task shall be started on=false if the task shall be stopped
// This is the back-end, the front-end is StartTimerFor()
{
kdDebug(5970) << "Entering Task::setRunning " << "on=" << on << "whenStarted=" << whenStarted << " whenStopped=" << whenStopped << endl;
if ( on )
{
if (!_timer->isActive())
{
_timer->start(1000);
storage->startTimer(this);
_currentPic=7;
_lastStart = whenStarted;
updateActiveIcon();
}
}
else
{
if (_timer->isActive())
{
_timer->stop();
if ( ! _removing )
{
storage->stopTimer(this, whenStopped);
setPixmap(1, UserIcon(QString::fromLatin1("empty-watch.xpm")));
}
}
}
}
void Task::setUid(QString uid) {
_uid = uid;
}
bool Task::isRunning() const
{
return _timer->isActive();
}
void Task::setName( const QString& name, KarmStorage* storage )
{
kdDebug(5970) << "Task:setName: " << name << endl;
QString oldname = _name;
if ( oldname != name ) {
_name = name;
storage->setName(this, oldname);
update();
}
}
void Task::setPercentComplete(const int percent, KarmStorage *storage)
{
kdDebug(5970) << "Task::setPercentComplete(" << percent << ", storage): "
<< _uid << endl;
if (!percent)
_percentcomplete = 0;
else if (percent > 100)
_percentcomplete = 100;
else if (percent < 0)
_percentcomplete = 0;
else
_percentcomplete = percent;
if (isRunning() && _percentcomplete==100) taskView()->stopTimerFor(this);
setPixmapProgress();
// When parent marked as complete, mark all children as complete as well.
// Complete tasks are not displayed in the task view, so if a parent is
// marked as complete and some of the children are not, then we get an error
// message. KArm actually keep chugging along in this case and displays the
// child tasks just fine, so an alternative solution is to remove that error
// message (from KarmStorage::load). But I think it makes more sense that
// if you mark a parent task as complete, then all children should be
// complete as well.
//
// This behavior is consistent with KOrganizer (as of 2003-09-24).
if (_percentcomplete == 100)
{
for (Task* child= this->firstChild(); child; child = child->nextSibling())
child->setPercentComplete(_percentcomplete, storage);
}
}
void Task::setPixmapProgress()
{
QPixmap* icon = new QPixmap();
if (_percentcomplete >= 100)
*icon = UserIcon("task-complete.xpm");
else
*icon = UserIcon("task-incomplete.xpm");
setPixmap(0, *icon);
}
bool Task::isComplete() { return _percentcomplete == 100; }
void Task::removeFromView()
{
while ( Task* child = firstChild() )
child->removeFromView();
delete this;
}
void Task::setDesktopList ( DesktopList desktopList )
{
_desktops = desktopList;
}
void Task::changeTime( long minutes, KarmStorage* storage )
{
changeTimes( minutes, minutes, storage);
}
void Task::changeTimes( long minutesSession, long minutes, KarmStorage* storage)
{
if( minutesSession != 0 || minutes != 0)
{
_sessionTime += minutesSession;
_time += minutes;
if ( storage ) storage->changeTime(this, minutes * gSecondsPerMinute);
changeTotalTimes( minutesSession, minutes );
}
}
void Task::changeTotalTimes( long minutesSession, long minutes )
{
kdDebug(5970)
<< "Task::changeTotalTimes(" << minutesSession << ", "
<< minutes << ") for " << name() << endl;
_totalSessionTime += minutesSession;
_totalTime += minutes;
update();
changeParentTotalTimes( minutesSession, minutes );
}
void Task::resetTimes()
{
_totalSessionTime -= _sessionTime;
_totalTime -= _time;
changeParentTotalTimes( -_sessionTime, -_time);
_sessionTime = 0;
_time = 0;
update();
}
void Task::changeParentTotalTimes( long minutesSession, long minutes )
{
//kdDebug(5970)
// << "Task::changeParentTotalTimes(" << minutesSession << ", "
// << minutes << ") for " << name() << endl;
if ( isRoot() )
emit totalTimesChanged( minutesSession, minutes );
else
parent()->changeTotalTimes( minutesSession, minutes );
}
bool Task::remove( QPtrList<Task>& activeTasks, KarmStorage* storage)
{
kdDebug(5970) << "Task::remove: " << _name << endl;
bool ok = true;
_removing = true;
storage->removeTask(this);
if( isRunning() ) setRunning( false, storage );
for (Task* child = this->firstChild(); child; child = child->nextSibling())
{
if (child->isRunning())
child->setRunning(false, storage);
child->remove(activeTasks, storage);
}
changeParentTotalTimes( -_sessionTime, -_time);
_removing = false;
return ok;
}
void Task::updateActiveIcon()
{
_currentPic = (_currentPic+1) % 8;
setPixmap(1, *(*icons)[_currentPic]);
}
QString Task::fullName() const
{
if (isRoot())
return name();
else
return parent()->fullName() + QString::fromLatin1("/") + name();
}
KCal::Todo* Task::asTodo(KCal::Todo* todo) const
{
Q_ASSERT( todo != NULL );
kdDebug(5970) << "Task::asTodo: name() = '" << name() << "'" << endl;
todo->setSummary( name() );
// Note: if the date start is empty, the KOrganizer GUI will have the
// checkbox blank, but will prefill the todo's starting datetime to the
// time the file is opened.
// todo->setDtStart( current );
todo->setCustomProperty( kapp->instanceName(),
QCString( "totalTaskTime" ), QString::number( _time ) );
todo->setCustomProperty( kapp->instanceName(),
QCString( "totalSessionTime" ), QString::number( _sessionTime) );
if (getDesktopStr().isEmpty())
todo->removeCustomProperty(kapp->instanceName(), QCString("desktopList"));
else
todo->setCustomProperty( kapp->instanceName(),
QCString( "desktopList" ), getDesktopStr() );
todo->setOrganizer( Preferences::instance()->userRealName() );
todo->setPercentComplete(_percentcomplete);
return todo;
}
bool Task::parseIncidence( KCal::Incidence* incident, long& minutes,
long& sessionMinutes, QString& name, DesktopList& desktops,
int& percent_complete )
{
bool ok;
name = incident->summary();
_uid = incident->uid();
_comment = incident->description();
ok = false;
minutes = incident->customProperty( kapp->instanceName(),
QCString( "totalTaskTime" )).toInt( &ok );
if ( !ok )
minutes = 0;
ok = false;
sessionMinutes = incident->customProperty( kapp->instanceName(),
QCString( "totalSessionTime" )).toInt( &ok );
if ( !ok )
sessionMinutes = 0;
QString desktopList = incident->customProperty( kapp->instanceName(),
QCString( "desktopList" ) );
QStringList desktopStrList = QStringList::split( QString::fromLatin1(","),
desktopList );
desktops.clear();
for ( QStringList::iterator iter = desktopStrList.begin();
iter != desktopStrList.end();
++iter ) {
int desktopInt = (*iter).toInt( &ok );
if ( ok ) {
desktops.push_back( desktopInt );
}
}
percent_complete = static_cast<KCal::Todo*>(incident)->percentComplete();
//kdDebug(5970) << "Task::parseIncidence: "
// << name << ", Minutes: " << minutes
// << ", desktop: " << desktopList << endl;
return true;
}
QString Task::getDesktopStr() const
{
if ( _desktops.empty() )
return QString();
QString desktopstr;
for ( DesktopList::const_iterator iter = _desktops.begin();
iter != _desktops.end();
++iter ) {
desktopstr += QString::number( *iter ) + QString::fromLatin1( "," );
}
desktopstr.remove( desktopstr.length() - 1, 1 );
return desktopstr;
}
void Task::cut()
{
//kdDebug(5970) << "Task::cut - " << name() << endl;
changeParentTotalTimes( -_totalSessionTime, -_totalTime);
if ( ! parent())
listView()->takeItem(this);
else
parent()->takeItem(this);
}
void Task::move(Task* destination)
{
cut();
paste(destination);
}
void Task::paste(Task* destination)
{
destination->insertItem(this);
changeParentTotalTimes( _totalSessionTime, _totalTime);
}
void Task::update()
{
setText(0, _name);
setText(1, formatTime(_sessionTime));
setText(2, formatTime(_time));
setText(3, formatTime(_totalSessionTime));
setText(4, formatTime(_totalTime));
}
void Task::addComment( QString comment, KarmStorage* storage )
{
_comment = _comment + QString::fromLatin1("\n") + comment;
storage->addComment(this, comment);
}
QString Task::comment() const
{
return _comment;
}
int Task::compare ( QListViewItem * i, int col, bool ascending ) const
{
long thistime = 0;
long thattime = 0;
Task *task = static_cast<Task*>(i);
switch ( col )
{
case 1:
thistime = _sessionTime;
thattime = task->sessionTime();
break;
case 2:
thistime = _time;
thattime = task->time();
break;
case 3:
thistime = _totalSessionTime;
thattime = task->totalSessionTime();
break;
case 4:
thistime = _totalTime;
thattime = task->totalTime();
break;
default:
return key(col, ascending).localeAwareCompare( i->key(col, ascending) );
}
if ( thistime < thattime ) return -1;
if ( thistime > thattime ) return 1;
return 0;
}
#include "task.moc"