karm

mainwindow.cpp
00001 /*
00002 * Top Level window for KArm.
00003 * Distributed under the GPL.
00004 */
00005 
00006 #include <numeric>
00007 
00008 #include "tdeaccelmenuwatch.h"
00009 #include <dcopclient.h>
00010 #include <tdeaccel.h>
00011 #include <tdeaction.h>
00012 #include <tdeapplication.h>       // kapp
00013 #include <tdeconfig.h>
00014 #include <kdebug.h>
00015 #include <tdeglobal.h>
00016 #include <kkeydialog.h>
00017 #include <tdelocale.h>            // i18n
00018 #include <tdemessagebox.h>
00019 #include <kstatusbar.h>         // statusBar()
00020 #include <kstdaction.h>
00021 #include <tqkeycode.h>
00022 #include <tqpopupmenu.h>
00023 #include <tqptrlist.h>
00024 #include <tqstring.h>
00025 
00026 #include "karmerrors.h"
00027 #include "karmutility.h"
00028 #include "mainwindow.h"
00029 #include "preferences.h"
00030 #include "print.h"
00031 #include "task.h"
00032 #include "taskview.h"
00033 #include "timekard.h"
00034 #include "tray.h"
00035 #include "version.h"
00036 
00037 MainWindow::MainWindow( const TQString &icsfile )
00038   : DCOPObject ( "KarmDCOPIface" ),
00039     KParts::MainWindow(0,TQt::WStyle_ContextHelp), 
00040     _accel     ( new TDEAccel( this ) ),
00041     _watcher   ( new TDEAccelMenuWatch( _accel, TQT_TQOBJECT(this) ) ),
00042     _totalSum  ( 0 ),
00043     _sessionSum( 0 )
00044 {
00045 
00046   _taskView  = new TaskView( this, 0, icsfile );
00047 
00048   setCentralWidget( _taskView );
00049   // status bar
00050   startStatusBar();
00051 
00052   // setup PreferenceDialog.
00053   _preferences = Preferences::instance();
00054 
00055   // popup menus
00056   makeMenus();
00057   _watcher->updateMenus();
00058 
00059   // connections
00060   connect( _taskView, TQT_SIGNAL( totalTimesChanged( long, long ) ),
00061            this, TQT_SLOT( updateTime( long, long ) ) );
00062   connect( _taskView, TQT_SIGNAL( selectionChanged ( TQListViewItem * )),
00063            this, TQT_SLOT(slotSelectionChanged()));
00064   connect( _taskView, TQT_SIGNAL( updateButtons() ),
00065            this, TQT_SLOT(slotSelectionChanged()));
00066   connect( _taskView, TQT_SIGNAL( setStatusBar( TQString ) ),
00067            this, TQT_SLOT(setStatusBar( TQString )));
00068 
00069   loadGeometry();
00070 
00071   // Setup context menu request handling
00072   connect( _taskView,
00073            TQT_SIGNAL( contextMenuRequested( TQListViewItem*, const TQPoint&, int )),
00074            this,
00075            TQT_SLOT( contextMenuRequest( TQListViewItem*, const TQPoint&, int )));
00076 
00077   _tray = new KarmTray( this );
00078 
00079   connect( _tray, TQT_SIGNAL( quitSelected() ), TQT_SLOT( quit() ) );
00080 
00081   connect( _taskView, TQT_SIGNAL( timersActive() ), _tray, TQT_SLOT( startClock() ) );
00082   connect( _taskView, TQT_SIGNAL( timersActive() ), this,  TQT_SLOT( enableStopAll() ));
00083   connect( _taskView, TQT_SIGNAL( timersInactive() ), _tray, TQT_SLOT( stopClock() ) );
00084   connect( _taskView, TQT_SIGNAL( timersInactive() ),  this,  TQT_SLOT( disableStopAll()));
00085   connect( _taskView, TQT_SIGNAL( tasksChanged( TQPtrList<Task> ) ),
00086                       _tray, TQT_SLOT( updateToolTip( TQPtrList<Task> ) ));
00087 
00088   _taskView->load();
00089 
00090   // Everything that uses Preferences has been created now, we can let it
00091   // emit its signals
00092   _preferences->emitSignals();
00093   slotSelectionChanged();
00094 
00095   // Register with DCOP
00096   if ( !kapp->dcopClient()->isRegistered() ) 
00097   {
00098     kapp->dcopClient()->registerAs( "karm" );
00099     kapp->dcopClient()->setDefaultObject( objId() );
00100   }
00101 
00102   // Set up DCOP error messages
00103   m_error[ KARM_ERR_GENERIC_SAVE_FAILED ] = 
00104     i18n( "Save failed, most likely because the file could not be locked." );
00105   m_error[ KARM_ERR_COULD_NOT_MODIFY_RESOURCE ] = 
00106     i18n( "Could not modify calendar resource." );
00107   m_error[ KARM_ERR_MEMORY_EXHAUSTED ] = 
00108     i18n( "Out of memory--could not create object." );
00109   m_error[ KARM_ERR_UID_NOT_FOUND ] = 
00110     i18n( "UID not found." );
00111   m_error[ KARM_ERR_INVALID_DATE ] = 
00112     i18n( "Invalidate date--format is YYYY-MM-DD." );
00113   m_error[ KARM_ERR_INVALID_TIME ] = 
00114     i18n( "Invalid time--format is YYYY-MM-DDTHH:MM:SS." );
00115   m_error[ KARM_ERR_INVALID_DURATION ] = 
00116     i18n( "Invalid task duration--must be greater than zero." );
00117 }
00118 
00119 void MainWindow::slotSelectionChanged()
00120 {
00121   Task* item= _taskView->current_item();
00122   actionDelete->setEnabled(item);
00123   actionEdit->setEnabled(item);
00124   actionStart->setEnabled(item && !item->isRunning() && !item->isComplete());
00125   actionStop->setEnabled(item && item->isRunning());
00126   actionMarkAsComplete->setEnabled(item && !item->isComplete());
00127   actionMarkAsIncomplete->setEnabled(item && item->isComplete());
00128 }
00129 
00130 // This is _old_ code, but shows how to enable/disable add comment menu item.
00131 // We'll need this kind of logic when comments are implemented.
00132 //void MainWindow::timeLoggingChanged(bool on)
00133 //{
00134 //  actionAddComment->setEnabled( on );
00135 //}
00136 
00137 void MainWindow::setStatusBar(TQString qs)
00138 {
00139   statusBar()->message(qs.isEmpty() ? "" : i18n(qs.ascii()));
00140 }
00141 
00142 bool MainWindow::save()
00143 {
00144   kdDebug(5970) << "Saving time data to disk." << endl;
00145   TQString err=_taskView->save();  // untranslated error msg.
00146   if (err.isEmpty()) statusBar()->message(i18n("Successfully saved tasks and history"),1807);
00147   else statusBar()->message(i18n(err.ascii()),7707); // no msgbox since save is called when exiting
00148   saveGeometry();
00149   return true;
00150 }
00151 
00152 void MainWindow::exportcsvHistory()
00153 {
00154   kdDebug(5970) << "Exporting History to disk." << endl;
00155   TQString err=_taskView->exportcsvHistory();
00156   if (err.isEmpty()) statusBar()->message(i18n("Successfully exported History to CSV-file"),1807);
00157   else KMessageBox::error(this, err.ascii());
00158   saveGeometry();
00159   
00160 }
00161 
00162 void MainWindow::quit()
00163 {
00164   kapp->quit();
00165 }
00166 
00167 
00168 MainWindow::~MainWindow()
00169 {
00170   kdDebug(5970) << "MainWindow::~MainWindows: Quitting karm." << endl;
00171   _taskView->stopAllTimers();
00172   save();
00173   _taskView->closeStorage();
00174 }
00175 
00176 void MainWindow::enableStopAll()
00177 {
00178   actionStopAll->setEnabled(true);
00179 }
00180 
00181 void MainWindow::disableStopAll()
00182 {
00183   actionStopAll->setEnabled(false);
00184 }
00185 
00186 
00192 void MainWindow::updateTime( long sessionDiff, long totalDiff )
00193 {
00194   _sessionSum += sessionDiff;
00195   _totalSum   += totalDiff;
00196 
00197   updateStatusBar();
00198 }
00199 
00200 void MainWindow::updateStatusBar( )
00201 {
00202   TQString time;
00203 
00204   time = formatTime( _sessionSum );
00205   statusBar()->changeItem( i18n("Session: %1").arg(time), 0 );
00206 
00207   time = formatTime( _totalSum );
00208   statusBar()->changeItem( i18n("Total: %1" ).arg(time), 1);
00209 }
00210 
00211 void MainWindow::startStatusBar()
00212 {
00213   statusBar()->insertItem( i18n("Session"), 0, 0, true );
00214   statusBar()->insertItem( i18n("Total" ), 1, 0, true );
00215 }
00216 
00217 void MainWindow::saveProperties( TDEConfig* cfg )
00218 {
00219   _taskView->stopAllTimers();
00220   _taskView->save();
00221   cfg->writeEntry( "WindowShown", isVisible());
00222 }
00223 
00224 void MainWindow::readProperties( TDEConfig* cfg )
00225 {
00226   if( cfg->readBoolEntry( "WindowShown", true ))
00227     show();
00228 }
00229 
00230 void MainWindow::keyBindings()
00231 {
00232   KKeyDialog::configure( actionCollection(), this );
00233 }
00234 
00235 void MainWindow::startNewSession()
00236 {
00237   _taskView->startNewSession();
00238 }
00239 
00240 void MainWindow::resetAllTimes()
00241 {
00242   if ( KMessageBox::warningContinueCancel( this, i18n( "Do you really want to reset the time to zero for all tasks?" ),
00243        i18n( "Confirmation Required" ), KGuiItem( i18n( "Reset All Times" ) ) ) == KMessageBox::Continue )
00244     _taskView->resetTimeForAllTasks();
00245 }
00246 
00247 void MainWindow::makeMenus()
00248 {
00249   TDEAction
00250     *actionKeyBindings,
00251     *actionNew,
00252     *actionNewSub;
00253 
00254   (void) KStdAction::quit(  TQT_TQOBJECT(this), TQT_SLOT( quit() ),  actionCollection());
00255   (void) KStdAction::print( TQT_TQOBJECT(this), TQT_SLOT( print() ), actionCollection());
00256   actionKeyBindings = KStdAction::keyBindings( TQT_TQOBJECT(this), TQT_SLOT( keyBindings() ),
00257       actionCollection() );
00258   actionPreferences = KStdAction::preferences(TQT_TQOBJECT(_preferences),
00259       TQT_SLOT(showDialog()),
00260       actionCollection() );
00261   (void) KStdAction::save( TQT_TQOBJECT(this), TQT_SLOT( save() ), actionCollection() );
00262   TDEAction* actionStartNewSession = new TDEAction( i18n("Start &New Session"),
00263       0,
00264       TQT_TQOBJECT(this),
00265       TQT_SLOT( startNewSession() ),
00266       actionCollection(),
00267       "start_new_session");
00268   TDEAction* actionResetAll = new TDEAction( i18n("&Reset All Times"),
00269       0,
00270       TQT_TQOBJECT(this),
00271       TQT_SLOT( resetAllTimes() ),
00272       actionCollection(),
00273       "reset_all_times");
00274   actionStart = new TDEAction( i18n("&Start"),
00275       TQString::fromLatin1("1rightarrow"), Key_S,
00276       TQT_TQOBJECT(_taskView),
00277       TQT_SLOT( startCurrentTimer() ), actionCollection(),
00278       "start");
00279   actionStop = new TDEAction( i18n("S&top"),
00280       TQString::fromLatin1("process-stop"), Key_S,
00281       TQT_TQOBJECT(_taskView),
00282       TQT_SLOT( stopCurrentTimer() ), actionCollection(),
00283       "stop");
00284   actionStopAll = new TDEAction( i18n("Stop &All Timers"),
00285       Key_Escape,
00286       TQT_TQOBJECT(_taskView),
00287       TQT_SLOT( stopAllTimers() ), actionCollection(),
00288       "stopAll");
00289   actionStopAll->setEnabled(false);
00290 
00291   actionNew = new TDEAction( i18n("&New..."),
00292       TQString::fromLatin1("document-new"), CTRL+Key_N,
00293       TQT_TQOBJECT(_taskView),
00294       TQT_SLOT( newTask() ), actionCollection(),
00295       "new_task");
00296   actionNewSub = new TDEAction( i18n("New &Subtask..."),
00297       TQString::fromLatin1("application-vnd.tde.tdemultiple"), CTRL+ALT+Key_N,
00298       TQT_TQOBJECT(_taskView),
00299       TQT_SLOT( newSubTask() ), actionCollection(),
00300       "new_sub_task");
00301   actionDelete = new TDEAction( i18n("&Delete"),
00302       TQString::fromLatin1("edit-delete"), Key_Delete,
00303       TQT_TQOBJECT(_taskView),
00304       TQT_SLOT( deleteTask() ), actionCollection(),
00305       "delete_task");
00306   actionEdit = new TDEAction( i18n("&Edit..."),
00307       TQString::fromLatin1("edit"), CTRL + Key_E,
00308       TQT_TQOBJECT(_taskView),
00309       TQT_SLOT( editTask() ), actionCollection(),
00310       "edit_task");
00311 //  actionAddComment = new TDEAction( i18n("&Add Comment..."),
00312 //      TQString::fromLatin1("text-x-generic"),
00313 //      CTRL+ALT+Key_E,
00314 //      TQT_TQOBJECT(_taskView),
00315 //      TQT_SLOT( addCommentToTask() ),
00316 //      actionCollection(),
00317 //      "add_comment_to_task");
00318   actionMarkAsComplete = new TDEAction( i18n("&Mark as Complete"),
00319       TQString::fromLatin1("text-x-generic"),
00320       CTRL+Key_M,
00321       TQT_TQOBJECT(_taskView),
00322       TQT_SLOT( markTaskAsComplete() ),
00323       actionCollection(),
00324       "mark_as_complete");
00325   actionMarkAsIncomplete = new TDEAction( i18n("&Mark as Incomplete"),
00326       TQString::fromLatin1("text-x-generic"),
00327       CTRL+Key_M,
00328       TQT_TQOBJECT(_taskView),
00329       TQT_SLOT( markTaskAsIncomplete() ),
00330       actionCollection(),
00331       "mark_as_incomplete");
00332   actionClipTotals = new TDEAction( i18n("&Copy Totals to Clipboard"),
00333       TQString::fromLatin1("klipper"),
00334       CTRL+Key_C,
00335       TQT_TQOBJECT(_taskView),
00336       TQT_SLOT( clipTotals() ),
00337       actionCollection(),
00338       "clip_totals");
00339   // actionClipTotals will never be used again, overwrite it
00340   actionClipTotals = new TDEAction( i18n("&Copy Session Time to Clipboard"),
00341       TQString::fromLatin1("klipper"),
00342       0,
00343       TQT_TQOBJECT(_taskView),
00344       TQT_SLOT( clipSession() ),
00345       actionCollection(),
00346       "clip_session");
00347   actionClipHistory = new TDEAction( i18n("Copy &History to Clipboard"),
00348       TQString::fromLatin1("klipper"),
00349       CTRL+ALT+Key_C,
00350       TQT_TQOBJECT(_taskView),
00351       TQT_SLOT( clipHistory() ),
00352       actionCollection(),
00353       "clip_history");
00354 
00355   new TDEAction( i18n("Import &Legacy Flat File..."), 0,
00356       TQT_TQOBJECT(_taskView), TQT_SLOT(loadFromFlatFile()), actionCollection(),
00357       "import_flatfile");
00358   new TDEAction( i18n("&Export to CSV File..."), 0,
00359       TQT_TQOBJECT(_taskView), TQT_SLOT(exportcsvFile()), actionCollection(),
00360       "export_csvfile");
00361   new TDEAction( i18n("Export &History to CSV File..."), 0,
00362       TQT_TQOBJECT(this), TQT_SLOT(exportcsvHistory()), actionCollection(),
00363       "export_csvhistory");
00364   new TDEAction( i18n("Import Tasks From &Planner..."), 0,
00365       TQT_TQOBJECT(_taskView), TQT_SLOT(importPlanner()), actionCollection(),
00366       "import_planner");  
00367 
00368 /*
00369   new TDEAction( i18n("Import E&vents"), 0,
00370                             _taskView,
00371                             TQT_SLOT( loadFromKOrgEvents() ), actionCollection(),
00372                             "import_korg_events");
00373   */
00374 
00375   setXMLFile( TQString::fromLatin1("karmui.rc") );
00376   createGUI( 0 );
00377 
00378   // Tool tips must be set after the createGUI.
00379   actionKeyBindings->setToolTip( i18n("Configure key bindings") );
00380   actionKeyBindings->setWhatsThis( i18n("This will let you configure key"
00381                                         "bindings which is specific to karm") );
00382 
00383   actionStartNewSession->setToolTip( i18n("Start a new session") );
00384   actionStartNewSession->setWhatsThis( i18n("This will reset the session time "
00385                                             "to 0 for all tasks, to start a "
00386                                             "new session, without affecting "
00387                                             "the totals.") );
00388   actionResetAll->setToolTip( i18n("Reset all times") );
00389   actionResetAll->setWhatsThis( i18n("This will reset the session and total "
00390                                      "time to 0 for all tasks, to restart from "
00391                                      "scratch.") );
00392 
00393   actionStart->setToolTip( i18n("Start timing for selected task") );
00394   actionStart->setWhatsThis( i18n("This will start timing for the selected "
00395                                   "task.\n"
00396                                   "It is even possible to time several tasks "
00397                                   "simultaneously.\n\n"
00398                                   "You may also start timing of a tasks by "
00399                                   "double clicking the left mouse "
00400                                   "button on a given task. This will, however, "
00401                                   "stop timing of other tasks."));
00402 
00403   actionStop->setToolTip( i18n("Stop timing of the selected task") );
00404   actionStop->setWhatsThis( i18n("Stop timing of the selected task") );
00405 
00406   actionStopAll->setToolTip( i18n("Stop all of the active timers") );
00407   actionStopAll->setWhatsThis( i18n("Stop all of the active timers") );
00408 
00409   actionNew->setToolTip( i18n("Create new top level task") );
00410   actionNew->setWhatsThis( i18n("This will create a new top level task.") );
00411 
00412   actionDelete->setToolTip( i18n("Delete selected task") );
00413   actionDelete->setWhatsThis( i18n("This will delete the selected task and "
00414                                    "all its subtasks.") );
00415 
00416   actionEdit->setToolTip( i18n("Edit name or times for selected task") );
00417   actionEdit->setWhatsThis( i18n("This will bring up a dialog box where you "
00418                                  "may edit the parameters for the selected "
00419                                  "task."));
00420   //actionAddComment->setToolTip( i18n("Add a comment to a task") );
00421   //actionAddComment->setWhatsThis( i18n("This will bring up a dialog box where "
00422   //                                     "you can add a comment to a task. The "
00423   //                                     "comment can for instance add information on what you "
00424   //                                     "are currently doing. The comment will "
00425   //                                     "be logged in the log file."));
00426   actionClipTotals->setToolTip(i18n("Copy task totals to clipboard"));
00427   actionClipHistory->setToolTip(i18n("Copy time card history to clipboard."));
00428 
00429   slotSelectionChanged();
00430 }
00431 
00432 void MainWindow::print()
00433 {
00434   MyPrinter printer(_taskView);
00435   printer.print();
00436 }
00437 
00438 void MainWindow::loadGeometry()
00439 {
00440   if (initialGeometrySet()) setAutoSaveSettings();
00441   else
00442   {
00443     TDEConfig &config = *kapp->config();
00444 
00445     config.setGroup( TQString::fromLatin1("Main Window Geometry") );
00446     int w = config.readNumEntry( TQString::fromLatin1("Width"), 100 );
00447     int h = config.readNumEntry( TQString::fromLatin1("Height"), 100 );
00448     w = TQMAX( w, sizeHint().width() );
00449     h = TQMAX( h, sizeHint().height() );
00450     resize(w, h);
00451   }
00452 }
00453 
00454 
00455 void MainWindow::saveGeometry()
00456 {
00457   TDEConfig &config = *TDEGlobal::config();
00458   config.setGroup( TQString::fromLatin1("Main Window Geometry"));
00459   config.writeEntry( TQString::fromLatin1("Width"), width());
00460   config.writeEntry( TQString::fromLatin1("Height"), height());
00461   config.sync();
00462 }
00463 
00464 bool MainWindow::queryClose()
00465 {
00466   if ( !kapp->sessionSaving() ) {
00467     hide();
00468     return false;
00469   }
00470   return TDEMainWindow::queryClose();
00471 }
00472 
00473 void MainWindow::contextMenuRequest( TQListViewItem*, const TQPoint& point, int )
00474 {
00475     TQPopupMenu* pop = dynamic_cast<TQPopupMenu*>(
00476                           factory()->container( i18n( "task_popup" ), this ) );
00477     if ( pop )
00478       pop->popup( point );
00479 }
00480 
00481 //----------------------------------------------------------------------------
00482 //
00483 //                       D C O P   I N T E R F A C E
00484 //
00485 //----------------------------------------------------------------------------
00486 
00487 TQString MainWindow::version() const
00488 {
00489   return KARM_VERSION;
00490 }
00491 
00492 TQString MainWindow::deletetodo()
00493 {
00494   _taskView->deleteTask();
00495   return "";
00496 }
00497 
00498 bool MainWindow::getpromptdelete()
00499 {
00500   return _preferences->promptDelete();
00501 }
00502 
00503 TQString MainWindow::setpromptdelete( bool prompt )
00504 {
00505   _preferences->setPromptDelete( prompt );
00506   return "";
00507 }
00508 
00509 TQString MainWindow::taskIdFromName( const TQString &taskname ) const
00510 {
00511   TQString rval = "";
00512 
00513   Task* task = _taskView->first_child();
00514   while ( rval.isEmpty() && task )
00515   {
00516     rval = _hasTask( task, taskname );
00517     task = task->nextSibling();
00518   }
00519   
00520   return rval;
00521 }
00522 
00523 int MainWindow::addTask( const TQString& taskname ) 
00524 {
00525   DesktopList desktopList;
00526   TQString uid = _taskView->addTask( taskname, 0, 0, desktopList );
00527   kdDebug(5970) << "MainWindow::addTask( " << taskname << " ) returns " << uid << endl;
00528   if ( uid.length() > 0 ) return 0;
00529   else
00530   {
00531     // We can't really tell what happened, b/c the resource framework only
00532     // returns a boolean.
00533     return KARM_ERR_GENERIC_SAVE_FAILED;
00534   }
00535 }
00536 
00537 TQString MainWindow::setPerCentComplete( const TQString& taskName, int perCent )
00538 {
00539   int index;
00540   TQString err="no such task";
00541   for (int i=0; i<_taskView->count(); i++)
00542   {
00543     if ((_taskView->item_at_index(i)->name()==taskName))
00544     {
00545       index=i;
00546       if (err==TQString()) err="task name is abigious";
00547       if (err=="no such task") err=TQString();
00548     }
00549   }
00550   if (err==TQString()) 
00551   {
00552     _taskView->item_at_index(index)->setPercentComplete( perCent, _taskView->storage() );
00553   }
00554   return err;
00555 }
00556 
00557 int MainWindow::bookTime
00558 ( const TQString& taskId, const TQString& datetime, long minutes )
00559 {
00560   int rval = 0;
00561   TQDate startDate;
00562   TQTime startTime;
00563   TQDateTime startDateTime;
00564   Task *task, *t;
00565 
00566   if ( minutes <= 0 ) rval = KARM_ERR_INVALID_DURATION;
00567 
00568   // Find task
00569   task = _taskView->first_child();
00570   t = NULL;
00571   while ( !t && task )
00572   {
00573     t = _hasUid( task, taskId );
00574     task = task->nextSibling();
00575   }
00576   if ( t == NULL ) rval = KARM_ERR_UID_NOT_FOUND;
00577 
00578   // Parse datetime
00579   if ( !rval ) 
00580   {
00581     startDate = TQDate::fromString( datetime, Qt::ISODate );
00582     if ( datetime.length() > 10 )  // "YYYY-MM-DD".length() = 10
00583     {
00584       startTime = TQTime::fromString( datetime, Qt::ISODate );
00585     }
00586     else startTime = TQTime( 12, 0 );
00587     if ( startDate.isValid() && startTime.isValid() )
00588     {
00589       startDateTime = TQDateTime( startDate, startTime );
00590     }
00591     else rval = KARM_ERR_INVALID_DATE;
00592 
00593   }
00594 
00595   // Update task totals (session and total) and save to disk
00596   if ( !rval )
00597   {
00598     t->changeTotalTimes( t->sessionTime() + minutes, t->totalTime() + minutes );
00599     if ( ! _taskView->storage()->bookTime( t, startDateTime, minutes * 60 ) )
00600     {
00601       rval = KARM_ERR_GENERIC_SAVE_FAILED;
00602     }
00603   }
00604 
00605   return rval;
00606 }
00607 
00608 // There was something really bad going on with DCOP when I used a particular
00609 // argument name; if I recall correctly, the argument name was errno.
00610 TQString MainWindow::getError( int mkb ) const
00611 {
00612   if ( mkb <= KARM_MAX_ERROR_NO ) return m_error[ mkb ];
00613   else return i18n( "Invalid error number: %1" ).arg( mkb );
00614 }
00615 
00616 int MainWindow::totalMinutesForTaskId( const TQString& taskId )
00617 {
00618   int rval = 0;
00619   Task *task, *t;
00620   
00621   kdDebug(5970) << "MainWindow::totalTimeForTask( " << taskId << " )" << endl;
00622 
00623   // Find task
00624   task = _taskView->first_child();
00625   t = NULL;
00626   while ( !t && task )
00627   {
00628     t = _hasUid( task, taskId );
00629     task = task->nextSibling();
00630   }
00631   if ( t != NULL ) 
00632   {
00633     rval = t->totalTime();
00634     kdDebug(5970) << "MainWindow::totalTimeForTask - task found: rval = " << rval << endl;
00635   }
00636   else 
00637   {
00638     kdDebug(5970) << "MainWindow::totalTimeForTask - task not found" << endl;
00639     rval = KARM_ERR_UID_NOT_FOUND;
00640   }
00641 
00642   return rval;
00643 }
00644 
00645 TQString MainWindow::_hasTask( Task* task, const TQString &taskname ) const
00646 {
00647   TQString rval = "";
00648   if ( task->name() == taskname ) 
00649   {
00650     rval = task->uid();
00651   }
00652   else
00653   {
00654     Task* nexttask = task->firstChild();
00655     while ( rval.isEmpty() && nexttask )
00656     {
00657       rval = _hasTask( nexttask, taskname );
00658       nexttask = nexttask->nextSibling();
00659     }
00660   }
00661   return rval;
00662 }
00663 
00664 Task* MainWindow::_hasUid( Task* task, const TQString &uid ) const
00665 {
00666   Task *rval = NULL;
00667 
00668   //kdDebug(5970) << "MainWindow::_hasUid( " << task << ", " << uid << " )" << endl;
00669 
00670   if ( task->uid() == uid ) rval = task;
00671   else
00672   {
00673     Task* nexttask = task->firstChild();
00674     while ( !rval && nexttask )
00675     {
00676       rval = _hasUid( nexttask, uid );
00677       nexttask = nexttask->nextSibling();
00678     }
00679   }
00680   return rval;
00681 }
00682 TQString MainWindow::starttimerfor( const TQString& taskname )
00683 {
00684   int index;
00685   TQString err="no such task";
00686   for (int i=0; i<_taskView->count(); i++)
00687   {
00688     if ((_taskView->item_at_index(i)->name()==taskname))
00689     {
00690       index=i;
00691       if (err==TQString()) err="task name is abigious";
00692       if (err=="no such task") err=TQString();
00693     }
00694   }
00695   if (err==TQString()) _taskView->startTimerFor( _taskView->item_at_index(index) );
00696   return err;
00697 }
00698 
00699 TQString MainWindow::stoptimerfor( const TQString& taskname )
00700 {
00701   int index;
00702   TQString err="no such task";
00703   for (int i=0; i<_taskView->count(); i++)
00704   {
00705     if ((_taskView->item_at_index(i)->name()==taskname))
00706     {
00707       index=i;
00708       if (err==TQString()) err="task name is abigious";
00709       if (err=="no such task") err=TQString();
00710     }
00711   }
00712   if (err==TQString()) _taskView->stopTimerFor( _taskView->item_at_index(index) );
00713   return err;
00714 }
00715 
00716 TQString MainWindow::exportcsvfile( TQString filename, TQString from, TQString to, int type, bool decimalMinutes, bool allTasks, TQString delimiter, TQString quote )
00717 {
00718   ReportCriteria rc;
00719   rc.url=filename;
00720   rc.from=TQDate::fromString( from );
00721   if ( rc.from.isNull() ) rc.from=TQDate::fromString( from, Qt::ISODate );
00722   kdDebug(5970) << "rc.from " << rc.from << endl;
00723   rc.to=TQDate::fromString( to );
00724   if ( rc.to.isNull() ) rc.to=TQDate::fromString( to, Qt::ISODate );
00725   kdDebug(5970) << "rc.to " << rc.to << endl;
00726   rc.reportType=(ReportCriteria::REPORTTYPE) type;  // history report or totals report 
00727   rc.decimalMinutes=decimalMinutes;
00728   rc.allTasks=allTasks;
00729   rc.delimiter=delimiter;
00730   rc.quote=quote;
00731   return _taskView->report( rc );
00732 }
00733 
00734 TQString MainWindow::importplannerfile( TQString fileName )
00735 {
00736   return _taskView->importPlanner(fileName);
00737 }
00738 
00739 
00740 #include "mainwindow.moc"