Sat, 20 Oct 2012 12:34:26 +0200
Implemented some more of the TimeTrackerWidget.
--- 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>