1 #include <tqclipboard.h>
5 #include <tqlistview.h>
7 #include <tqptrstack.h>
9 #include <tqtextstream.h>
13 #include "tdeapplication.h"
14 #include <tdeconfig.h>
16 #include <tdefiledialog.h>
17 #include <tdelocale.h>
18 #include <tdemessagebox.h>
19 #include <kurlrequester.h>
21 #include "csvexportdialog.h"
22 #include "desktoptracker.h"
23 #include "edittaskdialog.h"
24 #include "idletimedetector.h"
25 #include "karmstorage.h"
26 #include "plannerparser.h"
27 #include "preferences.h"
28 #include "printdialog.h"
29 #include "reportcriteria.h"
33 #include "taskviewwhatsthis.h"
35 #define T_LINESIZE 1023
36 #define HIDDEN_COLUMN -10
40 TaskView::TaskView(TQWidget *parent,
const char *name,
const TQString &icsfile ):TDEListView(parent,name)
42 _preferences = Preferences::instance( icsfile );
43 _storage = KarmStorage::instance();
45 connect(
this, TQ_SIGNAL( expanded( TQListViewItem * ) ),
46 this, TQ_SLOT( itemStateChanged( TQListViewItem * ) ) );
47 connect(
this, TQ_SIGNAL( collapsed( TQListViewItem * ) ),
48 this, TQ_SLOT( itemStateChanged( TQListViewItem * ) ) );
51 previousColumnWidths[0] = previousColumnWidths[1]
52 = previousColumnWidths[2] = previousColumnWidths[3] = HIDDEN_COLUMN;
54 addColumn( i18n(
"Task Name") );
55 addColumn( i18n(
"Session Time") );
56 addColumn( i18n(
"Time") );
57 addColumn( i18n(
"Total Session Time") );
58 addColumn( i18n(
"Total Time") );
59 setColumnAlignment( 1, TQt::AlignRight );
60 setColumnAlignment( 2, TQt::AlignRight );
61 setColumnAlignment( 3, TQt::AlignRight );
62 setColumnAlignment( 4, TQt::AlignRight );
64 setAllColumnsShowFocus(
true );
67 _minuteTimer =
new TQTimer(
this);
68 connect( _minuteTimer, TQ_SIGNAL( timeout() ),
this, TQ_SLOT( minuteUpdate() ));
69 _minuteTimer->start(1000 * secsPerMinute);
72 connect(_preferences, TQ_SIGNAL(iCalFile(TQString)),
73 this, TQ_SLOT(iCalFileChanged(TQString)));
76 connect(_preferences, TQ_SIGNAL( setupChanged() ),
this,TQ_SLOT( adaptColumns() ));
78 _minuteTimer->start(1000 * secsPerMinute);
82 connect( _idleTimeDetector, TQ_SIGNAL( extractTime(
int) ),
83 this, TQ_SLOT( extractTime(
int) ));
84 connect( _idleTimeDetector, TQ_SIGNAL( stopAllTimersAt(TQDateTime) ),
85 this, TQ_SLOT( stopAllTimersAt(TQDateTime) ));
86 connect( _preferences, TQ_SIGNAL( idlenessTimeout(
int) ),
87 _idleTimeDetector, TQ_SLOT( setMaxIdle(
int) ));
88 connect( _preferences, TQ_SIGNAL( detectIdleness(
bool) ),
89 _idleTimeDetector, TQ_SLOT( toggleOverAllIdleDetection(
bool) ));
90 if (!_idleTimeDetector->isIdleDetectionPossible())
91 _preferences->disableIdleDetection();
94 _autoSaveTimer =
new TQTimer(
this);
95 connect( _preferences, TQ_SIGNAL( autoSave(
bool) ),
96 this, TQ_SLOT( autoSaveChanged(
bool) ));
97 connect( _preferences, TQ_SIGNAL( autoSavePeriod(
int) ),
98 this, TQ_SLOT( autoSavePeriodChanged(
int) ));
99 connect( _autoSaveTimer, TQ_SIGNAL( timeout() ),
this, TQ_SLOT( save() ));
102 _manualSaveTimer =
new TQTimer(
this);
103 connect( _manualSaveTimer, TQ_SIGNAL( timeout() ),
this, TQ_SLOT( save() ));
107 connect( _desktopTracker, TQ_SIGNAL( reachedtActiveDesktop(
Task* ) ),
108 this, TQ_SLOT( startTimerFor(
Task*) ));
109 connect( _desktopTracker, TQ_SIGNAL( leftActiveDesktop(
Task* ) ),
110 this, TQ_SLOT( stopTimerFor(
Task*) ));
119 void TaskView::contentsMousePressEvent ( TQMouseEvent * e )
121 kdDebug(5970) <<
"entering contentsMousePressEvent" << endl;
122 TDEListView::contentsMousePressEvent(e);
131 int leftborder = treeStepSize() * ( task->depth() + ( rootIsDecorated() ? 1 : 0)) + itemMargin();
132 if ((leftborder < e->x()) && (e->x() < 19 + leftborder ))
134 if ( e->button() == TQt::LeftButton )
138 emit updateButtons();
142 void TaskView::contentsMouseDoubleClickEvent ( TQMouseEvent * e )
147 kdDebug(5970) <<
"entering contentsMouseDoubleClickEvent" << endl;
148 TDEListView::contentsMouseDoubleClickEvent(e);
154 if ( e->pos().y() >= task->itemPos() &&
155 e->pos().y() < task->itemPos()+task->height() )
157 if ( activeTasks.findRef(task) == -1 )
167 TaskView::~TaskView()
169 _preferences->save();
174 return static_cast<Task*
>(firstChild());
179 return static_cast<Task*
>(currentItem());
184 return static_cast<Task*
>(itemAtIndex(i));
192 TQString err = _storage->load(
this, _preferences, fileName);
196 KMessageBox::error(
this, err);
204 _desktopTracker->registerForDesktops( t, t->getDesktops() );
210 if ( _desktopTracker->startTracking() != TQString() )
211 KMessageBox::error( 0, i18n(
"You are on a too high logical desktop, desktop tracking will not work") );
216 void TaskView::restoreItemState( TQListViewItem *item )
221 t->setOpen( _preferences->readBoolEntry( t->
uid() ) );
222 if( item->childCount() > 0 ) restoreItemState( item->firstChild() );
223 item = item->nextSibling();
229 if ( !item || _isloading )
return;
231 kdDebug(5970) <<
"TaskView::itemStateChanged()"
232 <<
" uid=" << t->
uid() <<
" state=" << t->isOpen()
234 if( _preferences ) _preferences->writeEntry( t->
uid(), t->isOpen() );
241 kdDebug(5970) <<
"entering iCalFileModified" << endl;
242 kdDebug(5970) << rc->infoText() << endl;
244 _storage->buildTaskView(rc,
this);
245 kdDebug(5970) <<
"exiting iCalFileModified" << endl;
250 kdDebug(5970) <<
"entering TaskView::refresh()" << endl;
251 this->setRootIsDecorated(
true);
259 bool anyChilds =
false;
262 child = child->nextSibling()) {
263 if (child->childCount() != 0) {
269 setRootIsDecorated(
false);
271 emit updateButtons();
272 kdDebug(5970) <<
"exiting TaskView::refresh()" << endl;
277 kdDebug(5970) <<
"TaskView::loadFromFlatFile()" << endl;
281 TQString fileName(KFileDialog::getOpenFileName(TQString(), TQString(),
283 if (!fileName.isEmpty()) {
287 KMessageBox::error(
this, err);
296 _desktopTracker->registerForDesktops( task, task->getDesktops() );
303 if ( _desktopTracker->startTracking() != TQString() )
304 KMessageBox::error(0, i18n(
"You are on a too high logical desktop, desktop tracking will not work") );
310 kdDebug(5970) <<
"entering importPlanner" << endl;
312 if (fileName.isEmpty()) fileName=KFileDialog::getOpenFileName(TQString(), TQString(), 0);
313 TQFile xmlFile( fileName );
314 TQXmlInputSource source( xmlFile );
315 TQXmlSimpleReader reader;
316 reader.setContentHandler( handler );
317 reader.parse( source );
324 return _storage->
report(
this, rc );
329 kdDebug(5970) <<
"TaskView::exportcsvFile()" << endl;
331 CSVExportDialog dialog( ReportCriteria::CSVTotalsExport,
this );
333 dialog.enableTasksToExportQuestion();
334 dialog.urlExportTo->KURLRequester::setMode(KFile::File);
335 if ( dialog.exec() ) {
336 TQString err = _storage->
report(
this, dialog.reportCriteria() );
337 if ( !err.isEmpty() ) KMessageBox::error(
this, i18n(err.ascii()) );
343 kdDebug(5970) <<
"TaskView::exportcsvHistory()" << endl;
346 CSVExportDialog dialog( ReportCriteria::CSVHistoryExport,
this );
348 dialog.enableTasksToExportQuestion();
349 dialog.urlExportTo->KURLRequester::setMode(KFile::File);
350 if ( dialog.exec() ) {
351 err = _storage->
report(
this, dialog.reportCriteria() );
358 kdDebug(5970) <<
"Entering TaskView::scheduleSave" << endl;
360 _manualSaveTimer->start( 10,
true );
368 kdDebug(5970) <<
"Entering TaskView::save" << endl;
369 TQString err = _storage->save(
this);
370 emit(setStatusBar(err));
388 kdDebug(5970) <<
"Entering TaskView::startTimerFor" << endl;
389 if (
save()==TQString())
391 if (task != 0 && activeTasks.findRef(task) == -1)
397 activeTasks.append(task);
398 emit updateButtons();
399 if ( activeTasks.count() == 1 )
401 emit tasksChanged( activeTasks);
405 else KMessageBox::error(0,i18n(
"Saving is impossible, so timing is useless. \nSaving problems may result from a full harddisk, a directory name instead of a file name, or stale locks. Check that your harddisk has enough space, that your calendar file exists and is a file and remove stale locks, typically from ~/.trinity/share/apps/tdeabc/lock."));
415 kdDebug(5970) <<
"Entering TaskView::stopAllTimers()" << endl;
416 for (
unsigned int i = 0; i < activeTasks.count(); i++ )
417 activeTasks.at(i)->setRunning(
false, _storage);
421 emit updateButtons();
422 emit timersInactive();
423 emit tasksChanged( activeTasks );
430 kdDebug(5970) <<
"Entering TaskView::stopAllTimersAt " << qdt << endl;
431 for (
unsigned int i = 0; i < activeTasks.count(); i++ )
433 activeTasks.at(i)->setRunning(
false, _storage, qdt, qdt);
434 kdDebug() << activeTasks.at(i)->name() << endl;
439 emit updateButtons();
440 emit timersInactive();
441 emit tasksChanged( activeTasks );
447 for ( ; item.current(); ++item ) {
448 Task * task = (
Task *) item.current();
456 for ( ; item.current(); ++item ) {
457 Task * task = (
Task *) item.current();
462 void TaskView::stopTimerFor(
Task* task)
464 kdDebug(5970) <<
"Entering stopTimerFor. task = " << task->
name() << endl;
465 if ( task != 0 && activeTasks.findRef(task) != -1 ) {
466 activeTasks.removeRef(task);
468 if ( activeTasks.count() == 0 ) {
470 emit timersInactive();
472 emit updateButtons();
474 emit tasksChanged( activeTasks);
482 void TaskView::minuteUpdate()
484 addTimeToActiveTasks(1,
false);
487 void TaskView::addTimeToActiveTasks(
int minutes,
bool save_data)
489 for(
unsigned int i = 0; i < activeTasks.count(); i++ )
490 activeTasks.at(i)->changeTime(minutes, ( save_data ? _storage : 0 ) );
501 long total, totalDiff, session, sessionDiff;
502 DesktopList desktopList;
504 int result = dialog->exec();
505 if ( result == TQDialog::Accepted ) {
506 TQString taskName = i18n(
"Unnamed Task" );
507 if ( !dialog->taskName().isEmpty()) taskName = dialog->taskName();
509 total = totalDiff = session = sessionDiff = 0;
510 dialog->status( &total, &totalDiff, &session, &sessionDiff, &desktopList );
514 if ( desktopList.size() == (
unsigned int ) _desktopTracker->desktopCount() )
517 TQString uid =
addTask( taskName, total, session, desktopList, parent );
520 KMessageBox::error( 0, i18n(
521 "Error storing new task. Your changes were not saved. Make sure you can edit your iCalendar file. Also quit all applications using this file and remove any lock file related to its name from ~/.trinity/share/apps/tdeabc/lock/ " ) );
529 (
const TQString& taskname,
long total,
long session,
530 const DesktopList& desktops,
Task* parent )
533 kdDebug(5970) <<
"TaskView::addTask: taskname = " << taskname << endl;
535 if ( parent ) task =
new Task( taskname, total, session, desktops, parent );
536 else task =
new Task( taskname, total, session, desktops,
this );
538 task->
setUid( _storage->addTask( task, parent ) );
539 TQString taskuid=task->
uid();
540 if ( ! taskuid.isNull() )
542 _desktopTracker->registerForDesktops( task, desktops );
543 setCurrentItem( task );
544 setSelected( task,
true );
560 newTask(i18n(
"New Sub Task"), task);
565 void TaskView::editTask()
571 DesktopList desktopList = task->getDesktops();
573 dialog->setTask( task->
name(),
575 task->sessionTime() );
576 int result = dialog->exec();
577 if (result == TQDialog::Accepted) {
578 TQString taskName = i18n(
"Unnamed Task");
579 if (!dialog->taskName().isEmpty()) {
580 taskName = dialog->taskName();
583 task->
setName(taskName, _storage);
586 long total, session, totalDiff, sessionDiff;
587 total = totalDiff = session = sessionDiff = 0;
588 DesktopList desktopList;
589 dialog->status( &total, &totalDiff, &session, &sessionDiff, &desktopList);
591 if( totalDiff != 0 || sessionDiff != 0)
592 task->
changeTimes( sessionDiff, totalDiff, _storage );
596 if (desktopList.size() == (
unsigned int)_desktopTracker->desktopCount())
599 task->setDesktopList(desktopList);
601 _desktopTracker->registerForDesktops( task, desktopList );
603 emit updateButtons();
626 KMessageBox::information(0,i18n(
"No task selected."));
630 if (completion<0) completion=0;
636 emit updateButtons();
644 KMessageBox::information(0,i18n(
"No task selected."));
648 int response = KMessageBox::Continue;
649 if (!markingascomplete && _preferences->promptDelete()) {
650 if (task->childCount() == 0) {
651 response = KMessageBox::warningContinueCancel( 0,
652 i18n(
"Are you sure you want to delete "
653 "the task named\n\"%1\" and its entire history?")
655 i18n(
"Deleting Task"), KStdGuiItem::del());
658 response = KMessageBox::warningContinueCancel( 0,
659 i18n(
"Are you sure you want to delete the task named"
660 "\n\"%1\" and its entire history?\n"
661 "NOTE: all its subtasks and their history will also "
662 "be deleted.").arg(task->
name()),
663 i18n(
"Deleting Task"), KStdGuiItem::del());
667 if (response == KMessageBox::Continue)
669 if (markingascomplete)
674 emit updateButtons();
684 TQString uid=task->
uid();
685 task->
remove(activeTasks, _storage);
687 if( _preferences ) _preferences->deleteEntry( uid );
695 if (activeTasks.count() == 0) {
697 emit timersInactive();
700 emit tasksChanged( activeTasks );
711 kdDebug(5970) <<
"Entering extractTime" << endl;
712 addTimeToActiveTasks(-minutes,
false);
715 void TaskView::autoSaveChanged(
bool on)
717 if (on) _autoSaveTimer->start(_preferences->autoSavePeriod()*1000*secsPerMinute);
718 else if (_autoSaveTimer->isActive()) _autoSaveTimer->stop();
721 void TaskView::autoSavePeriodChanged(
int )
723 autoSaveChanged(_preferences->autoSave());
726 void TaskView::adaptColumns()
737 for(
int x=1; x <= 4; x++) {
739 if( _preferences->displayColumn(x-1)
740 && previousColumnWidths[x-1] != HIDDEN_COLUMN )
742 setColumnWidth( x, previousColumnWidths[x-1] );
743 previousColumnWidths[x-1] = HIDDEN_COLUMN;
744 setColumnWidthMode( x, TQListView::Maximum );
748 if( ! _preferences->displayColumn(x-1)
749 && previousColumnWidths[x-1] == HIDDEN_COLUMN )
751 setColumnWidthMode( x, TQListView::Manual );
753 previousColumnWidths[x-1] = columnWidth( x );
754 setColumnWidth( x, 0 );
761 DesktopList desktopList;
763 _desktopTracker->registerForDesktops( deletedTask, desktopList );
764 activeTasks.removeRef( deletedTask );
766 emit tasksChanged( activeTasks);
773 kdDebug(5970) <<
"TaskView:iCalFileChanged: " << file << endl;
774 if (_storage->icalfile() != file)
777 _storage->save(
this);
783 const TQDate& to)
const
788 void TaskView::markTaskAsComplete()
791 kdDebug(5970) <<
"TaskView::markTaskAsComplete: "
794 kdDebug(5970) <<
"TaskView::markTaskAsComplete: null current_item()" << endl;
796 bool markingascomplete =
true;
800 void TaskView::markTaskAsIncomplete()
803 kdDebug(5970) <<
"TaskView::markTaskAsComplete: "
806 kdDebug(5970) <<
"TaskView::markTaskAsComplete: null current_item()" << endl;
817 int response = KMessageBox::questionYesNo( 0,
818 i18n(
"Copy totals for just this task and its subtasks, or copy totals for all tasks?"),
819 i18n(
"Copy Totals to Clipboard"),
820 i18n(
"Copy This Task"), i18n(
"Copy All Tasks") );
821 if (response == KMessageBox::Yes)
823 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
true, TimeKard::TotalTime));
827 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
false, TimeKard::TotalTime));
832 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
true, TimeKard::TotalTime));
841 int response = KMessageBox::questionYesNo( 0,
842 i18n(
"Copy session time for just this task and its subtasks, or copy session time for all tasks?"),
843 i18n(
"Copy Session Time to Clipboard"),
844 i18n(
"Copy This Task"), i18n(
"Copy All Tasks") );
845 if (response == KMessageBox::Yes)
847 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
true, TimeKard::SessionTime));
851 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
false, TimeKard::SessionTime));
856 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
true, TimeKard::SessionTime));
863 if (dialog.exec()== TQDialog::Accepted)
866 TDEApplication::clipboard()->
867 setText( t.
historyAsText(
this, dialog.from(), dialog.to(), !dialog.allTasks(), dialog.perWeek(), dialog.totalsOnly() ) );
871 #include "taskview.moc"