Implemented some more of the TimeTrackerWidget.

Sat, 20 Oct 2012 12:34:26 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 20 Oct 2012 12:34:26 +0200
changeset 4
c67abfea9955
parent 3
ce9309868f8a
child 5
6633e2836f8f

Implemented some more of the TimeTrackerWidget.

TimeTracker/TimeTrackEntry.py file | annotate | diff | comparison | revisions
TimeTracker/TimeTracker.py file | annotate | diff | comparison | revisions
TimeTracker/TimeTrackerWidget.py file | annotate | diff | comparison | revisions
TimeTracker/TimeTrackerWidget.ui file | annotate | diff | comparison | revisions
TimeTracker/icons/clock.png file | annotate | diff | comparison | revisions
--- a/TimeTracker/TimeTrackEntry.py	Fri Oct 19 22:26:57 2012 +0200
+++ b/TimeTracker/TimeTrackEntry.py	Sat Oct 20 12:34:26 2012 +0200
@@ -21,7 +21,8 @@
         """
         Constructor
         """
-        self.__entryMembersCount = 4
+        self.__entryMembersCount = 5
+        self.__id = -1
         self.__startDateTime = QDateTime()      # start date and time
         self.__duration = 0                     # duration in minutes
         self.__task = ""                        # task specification
@@ -47,6 +48,7 @@
         """
         if self.__valid:
             dataLine = TimeTrackEntry.Separator.join([
+                str(self.__id),
                 self.__startDateTime.toString(Qt.ISODate),
                 str(self.__duration),
                 self.__task,
@@ -61,32 +63,37 @@
         Public method to populate the entry from the given string.
         
         @param line stringified entry data as generated by toString() (string)
-        @return flag indicating valid data
+        @return ID of the tracker entry; -1 indicates an error (integer)
         """
         if not line.startswith(TimeTrackEntry.LineMarker):
-            return False
+            return -1
         
         line = line.replace(TimeTrackEntry.LineMarker, "")
         dataList = line.split(TimeTrackEntry.Separator)
         if len(dataList) != self.__entryMembersCount:
-            return False
+            return -1
         
-        dt = QDateTime.fromString(dataList[0], Qt.ISODate)
+        try:
+            self.__id = int(dataList[0])
+        except ValueError:
+            return -1
+        
+        dt = QDateTime.fromString(dataList[1], Qt.ISODate)
         if not dt.isValid():
-            return False
+            return -1
         self.__startDateTime = dt
         
         try:
-            dt = int(dataList[1])
+            dt = int(dataList[2])
         except ValueError:
-            return False
+            return -1
         self.__duration = dt
         
-        self.__task = dataList[2]
-        self.__comment = dataList[3]
+        self.__task = dataList[3]
+        self.__comment = dataList[4]
         
         self.__valid = True
-        return True
+        return self.__id
     
     def isValid(self):
         """
@@ -160,6 +167,14 @@
         
         return minutes
     
+    def setID(self, eid):
+        """
+        Public method to assign an ID to the entry.
+        
+        @param eid ID for the entry (integer)
+        """
+        self.__id = eid
+    
     def setTask(self, description):
         """
         Public method to set the task description.
@@ -189,6 +204,7 @@
             a paused state (boolean)
         """
         return (
+            self.__id,
             self.__startDateTime.toString("yyyy-MM-dd"),
             self.__startDateTime.toString("hh:mm"),
             self.__duration,
@@ -212,3 +228,11 @@
         @return duration (integer)
         """
         return self.__duration
+    
+    def getID(self):
+        """
+        Public method to get the ID of the entry.
+        
+        @return ID of the entry (integer)
+        """
+        return self.__id
--- a/TimeTracker/TimeTracker.py	Fri Oct 19 22:26:57 2012 +0200
+++ b/TimeTracker/TimeTracker.py	Sat Oct 20 12:34:26 2012 +0200
@@ -55,7 +55,7 @@
         self.__trackerFilePath = ''
         self.__projectOpen = False
         
-        self.__entries = []
+        self.__entries = {}         # key: entry ID, value tracker entry
         self.__currentEntry = None
         
         self.__widget.clear()
@@ -74,23 +74,16 @@
             TimeTracker.FileName)
         
         self.__readTrackerEntries()
-        self.__widget.showTrackerEntries(sorted(self.__entries, reverse=True))
+        self.__widget.showTrackerEntries(sorted(self.__entries.values(), reverse=True))
         
-        self.__currentEntry = TimeTrackEntry()
-        self.__currentEntry.start()
-        self.__widget.setCurrentEntry(self.__currentEntry)
+        self.startTrackerEntry()
     
     def projectClosed(self):
         """
         Public slot to handle the projectClosed signal.
         """
-        if self.__currentEntry is not None:
-            self.__currentEntry.stop()
-            if self.__currentEntry.isValid():
-                self.__entries.append(self.__currentEntry)
-        
+        self.stopTrackerEntry()
         self.__saveTrackerEntries()
-        
         self.__initialize()
     
     def __readTrackerEntries(self):
@@ -113,8 +106,9 @@
             invalidCount = 0
             for line in data.splitlines():
                 entry = TimeTrackEntry()
-                if entry.fromString(line.strip()):
-                    self.__entries.append(entry)
+                eid = entry.fromString(line.strip())
+                if eid > -1:
+                    self.__entries[eid] = entry
                 else:
                     invalidCount += 1
             
@@ -131,7 +125,7 @@
         """
         try:
             f = open(self.__trackerFilePath, "w", encoding="utf-8")
-            for entry in self.__entries:
+            for entry in self.__entries.values():
                 if entry.isValid():
                     f.write(entry.toString() + "\n")
             f.close()
@@ -154,25 +148,39 @@
         """
         self.__currentEntry.continue_()
     
+    def stopTrackerEntry(self):
+        """
+        Public method to stop the current tracker entry.
+        
+        @return tuple of the ID assigned to the stopped tracker entry and
+            the duration (integer, integer)
+        """
+        duration = 0
+        nextID = -1
+        if self.__currentEntry is not None:
+            self.__currentEntry.stop()
+            if self.__currentEntry.isValid():
+                if len(self.__entries.keys()):
+                    nextID = max(self.__entries.keys()) + 1
+                else:
+                    nextID = 0
+                self.__currentEntry.setID(nextID)
+                self.__entries[nextID] = self.__currentEntry
+                duration = self.__currentEntry.getDuration()
+            self.__currentEntry = None
+        
+        return nextID, duration
+    
+    def startTrackerEntry(self):
+        """
+        Public method to start a new tracker entry.
+        """
+        self.__currentEntry = TimeTrackEntry()
+        self.__currentEntry.start()
+        self.__widget.setCurrentEntry(self.__currentEntry)
+    
     def getCurrentEntry(self):
         """
         Public method to get a reference to the current tracker entry.
         """
         return self.__currentEntry
-    
-    def newEntry(self):
-        """
-        Public method to stop the current tracker entry and start a new one.
-        """
-        # stop the current time tracker entry
-        if self.__currentEntry is not None:
-            self.__currentEntry.stop()
-            if self.__currentEntry.isValid():
-                self.__entries.append(self.__currentEntry)
-        
-        # save the tracker entries
-        self.__saveTrackerEntries()
-        
-        # start a new time tracker entry
-        self.__currentEntry = TimeTrackEntry()
-        self.__currentEntry.start()
--- a/TimeTracker/TimeTrackerWidget.py	Fri Oct 19 22:26:57 2012 +0200
+++ b/TimeTracker/TimeTrackerWidget.py	Sat Oct 20 12:34:26 2012 +0200
@@ -73,18 +73,27 @@
             duration = entry.getDuration()
             
             itm = self.entriesList.topLevelItem(0)
-            itm.setText(self.DurationColumn, str(duration))
+            itm.setText(self.DurationColumn, self.tr("{0} min").format(duration))
             self.entriesList.resizeColumnToContents(self.CommentColumn)
+            
+            self.durationSpinBox.setValue(duration)
         else:
             self.__tracker.continueTrackerEntry()
     
     @pyqtSlot()
     def on_newButton_clicked(self):
         """
-        Slot documentation goes here.
+        Private slot to end the current timer and start a new one.
         """
-        # TODO: not implemented yet
-        raise NotImplementedError
+        # stop the current tracker
+        eid, duration = self.__tracker.stopTrackerEntry()
+        itm = self.entriesList.topLevelItem(0)
+        itm.setText(self.DurationColumn, self.tr("{0} min").format(duration))
+        itm.setData(0, Qt.UserRole, eid)
+        self.entriesList.resizeColumnToContents(self.CommentColumn)
+        
+        # start a new one
+        self.__tracker.startTrackerEntry()
     
     @pyqtSlot(QPoint)
     def on_entriesList_customContextMenuRequested(self, pos):
@@ -156,10 +165,12 @@
         @param index index the entry is to be inserted; -1 for at the end
             (integer)
         """
-        date, time, duration, task, comment, paused = entry.getEntryData()
+        eid, date, time, duration, task, comment, paused = entry.getEntryData()
         itm = QTreeWidgetItem(
-            ["{0}, {1}".format(date, time), str(duration), task, comment])
+            [self.tr("{0}, {1}", "date, time").format(date, time),
+             self.tr("{0} min").format(duration), task, comment])
         itm.setTextAlignment(1, Qt.AlignRight)
+        itm.setData(0, Qt.UserRole, eid)
         if index == -1:
             self.entriesList.addTopLevelItem(itm)
         else:
@@ -191,7 +202,7 @@
         self.__insertEntry(entry, 0)
         self.__resizeColumns()
         
-        date, time, duration, task, comment, paused = entry.getEntryData()
+        eid, date, time, duration, task, comment, paused = entry.getEntryData()
         self.startDateTimeEdit.setDateTime(entry.getStartDateTime())
         self.durationSpinBox.setValue(duration)
         self.taskCombo.setEditText(task)
--- a/TimeTracker/TimeTrackerWidget.ui	Fri Oct 19 22:26:57 2012 +0200
+++ b/TimeTracker/TimeTrackerWidget.ui	Sat Oct 20 12:34:26 2012 +0200
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>609</width>
-    <height>149</height>
+    <height>185</height>
    </rect>
   </property>
   <layout class="QVBoxLayout" name="verticalLayout">
@@ -46,6 +46,9 @@
      </item>
      <item row="1" column="0">
       <widget class="QDateTimeEdit" name="startDateTimeEdit">
+       <property name="focusPolicy">
+        <enum>Qt::NoFocus</enum>
+       </property>
        <property name="toolTip">
         <string>Shows the start date and time of the current timer</string>
        </property>
@@ -62,6 +65,9 @@
      </item>
      <item row="1" column="1">
       <widget class="QSpinBox" name="durationSpinBox">
+       <property name="focusPolicy">
+        <enum>Qt::NoFocus</enum>
+       </property>
        <property name="toolTip">
         <string>Shows the duration of the current timer</string>
        </property>
Binary file TimeTracker/icons/clock.png has changed

eric ide

mercurial