kde-playground/kdepim/ktimetracker/timetrackerwidget.cpp
2015-04-14 21:49:29 +00:00

990 lines
31 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
* Copyright (C) 2007 by Mathias Soeken <msoeken@tzi.de>
*
* 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 <QDBusConnection>
#include <QFileInfo>
#include <QHBoxLayout>
#include <QKeyEvent>
#include <QKeySequence>
#include <QMap>
#include <QVBoxLayout>
#include <QVector>
#include <KApplication>
#include <KAction>
#include <KActionCollection>
#include <KConfig>
#include <KConfigDialog>
#include <KDebug>
#include <KFileDialog>
#include <KGlobal>
#include <KIcon>
#include <KLocale>
#include <KMessageBox>
#include <KRecentFilesAction>
#include <KStandardAction>
#include <KTabWidget>
#include <KTemporaryFile>
#include <KTreeWidgetSearchLine>
#include <KUrl>
#include <KIO/Job>
#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<QString, KAction*> 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<Task*>)),
this, SIGNAL(tasksChanged(QList<Task*>)));
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<Task*>)),
this, SIGNAL(tasksChanged(QList<Task*>)) );
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<Task*>)), // FIXME signature
this, SIGNAL(tasksChanged(QList<Task*>)) );
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 &quote )
{
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
/* @} */