karm

karm_part.cpp

00001 
00002 #include "kaccelmenuwatch.h"
00003 #include "karm_part.h"
00004 #include "karmerrors.h"
00005 #include "task.h"
00006 #include "preferences.h"
00007 #include "tray.h"
00008 #include "version.h"
00009 #include <kaccel.h>
00010 
00011 #include <kinstance.h>
00012 #include <kaction.h>
00013 #include <kstdaction.h>
00014 #include <kfiledialog.h>
00015 #include <kglobal.h>
00016 #include <klocale.h>
00017 
00018 #include <qfile.h>
00019 #include <qtextstream.h>
00020 #include <qmultilineedit.h>
00021 
00022 karmPart::karmPart( QWidget *parentWidget, const char *widgetName,
00023                                   QObject *parent, const char *name )
00024     : DCOPObject ( "KarmDCOPIface" ), KParts::ReadWritePart(parent, name), 
00025     _accel     ( new KAccel( parentWidget ) ),
00026     _watcher   ( new KAccelMenuWatch( _accel, parentWidget ) )
00027 {
00028     // we need an instance
00029     setInstance( karmPartFactory::instance() );
00030 
00031     // this should be your custom internal widget
00032     _taskView = new TaskView( parentWidget, widgetName );
00033 
00034     // setup PreferenceDialog.
00035     _preferences = Preferences::instance();
00036 
00037    // notify the part that this is our internal widget
00038     setWidget(_taskView);
00039 
00040     // create our actions
00041     KStdAction::open(this, SLOT(fileOpen()), actionCollection());
00042     KStdAction::saveAs(this, SLOT(fileSaveAs()), actionCollection());
00043     KStdAction::save(this, SLOT(save()), actionCollection());
00044 
00045     makeMenus();
00046 
00047   _watcher->updateMenus();
00048 
00049   // connections
00050 
00051   connect( _taskView, SIGNAL( totalTimesChanged( long, long ) ),
00052            this, SLOT( updateTime( long, long ) ) );
00053   connect( _taskView, SIGNAL( selectionChanged ( QListViewItem * )),
00054            this, SLOT(slotSelectionChanged()));
00055   connect( _taskView, SIGNAL( updateButtons() ),
00056            this, SLOT(slotSelectionChanged()));
00057 
00058   // Setup context menu request handling
00059   connect( _taskView,
00060            SIGNAL( contextMenuRequested( QListViewItem*, const QPoint&, int )),
00061            this,
00062            SLOT( contextMenuRequest( QListViewItem*, const QPoint&, int )));
00063 
00064   _tray = new KarmTray( this );
00065 
00066   connect( _tray, SIGNAL( quitSelected() ), SLOT( quit() ) );
00067 
00068   connect( _taskView, SIGNAL( timersActive() ), _tray, SLOT( startClock() ) );
00069   connect( _taskView, SIGNAL( timersActive() ), this,  SLOT( enableStopAll() ));
00070   connect( _taskView, SIGNAL( timersInactive() ), _tray, SLOT( stopClock() ) );
00071   connect( _taskView, SIGNAL( timersInactive() ),  this,  SLOT( disableStopAll()));
00072   connect( _taskView, SIGNAL( tasksChanged( QPtrList<Task> ) ),
00073                       _tray, SLOT( updateToolTip( QPtrList<Task> ) ));
00074 
00075   _taskView->load();
00076 
00077   // Everything that uses Preferences has been created now, we can let it
00078   // emit its signals
00079   _preferences->emitSignals();
00080   slotSelectionChanged();
00081 
00082     // set our XML-UI resource file
00083     setXMLFile("karmui.rc");
00084 
00085     // we are read-write by default
00086     setReadWrite(true);
00087 
00088     // we are not modified since we haven't done anything yet
00089     setModified(false);
00090 }
00091 
00092 karmPart::~karmPart()
00093 {
00094 }
00095 
00096 void karmPart::slotSelectionChanged()
00097 {
00098   Task* item= _taskView->current_item();
00099   actionDelete->setEnabled(item);
00100   actionEdit->setEnabled(item);
00101   actionStart->setEnabled(item && !item->isRunning() && !item->isComplete());
00102   actionStop->setEnabled(item && item->isRunning());
00103   actionMarkAsComplete->setEnabled(item && !item->isComplete());
00104   actionMarkAsIncomplete->setEnabled(item && item->isComplete());
00105 }
00106 
00107 void karmPart::makeMenus()
00108 {
00109   KAction
00110     *actionKeyBindings,
00111     *actionNew,
00112     *actionNewSub;
00113 
00114   (void) KStdAction::quit(  this, SLOT( quit() ),  actionCollection());
00115   (void) KStdAction::print( this, SLOT( print() ), actionCollection());
00116   actionKeyBindings = KStdAction::keyBindings( this, SLOT( keyBindings() ),
00117       actionCollection() );
00118   actionPreferences = KStdAction::preferences(_preferences,
00119       SLOT(showDialog()),
00120       actionCollection() );
00121   (void) KStdAction::save( this, SLOT( save() ), actionCollection() );
00122   KAction* actionStartNewSession = new KAction( i18n("Start &New Session"),
00123       0,
00124       this,
00125       SLOT( startNewSession() ),
00126       actionCollection(),
00127       "start_new_session");
00128   KAction* actionResetAll = new KAction( i18n("&Reset All Times"),
00129       0,
00130       this,
00131       SLOT( resetAllTimes() ),
00132       actionCollection(),
00133       "reset_all_times");
00134   actionStart = new KAction( i18n("&Start"),
00135       QString::fromLatin1("1rightarrow"), Key_S,
00136       _taskView,
00137       SLOT( startCurrentTimer() ), actionCollection(),
00138       "start");
00139   actionStop = new KAction( i18n("S&top"),
00140       QString::fromLatin1("stop"), 0,
00141       _taskView,
00142       SLOT( stopCurrentTimer() ), actionCollection(),
00143       "stop");
00144   actionStopAll = new KAction( i18n("Stop &All Timers"),
00145       Key_Escape,
00146       _taskView,
00147       SLOT( stopAllTimers() ), actionCollection(),
00148       "stopAll");
00149   actionStopAll->setEnabled(false);
00150 
00151   actionNew = new KAction( i18n("&New..."),
00152       QString::fromLatin1("filenew"), CTRL+Key_N,
00153       _taskView,
00154       SLOT( newTask() ), actionCollection(),
00155       "new_task");
00156   actionNewSub = new KAction( i18n("New &Subtask..."),
00157       QString::fromLatin1("kmultiple"), CTRL+ALT+Key_N,
00158       _taskView,
00159       SLOT( newSubTask() ), actionCollection(),
00160       "new_sub_task");
00161   actionDelete = new KAction( i18n("&Delete"),
00162       QString::fromLatin1("editdelete"), Key_Delete,
00163       _taskView,
00164       SLOT( deleteTask() ), actionCollection(),
00165       "delete_task");
00166   actionEdit = new KAction( i18n("&Edit..."),
00167       QString::fromLatin1("edit"), CTRL + Key_E,
00168       _taskView,
00169       SLOT( editTask() ), actionCollection(),
00170       "edit_task");
00171 //  actionAddComment = new KAction( i18n("&Add Comment..."),
00172 //      QString::fromLatin1("document"),
00173 //      CTRL+ALT+Key_E,
00174 //      _taskView,
00175 //      SLOT( addCommentToTask() ),
00176 //      actionCollection(),
00177 //      "add_comment_to_task");
00178   actionMarkAsComplete = new KAction( i18n("&Mark as Complete"),
00179       QString::fromLatin1("document"),
00180       CTRL+Key_M,
00181       _taskView,
00182       SLOT( markTaskAsComplete() ),
00183       actionCollection(),
00184       "mark_as_complete");
00185   actionMarkAsIncomplete = new KAction( i18n("&Mark as Incomplete"),
00186       QString::fromLatin1("document"),
00187       CTRL+Key_M,
00188       _taskView,
00189       SLOT( markTaskAsIncomplete() ),
00190       actionCollection(),
00191       "mark_as_incomplete");
00192   actionClipTotals = new KAction( i18n("&Copy Totals to Clipboard"),
00193       QString::fromLatin1("klipper"),
00194       CTRL+Key_C,
00195       _taskView,
00196       SLOT( clipTotals() ),
00197       actionCollection(),
00198       "clip_totals");
00199   actionClipHistory = new KAction( i18n("Copy &History to Clipboard"),
00200       QString::fromLatin1("klipper"),
00201       CTRL+ALT+Key_C,
00202       _taskView,
00203       SLOT( clipHistory() ),
00204       actionCollection(),
00205       "clip_history");
00206 
00207   new KAction( i18n("Import &Legacy Flat File..."), 0,
00208       _taskView, SLOT(loadFromFlatFile()), actionCollection(),
00209       "import_flatfile");
00210   new KAction( i18n("&Export to CSV File..."), 0,
00211       _taskView, SLOT(exportcsvFile()), actionCollection(),
00212       "export_csvfile");
00213   new KAction( i18n("Export &History to CSV File..."), 0,
00214       this, SLOT(exportcsvHistory()), actionCollection(),
00215       "export_csvhistory");
00216   new KAction( i18n("Import Tasks From &Planner..."), 0,
00217       _taskView, SLOT(importPlanner()), actionCollection(),
00218       "import_planner");  
00219   new KAction( i18n("Configure KArm..."), 0,
00220       _preferences, SLOT(showDialog()), actionCollection(),
00221       "configure_karm");  
00222 
00223 /*
00224   new KAction( i18n("Import E&vents"), 0,
00225                             _taskView,
00226                             SLOT( loadFromKOrgEvents() ), actionCollection(),
00227                             "import_korg_events");
00228   */
00229 
00230   // Tool tops must be set after the createGUI.
00231   actionKeyBindings->setToolTip( i18n("Configure key bindings") );
00232   actionKeyBindings->setWhatsThis( i18n("This will let you configure key"
00233                                         "bindings which is specific to karm") );
00234 
00235   actionStartNewSession->setToolTip( i18n("Start a new session") );
00236   actionStartNewSession->setWhatsThis( i18n("This will reset the session time "
00237                                             "to 0 for all tasks, to start a "
00238                                             "new session, without affecting "
00239                                             "the totals.") );
00240   actionResetAll->setToolTip( i18n("Reset all times") );
00241   actionResetAll->setWhatsThis( i18n("This will reset the session and total "
00242                                      "time to 0 for all tasks, to restart from "
00243                                      "scratch.") );
00244 
00245   actionStart->setToolTip( i18n("Start timing for selected task") );
00246   actionStart->setWhatsThis( i18n("This will start timing for the selected "
00247                                   "task.\n"
00248                                   "It is even possible to time several tasks "
00249                                   "simultaneously.\n\n"
00250                                   "You may also start timing of a tasks by "
00251                                   "double clicking the left mouse "
00252                                   "button on a given task. This will, however, "
00253                                   "stop timing of other tasks."));
00254 
00255   actionStop->setToolTip( i18n("Stop timing of the selected task") );
00256   actionStop->setWhatsThis( i18n("Stop timing of the selected task") );
00257 
00258   actionStopAll->setToolTip( i18n("Stop all of the active timers") );
00259   actionStopAll->setWhatsThis( i18n("Stop all of the active timers") );
00260 
00261   actionNew->setToolTip( i18n("Create new top level task") );
00262   actionNew->setWhatsThis( i18n("This will create a new top level task.") );
00263 
00264   actionDelete->setToolTip( i18n("Delete selected task") );
00265   actionDelete->setWhatsThis( i18n("This will delete the selected task and "
00266                                    "all its subtasks.") );
00267 
00268   actionEdit->setToolTip( i18n("Edit name or times for selected task") );
00269   actionEdit->setWhatsThis( i18n("This will bring up a dialog box where you "
00270                                  "may edit the parameters for the selected "
00271                                  "task."));
00272   //actionAddComment->setToolTip( i18n("Add a comment to a task") );
00273   //actionAddComment->setWhatsThis( i18n("This will bring up a dialog box where "
00274   //                                     "you can add a comment to a task. The "
00275   //                                     "comment can for instance add information on what you "
00276   //                                     "are currently doing. The comment will "
00277   //                                     "be logged in the log file."));
00278   actionClipTotals->setToolTip(i18n("Copy task totals to clipboard"));
00279   actionClipHistory->setToolTip(i18n("Copy time card history to clipboard."));
00280 
00281   slotSelectionChanged();
00282 }
00283 
00284 void karmPart::setReadWrite(bool rw)
00285 {
00286     // notify your internal widget of the read-write state
00287     if (rw)
00288         connect(_taskView, SIGNAL(textChanged()),
00289                 this,     SLOT(setModified()));
00290     else
00291     {
00292         disconnect(_taskView, SIGNAL(textChanged()),
00293                    this,     SLOT(setModified()));
00294     }
00295 
00296     ReadWritePart::setReadWrite(rw);
00297 }
00298 
00299 void karmPart::setModified(bool modified)
00300 {
00301     // get a handle on our Save action and make sure it is valid
00302     KAction *save = actionCollection()->action(KStdAction::stdName(KStdAction::Save));
00303     if (!save)
00304         return;
00305 
00306     // if so, we either enable or disable it based on the current
00307     // state
00308     if (modified)
00309         save->setEnabled(true);
00310     else
00311         save->setEnabled(false);
00312 
00313     // in any event, we want our parent to do it's thing
00314     ReadWritePart::setModified(modified);
00315 }
00316 
00317 bool karmPart::openFile()
00318 {
00319     // m_file is always local so we can use QFile on it
00320     _taskView->load(m_file);
00321 
00322     // just for fun, set the status bar
00323     emit setStatusBarText( m_url.prettyURL() );
00324 
00325     return true;
00326 }
00327 
00328 bool karmPart::saveFile()
00329 {
00330     // if we aren't read-write, return immediately
00331     if (isReadWrite() == false)
00332         return false;
00333 
00334     // m_file is always local, so we use QFile
00335     QFile file(m_file);
00336     if (file.open(IO_WriteOnly) == false)
00337         return false;
00338 
00339     // use QTextStream to dump the text to the file
00340     QTextStream stream(&file);
00341 
00342     file.close();
00343 
00344     return true;
00345 }
00346 
00347 void karmPart::fileOpen()
00348 {
00349     // this slot is called whenever the File->Open menu is selected,
00350     // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar
00351     // button is clicked
00352     QString file_name = KFileDialog::getOpenFileName();
00353 
00354     if (file_name.isEmpty() == false)
00355         openURL(file_name);
00356 }
00357 
00358 void karmPart::fileSaveAs()
00359 {
00360     // this slot is called whenever the File->Save As menu is selected,
00361     QString file_name = KFileDialog::getSaveFileName();
00362     if (file_name.isEmpty() == false)
00363         saveAs(file_name);
00364 }
00365 
00366 
00367 // It's usually safe to leave the factory code alone.. with the
00368 // notable exception of the KAboutData data
00369 #include <kaboutdata.h>
00370 #include <klocale.h>
00371 
00372 KInstance*  karmPartFactory::s_instance = 0L;
00373 KAboutData* karmPartFactory::s_about = 0L;
00374 
00375 karmPartFactory::karmPartFactory()
00376     : KParts::Factory()
00377 {
00378 }
00379 
00380 karmPartFactory::~karmPartFactory()
00381 {
00382     delete s_instance;
00383     delete s_about;
00384 
00385     s_instance = 0L;
00386 }
00387 
00388 KParts::Part* karmPartFactory::createPartObject( QWidget *parentWidget, const char *widgetName,
00389                                                         QObject *parent, const char *name,
00390                                                         const char *classname, const QStringList &args )
00391 {
00392     // Create an instance of our Part
00393     karmPart* obj = new karmPart( parentWidget, widgetName, parent, name );
00394 
00395     // See if we are to be read-write or not
00396     if (QCString(classname) == "KParts::ReadOnlyPart")
00397         obj->setReadWrite(false);
00398 
00399     return obj;
00400 }
00401 
00402 KInstance* karmPartFactory::instance()
00403 {
00404     if( !s_instance )
00405     {
00406         s_about = new KAboutData("karmpart", I18N_NOOP("karmPart"), "0.1");
00407         s_about->addAuthor("Thorsten Staerk", 0, "thorsten@staerk.de");
00408         s_instance = new KInstance(s_about);
00409     }
00410     return s_instance;
00411 }
00412 
00413 extern "C"
00414 {
00415     KDE_EXPORT void* init_libkarmpart()
00416     {
00417     KGlobal::locale()->insertCatalogue("karm");
00418         return new karmPartFactory;
00419     }
00420 }
00421 
00422 //----------------------------------------------------------------------------
00423 //
00424 //                       D C O P   I N T E R F A C E
00425 //
00426 //----------------------------------------------------------------------------
00427 
00428 QString karmPart::version() const
00429 {
00430   return KARM_VERSION;
00431 }
00432 
00433 QString karmPart::deletetodo()
00434 {
00435   _taskView->deleteTask();
00436   return "";
00437 }
00438 
00439 bool karmPart::getpromptdelete()
00440 {
00441   return _preferences->promptDelete();
00442 }
00443 
00444 QString karmPart::setpromptdelete( bool prompt )
00445 {
00446   _preferences->setPromptDelete( prompt );
00447   return "";
00448 }
00449 
00450 QString karmPart::taskIdFromName( const QString &taskname ) const
00451 {
00452   QString rval = "";
00453 
00454   Task* task = _taskView->first_child();
00455   while ( rval.isEmpty() && task )
00456   {
00457     rval = _hasTask( task, taskname );
00458     task = task->nextSibling();
00459   }
00460   
00461   return rval;
00462 }
00463 
00464 void karmPart::quit()
00465 {
00466   // TODO: write something for kapp->quit();
00467 }
00468 
00469 bool karmPart::save()
00470 {
00471   kdDebug(5970) << "Saving time data to disk." << endl;
00472   QString err=_taskView->save();  // untranslated error msg.
00473   // TODO:
00474   /* if (err.isEmpty()) statusBar()->message(i18n("Successfully saved tasks and history"),1807);
00475   else statusBar()->message(i18n(err.ascii()),7707); // no msgbox since save is called when exiting */
00476   return true;
00477 }
00478 
00479 int karmPart::addTask( const QString& taskname ) 
00480 {
00481   DesktopList desktopList;
00482   QString uid = _taskView->addTask( taskname, 0, 0, desktopList );
00483   kdDebug(5970) << "MainWindow::addTask( " << taskname << " ) returns " << uid << endl;
00484   if ( uid.length() > 0 ) return 0;
00485   else
00486   {
00487     // We can't really tell what happened, b/c the resource framework only
00488     // returns a boolean.
00489     return KARM_ERR_GENERIC_SAVE_FAILED;
00490   }
00491 }
00492 
00493 QString karmPart::setPerCentComplete( const QString& taskName, int perCent )
00494 {
00495   int index;
00496   QString err="no such task";
00497   for (int i=0; i<_taskView->count(); i++)
00498   {
00499     if ((_taskView->item_at_index(i)->name()==taskName))
00500     {
00501       index=i;
00502       if (err==QString::null) err="task name is abigious";
00503       if (err=="no such task") err=QString::null;
00504     }
00505   }
00506   if (err==QString::null) 
00507   {
00508     _taskView->item_at_index(index)->setPercentComplete( perCent, _taskView->storage() );
00509   }
00510   return err;
00511 }
00512 
00513 int karmPart::bookTime
00514 ( const QString& taskId, const QString& datetime, long minutes )
00515 {
00516   int rval = 0;
00517   QDate startDate;
00518   QTime startTime;
00519   QDateTime startDateTime;
00520   Task *task, *t;
00521 
00522   if ( minutes <= 0 ) rval = KARM_ERR_INVALID_DURATION;
00523 
00524   // Find task
00525   task = _taskView->first_child();
00526   t = NULL;
00527   while ( !t && task )
00528   {
00529     t = _hasUid( task, taskId );
00530     task = task->nextSibling();
00531   }
00532   if ( t == NULL ) rval = KARM_ERR_UID_NOT_FOUND;
00533 
00534   // Parse datetime
00535   if ( !rval ) 
00536   {
00537     startDate = QDate::fromString( datetime, Qt::ISODate );
00538     if ( datetime.length() > 10 )  // "YYYY-MM-DD".length() = 10
00539     {
00540       startTime = QTime::fromString( datetime, Qt::ISODate );
00541     }
00542     else startTime = QTime( 12, 0 );
00543     if ( startDate.isValid() && startTime.isValid() )
00544     {
00545       startDateTime = QDateTime( startDate, startTime );
00546     }
00547     else rval = KARM_ERR_INVALID_DATE;
00548 
00549   }
00550 
00551   // Update task totals (session and total) and save to disk
00552   if ( !rval )
00553   {
00554     t->changeTotalTimes( t->sessionTime() + minutes, t->totalTime() + minutes );
00555     if ( ! _taskView->storage()->bookTime( t, startDateTime, minutes * 60 ) )
00556     {
00557       rval = KARM_ERR_GENERIC_SAVE_FAILED;
00558     }
00559   }
00560 
00561   return rval;
00562 }
00563 
00564 // There was something really bad going on with DCOP when I used a particular
00565 // argument name; if I recall correctly, the argument name was errno.
00566 QString karmPart::getError( int mkb ) const
00567 {
00568   if ( mkb <= KARM_MAX_ERROR_NO ) return m_error[ mkb ];
00569   else return i18n( "Invalid error number: %1" ).arg( mkb );
00570 }
00571 
00572 int karmPart::totalMinutesForTaskId( const QString& taskId )
00573 {
00574   int rval = 0;
00575   Task *task, *t;
00576   
00577   kdDebug(5970) << "MainWindow::totalTimeForTask( " << taskId << " )" << endl;
00578 
00579   // Find task
00580   task = _taskView->first_child();
00581   t = NULL;
00582   while ( !t && task )
00583   {
00584     t = _hasUid( task, taskId );
00585     task = task->nextSibling();
00586   }
00587   if ( t != NULL ) 
00588   {
00589     rval = t->totalTime();
00590     kdDebug(5970) << "MainWindow::totalTimeForTask - task found: rval = " << rval << endl;
00591   }
00592   else 
00593   {
00594     kdDebug(5970) << "MainWindow::totalTimeForTask - task not found" << endl;
00595     rval = KARM_ERR_UID_NOT_FOUND;
00596   }
00597 
00598   return rval;
00599 }
00600 
00601 QString karmPart::_hasTask( Task* task, const QString &taskname ) const
00602 {
00603   QString rval = "";
00604   if ( task->name() == taskname ) 
00605   {
00606     rval = task->uid();
00607   }
00608   else
00609   {
00610     Task* nexttask = task->firstChild();
00611     while ( rval.isEmpty() && nexttask )
00612     {
00613       rval = _hasTask( nexttask, taskname );
00614       nexttask = nexttask->nextSibling();
00615     }
00616   }
00617   return rval;
00618 }
00619 
00620 Task* karmPart::_hasUid( Task* task, const QString &uid ) const
00621 {
00622   Task *rval = NULL;
00623 
00624   //kdDebug(5970) << "MainWindow::_hasUid( " << task << ", " << uid << " )" << endl;
00625 
00626   if ( task->uid() == uid ) rval = task;
00627   else
00628   {
00629     Task* nexttask = task->firstChild();
00630     while ( !rval && nexttask )
00631     {
00632       rval = _hasUid( nexttask, uid );
00633       nexttask = nexttask->nextSibling();
00634     }
00635   }
00636   return rval;
00637 }
00638 
00639 QString karmPart::starttimerfor( const QString& taskname )
00640 {
00641   QString err="no such task";
00642   for (int i=0; i<_taskView->count(); i++)
00643   {
00644     if ((_taskView->item_at_index(i)->name()==taskname))
00645     {
00646       _taskView->startTimerFor( _taskView->item_at_index(i) );
00647       err="";
00648     }
00649   }
00650   return err;
00651 }
00652 
00653 QString karmPart::stoptimerfor( const QString& taskname )
00654 {
00655   QString err="no such task";
00656   for (int i=0; i<_taskView->count(); i++)
00657   {
00658     if ((_taskView->item_at_index(i)->name()==taskname))
00659     {
00660       _taskView->stopTimerFor( _taskView->item_at_index(i) );
00661       err="";
00662     }
00663   }
00664   return err;
00665 }
00666 
00667 QString karmPart::exportcsvfile( QString filename, QString from, QString to, int type, bool decimalMinutes, bool allTasks, QString delimiter, QString quote )
00668 {
00669   ReportCriteria rc;
00670   rc.allTasks=allTasks;
00671   rc.decimalMinutes=decimalMinutes;
00672   rc.delimiter=delimiter;
00673   rc.from=QDate::fromString( from );
00674   rc.quote=quote;
00675   rc.reportType=(ReportCriteria::REPORTTYPE) type;
00676   rc.to=QDate::fromString( to );
00677   rc.url=filename;
00678   return _taskView->report( rc );
00679 }
00680 
00681 QString karmPart::importplannerfile( QString fileName )
00682 {
00683   return _taskView->importPlanner(fileName);
00684 }
00685 
00686 
00687 
00688 #include <qpopupmenu.h>
00689 #include "karm_part.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys