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, TQT_SIGNAL( expanded( TQListViewItem * ) ),
46 this, TQT_SLOT( itemStateChanged( TQListViewItem * ) ) );
47 connect(
this, TQT_SIGNAL( collapsed( TQListViewItem * ) ),
48 this, TQT_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, TQT_SIGNAL( timeout() ),
this, TQT_SLOT( minuteUpdate() ));
69 _minuteTimer->start(1000 * secsPerMinute);
72 connect(_preferences, TQT_SIGNAL(iCalFile(TQString)),
73 this, TQT_SLOT(iCalFileChanged(TQString)));
76 connect(_preferences, TQT_SIGNAL( setupChanged() ),
this,TQT_SLOT( adaptColumns() ));
78 _minuteTimer->start(1000 * secsPerMinute);
82 connect( _idleTimeDetector, TQT_SIGNAL( extractTime(
int) ),
83 this, TQT_SLOT( extractTime(
int) ));
84 connect( _idleTimeDetector, TQT_SIGNAL( stopAllTimersAt(TQDateTime) ),
85 this, TQT_SLOT( stopAllTimersAt(TQDateTime) ));
86 connect( _preferences, TQT_SIGNAL( idlenessTimeout(
int) ),
87 _idleTimeDetector, TQT_SLOT( setMaxIdle(
int) ));
88 connect( _preferences, TQT_SIGNAL( detectIdleness(
bool) ),
89 _idleTimeDetector, TQT_SLOT( toggleOverAllIdleDetection(
bool) ));
90 if (!_idleTimeDetector->isIdleDetectionPossible())
91 _preferences->disableIdleDetection();
94 _autoSaveTimer =
new TQTimer(
this);
95 connect( _preferences, TQT_SIGNAL( autoSave(
bool) ),
96 this, TQT_SLOT( autoSaveChanged(
bool) ));
97 connect( _preferences, TQT_SIGNAL( autoSavePeriod(
int) ),
98 this, TQT_SLOT( autoSavePeriodChanged(
int) ));
99 connect( _autoSaveTimer, TQT_SIGNAL( timeout() ),
this, TQT_SLOT( save() ));
102 _manualSaveTimer =
new TQTimer(
this);
103 connect( _manualSaveTimer, TQT_SIGNAL( timeout() ),
this, TQT_SLOT( save() ));
107 connect( _desktopTracker, TQT_SIGNAL( reachedtActiveDesktop(
Task* ) ),
108 this, TQT_SLOT( startTimerFor(
Task*) ));
109 connect( _desktopTracker, TQT_SIGNAL( leftActiveDesktop(
Task* ) ),
110 this, TQT_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() == Qt::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);
487 void TaskView::minuteUpdate()
489 addTimeToActiveTasks(1,
false);
492 void TaskView::addTimeToActiveTasks(
int minutes,
bool save_data)
494 for(
unsigned int i = 0; i < activeTasks.count(); i++ )
495 activeTasks.at(i)->changeTime(minutes, ( save_data ? _storage : 0 ) );
506 long total, totalDiff, session, sessionDiff;
507 DesktopList desktopList;
509 int result = dialog->exec();
510 if ( result == TQDialog::Accepted ) {
511 TQString taskName = i18n(
"Unnamed Task" );
512 if ( !dialog->taskName().isEmpty()) taskName = dialog->taskName();
514 total = totalDiff = session = sessionDiff = 0;
515 dialog->status( &total, &totalDiff, &session, &sessionDiff, &desktopList );
519 if ( desktopList.size() == (
unsigned int ) _desktopTracker->desktopCount() )
522 TQString uid =
addTask( taskName, total, session, desktopList, parent );
525 KMessageBox::error( 0, i18n(
526 "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/ " ) );
534 (
const TQString& taskname,
long total,
long session,
535 const DesktopList& desktops,
Task* parent )
538 kdDebug(5970) <<
"TaskView::addTask: taskname = " << taskname << endl;
540 if ( parent ) task =
new Task( taskname, total, session, desktops, parent );
541 else task =
new Task( taskname, total, session, desktops,
this );
543 task->
setUid( _storage->addTask( task, parent ) );
544 TQString taskuid=task->
uid();
545 if ( ! taskuid.isNull() )
547 _desktopTracker->registerForDesktops( task, desktops );
548 setCurrentItem( task );
549 setSelected( task,
true );
565 newTask(i18n(
"New Sub Task"), task);
570 void TaskView::editTask()
576 DesktopList desktopList = task->getDesktops();
578 dialog->setTask( task->
name(),
580 task->sessionTime() );
581 int result = dialog->exec();
582 if (result == TQDialog::Accepted) {
583 TQString taskName = i18n(
"Unnamed Task");
584 if (!dialog->taskName().isEmpty()) {
585 taskName = dialog->taskName();
588 task->
setName(taskName, _storage);
591 long total, session, totalDiff, sessionDiff;
592 total = totalDiff = session = sessionDiff = 0;
593 DesktopList desktopList;
594 dialog->status( &total, &totalDiff, &session, &sessionDiff, &desktopList);
596 if( totalDiff != 0 || sessionDiff != 0)
597 task->
changeTimes( sessionDiff, totalDiff, _storage );
601 if (desktopList.size() == (
unsigned int)_desktopTracker->desktopCount())
604 task->setDesktopList(desktopList);
606 _desktopTracker->registerForDesktops( task, desktopList );
608 emit updateButtons();
631 KMessageBox::information(0,i18n(
"No task selected."));
635 if (completion<0) completion=0;
641 emit updateButtons();
649 KMessageBox::information(0,i18n(
"No task selected."));
653 int response = KMessageBox::Continue;
654 if (!markingascomplete && _preferences->promptDelete()) {
655 if (task->childCount() == 0) {
656 response = KMessageBox::warningContinueCancel( 0,
657 i18n(
"Are you sure you want to delete "
658 "the task named\n\"%1\" and its entire history?")
660 i18n(
"Deleting Task"), KStdGuiItem::del());
663 response = KMessageBox::warningContinueCancel( 0,
664 i18n(
"Are you sure you want to delete the task named"
665 "\n\"%1\" and its entire history?\n"
666 "NOTE: all its subtasks and their history will also "
667 "be deleted.").arg(task->
name()),
668 i18n(
"Deleting Task"), KStdGuiItem::del());
672 if (response == KMessageBox::Continue)
674 if (markingascomplete)
679 emit updateButtons();
689 TQString uid=task->
uid();
690 task->
remove(activeTasks, _storage);
692 if( _preferences ) _preferences->deleteEntry( uid );
700 if (activeTasks.count() == 0) {
702 emit timersInactive();
705 emit tasksChanged( activeTasks );
716 kdDebug(5970) <<
"Entering extractTime" << endl;
717 addTimeToActiveTasks(-minutes,
false);
720 void TaskView::autoSaveChanged(
bool on)
722 if (on) _autoSaveTimer->start(_preferences->autoSavePeriod()*1000*secsPerMinute);
723 else if (_autoSaveTimer->isActive()) _autoSaveTimer->stop();
726 void TaskView::autoSavePeriodChanged(
int )
728 autoSaveChanged(_preferences->autoSave());
731 void TaskView::adaptColumns()
742 for(
int x=1; x <= 4; x++) {
744 if( _preferences->displayColumn(x-1)
745 && previousColumnWidths[x-1] != HIDDEN_COLUMN )
747 setColumnWidth( x, previousColumnWidths[x-1] );
748 previousColumnWidths[x-1] = HIDDEN_COLUMN;
749 setColumnWidthMode( x, TQListView::Maximum );
753 if( ! _preferences->displayColumn(x-1)
754 && previousColumnWidths[x-1] == HIDDEN_COLUMN )
756 setColumnWidthMode( x, TQListView::Manual );
758 previousColumnWidths[x-1] = columnWidth( x );
759 setColumnWidth( x, 0 );
766 DesktopList desktopList;
768 _desktopTracker->registerForDesktops( deletedTask, desktopList );
769 activeTasks.removeRef( deletedTask );
771 emit tasksChanged( activeTasks);
778 kdDebug(5970) <<
"TaskView:iCalFileChanged: " << file << endl;
779 if (_storage->icalfile() != file)
782 _storage->save(
this);
788 const TQDate& to)
const
793 void TaskView::markTaskAsComplete()
796 kdDebug(5970) <<
"TaskView::markTaskAsComplete: "
799 kdDebug(5970) <<
"TaskView::markTaskAsComplete: null current_item()" << endl;
801 bool markingascomplete =
true;
805 void TaskView::markTaskAsIncomplete()
808 kdDebug(5970) <<
"TaskView::markTaskAsComplete: "
811 kdDebug(5970) <<
"TaskView::markTaskAsComplete: null current_item()" << endl;
822 int response = KMessageBox::questionYesNo( 0,
823 i18n(
"Copy totals for just this task and its subtasks, or copy totals for all tasks?"),
824 i18n(
"Copy Totals to Clipboard"),
825 i18n(
"Copy This Task"), i18n(
"Copy All Tasks") );
826 if (response == KMessageBox::Yes)
828 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
true, TimeKard::TotalTime));
832 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
false, TimeKard::TotalTime));
837 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
true, TimeKard::TotalTime));
846 int response = KMessageBox::questionYesNo( 0,
847 i18n(
"Copy session time for just this task and its subtasks, or copy session time for all tasks?"),
848 i18n(
"Copy Session Time to Clipboard"),
849 i18n(
"Copy This Task"), i18n(
"Copy All Tasks") );
850 if (response == KMessageBox::Yes)
852 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
true, TimeKard::SessionTime));
856 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
false, TimeKard::SessionTime));
861 TDEApplication::clipboard()->setText(t.
totalsAsText(
this,
true, TimeKard::SessionTime));
868 if (dialog.exec()== TQDialog::Accepted)
871 TDEApplication::clipboard()->
872 setText( t.
historyAsText(
this, dialog.from(), dialog.to(), !dialog.allTasks(), dialog.perWeek(), dialog.totalsOnly() ) );
876 #include "taskview.moc"