Sat, 31 Dec 2022 16:27:55 +0100
Updated copyright for 2023.
# -*- coding: utf-8 -*- # Copyright (c) 2012 - 2023 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing the time track entry class. """ from PyQt6.QtCore import QDateTime, Qt, QTime class TimeTrackEntry: """ Class implementing the time track entry. """ LineMarker = "Entry: " Separator = "@@" def __init__(self, plugin): """ Constructor @param plugin reference to the plugin object @type TimeTrackerPlugin """ self.__plugin = plugin self.__entryMembersCount = 5 self.__id = -1 self.__startDateTime = QDateTime() # start date and time self.__duration = 0 # duration in minutes self.__task = "" # task specification self.__comment = "" # comment string self.__valid = False # flag for a valid entry self.__continueDateTime = QDateTime() self.__paused = False def __lt__(self, other): """ Special method implementing the less than function. @param other reference to the other object @type TimeTrackEntry @return flag indicating that self is less than other @rtype bool """ return self.__startDateTime < other.getStartDateTime() def toDict(self): """ Public method to convert the time track entry into a dictionary. @return dictionary containing the time track entry data @rtype dict """ if self.__valid: return { "id": self.__id, "start": self.__startDateTime.toString(Qt.DateFormat.ISODate), "duration": self.__duration, "task": self.__task, "comment": self.__comment, } else: return {} def fromDict(self, data): """ Public method to populate the time track entry from a dictionary. @param data dictionary containing the time track entry data @type dict @return ID of the tracker entry; -1 indicates an error @rtype int """ if len(data) != self.__entryMembersCount: return -1 self.__id = data["id"] dt = QDateTime.fromString(data["start"], Qt.DateFormat.ISODate) if not dt.isValid(): return -1 self.__startDateTime = dt self.__duration = data["duration"] self.__task = data["task"] self.__comment = data["comment"] self.__valid = True return self.__id def isValid(self): """ Public method to check the validity of the entry. @return validity of the entry @rtype bool """ return self.__valid def start(self): """ Public method to set the start time of this entry. """ self.__startDateTime = self.__currentDateTime() self.__continueDateTime = QDateTime(self.__startDateTime) def stop(self): """ Public method to stop this entry. """ if not self.__paused: minutes = self.__calculateDuration( self.__continueDateTime, QDateTime.currentDateTime() ) self.__duration += minutes if self.__duration >= self.__plugin.getPreferences("MinimumDuration"): self.__valid = True else: self.__duration = 0 self.__valid = False def pause(self): """ Public method to pause the entry. """ if not self.__paused: minutes = self.__calculateDuration( self.__continueDateTime, QDateTime.currentDateTime() ) self.__duration += minutes self.__paused = True def continue_(self): """ Public method to continue the entry. """ if self.__paused: self.__continueDateTime = self.__currentDateTime() self.__paused = False def isPaused(self): """ Public method to check for a paused state. @return flag indicating a paused state @rtype bool """ return self.__paused def __currentDateTime(self): """ Private method to get the current date and time without milliseconds. @return current date and time @rtype QDateTime """ dt = QDateTime.currentDateTime() t = dt.time() t2 = QTime(t.hour(), t.minute(), t.second()) dt.setTime(t2) return dt def __calculateDuration(self, start, stop): """ Private method to calculate the duration in minutes. @param start start date and time @type QDateTime @param stop end date and time @type QDateTime @return duration in minutes @rtype int """ secs = start.secsTo(stop) minutes = secs // 60 secsRemaining = secs % 60 if secsRemaining >= 30: minutes += 1 return minutes def getID(self): """ Public method to get the ID of the entry. @return ID of the entry @rtype int """ return self.__id def setID(self, eid): """ Public method to assign an ID to the entry. @param eid ID for the entry @type int """ self.__id = eid def getStartDateTime(self): """ Public method to get the start date and time. @return start date and time @rtype QDateTime """ return self.__startDateTime def setStartDateTime(self, startDateTime): """ Public method to set the start date and time. @param startDateTime start date and time @type QDateTime """ if startDateTime.isValid(): self.__startDateTime = startDateTime self.__valid = ( self.__startDateTime.isValid() and self.__duration >= self.__plugin.getPreferences("MinimumDuration") ) def getDuration(self): """ Public slot to get the duration. @return duration @rtype int """ return self.__duration def setDuration(self, duration): """ Public method to set the duration. @param duration duration in minutes @type int """ if duration >= self.__plugin.getPreferences("MinimumDuration"): self.__duration = duration self.__valid = ( self.__startDateTime.isValid() and self.__duration >= self.__plugin.getPreferences("MinimumDuration") ) def addDuration(self, duration): """ Public method to add a duration. @param duration duration to be added in minutes. Negative values are ignored. @type int """ if duration > 0: self.__duration += duration def getTask(self): """ Public method to get the task description. @return task description @rtype str """ return self.__task def setTask(self, description): """ Public method to set the task description. @param description task description @type str """ self.__task = ( description.replace("\r\n", " ").replace("\n", " ").replace("\r", " ") ) def getComment(self): """ Public method to get the comment. @return comment @rtype str """ return self.__comment def setComment(self, comment): """ Public method to set a comment. @param comment comment to set @type str """ self.__comment = ( comment.replace("\r\n", " ").replace("\n", " ").replace("\r", " ") ) def getEntryData(self): """ Public method to get the entry data. @return entry data as a dictionary with keys 'id', 'paused', 'start_date', 'start_time', 'duration', 'task' and 'comment' containing the entry ID, a flag indicating a paused state, the start date as a string, the start time as a string, the duration, the task and a comment @rtype dict """ return { "id": self.__id, "paused": self.__paused, "start_date": self.__startDateTime.toString("yyyy-MM-dd"), "start_time": self.__startDateTime.toString("hh:mm:ss"), "duration": self.__duration, "task": self.__task, "comment": self.__comment, }