Bug 84499

Summary: Add ability to edit task history
Product: ktimetracker Reporter: Marc Haber <mh+kde-bugs>
Component: generalAssignee: Thorsten Staerk <dev>
Status: RESOLVED FIXED    
Severity: wishlist CC: lassmann
Priority: HI    
Version: 4.2.x   
Target Milestone: ---   
Platform: unspecified   
OS: Linux   
Latest Commit: Version Fixed In:
Attachments: at least show history

Description Marc Haber 2004-07-05 10:01:08 UTC
Version:           1.3.1 (using KDE 3.2.3,  (testing/unstable))
Compiler:          gcc version 3.3.3 (Debian 20040422)
OS:                Linux (i686) release 2.4.26-vash

Hi,

karm currently seems to book all actions to the current day. However, it happens frequently that time is spent on a project without karm knowing about it (for example when I work on a project on a train or from home).

It should be possible to enter _now_ that I have spent two hours on a task two days ago.

Greetings
Marc
Comment 1 Mark Bucciarelli 2004-07-05 15:33:51 UTC
Yes, editing time card history is hard to do right now.  I actually change my system clock, edit the task, then change the date back.  Sub optimal.  ;)
Comment 2 Marc Haber 2004-07-05 15:50:14 UTC
Yes, that's a bad hack, breaking all time-related other things on the box (syslog, crypto stuff, ntp). A non-option for me.

Greetings
Marc
Comment 3 Raúl 2006-04-26 12:23:49 UTC
What I usually do is:

1 - Stop karm.
2 - Go to the ~/.kde/share/apps/karm
3 - Edit the karm.ics with the kalendar app
4 - Edit the X-karm tag with kwrite.

I think this is even worst, but I'm not convinced on changing the system time.
Comment 4 Raúl 2006-04-26 12:27:48 UTC
Sorry for my last comment, it was not very constructive.

My problem is that some days I forget to turn off karm timing so went I return to office the following day I have a lot of time assigned to a tasks which is not really spent on that (because of the oversight).

Then I have to manually change the karm.ics file but in step 3 you should read korganizer instead of kalendar.

Hope this is solved in following releases.
Comment 5 Thorsten Staerk 2006-04-26 13:29:33 UTC
I agree that this is the worst, and I hope too it will be in future releases. Please send me patches :)
FYI, my plans for development look like this:
1. allow adding/removing karm icon from the systray
2. unite karm kontact plugin and karm application
3. enable drag&drop
4. fix regression in "Configure Shortcuts"
5. care for task history

1-4 will take the next 2 months of my time.
have fun!
Comment 6 Thorsten Staerk 2007-01-14 16:26:56 UTC
Created attachment 19278 [details]
at least show history
Comment 7 Thorsten Staerk 2007-01-14 22:16:43 UTC
SVN commit 623445 by tstaerk:

Show history.
CCMAIL:spam@staerk.de
CCBUGS:84499


 M  +8 -4      karmstorage.cpp  
 M  +4 -1      karmstorage.h  
 M  +1 -0      karmui.rc  
 M  +17 -1     mainwindow.cpp  
 M  +1 -0      mainwindow.h  
 M  +30 -0     taskview.cpp  
 M  +3 -0      taskview.h  


--- trunk/KDE/kdepim/ktimetracker/karmstorage.cpp #623444:623445
@@ -28,6 +28,7 @@
 #include <cassert>
 
 #include <QFile>
+#include <QHeaderView>
 #include <QSize>
 #include <q3dict.h>
 #include <QDateTime>
@@ -54,6 +55,7 @@
 #include <karmutility.h>
 #include <kio/netaccess.h>
 #include <kurl.h>
+#include <qtablewidget.h>
 #include <vector>
 #include <kpassworddialog.h>
 #include <kprogressdialog.h>
@@ -303,6 +305,12 @@
   }
 }
 
+KCal::Event::List KarmStorage::rawevents()
+{
+  kDebug(5970) << "Entering KarmStorage::listallevents" << endl;
+  return _calendar->rawEvents();
+}
+
 QString KarmStorage::save(TaskView* taskview)
 {
   kDebug(5970) << "entering KarmStorage::save" << endl;
@@ -538,10 +546,6 @@
       i != eventList.end();
       ++i)
   {
-    //kDebug(5970) << "KarmStorage::removeTask: "
-    //  << (*i)->uid() << " - relatedToUid() "
-    //  << (*i)->relatedToUid()
-    //  << ", relatedTo() = " << (*i)->relatedTo() <<endl;
     if ( (*i)->relatedToUid() == task->uid()
         || ( (*i)->relatedTo()
             && (*i)->relatedTo()->uid() == task->uid()))
--- trunk/KDE/kdepim/ktimetracker/karmstorage.h #623444:623445
@@ -119,7 +119,10 @@
     /* Close calendar and clear view.  Release lock if holding one. */
     void closeStorage(TaskView* view);
 
-    /*
+    /** list of all events */
+    KCal::Event::List rawevents();
+
+    /**
      * Save all tasks and their totals to an iCalendar file.
      *
      * All tasks must have an associated VTODO object already created in the
--- trunk/KDE/kdepim/ktimetracker/karmui.rc #623444:623445
@@ -8,6 +8,7 @@
     <Action name="import_planner" />
     <Action name="export_times" />
     <Action name="export_history" />
+    <Action name="edit_history" />
   </Menu>
   <Menu name="clock" >
     <text>&amp;Clock</text>
--- trunk/KDE/kdepim/ktimetracker/mainwindow.cpp #623444:623445
@@ -129,6 +129,12 @@
   actionMarkAsIncomplete->setEnabled(item && item->isComplete());
 }
 
+void MainWindow::slotedithistory()
+{
+  kDebug(5970) << "This is slotedithistory" << endl;
+  _taskView->listallevents();
+}
+
 // This is _old_ code, but shows how to enable/disable add comment menu item.
 // We'll need this kind of logic when comments are implemented.
 //void MainWindow::timeLoggingChanged(bool on)
@@ -251,7 +257,8 @@
   KAction
     *actionKeyBindings,
     *actionNew,
-    *actionNewSub;
+    *actionNewSub,
+    *actionedithistory;
 
   (void) KStandardAction::quit(  this, SLOT( quit() ),  actionCollection());
   (void) KStandardAction::print( this, SLOT( print() ), actionCollection());
@@ -264,9 +271,18 @@
   QAction *actionStartNewSession  = new KAction(i18n("Start &New Session"), this);
   actionCollection()->addAction("start_new_session", actionStartNewSession );
   connect(actionStartNewSession, SIGNAL(triggered(bool)), SLOT( startNewSession() ));
+
+  // Edit history
+  // Show history must be changed into Edit history as soon as you can edit it.
+  actionedithistory = new KAction(i18n("Show history"), this);
+  connect(actionedithistory, SIGNAL(triggered(bool)), SLOT (slotedithistory()));
+  actionCollection()->addAction("edit_history", actionedithistory );
+
+  // Reset all times
   QAction *actionResetAll  = new KAction(i18n("&Reset All Times"), this);
   actionCollection()->addAction("reset_all_times", actionResetAll );
   connect(actionResetAll, SIGNAL(triggered(bool)), SLOT( resetAllTimes() ));
+
   actionStart  = new KAction(KIcon(QString::fromLatin1("1rightarrow")), i18n("&Start"), this);
   actionCollection()->addAction("start", actionStart );
   connect(actionStart, SIGNAL(triggered(bool) ), _taskView, SLOT( startCurrentTimer() ));
--- trunk/KDE/kdepim/ktimetracker/mainwindow.h #623444:623445
@@ -99,6 +99,7 @@
     void updateTime( long, long );
     void updateStatusBar();
     void exportcsvHistory();
+    void slotedithistory();
     void print();
     void slotSelectionChanged();
     void contextMenuRequest( Q3ListViewItem*, const QPoint&, int );
--- trunk/KDE/kdepim/ktimetracker/taskview.cpp #623444:623445
@@ -6,7 +6,9 @@
 #include <q3ptrlist.h>
 #include <q3ptrstack.h>
 #include <Q3Header>
+#include <QHeaderView>
 #include <QString>
+#include <QTableWidget>
 #include <QTextStream>
 #include <QTimer>
 #include <QtXml>
@@ -382,6 +384,34 @@
 
 Preferences* TaskView::preferences() { return _preferences; }
 
+QStringList TaskView::listallevents() 
+{
+  kDebug(5970) << "Entering TaskView::listallevents" << endl;
+  QTableWidget* tw=new QTableWidget;
+  QStringList labels;
+  labels << "Task" << "StartTime" << "EndTime";
+  tw->setColumnCount(3);
+  tw->setEditTriggers(QAbstractItemView::NoEditTriggers);
+  tw->setHorizontalHeaderLabels(labels);
+  tw->horizontalHeader()->setStretchLastSection(true);
+  KCal::Event::List eventList = _storage->rawevents();
+  for(KCal::Event::List::iterator i = eventList.begin();
+      i != eventList.end();
+      ++i)
+  {
+    kDebug(5970) << "Event ID is " << (*i)->uid() << " Task is named " << (*i)->relatedTo()->summary() << " starttime " << (*i)->dtStart() << endl;
+    int row=tw->rowCount();
+    kDebug() << "row=" << row << endl;
+    tw->insertRow(row);
+    QTableWidgetItem* item=new QTableWidgetItem((*i)->relatedTo()->summary());
+    item->setFlags(Qt::ItemIsEnabled);
+    tw->setItem(row,0,item);
+    tw->setItem(row,1,new QTableWidgetItem((*i)->dtStart().toString()));
+    tw->setItem(row,2,new QTableWidgetItem((*i)->dtEnd().toString()));
+  }
+  tw->show(); 
+}
+
 QString TaskView::save()
 {
     // DF: this code created a new event for the running task(s),
--- trunk/KDE/kdepim/ktimetracker/taskview.h #623444:623445
@@ -73,6 +73,9 @@
     /** Return list of start/stop events for given date range. */
     QList<HistoryEvent> getHistory(const QDate& from, const QDate& to) const;
 
+    /** List all events */
+    QStringList listallevents();
+
     /** Schedule that we should save very soon */
     void scheduleSave();
 
Comment 8 Thorsten Staerk 2007-02-03 14:32:25 UTC
*** Bug 99576 has been marked as a duplicate of this bug. ***
Comment 9 Thorsten Staerk 2007-03-16 20:39:35 UTC
SVN commit 643287 by tstaerk:

Allow the user to edit the start date of every event.
BUGS:84499


 M  +17 -0     taskview.cpp  


--- trunk/KDE/kdepim/ktimetracker/taskview.cpp #643286:643287
@@ -445,6 +445,23 @@
   kDebug(5970) << "row =" << row << " col =" << col << endl;
   static bool ready=false;
   if (row==-1) ready=true;
+  else if (ready && (col==1)) // EndDate
+  {
+    kDebug(5970) << "user changed StartDate to " << historywidget->item(row,col)->text() << endl;
+    QString uid=historywidget->item(row,4)->text();
+    kDebug() << "uid = " << uid << endl;
+    KCal::Event::List eventList = _storage->rawevents();
+    for(KCal::Event::List::iterator i = eventList.begin(); i != eventList.end(); ++i)
+    {
+      kDebug() << "row=" << row << " col=" << col << endl;
+      if ((*i)->uid() == uid)
+      {
+        (*i)->setDtStart(KDateTime::fromString(historywidget->item(row,col)->text())); 
+        kDebug() << "Program SetDtStart to " << historywidget->item(row,col)->text() << endl;
+      }
+    }
+    ready=false;
+  }
   else if (ready && (col==2)) // EndDate
   {
     kDebug(5970) << "user changed EndDate to " << historywidget->item(row,col)->text() << endl;