/* * Copyright (C) 2007 by Mathias Soeken * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the * Free Software Foundation, Inc. * 51 Franklin Street, Fifth Floor * Boston, MA 02110-1301 USA. * */ // TODO: what is the sense of tasksChanged()? #include "timetrackerwidget.h" #include "ktimetrackerconfigdialog.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "historydialog.h" #include "idletimedetector.h" #include "ktimetrackerutility.h" #include "ktimetracker.h" #include "mainadaptor.h" #include "reportcriteria.h" #include "task.h" #include "taskview.h" #include "kdepim-version.h" //@cond PRIVATE class TimetrackerWidget::Private { public: Private() : mTaskView( 0 ) {} QWidget *mSearchLine; KTreeWidgetSearchLine *mSearchWidget; TaskView *mTaskView; QMap mActions; struct ActionData { QString iconName; const char* caption; const char* slot; QString name; const char* toolTip; const char* whatsThis; }; }; //@endcond TimetrackerWidget::TimetrackerWidget( QWidget *parent ) : QWidget( parent ), d( new TimetrackerWidget::Private() ) { kDebug(5970) << "Entering function"; new MainAdaptor( this ); QDBusConnection::sessionBus().registerObject( "/KTimeTracker", this ); QLayout *layout = new QVBoxLayout; layout->setMargin( 0 ); layout->setSpacing( 0 ); QLayout *innerLayout = new QHBoxLayout; d->mSearchLine = new QWidget( this ); innerLayout->setMargin( KDialog::marginHint() ); innerLayout->setSpacing( KDialog::spacingHint() ); d->mSearchWidget = new KTreeWidgetSearchLine( d->mSearchLine ); d->mSearchWidget->setClickMessage( i18n( "Search or add task" ) ); d->mSearchWidget->setWhatsThis( i18n( "This is a combined field. As long as you do not type ENTER, it acts as a filter. Then, only tasks that match your input are shown. As soon as you type ENTER, your input is used as name to create a new task." ) ); d->mSearchWidget->installEventFilter( this ); innerLayout->addWidget( d->mSearchWidget ); d->mSearchLine->setLayout( innerLayout ); d->mTaskView = new TaskView( this ); layout->addWidget( d->mSearchLine ); layout->addWidget( d->mTaskView ); setLayout( layout ); showSearchBar( !KTimeTrackerSettings::configPDA() && KTimeTrackerSettings::showSearchBar() ); } TimetrackerWidget::~TimetrackerWidget() { delete d; } bool TimetrackerWidget::allEventsHaveEndTiMe() { return currentTaskView()->allEventsHaveEndTiMe(); } int TimetrackerWidget::focusSearchBar() { kDebug(5970) << "Entering function"; if ( d->mSearchWidget->isVisible() ) d->mSearchWidget->setFocus(); return 0; } void TimetrackerWidget::addTaskView( const QString &fileName ) { kDebug(5970) << "Entering function (fileName=" << fileName << ")"; bool isNew = fileName.isEmpty(); QString lFileName = fileName; if ( isNew ) { KTemporaryFile tempFile; tempFile.setAutoRemove( false ); if ( tempFile.open() ) { lFileName = tempFile.fileName(); tempFile.close(); } else { KMessageBox::error( this, i18n( "Cannot create new file." ) ); return; } } TaskView *taskView = d->mTaskView; connect( taskView, SIGNAL(contextMenuRequested(QPoint)), this, SIGNAL(contextMenuRequested(QPoint)) ); connect( taskView, SIGNAL(timersActive()), this, SIGNAL(timersActive()) ); connect( taskView, SIGNAL(timersInactive()), this, SIGNAL(timersInactive()) ); connect( taskView, SIGNAL(tasksChanged(QList)), this, SIGNAL(tasksChanged(QList))); emit setCaption( fileName ); taskView->load( lFileName ); d->mSearchWidget->addTreeWidget( taskView ); // When adding the first tab currentChanged is not emitted, so... if ( !d->mTaskView ) { emit currentTaskViewChanged(); slotCurrentChanged(); } } TaskView* TimetrackerWidget::currentTaskView() const { return qobject_cast< TaskView* >( d->mTaskView ); } Task* TimetrackerWidget::currentTask() { TaskView *taskView = 0; if ( ( taskView = currentTaskView() ) ) { return taskView->currentItem(); } else { return 0; } } void TimetrackerWidget::setupActions( KActionCollection *actionCollection ) { d->mActions.insert ("file_open", KStandardAction::open( this, SLOT(openFile()), actionCollection ) ); d->mActions.insert ("file_save", KStandardAction::save( this, SLOT(saveFile()), actionCollection ) ); d->mActions.insert ("file_quit", KStandardAction::quit( this, SLOT(quit()), actionCollection ) ); d->mActions.insert ("configure_ktimetracker", KStandardAction::preferences( this, SLOT(showSettingsDialog()), actionCollection ) ); Private::ActionData actions[] = { { QString(), I18N_NOOP("Start &New Session"), SLOT(startNewSession()), "start_new_session", I18N_NOOP("Starts a new session"), I18N_NOOP("This will reset the " "session time to 0 for all tasks, to start a new session, without " "affecting the totals.") }, { "view-history", I18N_NOOP("Edit History..."), SLOT(editHistory()), "edit_history", I18N_NOOP("Edits history of all tasks of the current document"), I18N_NOOP("A window will " "be opened where you can change start and stop times of tasks or add a " "comment to them.") }, { QString(), I18N_NOOP("&Reset All Times"), SLOT(resetAllTimes()), "reset_all_times", I18N_NOOP("Resets all times"), I18N_NOOP("This will reset the session " "and total time to 0 for all tasks, to restart from scratch.") }, { "media-playback-start", I18N_NOOP("&Start"), SLOT(startCurrentTimer()), "start", I18N_NOOP("Starts timing for selected task"), I18N_NOOP("This will start timing for the " "selected task.\nIt is even possible to time several tasks " "simultanously.\n\nYou may also start timing of tasks by double clicking " "the left mouse button on a given task. This will, however, stop timing " "of other tasks.") }, { "media-playback-stop", I18N_NOOP("S&top"), SLOT(stopCurrentTimer()), "stop", I18N_NOOP("Stops timing of the selected task"), I18N_NOOP("Stops timing of the selected task") }, { QString(), I18N_NOOP("Focus on Searchbar"), SLOT(focusSearchBar()), "focusSearchBar", I18N_NOOP("Sets the focus on the searchbar"), I18N_NOOP("Sets the focus on the searchbar") }, { QString(), I18N_NOOP("Stop &All Timers"), SLOT(stopAllTimers()), "stopAll", I18N_NOOP("Stops all of the active timers"), I18N_NOOP("Stops all of the active timers") }, { QString(), I18N_NOOP("Track Active Applications"), SLOT(focusTracking()), "focustracking", I18N_NOOP("Auto-creates and updates tasks when the focus of the " "current window has changed"), I18N_NOOP("If the focus of a window changes for the " "first time when this action is enabled, a new task will be created " "with the title of the window as its name and will be started. If there " "already exists such an task it will be started.") }, // in the following element, // document-new is the icon name, e.g. for the toolbar, new_task is how the action is // called in the ktimetrackerui.rc file, rest should be obvious { "document-new", I18N_NOOP("&New Task..."), SLOT(newTask()), "new_task", I18N_NOOP("Creates " "new top level task"), I18N_NOOP("This will create a new top level task.") }, { "subtask-new-ktimetracker", I18N_NOOP("New &Subtask..."), SLOT(newSubTask()), "new_sub_task", I18N_NOOP("Creates a new subtask to the current selected task"), I18N_NOOP("This will create a new subtask to the current selected task.") }, { "edit-delete", I18N_NOOP("&Delete"), SLOT(deleteTask()), "delete_task", I18N_NOOP("Deletes " "selected task"), I18N_NOOP("This will delete the selected task(s) and all " "subtasks.") }, { "document-properties", I18N_NOOP("&Edit..."), SLOT(editTask()), "edit_task", I18N_NOOP("Edits name or times for selected task"), I18N_NOOP("This will bring up a dialog " "box where you may edit the parameters for the selected task.") }, { QString(), I18N_NOOP("&Mark as Complete"), SLOT(markTaskAsComplete()), "mark_as_complete", "", "" }, { QString(), I18N_NOOP("&Mark as Incomplete"), SLOT(markTaskAsIncomplete()), "mark_as_incomplete", "", "" }, { QString(), I18N_NOOP("&Export Times..."), SLOT(exportcsvFile()), "export_times", "", "" }, { QString(), I18N_NOOP("Export &History..."), SLOT(exportcsvHistory()), "export_history", "", "" }, { QString(), I18N_NOOP("Import Tasks From &Planner..."), SLOT(importPlanner()), "import_planner", "", "" }, { QString(), I18N_NOOP("Show Searchbar"), SLOT(slotSearchBar()), "searchbar", "", "" } }; for ( unsigned int i = 0; i < ( sizeof( actions ) / sizeof( Private::ActionData ) ); ++i ) { Private::ActionData actionData = actions[i]; KAction *action; if ( actionData.iconName.isEmpty() ) { action = new KAction( i18n( actionData.caption ), this ); } else { action = new KAction( KIcon( actionData.iconName ), i18n( actionData.caption ), this ); } actionCollection->addAction( actionData.name, action ); connect( action, SIGNAL(triggered(bool)), actionData.slot ); action->setToolTip( i18n( actionData.toolTip ) ); action->setWhatsThis( i18n( actionData.whatsThis ) ); d->mActions.insert( actionData.name, action ); } // custom shortcuts d->mActions[ "start" ]->setShortcut( QKeySequence( Qt::Key_G) ); d->mActions[ "stopAll" ]->setShortcut( QKeySequence( Qt::Key_Escape ) ); d->mActions[ "new_task" ]->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_T ) ); d->mActions[ "focusSearchBar" ]->setShortcut( QKeySequence( Qt::Key_S ) ); d->mActions[ "new_sub_task" ]->setShortcut( QKeySequence( Qt::CTRL + Qt::ALT + Qt::Key_N ) ); d->mActions[ "delete_task" ]->setShortcut( QKeySequence( Qt::Key_Delete ) ); d->mActions[ "edit_task" ]->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_E ) ); d->mActions[ "mark_as_complete" ]->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_M ) ); d->mActions[ "mark_as_incomplete" ]->setShortcut( QKeySequence( Qt::CTRL + Qt::Key_M ) ); d->mActions[ "mark_as_complete" ]->setIcon( UserIcon( "task-complete.xpm" ) ); d->mActions[ "mark_as_incomplete" ]->setIcon( UserIcon( "task-incomplete.xpm" ) ); d->mActions[ "focustracking" ]->setCheckable( true ); d->mActions[ "searchbar" ]->setCheckable( true ); d->mActions[ "searchbar" ]->setChecked( KTimeTrackerSettings::self()->showSearchBar() ); connect( this, SIGNAL(currentTaskChanged()), this, SLOT(slotUpdateButtons()) ); connect( this, SIGNAL(currentTaskViewChanged()), this, SLOT(slotUpdateButtons()) ); connect( this, SIGNAL(updateButtons()), this, SLOT(slotUpdateButtons()) ); } KAction* TimetrackerWidget::action( const QString &name ) const { return d->mActions.value( name ); } void TimetrackerWidget::openFile( const QString &fileName ) { kDebug(5970) << "Entering function, fileName is " << fileName; QString newFileName = fileName; if ( newFileName.isEmpty() ) { newFileName = KFileDialog::getOpenFileName( QString(), QString(), this ); if ( newFileName.isEmpty() ) { return; } } addTaskView( newFileName ); } void TimetrackerWidget::openFile( const KUrl &fileName ) { openFile( fileName.toLocalFile() ); } bool TimetrackerWidget::closeFile() { kDebug(5970) << "Entering TimetrackerWidget::closeFile"; TaskView *taskView = currentTaskView(); if ( taskView ) { taskView->save(); taskView->closeStorage(); } d->mSearchWidget->removeTreeWidget( taskView ); emit currentTaskViewChanged(); emit setCaption( QString() ); slotCurrentChanged(); delete taskView; // removeTab does not delete its widget. d->mTaskView=0; return true; } void TimetrackerWidget::saveFile() { currentTaskView()->save(); } void TimetrackerWidget::showSearchBar( bool visible ) { d->mSearchLine->setVisible( visible ); } bool TimetrackerWidget::closeAllFiles() { kDebug(5970) << "Entering TimetrackerWidget::closeAllFiles"; bool err = true; if (d->mTaskView) { d->mTaskView->stopAllTimers(); err=closeFile(); } return err; } void TimetrackerWidget::slotCurrentChanged() { kDebug() << "entering KTimetrackerWidget::slotCurrentChanged"; if ( d->mTaskView ) { disconnect( d->mTaskView, SIGNAL(totalTimesChanged(long,long)) ); disconnect( d->mTaskView, SIGNAL(reSetTimes()) ); disconnect( d->mTaskView, SIGNAL(itemSelectionChanged()) ); disconnect( d->mTaskView, SIGNAL(updateButtons()) ); disconnect( d->mTaskView, SIGNAL(setStatusBarText(QString)) ); disconnect( d->mTaskView, SIGNAL(timersActive()) ); disconnect( d->mTaskView, SIGNAL(timersInactive()) ); disconnect( d->mTaskView, SIGNAL(tasksChanged(QList)), this, SIGNAL(tasksChanged(QList)) ); connect( d->mTaskView, SIGNAL(totalTimesChanged(long,long)), this, SIGNAL(totalTimesChanged(long,long)) ); connect( d->mTaskView, SIGNAL(reSetTimes()), this, SIGNAL(reSetTimes()) ); connect( d->mTaskView, SIGNAL(itemSelectionChanged()), this, SIGNAL(currentTaskChanged()) ); connect( d->mTaskView, SIGNAL(updateButtons()), this, SIGNAL(updateButtons()) ); connect( d->mTaskView, SIGNAL(setStatusBarText(QString)), // FIXME signature this, SIGNAL(statusBarTextChangeRequested(QString)) ); connect( d->mTaskView, SIGNAL(timersActive()), this, SIGNAL(timersActive()) ); connect( d->mTaskView, SIGNAL(timersInactive()), this, SIGNAL(timersInactive()) ); connect( d->mTaskView, SIGNAL(tasksChanged(QList)), // FIXME signature this, SIGNAL(tasksChanged(QList)) ); emit setCaption( d->mTaskView->storage()->icalfile() ); } d->mSearchWidget->setEnabled( d->mTaskView ); } bool TimetrackerWidget::eventFilter( QObject *obj, QEvent *event ) { if ( obj == d->mSearchWidget ) { if ( event->type() == QEvent::KeyPress ) { QKeyEvent *keyEvent = static_cast< QKeyEvent* >( event ); if ( keyEvent->key() == Qt::Key_Enter || keyEvent->key() == Qt::Key_Return ) { if ( !d->mSearchWidget->displayText().isEmpty() ) slotAddTask( d->mSearchWidget->displayText() ); return true; } } } return QObject::eventFilter( obj, event ); } void TimetrackerWidget::slotAddTask( const QString &taskName ) { TaskView *taskView = currentTaskView(); taskView->addTask( taskName, QString(), 0, 0, DesktopList(), 0 ); d->mSearchWidget->clear(); } void TimetrackerWidget::slotUpdateButtons() { kDebug(5970) << "Entering function"; Task *item = currentTask(); d->mActions[ "start" ]->setEnabled( item && !item->isRunning() && !item->isComplete() ); d->mActions[ "stop" ]->setEnabled( item && item->isRunning() ); d->mActions[ "delete_task" ]->setEnabled( item ); d->mActions[ "edit_task" ]->setEnabled( item ); d->mActions[ "mark_as_complete" ]->setEnabled( item && !item->isComplete() ); d->mActions[ "mark_as_incomplete" ]->setEnabled( item && item->isComplete() ); d->mActions[ "new_task" ]->setEnabled( currentTaskView() ); d->mActions[ "new_sub_task" ]->setEnabled( currentTaskView() && currentTaskView()->count() ); d->mActions[ "focustracking" ]->setEnabled( currentTaskView() ); d->mActions[ "focustracking" ]->setChecked( currentTaskView() && currentTaskView()->isFocusTrackingActive() ); d->mActions[ "start_new_session" ]->setEnabled( currentTaskView() ); d->mActions[ "edit_history" ]->setEnabled( currentTaskView() ); d->mActions[ "reset_all_times" ]->setEnabled( currentTaskView() ); d->mActions[ "export_times" ]->setEnabled( currentTaskView() ); d->mActions[ "export_history" ]->setEnabled( currentTaskView() ); d->mActions[ "import_planner" ]->setEnabled( currentTaskView() ); d->mActions[ "file_save" ]->setEnabled( currentTaskView() ); kDebug(5970) << "Leaving function"; } void TimetrackerWidget::showSettingsDialog() { kDebug(5970) << "Entering function"; /* show main window b/c if this method was started from tray icon and the window is not visible the application quits after accepting the settings dialog. */ window()->show(); KTimeTrackerConfigDialog *dialog=new KTimeTrackerConfigDialog(i18n( "Settings" ), this); dialog->exec(); delete dialog; KTimeTrackerSettings::self()->readConfig(); showSearchBar(!KTimeTrackerSettings::configPDA() && KTimeTrackerSettings::showSearchBar()); currentTaskView()->reconfigure(); } //BEGIN wrapper slots void TimetrackerWidget::startCurrentTimer() { currentTaskView()->startCurrentTimer(); } void TimetrackerWidget::stopCurrentTimer() { currentTaskView()->stopCurrentTimer(); } void TimetrackerWidget::stopAllTimers( const QDateTime &when ) { currentTaskView()->stopAllTimers(when); } void TimetrackerWidget::newTask() { currentTaskView()->newTask(); } void TimetrackerWidget::newSubTask() { currentTaskView()->newSubTask(); } void TimetrackerWidget::editTask() { currentTaskView()->editTask(); } void TimetrackerWidget::deleteTask() { currentTaskView()->deleteTask(); } void TimetrackerWidget::markTaskAsComplete() { currentTaskView()->markTaskAsComplete(); } void TimetrackerWidget::markTaskAsIncomplete() { currentTaskView()->markTaskAsIncomplete(); } void TimetrackerWidget::exportcsvFile() { currentTaskView()->exportcsvFile(); } void TimetrackerWidget::exportcsvHistory() { currentTaskView()->exportcsvHistory(); } void TimetrackerWidget::importPlanner( const QString &fileName ) { currentTaskView()->importPlanner(fileName); } void TimetrackerWidget::startNewSession() { currentTaskView()->startNewSession(); } void TimetrackerWidget::editHistory() { // historydialog is the new historydialog, but the EditHiStoryDiaLog exists as well. // historydialog can be edited with qtcreator and qtdesigner, EditHiStoryDiaLog cannot. if ( currentTaskView() ) { historydialog *dlg = new historydialog( currentTaskView() ); if (currentTaskView()->storage()->rawevents().count()!=0) dlg->exec(); else KMessageBox::information(0, i18nc("@info in message box", "There is no history yet. Start and stop a task and you will have an entry in your history.")); } } void TimetrackerWidget::resetAllTimes() { if ( currentTaskView() ) { if ( KMessageBox::warningContinueCancel( this, i18n( "Do you really want to reset the time to zero for all tasks? This will delete the entire history." ), i18n( "Confirmation Required" ), KGuiItem( i18n( "Reset All Times" ) ) ) == KMessageBox::Continue ) currentTaskView()->resetTimeForAllTasks(); } } void TimetrackerWidget::focusTracking() { currentTaskView()->toggleFocusTracking(); d->mActions["focustracking"]->setChecked(currentTaskView()->isFocusTrackingActive()); } void TimetrackerWidget::slotSearchBar() { bool currentVisible = KTimeTrackerSettings::self()->showSearchBar(); KTimeTrackerSettings::self()->setShowSearchBar( !currentVisible ); d->mActions[ "searchbar" ]->setChecked( !currentVisible ); showSearchBar( !currentVisible ); } //END /** \defgroup dbus slots ‘‘dbus slots’’ */ /* @{ */ QString TimetrackerWidget::version() const { return KDEPIM_VERSION; } QStringList TimetrackerWidget::taskIdsFromName( const QString &taskName ) const { QStringList result; TaskView *taskView = currentTaskView(); if ( !taskView ) return result; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->name() == taskName ) { result << task->uid(); } ++it; } return result; } void TimetrackerWidget::addTask( const QString &taskName ) { TaskView *taskView = currentTaskView(); if ( taskView ) { taskView->addTask( taskName, QString(), 0, 0, DesktopList(), 0 ); } } void TimetrackerWidget::addSubTask( const QString& taskName, const QString &taskId ) { TaskView *taskView = currentTaskView(); if ( taskView ) { taskView->addTask( taskName, QString(), 0, 0, DesktopList(), taskView->task( taskId) ); taskView->refresh(); } } void TimetrackerWidget::deleteTask( const QString &taskId ) { TaskView *taskView = currentTaskView(); if ( !taskView ) return; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->uid() == taskId ) { taskView->deleteTaskBatch( task ); } ++it; } } void TimetrackerWidget::setPercentComplete( const QString &taskId, int percent ) { TaskView *taskView = currentTaskView(); if ( !taskView ) return; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->uid() == taskId ) { task->setPercentComplete( percent, taskView->storage() ); } ++it; } } int TimetrackerWidget::changeTime( const QString &taskId, int minutes ) { int result=0; QDate startDate; QTime startTime; QDateTime startDateTime; Task *task = 0, *t = 0; TaskView *taskView; if ( minutes <= 0 ) return KTIMETRACKER_ERR_INVALID_DURATION; // Find task taskView = currentTaskView(); if ( taskView ) return KTIMETRACKER_ERR_UID_NOT_FOUND; //FIXME: it mimics the behaviour with the for loop, but I am not sure semantics were right. Maybe a new error code must be defined? QTreeWidgetItemIterator it( taskView ); while ( *it ) { t = static_cast< Task* >( *it ); if ( t && t->uid() == taskId ) { task = t; break; } ++it; } if ( !task ) result=KTIMETRACKER_ERR_UID_NOT_FOUND; else task->changeTime(minutes, task->taskView()->storage()); return result; } QString TimetrackerWidget::error( int errorCode ) const { switch ( errorCode ) { case KTIMETRACKER_ERR_GENERIC_SAVE_FAILED: return i18n( "Save failed, most likely because the file could not be locked." ); case KTIMETRACKER_ERR_COULD_NOT_MODIFY_RESOURCE: return i18n( "Could not modify calendar resource." ); case KTIMETRACKER_ERR_MEMORY_EXHAUSTED: return i18n( "Out of memory--could not create object." ); case KTIMETRACKER_ERR_UID_NOT_FOUND: return i18n( "UID not found." ); case KTIMETRACKER_ERR_INVALID_DATE: return i18n( "Invalidate date--format is YYYY-MM-DD." ); case KTIMETRACKER_ERR_INVALID_TIME: return i18n( "Invalid time--format is YYYY-MM-DDTHH:MM:SS." ); case KTIMETRACKER_ERR_INVALID_DURATION: return i18n( "Invalid task duration--must be greater than zero." ); default: return i18n( "Invalid error number: %1", errorCode ); } } bool TimetrackerWidget::isIdleDetectionPossible() const { bool result; IdleTimeDetector *idletimedetector1=new IdleTimeDetector(50); result=idletimedetector1->isIdleDetectionPossible(); delete idletimedetector1; return result; } int TimetrackerWidget::totalMinutesForTaskId( const QString &taskId ) const { TaskView *taskView = currentTaskView(); if ( !taskView ) return -1; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->uid() == taskId ) { return task->totalTime(); } ++it; } return -1; } void TimetrackerWidget::startTimerFor( const QString &taskId ) { kDebug(); TaskView *taskView = currentTaskView(); if ( !taskView ) return; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->uid() == taskId ) { taskView->startTimerFor( task ); return; } ++it; } } bool TimetrackerWidget::startTimerForTaskName( const QString &taskName ) { TaskView *taskView = currentTaskView(); if ( !taskView ) return false; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->name() == taskName ) { taskView->startTimerFor( task ); return true; } ++it; } return false; } bool TimetrackerWidget::stopTimerForTaskName( const QString &taskName ) { TaskView *taskView = currentTaskView(); if ( !taskView ) return false; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->name() == taskName ) { taskView->stopTimerFor( task ); return true; } ++it; } return false; } void TimetrackerWidget::stopTimerFor( const QString &taskId ) { TaskView *taskView = currentTaskView(); if ( !taskView ) return; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->uid() == taskId ) { taskView->stopTimerFor( task ); return; } ++it; } } void TimetrackerWidget::stopAllTimersDBUS() { TaskView *taskView = currentTaskView(); if (taskView) taskView->stopAllTimers(); } QString TimetrackerWidget::exportCSVFile( const QString &filename, const QString &from, const QString &to, int type, bool decimalMinutes, bool allTasks, const QString &delimiter, const QString "e ) { TaskView *taskView = currentTaskView(); if ( !taskView ) return ""; ReportCriteria rc; rc.url = filename; rc.from = QDate::fromString( from ); if ( rc.from.isNull() ) rc.from = QDate::fromString( from, Qt::ISODate ); rc.to = QDate::fromString( to ); if ( rc.to.isNull() ) rc.to = QDate::fromString( to, Qt::ISODate ); rc.reportType = ( ReportCriteria::REPORTTYPE )type; rc.decimalMinutes = decimalMinutes; rc.allTasks = allTasks; rc.delimiter = delimiter; rc.quote = quote; return taskView->report( rc ); } void TimetrackerWidget::importPlannerFile( const QString &filename ) { TaskView *taskView = currentTaskView(); if ( !taskView ) return; taskView->importPlanner( filename ); } bool TimetrackerWidget::isActive( const QString &taskId ) const { TaskView *taskView = currentTaskView(); if ( !taskView ) return false; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->uid() == taskId ) { return task->isRunning(); } ++it; } return false; } bool TimetrackerWidget::isTaskNameActive( const QString &taskName ) const { TaskView *taskView = currentTaskView(); if ( !taskView ) return false; QTreeWidgetItemIterator it( taskView ); while ( *it ) { Task *task = static_cast< Task* >( *it ); if ( task && task->name() == taskName ) { return task->isRunning(); } ++it; } return false; } QStringList TimetrackerWidget::tasks() const { QStringList result; TaskView *taskView = currentTaskView(); if ( !taskView ) return result; QTreeWidgetItemIterator it( taskView ); while ( *it ) { result << static_cast< Task* >( *it )->name(); ++it; } return result; } QStringList TimetrackerWidget::activeTasks() const { QStringList result; TaskView *taskView = currentTaskView(); if ( !taskView ) return result; for ( int j = 0; j < taskView->count(); ++j ) { if ( taskView->itemAt( j )->isRunning() ) { result << taskView->itemAt( j )->name(); } } return result; } void TimetrackerWidget::saveAll() { currentTaskView()->save(); } bool TimetrackerWidget::event ( QEvent * event ) // inherited from QWidget { if (event->type()==QEvent::QueryWhatsThis) { if ( d->mTaskView->count() == 0 ) setWhatsThis( i18n("This is ktimetracker, KDE's program to help you track your time. Best, start with creating your first task - enter it into the field where you see \"search or add task\".") ); else setWhatsThis( i18n("You have already created a task. You can now start and stop timing") ); } return QWidget::event(event); } void TimetrackerWidget::quit() { kDebug(5970) << "Entering TimetrackerWidget::quit"; if ( closeAllFiles() ) { kapp->quit(); } } // END of dbus slots group /* @} */