8 #include "tdeaccelmenuwatch.h"
9 #include <dcopclient.h>
11 #include <tdeaction.h>
12 #include <tdeapplication.h>
13 #include <tdeconfig.h>
15 #include <tdeglobal.h>
16 #include <kkeydialog.h>
17 #include <tdelocale.h>
18 #include <tdemessagebox.h>
19 #include <kstatusbar.h>
20 #include <kstdaction.h>
21 #include <tqkeycode.h>
22 #include <tqpopupmenu.h>
23 #include <tqptrlist.h>
26 #include "karmerrors.h"
27 #include "karmutility.h"
28 #include "mainwindow.h"
29 #include "preferences.h"
37 MainWindow::MainWindow(
const TQString &icsfile )
38 : DCOPObject (
"KarmDCOPIface" ),
40 _accel ( new TDEAccel( this ) ),
46 _taskView =
new TaskView(
this, 0, icsfile );
48 setCentralWidget( _taskView );
53 _preferences = Preferences::instance();
57 _watcher->updateMenus();
60 connect( _taskView, TQ_SIGNAL( totalTimesChanged(
long,
long ) ),
61 this, TQ_SLOT( updateTime(
long,
long ) ) );
62 connect( _taskView, TQ_SIGNAL( selectionChanged ( TQListViewItem * )),
63 this, TQ_SLOT(slotSelectionChanged()));
64 connect( _taskView, TQ_SIGNAL( updateButtons() ),
65 this, TQ_SLOT(slotSelectionChanged()));
66 connect( _taskView, TQ_SIGNAL( setStatusBar( TQString ) ),
67 this, TQ_SLOT(setStatusBar( TQString )));
73 TQ_SIGNAL( contextMenuRequested( TQListViewItem*,
const TQPoint&,
int )),
75 TQ_SLOT( contextMenuRequest( TQListViewItem*,
const TQPoint&,
int )));
77 _tray =
new KarmTray(
this );
79 connect( _tray, TQ_SIGNAL( quitSelected() ), TQ_SLOT( quit() ) );
81 connect( _taskView, TQ_SIGNAL( timersActive() ), _tray, TQ_SLOT( startClock() ) );
82 connect( _taskView, TQ_SIGNAL( timersActive() ),
this, TQ_SLOT( enableStopAll() ));
83 connect( _taskView, TQ_SIGNAL( timersInactive() ), _tray, TQ_SLOT( stopClock() ) );
84 connect( _taskView, TQ_SIGNAL( timersInactive() ),
this, TQ_SLOT( disableStopAll()));
85 connect( _taskView, TQ_SIGNAL( tasksChanged( TQPtrList<Task> ) ),
86 _tray, TQ_SLOT( updateToolTip( TQPtrList<Task> ) ));
92 _preferences->emitSignals();
93 slotSelectionChanged();
96 if ( !kapp->dcopClient()->isRegistered() )
98 kapp->dcopClient()->registerAs(
"karm" );
99 kapp->dcopClient()->setDefaultObject( objId() );
103 m_error[ KARM_ERR_GENERIC_SAVE_FAILED ] =
104 i18n(
"Save failed, most likely because the file could not be locked." );
105 m_error[ KARM_ERR_COULD_NOT_MODIFY_RESOURCE ] =
106 i18n(
"Could not modify calendar resource." );
107 m_error[ KARM_ERR_MEMORY_EXHAUSTED ] =
108 i18n(
"Out of memory--could not create object." );
109 m_error[ KARM_ERR_UID_NOT_FOUND ] =
110 i18n(
"UID not found." );
111 m_error[ KARM_ERR_INVALID_DATE ] =
112 i18n(
"Invalidate date--format is YYYY-MM-DD." );
113 m_error[ KARM_ERR_INVALID_TIME ] =
114 i18n(
"Invalid time--format is YYYY-MM-DDTHH:MM:SS." );
115 m_error[ KARM_ERR_INVALID_DURATION ] =
116 i18n(
"Invalid task duration--must be greater than zero." );
119 void MainWindow::slotSelectionChanged()
122 actionDelete->setEnabled(item);
123 actionEdit->setEnabled(item);
125 actionStop->setEnabled(item && item->
isRunning());
126 actionMarkAsComplete->setEnabled(item && !item->
isComplete());
127 actionMarkAsIncomplete->setEnabled(item && item->
isComplete());
137 void MainWindow::setStatusBar(TQString qs)
139 statusBar()->message(qs.isEmpty() ?
"" : i18n(qs.ascii()));
142 bool MainWindow::save()
144 kdDebug(5970) <<
"Saving time data to disk." << endl;
145 TQString err=_taskView->
save();
146 if (err.isEmpty()) statusBar()->message(i18n(
"Successfully saved tasks and history"),1807);
147 else statusBar()->message(i18n(err.ascii()),7707);
152 void MainWindow::exportcsvHistory()
154 kdDebug(5970) <<
"Exporting History to disk." << endl;
156 if (err.isEmpty()) statusBar()->message(i18n(
"Successfully exported History to CSV-file"),1807);
157 else KMessageBox::error(
this, err.ascii());
162 void MainWindow::quit()
168 MainWindow::~MainWindow()
170 kdDebug(5970) <<
"MainWindow::~MainWindows: Quitting karm." << endl;
176 void MainWindow::enableStopAll()
178 actionStopAll->setEnabled(
true);
181 void MainWindow::disableStopAll()
183 actionStopAll->setEnabled(
false);
194 _sessionSum += sessionDiff;
195 _totalSum += totalDiff;
200 void MainWindow::updateStatusBar( )
204 time = formatTime( _sessionSum );
205 statusBar()->changeItem( i18n(
"Session: %1").arg(time), 0 );
207 time = formatTime( _totalSum );
208 statusBar()->changeItem( i18n(
"Total: %1" ).arg(time), 1);
211 void MainWindow::startStatusBar()
213 statusBar()->insertItem( i18n(
"Session"), 0, 0,
true );
214 statusBar()->insertItem( i18n(
"Total" ), 1, 0,
true );
217 void MainWindow::saveProperties( TDEConfig* cfg )
221 cfg->writeEntry(
"WindowShown", isVisible());
224 void MainWindow::readProperties( TDEConfig* cfg )
226 if( cfg->readBoolEntry(
"WindowShown",
true ))
230 void MainWindow::keyBindings()
232 KKeyDialog::configure( actionCollection(),
this );
235 void MainWindow::startNewSession()
240 void MainWindow::resetAllTimes()
242 if ( KMessageBox::warningContinueCancel(
this, i18n(
"Do you really want to reset the time to zero for all tasks?" ),
243 i18n(
"Confirmation Required" ), KGuiItem( i18n(
"Reset All Times" ) ) ) == KMessageBox::Continue )
247 void MainWindow::makeMenus()
254 (void) KStdAction::quit(
this, TQ_SLOT( quit() ), actionCollection());
255 (void) KStdAction::print(
this, TQ_SLOT( print() ), actionCollection());
256 actionKeyBindings = KStdAction::keyBindings(
this, TQ_SLOT( keyBindings() ),
257 actionCollection() );
258 actionPreferences = KStdAction::preferences(_preferences,
259 TQ_SLOT(showDialog()),
260 actionCollection() );
261 (void) KStdAction::save(
this, TQ_SLOT( save() ), actionCollection() );
262 TDEAction* actionStartNewSession =
new TDEAction( i18n(
"Start &New Session"),
265 TQ_SLOT( startNewSession() ),
267 "start_new_session");
268 TDEAction* actionResetAll =
new TDEAction( i18n(
"&Reset All Times"),
271 TQ_SLOT( resetAllTimes() ),
274 actionStart =
new TDEAction( i18n(
"&Start"),
275 TQString::fromLatin1(
"1rightarrow"), Key_S,
277 TQ_SLOT( startCurrentTimer() ), actionCollection(),
279 actionStop =
new TDEAction( i18n(
"S&top"),
280 TQString::fromLatin1(
"process-stop"), Key_S,
282 TQ_SLOT( stopCurrentTimer() ), actionCollection(),
284 actionStopAll =
new TDEAction( i18n(
"Stop &All Timers"),
287 TQ_SLOT( stopAllTimers() ), actionCollection(),
289 actionStopAll->setEnabled(
false);
291 actionNew =
new TDEAction( i18n(
"&New..."),
292 TQString::fromLatin1(
"document-new"), CTRL+Key_N,
294 TQ_SLOT( newTask() ), actionCollection(),
296 actionNewSub =
new TDEAction( i18n(
"New &Subtask..."),
297 TQString::fromLatin1(
"application-vnd.tde.tdemultiple"), CTRL+ALT+Key_N,
299 TQ_SLOT( newSubTask() ), actionCollection(),
301 actionDelete =
new TDEAction( i18n(
"&Delete"),
302 TQString::fromLatin1(
"edit-delete"), Key_Delete,
304 TQ_SLOT( deleteTask() ), actionCollection(),
306 actionEdit =
new TDEAction( i18n(
"&Edit..."),
307 TQString::fromLatin1(
"edit"), CTRL + Key_E,
309 TQ_SLOT( editTask() ), actionCollection(),
318 actionMarkAsComplete =
new TDEAction( i18n(
"&Mark as Complete"),
319 TQString::fromLatin1(
"text-x-generic"),
322 TQ_SLOT( markTaskAsComplete() ),
325 actionMarkAsIncomplete =
new TDEAction( i18n(
"&Mark as Incomplete"),
326 TQString::fromLatin1(
"text-x-generic"),
329 TQ_SLOT( markTaskAsIncomplete() ),
331 "mark_as_incomplete");
332 actionClipTotals =
new TDEAction( i18n(
"&Copy Totals to Clipboard"),
333 TQString::fromLatin1(
"klipper"),
336 TQ_SLOT( clipTotals() ),
340 actionClipTotals =
new TDEAction( i18n(
"&Copy Session Time to Clipboard"),
341 TQString::fromLatin1(
"klipper"),
344 TQ_SLOT( clipSession() ),
347 actionClipHistory =
new TDEAction( i18n(
"Copy &History to Clipboard"),
348 TQString::fromLatin1(
"klipper"),
351 TQ_SLOT( clipHistory() ),
355 new TDEAction( i18n(
"Import &Legacy Flat File..."), 0,
356 _taskView, TQ_SLOT(loadFromFlatFile()), actionCollection(),
358 new TDEAction( i18n(
"&Export to CSV File..."), 0,
359 _taskView, TQ_SLOT(exportcsvFile()), actionCollection(),
361 new TDEAction( i18n(
"Export &History to CSV File..."), 0,
362 this, TQ_SLOT(exportcsvHistory()), actionCollection(),
363 "export_csvhistory");
364 new TDEAction( i18n(
"Import Tasks From &Planner..."), 0,
365 _taskView, TQ_SLOT(importPlanner()), actionCollection(),
375 setXMLFile( TQString::fromLatin1(
"karmui.rc") );
379 actionKeyBindings->setToolTip( i18n(
"Configure key bindings") );
380 actionKeyBindings->setWhatsThis( i18n(
"This will let you configure key"
381 "bindings which is specific to karm") );
383 actionStartNewSession->setToolTip( i18n(
"Start a new session") );
384 actionStartNewSession->setWhatsThis( i18n(
"This will reset the session time "
385 "to 0 for all tasks, to start a "
386 "new session, without affecting "
388 actionResetAll->setToolTip( i18n(
"Reset all times") );
389 actionResetAll->setWhatsThis( i18n(
"This will reset the session and total "
390 "time to 0 for all tasks, to restart from "
393 actionStart->setToolTip( i18n(
"Start timing for selected task") );
394 actionStart->setWhatsThis( i18n(
"This will start timing for the selected "
396 "It is even possible to time several tasks "
397 "simultaneously.\n\n"
398 "You may also start timing of a tasks by "
399 "double clicking the left mouse "
400 "button on a given task. This will, however, "
401 "stop timing of other tasks."));
403 actionStop->setToolTip( i18n(
"Stop timing of the selected task") );
404 actionStop->setWhatsThis( i18n(
"Stop timing of the selected task") );
406 actionStopAll->setToolTip( i18n(
"Stop all of the active timers") );
407 actionStopAll->setWhatsThis( i18n(
"Stop all of the active timers") );
409 actionNew->setToolTip( i18n(
"Create new top level task") );
410 actionNew->setWhatsThis( i18n(
"This will create a new top level task.") );
412 actionDelete->setToolTip( i18n(
"Delete selected task") );
413 actionDelete->setWhatsThis( i18n(
"This will delete the selected task and "
414 "all its subtasks.") );
416 actionEdit->setToolTip( i18n(
"Edit name or times for selected task") );
417 actionEdit->setWhatsThis( i18n(
"This will bring up a dialog box where you "
418 "may edit the parameters for the selected "
426 actionClipTotals->setToolTip(i18n(
"Copy task totals to clipboard"));
427 actionClipHistory->setToolTip(i18n(
"Copy time card history to clipboard."));
429 slotSelectionChanged();
432 void MainWindow::print()
438 void MainWindow::loadGeometry()
440 if (initialGeometrySet()) setAutoSaveSettings();
443 TDEConfig &config = *kapp->config();
445 config.setGroup( TQString::fromLatin1(
"Main Window Geometry") );
446 int w = config.readNumEntry( TQString::fromLatin1(
"Width"), 100 );
447 int h = config.readNumEntry( TQString::fromLatin1(
"Height"), 100 );
448 w = TQMAX( w, sizeHint().width() );
449 h = TQMAX( h, sizeHint().height() );
455 void MainWindow::saveGeometry()
457 TDEConfig &config = *TDEGlobal::config();
458 config.setGroup( TQString::fromLatin1(
"Main Window Geometry"));
459 config.writeEntry( TQString::fromLatin1(
"Width"), width());
460 config.writeEntry( TQString::fromLatin1(
"Height"), height());
464 bool MainWindow::queryClose()
466 if ( !kapp->sessionSaving() ) {
470 return TDEMainWindow::queryClose();
473 void MainWindow::contextMenuRequest( TQListViewItem*,
const TQPoint& point,
int )
475 TQPopupMenu* pop =
dynamic_cast<TQPopupMenu*
>(
476 factory()->container( i18n(
"task_popup" ),
this ) );
500 return _preferences->promptDelete();
505 _preferences->setPromptDelete( prompt );
514 while ( rval.isEmpty() && task )
516 rval = _hasTask( task, taskname );
517 task = task->nextSibling();
525 DesktopList desktopList;
526 TQString uid = _taskView->
addTask( taskname, 0, 0, desktopList );
527 kdDebug(5970) <<
"MainWindow::addTask( " << taskname <<
" ) returns " << uid << endl;
528 if ( uid.length() > 0 )
return 0;
533 return KARM_ERR_GENERIC_SAVE_FAILED;
540 TQString err=
"no such task";
541 for (
int i=0; i<_taskView->
count(); i++)
546 if (err==TQString()) err=
"task name is abigious";
547 if (err==
"no such task") err=TQString();
558 (
const TQString& taskId,
const TQString& datetime,
long minutes )
563 TQDateTime startDateTime;
566 if ( minutes <= 0 ) rval = KARM_ERR_INVALID_DURATION;
573 t = _hasUid( task, taskId );
574 task = task->nextSibling();
576 if ( t == NULL ) rval = KARM_ERR_UID_NOT_FOUND;
581 startDate = TQDate::fromString( datetime, TQt::ISODate );
582 if ( datetime.length() > 10 )
584 startTime = TQTime::fromString( datetime, TQt::ISODate );
586 else startTime = TQTime( 12, 0 );
587 if ( startDate.isValid() && startTime.isValid() )
589 startDateTime = TQDateTime( startDate, startTime );
591 else rval = KARM_ERR_INVALID_DATE;
598 t->
changeTotalTimes( t->sessionTime() + minutes, t->totalTime() + minutes );
599 if ( ! _taskView->
storage()->
bookTime( t, startDateTime, minutes * 60 ) )
601 rval = KARM_ERR_GENERIC_SAVE_FAILED;
612 if ( mkb <= KARM_MAX_ERROR_NO )
return m_error[ mkb ];
613 else return i18n(
"Invalid error number: %1" ).arg( mkb );
621 kdDebug(5970) <<
"MainWindow::totalTimeForTask( " << taskId <<
" )" << endl;
628 t = _hasUid( task, taskId );
629 task = task->nextSibling();
633 rval = t->totalTime();
634 kdDebug(5970) <<
"MainWindow::totalTimeForTask - task found: rval = " << rval << endl;
638 kdDebug(5970) <<
"MainWindow::totalTimeForTask - task not found" << endl;
639 rval = KARM_ERR_UID_NOT_FOUND;
645 TQString MainWindow::_hasTask(
Task* task,
const TQString &taskname )
const
648 if ( task->
name() == taskname )
655 while ( rval.isEmpty() && nexttask )
657 rval = _hasTask( nexttask, taskname );
658 nexttask = nexttask->nextSibling();
664 Task* MainWindow::_hasUid(
Task* task,
const TQString &uid )
const
670 if ( task->
uid() == uid ) rval = task;
674 while ( !rval && nexttask )
676 rval = _hasUid( nexttask, uid );
677 nexttask = nexttask->nextSibling();
685 TQString err=
"no such task";
686 for (
int i=0; i<_taskView->
count(); i++)
691 if (err==TQString()) err=
"task name is abigious";
692 if (err==
"no such task") err=TQString();
702 TQString err=
"no such task";
703 for (
int i=0; i<_taskView->
count(); i++)
708 if (err==TQString()) err=
"task name is abigious";
709 if (err==
"no such task") err=TQString();
712 if (err==TQString()) _taskView->stopTimerFor( _taskView->
item_at_index(index) );
716 TQString
MainWindow::exportcsvfile( TQString filename, TQString from, TQString to,
int type,
bool decimalMinutes,
bool allTasks, TQString delimiter, TQString quote )
720 rc.
from=TQDate::fromString( from );
721 if ( rc.
from.isNull() ) rc.
from=TQDate::fromString( from, TQt::ISODate );
722 kdDebug(5970) <<
"rc.from " << rc.
from << endl;
723 rc.
to=TQDate::fromString( to );
724 if ( rc.
to.isNull() ) rc.
to=TQDate::fromString( to, TQt::ISODate );
725 kdDebug(5970) <<
"rc.to " << rc.
to << endl;
731 return _taskView->
report( rc );
740 #include "mainwindow.moc"
bool bookTime(const Task *task, const TQDateTime &startDateTime, long durationInSeconds)
Book time to a task.
Main window to tie the application together.
int addTask(const TQString &storage)
TQString setPerCentComplete(const TQString &taskName, int PerCent)
TQString setpromptdelete(bool prompt)
set if there will be a "really delete" question
TQString exportcsvfile(TQString filename, TQString from, TQString to, int type, bool decimalMinutes, bool allTasks, TQString delimiter, TQString quote)
export csv history or totals file
int totalMinutesForTaskId(const TQString &taskId)
Total time currently associated with a task.
int bookTime(const TQString &taskId, const TQString &iso8601StartDateTime, long durationInMinutes)
TQString stoptimerfor(const TQString &taskname)
stop the timer for taskname
TQString getError(int karmErrorNumber) const
TQString version() const
Return karm version.
TQString starttimerfor(const TQString &taskname)
start the timer for taskname
TQString taskIdFromName(const TQString &taskName) const
Return id of task found, empty string if no match.
bool getpromptdelete()
shall there be a "really delete" question
TQString importplannerfile(TQString filename)
import planner project file
void updateTime(long, long)
Calculate the sum of the session time and the total time for all toplevel tasks and put it in the sta...
TQString deletetodo()
delete the current item
Provide printing capabilities.
Stores entries from export dialog.
bool decimalMinutes
True if the durations should be output in decimal hours.
REPORTTYPE
The different report types.
TQString quote
The quote to use for text fields when outputting comma-seperated reports.
TQDate to
For history reports, the upper bound of the date range to report on.
bool allTasks
True if the report should contain all tasks in Karm.
KURL url
For reports that write to a file, the filename to write to.
TQString delimiter
The delimiter to use when outputting comma-seperated value reports.
REPORTTYPE reportType
The type of report we are running.
TQDate from
For history reports, the lower bound of the date range to report on.
Container and interface for the tasks.
KarmStorage * storage()
Returns a pointer to storage object.
Task * first_child() const
Return the first item in the view, cast to a Task pointer.
long count()
Return the total number if items in the view.
TQString exportcsvHistory()
Export comma-separated values format for task history.
void resetTimeForAllTasks()
Reset session and total time to zero for all tasks.
TQString importPlanner(TQString fileName="")
used to import tasks from imendio planner
void closeStorage()
Close the storage and release lock.
TQString addTask(const TQString &taskame, long total, long session, const DesktopList &desktops, Task *parent=0)
Add a task to view and storage.
TQString report(const ReportCriteria &rc)
call export function for csv totals or history
Task * current_item() const
Return the current item in the view, cast to a Task pointer.
TQString save()
Save to persistent storage.
Task * item_at_index(int i)
Return the i'th item (zero-based), cast to a Task pointer.
void deleteTask(bool markingascomplete=false)
Delete task (and children) from view.
void startTimerFor(Task *task, TQDateTime startTime=TQDateTime::currentDateTime())
starts timer for task.
void stopAllTimers()
Stop all running timers.
void startNewSession()
Reset session time to zero for all tasks.
A class representing a task.
bool isComplete()
Return true if task is complete (percent complete equals 100).
TQString name() const
returns the name of this task.
Task * firstChild() const
return parent Task or null in case of TaskView.
void changeTotalTimes(long minutesSession, long minutes)
adds minutes to total and session time
TQString uid() const
Return unique iCalendar Todo ID for this task.
void setPercentComplete(const int percent, KarmStorage *storage)
Update percent complete for this task.
bool isRunning() const
return the state of a task - if it's running or not