Tue, 20 Sep 2022 19:10:20 +0200
Reformatted the source code with 'Black'.
--- a/PluginTimeTracker.epj Thu Dec 30 12:38:13 2021 +0100 +++ b/PluginTimeTracker.epj Tue Sep 20 19:10:20 2022 +0200 @@ -1,19 +1,21 @@ { "header": { "comment": "eric project file for project PluginTimeTracker", - "copyright": "Copyright (C) 2021 Detlev Offenbach, detlev@die-offenbachs.de" + "copyright": "Copyright (C) 2022 Detlev Offenbach, detlev@die-offenbachs.de" }, "project": { "AUTHOR": "Detlev Offenbach", "CHECKERSPARMS": { "Pep8Checker": { "AnnotationsChecker": { + "AllowStarArgAny": false, "AllowUntypedDefs": false, "AllowUntypedNested": false, "DispatchDecorators": [ "singledispatch", "singledispatchmethod" ], + "ForceFutureAnnotations": false, "MaximumComplexity": 3, "MaximumLength": 7, "MinimumCoverage": 75, @@ -59,20 +61,25 @@ }, "CopyrightAuthor": "", "CopyrightMinFileSize": 0, - "DocstringType": "eric", + "DocstringType": "eric_black", "EnabledCheckerCategories": "C, D, E, M, N, S, Y, W", "ExcludeFiles": "*/Ui_*.py, */*_rc.py,", - "ExcludeMessages": "C101,E265,E266,E305,E402,M201,M301,M302,M303,M304,M305,M306,M307,M308,M311,M312,M313,M314,M315,M321,M701,M702,M811,M834,N802,N803,N807,N808,N821,W293,W504,Y119,Y401,Y402", + "ExcludeMessages": "C101,E265,E266,E305,E402,M201,M301,M302,M303,M304,M305,M306,M307,M308,M311,M312,M313,M314,M315,M321,M701,M702,M811,M834,N802,N803,N807,N808,N821,W293,W503,Y119,Y401,Y402", "FixCodes": "", "FixIssues": false, "FutureChecker": "", "HangClosing": false, + "ImportsChecker": { + "ApplicationPackageNames": [], + "BanRelativeImports": "", + "BannedModules": [] + }, "IncludeMessages": "", "LineComplexity": 25, "LineComplexityScore": 10, "MaxCodeComplexity": 10, - "MaxDocLineLength": 79, - "MaxLineLength": 79, + "MaxDocLineLength": 88, + "MaxLineLength": 88, "NoFixCodes": "E501", "RepeatMessages": true, "SecurityChecker": { @@ -129,6 +136,7 @@ } }, "EMAIL": "detlev@die-offenbachs.de", + "EMBEDDED_VENV": false, "EOL": 1, "FILETYPES": { "*.epj": "OTHERS", @@ -164,6 +172,7 @@ }, "INTERFACES": [], "LEXERASSOCS": {}, + "LICENSE": "GNU General Public License v3 or later (GPLv3+)", "MAINSCRIPT": "PluginTimeTracker.py", "MAKEPARAMS": { "MakeEnabled": false, @@ -178,14 +187,31 @@ ".hgignore", "ChangeLog", "PKGLIST", + "PluginTimeTracker.epj", "PluginTimeTracker.zip", "TimeTracker/Documentation/LICENSE.GPL3", "TimeTracker/Documentation/source", "TimeTracker/icons/clock-dark.svg", - "TimeTracker/icons/clock-light.svg", - "PluginTimeTracker.epj" + "TimeTracker/icons/clock-light.svg" ], - "OTHERTOOLSPARMS": {}, + "OTHERTOOLSPARMS": { + "Black": { + "exclude": "/(\\.direnv|\\.eggs|\\.git|\\.hg|\\.mypy_cache|\\.nox|\\.tox|\\.venv|venv|\\.svn|_build|buck-out|build|dist|__pypackages__)/", + "extend-exclude": "", + "force-exclude": "", + "line-length": 88, + "skip-magic-trailing-comma": false, + "skip-string-normalization": false, + "source": "project", + "target-version": [ + "py311", + "py310", + "py39", + "py38", + "py37" + ] + } + }, "PACKAGERSPARMS": {}, "PROGLANGUAGE": "Python3", "PROJECTTYPE": "E7Plugin", @@ -212,6 +238,7 @@ "SPELLEXCLUDES": "", "SPELLLANGUAGE": "en", "SPELLWORDS": "", + "TESTING_FRAMEWORK": "", "TRANSLATIONEXCEPTIONS": [], "TRANSLATIONPATTERN": "TimeTracker/i18n/timetracker_%language%.ts", "TRANSLATIONS": [
--- a/PluginTimeTracker.py Thu Dec 30 12:38:13 2021 +0100 +++ b/PluginTimeTracker.py Tue Sep 20 19:10:20 2022 +0200 @@ -38,12 +38,12 @@ error = "" timeTrackerPluginObject = None - + def createTimeTrackerPage(configDlg): """ Module function to create the Time Tracker configuration page. - + @param configDlg reference to the configuration dialog @type ConfigurationWidget @return reference to the configuration page @@ -51,26 +51,28 @@ """ global timeTrackerPluginObject from TimeTracker.ConfigurationPage.TimeTrackerPage import TimeTrackerPage + return TimeTrackerPage(timeTrackerPluginObject) def getConfigData(): """ Module function returning data as required by the configuration dialog. - + @return dictionary containing the relevant data @rtype dict """ usesDarkPalette = ericApp().usesDarkPalette() iconSuffix = "dark" if usesDarkPalette else "light" - + return { "timeTrackerPage": [ - QCoreApplication.translate("TimeTrackerPlugin", - "Time Tracker"), - os.path.join("TimeTracker", "icons", - "clock-{0}".format(iconSuffix)), - createTimeTrackerPage, None, None], + QCoreApplication.translate("TimeTrackerPlugin", "Time Tracker"), + os.path.join("TimeTracker", "icons", "clock-{0}".format(iconSuffix)), + createTimeTrackerPage, + None, + None, + ], } @@ -85,86 +87,81 @@ """ Class implementing the Eric assistant plugin. """ + PreferencesKey = "TimeTracker" - + def __init__(self, ui): """ Constructor - + @param ui reference to the user interface object @type UserInterface """ QObject.__init__(self, ui) self.__ui = ui self.__initialize() - + self.__defaults = { "MinimumDuration": 2, "AutoSave": False, "AllowDuplicates": False, } - + self.__translator = None self.__loadTranslator() - + def __initialize(self): """ Private slot to (re)initialize the plugin. """ self.__object = None - + self.__ericProject = ericApp().getObject("Project") - + def activate(self): """ Public method to activate this plugin. - + @return tuple of None and activation status @rtype bool """ global error - error = "" # clear previous error - + error = "" # clear previous error + global timeTrackerPluginObject timeTrackerPluginObject = self - + usesDarkPalette = ericApp().usesDarkPalette() iconSuffix = "dark" if usesDarkPalette else "light" - + self.__object = TimeTracker(self, iconSuffix, self.__ui) self.__object.activate() ericApp().registerPluginObject("TimeTracker", self.__object) - + if self.__ericProject.isOpen(): self.__object.projectOpened() - - self.__ericProject.newProject.connect( - self.__object.projectOpened) - self.__ericProject.projectOpened.connect( - self.__object.projectOpened) - self.__ericProject.projectClosed.connect( - self.__object.projectClosed) - + + self.__ericProject.newProject.connect(self.__object.projectOpened) + self.__ericProject.projectOpened.connect(self.__object.projectOpened) + self.__ericProject.projectClosed.connect(self.__object.projectClosed) + return None, True - + def deactivate(self): """ Public method to deactivate this plugin. """ ericApp().unregisterPluginObject("TimeTracker") self.__object.deactivate() - - self.__ericProject.newProject.disconnect( - self.__object.projectOpened) - self.__ericProject.projectOpened.disconnect( - self.__object.projectOpened) - self.__ericProject.projectClosed.disconnect( - self.__object.projectClosed) - + + self.__ericProject.newProject.disconnect(self.__object.projectOpened) + self.__ericProject.projectOpened.disconnect(self.__object.projectOpened) + self.__ericProject.projectClosed.disconnect(self.__object.projectClosed) + self.__object.projectClosed() - + self.__initialize() - + def __loadTranslator(self): """ Private method to load the translation file. @@ -173,7 +170,8 @@ loc = self.__ui.getLocale() if loc and loc != "C": locale_dir = os.path.join( - os.path.dirname(__file__), "TimeTracker", "i18n") + os.path.dirname(__file__), "TimeTracker", "i18n" + ) translation = "timetracker_{0}".format(loc) translator = QTranslator(None) loaded = translator.load(translation, locale_dir) @@ -181,41 +179,49 @@ self.__translator = translator ericApp().installTranslator(self.__translator) else: - print("Warning: translation file '{0}' could not be" - " loaded.".format(translation)) + print( + "Warning: translation file '{0}' could not be" + " loaded.".format(translation) + ) print("Using default.") - + def getPreferences(self, key): """ Public method to retrieve the various settings. - + @param key key of the value to get @type str @return value of the requested setting @rtype Any """ if key in ["MinimumDuration"]: - return int(Preferences.Prefs.settings.value( - self.PreferencesKey + "/" + key, self.__defaults[key])) + return int( + Preferences.Prefs.settings.value( + self.PreferencesKey + "/" + key, self.__defaults[key] + ) + ) elif key in ["AutoSave", "AllowDuplicates"]: return Preferences.toBool( Preferences.Prefs.settings.value( - self.PreferencesKey + "/" + key, self.__defaults[key])) + self.PreferencesKey + "/" + key, self.__defaults[key] + ) + ) else: return Preferences.Prefs.settings.value( - self.PreferencesKey + "/" + key, self.__defaults[key]) - + self.PreferencesKey + "/" + key, self.__defaults[key] + ) + def setPreferences(self, key, value): """ Public method to store the various settings. - + @param key key of the setting to be set @type str @param value value to be set @type Any """ - Preferences.Prefs.settings.setValue( - self.PreferencesKey + "/" + key, value) + Preferences.Prefs.settings.setValue(self.PreferencesKey + "/" + key, value) + # # eflag: noqa = M801
--- a/TimeTracker/ConfigurationPage/TimeTrackerPage.py Thu Dec 30 12:38:13 2021 +0100 +++ b/TimeTracker/ConfigurationPage/TimeTrackerPage.py Tue Sep 20 19:10:20 2022 +0200 @@ -7,9 +7,7 @@ Module implementing the Time Tracker configuration page. """ -from Preferences.ConfigurationPages.ConfigurationPageBase import ( - ConfigurationPageBase -) +from Preferences.ConfigurationPages.ConfigurationPageBase import ConfigurationPageBase from .Ui_TimeTrackerPage import Ui_TimeTrackerPage @@ -17,34 +15,33 @@ """ Class implementing the Time Tracker configuration page. """ + def __init__(self, plugin): """ Constructor - + @param plugin reference to the plugin object @type TimeTrackerPlugin """ super().__init__() self.setupUi(self) self.setObjectName("TimeTrackerPage") - + self.__plugin = plugin - + # set initial values - self.durationSpinBox.setValue( - self.__plugin.getPreferences("MinimumDuration")) - self.autosaveCheckBox.setChecked( - self.__plugin.getPreferences("AutoSave")) + self.durationSpinBox.setValue(self.__plugin.getPreferences("MinimumDuration")) + self.autosaveCheckBox.setChecked(self.__plugin.getPreferences("AutoSave")) self.duplicatesCheckBox.setChecked( - self.__plugin.getPreferences("AllowDuplicates")) - + self.__plugin.getPreferences("AllowDuplicates") + ) + def save(self): """ Public slot to save the Time Tracker configuration. """ - self.__plugin.setPreferences( - "MinimumDuration", self.durationSpinBox.value()) + self.__plugin.setPreferences("MinimumDuration", self.durationSpinBox.value()) + self.__plugin.setPreferences("AutoSave", self.autosaveCheckBox.isChecked()) self.__plugin.setPreferences( - "AutoSave", self.autosaveCheckBox.isChecked()) - self.__plugin.setPreferences( - "AllowDuplicates", self.duplicatesCheckBox.isChecked()) + "AllowDuplicates", self.duplicatesCheckBox.isChecked() + )
--- a/TimeTracker/TimeTrackEntry.py Thu Dec 30 12:38:13 2021 +0100 +++ b/TimeTracker/TimeTrackEntry.py Tue Sep 20 19:10:20 2022 +0200 @@ -14,44 +14,45 @@ """ 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.__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 """ @@ -65,11 +66,11 @@ } 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 @@ -77,62 +78,64 @@ """ 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.__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.__continueDateTime, QDateTime.currentDateTime() + ) self.__duration += minutes self.__paused = True - + def continue_(self): """ Public method to continue the entry. @@ -140,20 +143,20 @@ 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 """ @@ -162,11 +165,11 @@ 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 @@ -179,131 +182,128 @@ 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") + 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") + 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", " ") + 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
--- a/TimeTracker/TimeTracker.py Thu Dec 30 12:38:13 2021 +0100 +++ b/TimeTracker/TimeTracker.py Tue Sep 20 19:10:20 2022 +0200 @@ -24,12 +24,13 @@ """ Class implementing the time tracker object. """ + FileName = "TimeTracker.ttj" - + def __init__(self, plugin, iconSuffix, parent=None): """ Constructor - + @param plugin reference to the plugin object @type TimeTrackerPlugin @param iconSuffix suffix for the icons @@ -38,96 +39,100 @@ @type QObject """ QObject.__init__(self, parent) - + self.__plugin = plugin self.__iconSuffix = iconSuffix self.__ui = parent - + self.__ericProject = ericApp().getObject("Project") - + def __initialize(self): """ Private slot to initialize some member variables. """ - self.__projectPath = '' - self.__trackerFilePath = '' + self.__projectPath = "" + self.__trackerFilePath = "" self.__projectOpen = False - - self.__entries = {} # key: entry ID, value tracker entry + + self.__entries = {} # key: entry ID, value tracker entry self.__currentEntry = None - + self.__widget.clear() self.__widget.setEnabled(False) - + def activate(self): """ Public method to activate the time tracker. """ from .TimeTrackerWidget import TimeTrackerWidget - + self.__widget = TimeTrackerWidget(self) iconName = ( "sbTimeTracker96" - if self.__ui.getLayoutType() == "Sidebars" else - "clock-{0}".format(self.__iconSuffix) + if self.__ui.getLayoutType() == "Sidebars" + else "clock-{0}".format(self.__iconSuffix) ) self.__ui.addSideWidget( - self.__ui.BottomSide, self.__widget, - UI.PixmapCache.getIcon( - os.path.join("TimeTracker", "icons", iconName) - ), - self.tr("Time Tracker")) - + self.__ui.BottomSide, + self.__widget, + UI.PixmapCache.getIcon(os.path.join("TimeTracker", "icons", iconName)), + self.tr("Time Tracker"), + ) + self.__activateAct = EricAction( - self.tr('Time Tracker'), - self.tr('T&ime Tracker'), + self.tr("Time Tracker"), + self.tr("T&ime Tracker"), QKeySequence(self.tr("Alt+Shift+I")), - 0, self, - 'time_tracker_activate') - self.__activateAct.setStatusTip(self.tr( - "Switch the input focus to the Time Tracker window.")) - self.__activateAct.setWhatsThis(self.tr( - """<b>Activate Time Tracker</b>""" - """<p>This switches the input focus to the Time Tracker""" - """ window.</p>""" - )) + 0, + self, + "time_tracker_activate", + ) + self.__activateAct.setStatusTip( + self.tr("Switch the input focus to the Time Tracker window.") + ) + self.__activateAct.setWhatsThis( + self.tr( + """<b>Activate Time Tracker</b>""" + """<p>This switches the input focus to the Time Tracker""" + """ window.</p>""" + ) + ) self.__activateAct.triggered.connect(self.__activateWidget) - - self.__ui.addEricActions([self.__activateAct], 'ui') + + self.__ui.addEricActions([self.__activateAct], "ui") menu = self.__ui.getMenu("subwindow") menu.addAction(self.__activateAct) - + self.__initialize() - + def deactivate(self): """ Public method to deactivate the time tracker. """ menu = self.__ui.getMenu("subwindow") menu.removeAction(self.__activateAct) - self.__ui.removeEricActions([self.__activateAct], 'ui') + self.__ui.removeEricActions([self.__activateAct], "ui") self.__ui.removeSideWidget(self.__widget) - + def projectOpened(self): """ Public slot to handle the projectOpened signal. """ if self.__projectOpen: self.projectClosed() - + self.__projectOpen = True self.__projectPath = self.__ericProject.getProjectPath() self.__trackerFilePath = os.path.join( - self.__ericProject.getProjectManagementDir(), - TimeTracker.FileName) - + self.__ericProject.getProjectManagementDir(), TimeTracker.FileName + ) + self.__readTrackerEntries() - self.__widget.showTrackerEntries(sorted(self.__entries.values(), - reverse=True)) + self.__widget.showTrackerEntries(sorted(self.__entries.values(), reverse=True)) self.__widget.setEnabled(True) - + self.startTrackerEntry() - + def projectClosed(self): """ Public slot to handle the projectClosed signal. @@ -136,7 +141,7 @@ self.stopTrackerEntry() self.saveTrackerEntries() self.__initialize() - + def __readTrackerEntries(self): """ Private slot to read the time tracker entries from a file. @@ -150,13 +155,15 @@ EricMessageBox.critical( self.__ui, self.tr("Read Time Tracker File"), - self.tr("""<p>The time tracker file <b>{0}</b> could""" - """ not be read.</p><p>Reason: {1}</p>""") - .format(self.__trackerFilePath, str(err))) + self.tr( + """<p>The time tracker file <b>{0}</b> could""" + """ not be read.</p><p>Reason: {1}</p>""" + ).format(self.__trackerFilePath, str(err)), + ) return - + from .TimeTrackEntry import TimeTrackEntry - + invalidCount = 0 for data in entriesDataList: entry = TimeTrackEntry(self.__plugin) @@ -165,20 +172,24 @@ self.__entries[eid] = entry else: invalidCount += 1 - + if invalidCount: EricMessageBox.information( self.__ui, self.tr("Read Time Tracker File"), - self.tr("""<p>The time tracker file <b>{0}</b>""" - """ contained %n invalid entries. These""" - """ have been discarded.</p>""", "", - invalidCount).format(self.__trackerFilePath)) - + self.tr( + """<p>The time tracker file <b>{0}</b>""" + """ contained %n invalid entries. These""" + """ have been discarded.</p>""", + "", + invalidCount, + ).format(self.__trackerFilePath), + ) + def saveTrackerEntries(self, filePath="", ids=None): """ Public slot to save the tracker entries to a file. - + @param filePath path and name of the file to write the entries to @type str @param ids list of entry IDs to be written @@ -187,10 +198,9 @@ if not filePath: filePath = self.__trackerFilePath entriesDataList = ( - [self.__entries[eid].toDict() - for eid in ids if eid in self.__entries] - if ids else - [e.toDict() for e in self.__entries.values()] + [self.__entries[eid].toDict() for eid in ids if eid in self.__entries] + if ids + else [e.toDict() for e in self.__entries.values()] ) try: jsonString = json.dumps(entriesDataList, indent=2) @@ -200,14 +210,16 @@ EricMessageBox.critical( self.__ui, self.tr("Save Time Tracker File"), - self.tr("""<p>The time tracker file <b>{0}</b> could""" - """ not be saved.</p><p>Reason: {1}</p>""") - .format(self.__trackerFilePath, str(err))) - + self.tr( + """<p>The time tracker file <b>{0}</b> could""" + """ not be saved.</p><p>Reason: {1}</p>""" + ).format(self.__trackerFilePath, str(err)), + ) + def importTrackerEntries(self, fname): """ Public slot to import tracker entries from a file. - + @param fname name of the file to import (string) """ try: @@ -218,17 +230,19 @@ EricMessageBox.critical( self.__ui, self.tr("Import Time Tracker File"), - self.tr("""<p>The time tracker file <b>{0}</b> could""" - """ not be read.</p><p>Reason: {1}</p>""") - .format(fname, str(err))) + self.tr( + """<p>The time tracker file <b>{0}</b> could""" + """ not be read.</p><p>Reason: {1}</p>""" + ).format(fname, str(err)), + ) return - + from .TimeTrackEntry import TimeTrackEntry - + invalidCount = 0 duplicateCount = 0 entries = [] - + for data in entriesDataList: entry = TimeTrackEntry(self.__plugin) eid = entry.fromDict(data) @@ -236,63 +250,64 @@ entries.append(entry) else: invalidCount += 1 - + if not self.__plugin.getPreferences("AllowDuplicates"): - startDateTimes = [ - e.getStartDateTime() for e in self.__entries.values()] + startDateTimes = [e.getStartDateTime() for e in self.__entries.values()] for entry in entries[:]: if entry.getStartDateTime() in startDateTimes: entries.remove(entry) duplicateCount += 1 - - start = ( - max(self.__entries.keys()) + 1 - if len(self.__entries.keys()) else - 0 - ) + + start = max(self.__entries.keys()) + 1 if len(self.__entries.keys()) else 0 for nextID, entry in enumerate(entries, start=start): entry.setID(nextID) self.__entries[nextID] = entry - + if self.__plugin.getPreferences("AutoSave"): self.saveTrackerEntries() - + if invalidCount != 0 or duplicateCount != 0: if invalidCount != 0 and duplicateCount != 0: msg = self.tr( """<p>The time tracker file <b>{0}</b> contained""" """ %n invalid entries.""", - "", invalidCount).format(fname) + "", + invalidCount, + ).format(fname) msg += " " + self.tr( - """ %n duplicate entries were detected.""", "", - duplicateCount) + """ %n duplicate entries were detected.""", "", duplicateCount + ) elif duplicateCount != 0: msg = self.tr( """<p>The time tracker file <b>{0}</b> contained""" """ %n duplicate entries.""", - "", duplicateCount).format(fname) + "", + duplicateCount, + ).format(fname) elif invalidCount != 0: msg = self.tr( """<p>The time tracker file <b>{0}</b> contained""" """ %n invalid entries.""", - "", invalidCount).format(fname) + "", + invalidCount, + ).format(fname) msg += " " + self.tr( """ %n entries have been ignored.</p>""", - "", invalidCount + duplicateCount) + "", + invalidCount + duplicateCount, + ) EricMessageBox.information( - self.__ui, - self.tr("Import Time Tracker File"), - msg) - + self.__ui, self.tr("Import Time Tracker File"), msg + ) + self.__widget.clear() - self.__widget.showTrackerEntries(sorted(self.__entries.values(), - reverse=True)) + self.__widget.showTrackerEntries(sorted(self.__entries.values(), reverse=True)) self.__widget.setCurrentEntry(self.__currentEntry) - + def addTrackerEntry(self, startDateTime, duration, task, comment): """ Public method to add a new tracker entry based on the given data. - + @param startDateTime start date and time @type QDateTime @param duration duration in minutes @@ -304,21 +319,18 @@ """ if not self.__plugin.getPreferences("AllowDuplicates"): startDateTimes = [ - entry.getStartDateTime() for entry in self.__entries.values()] + entry.getStartDateTime() for entry in self.__entries.values() + ] if startDateTime in startDateTimes: return - + if duration < self.__plugin.getPreferences("MinimumDuration"): return - - nextID = ( - max(self.__entries.keys()) + 1 - if len(self.__entries.keys()) else - 0 - ) - + + nextID = max(self.__entries.keys()) + 1 if len(self.__entries.keys()) else 0 + from .TimeTrackEntry import TimeTrackEntry - + entry = TimeTrackEntry(self.__plugin) entry.setID(nextID) entry.setStartDateTime(startDateTime) @@ -326,28 +338,27 @@ entry.setTask(task) entry.setComment(comment) self.__entries[nextID] = entry - + self.__widget.clear() - self.__widget.showTrackerEntries( - sorted(self.__entries.values(), reverse=True)) + self.__widget.showTrackerEntries(sorted(self.__entries.values(), reverse=True)) self.__widget.setCurrentEntry(self.__currentEntry) - + def pauseTrackerEntry(self): """ Public method to pause the current tracker entry. """ self.__currentEntry.pause() - + def continueTrackerEntry(self): """ Public method to continue the current tracker entry. """ 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 @rtype tuple of (int, int) @@ -358,9 +369,7 @@ self.__currentEntry.stop() if self.__currentEntry.isValid(): nextID = ( - max(self.__entries.keys()) + 1 - if len(self.__entries.keys()) else - 0 + max(self.__entries.keys()) + 1 if len(self.__entries.keys()) else 0 ) self.__currentEntry.setID(nextID) self.__entries[nextID] = self.__currentEntry @@ -368,32 +377,32 @@ self.saveTrackerEntries() duration = self.__currentEntry.getDuration() self.__currentEntry = None - + return nextID, duration - + def startTrackerEntry(self): """ Public method to start a new tracker entry. """ from .TimeTrackEntry import TimeTrackEntry - + self.__currentEntry = TimeTrackEntry(self.__plugin) self.__currentEntry.start() self.__widget.setCurrentEntry(self.__currentEntry) - + def getCurrentEntry(self): """ Public method to get a reference to the current tracker entry. - + @return reference to the current entry @rtype TimeTrackEntry """ return self.__currentEntry - + def getEntry(self, eid): """ Public method to get a tracker entry given its ID. - + @param eid ID of the tracker entry @type int @return entry for the given ID or None @@ -403,21 +412,21 @@ return self.__entries[eid] else: return None - + def deleteTrackerEntry(self, eid): """ Public method to delete a tracker entry given its ID. - + @param eid ID of the tracker entry @type int """ if eid in self.__entries: del self.__entries[eid] - + def removeDuplicateTrackerEntries(self): """ Public slot to remove duplicate time tracker entries. - + If entries with the identical start date and time are found, the one with the longest duration is kept. """ @@ -429,24 +438,23 @@ entries[dt] = entry else: entries[dt] = entry - + self.__entries = {} for nextID, entry in enumerate(sorted(entries.values())): entry.setID(nextID) self.__entries[nextID] = entry - + if self.__plugin.getPreferences("AutoSave"): self.saveTrackerEntries() - + self.__widget.clear() - self.__widget.showTrackerEntries( - sorted(self.__entries.values(), reverse=True)) + self.__widget.showTrackerEntries(sorted(self.__entries.values(), reverse=True)) self.__widget.setCurrentEntry(self.__currentEntry) - + def mergeDuplicateTrackerEntries(self): """ Public slot to merge duplicate time tracker entries. - + If entries with the identical start date and time are found, the durations of these entries are added. """ @@ -457,44 +465,43 @@ entries[dt].addDuration(entry.getDuration()) else: entries[dt] = entry - + self.__entries = {} for nextID, entry in enumerate(sorted(entries.values())): entry.setID(nextID) self.__entries[nextID] = entry - + if self.__plugin.getPreferences("AutoSave"): self.saveTrackerEntries() - + self.__widget.clear() - self.__widget.showTrackerEntries( - sorted(self.__entries.values(), reverse=True)) + self.__widget.showTrackerEntries(sorted(self.__entries.values(), reverse=True)) self.__widget.setCurrentEntry(self.__currentEntry) - + def entryChanged(self): """ Public method to indicate an external change to any of the entries. """ if self.__plugin.getPreferences("AutoSave"): self.saveTrackerEntries() - + def getPreferences(self, key): """ Public method to retrieve the various settings. - + @param key key of the value to get @type str @return value of the requested setting @rtype Any """ return self.__plugin.getPreferences(key) - + def __activateWidget(self): """ Private slot to handle the activation of the time tracker widget. """ uiLayoutType = self.__ui.getLayoutType() - + if uiLayoutType == "Toolboxes": self.__ui.hToolboxDock.show() self.__ui.hToolbox.setCurrentWidget(self.__widget)
--- a/TimeTracker/TimeTrackerEntryDialog.py Thu Dec 30 12:38:13 2021 +0100 +++ b/TimeTracker/TimeTrackerEntryDialog.py Tue Sep 20 19:10:20 2022 +0200 @@ -17,10 +17,11 @@ """ Class implementing the time tracker edit dialog. """ + def __init__(self, tracker, entry, taskItems, commentItems, parent=None): """ Constructor - + @param tracker reference to the time tracker @type TimeTracker @param entry reference to the time tracker entry @@ -36,21 +37,18 @@ """ super().__init__(parent) self.setupUi(self) - - self.buttonBox.button( - QDialogButtonBox.StandardButton.Ok).setEnabled(False) - + + self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False) + self.taskCombo.addItems(taskItems) self.commentCombo.addItems(commentItems) - + # The allowed end time (i.e. start date and time plus duration must be # earlier or equal to the start date and time of the current entry. - self.__endDateTime = QDateTime( - tracker.getCurrentEntry().getStartDateTime()) - - self.durationSpinBox.setMinimum( - tracker.getPreferences("MinimumDuration")) - + self.__endDateTime = QDateTime(tracker.getCurrentEntry().getStartDateTime()) + + self.durationSpinBox.setMinimum(tracker.getPreferences("MinimumDuration")) + if entry is None: self.setWindowTitle(self.tr("Add Tracker Entry")) self.startDateTimeEdit.setDate(QDate.currentDate()) @@ -58,46 +56,47 @@ self.startDateTimeEdit.setDateTime(entry.getStartDateTime()) self.durationSpinBox.setValue(entry.getDuration()) self.durationSpinBox.setMaximum( - entry.getStartDateTime().secsTo(self.__endDateTime) // 60) + entry.getStartDateTime().secsTo(self.__endDateTime) // 60 + ) self.taskCombo.setEditText(entry.getTask()) self.commentCombo.setEditText(entry.getComment()) - + msh = self.minimumSizeHint() self.resize(max(self.width(), msh.width()), msh.height()) - + def __checkOk(self): """ Private slot to set the enabled state of the OK button. """ dt = self.startDateTimeEdit.dateTime() self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled( - dt.addSecs(self.durationSpinBox.value() * 60) <= - self.__endDateTime) - + dt.addSecs(self.durationSpinBox.value() * 60) <= self.__endDateTime + ) + @pyqtSlot(QDateTime) def on_startDateTimeEdit_dateTimeChanged(self, date): """ Private slot handling a change of the start date and time. - + @param date start date and time @type QDateTime """ self.__checkOk() - + @pyqtSlot(int) def on_durationSpinBox_valueChanged(self, value): """ Private slot handling a change of the duration. - + @param value value of the duration spin box @type int """ self.__checkOk() - + def getData(self): """ Public method to get the data. - + @return tuple with start date and time, duration, task description and comment @rtype tuple of (QDateTime, int, str, str)
--- a/TimeTracker/TimeTrackerWidget.py Thu Dec 30 12:38:13 2021 +0100 +++ b/TimeTracker/TimeTrackerWidget.py Tue Sep 20 19:10:20 2022 +0200 @@ -25,14 +25,15 @@ """ Class implementing the time tracker widget. """ + DurationColumn = 1 TaskColumn = 2 CommentColumn = 3 - + def __init__(self, tracker, parent=None): """ Constructor - + @param tracker reference to the time tracker @type TimeTracker @param parent reference to the parent widget @@ -40,15 +41,15 @@ """ super().__init__(parent) self.setupUi(self) - + self.__tracker = tracker - + @pyqtSlot(str) def on_taskCombo_editTextChanged(self, txt): """ Private slot handling changes of the task description of the current entry. - + @param txt new task description @type str """ @@ -56,16 +57,16 @@ if itm: itm.setText(self.TaskColumn, txt) self.entriesList.resizeColumnToContents(self.TaskColumn) - + entry = self.__tracker.getCurrentEntry() if entry: entry.setTask(txt) - + @pyqtSlot(str) def on_commentCombo_editTextChanged(self, txt): """ Private slot handling changes of the comment of the current entry. - + @param txt new comment @type str """ @@ -73,34 +74,33 @@ if itm: itm.setText(self.CommentColumn, txt) self.entriesList.resizeColumnToContents(self.CommentColumn) - + entry = self.__tracker.getCurrentEntry() if entry: entry.setComment(txt) - + @pyqtSlot(bool) def on_pauseButton_toggled(self, checked): """ Private slot to pause the current timing. - + @param checked flag indicating the checked status of the button @type bool """ if checked: self.__tracker.pauseTrackerEntry() - + entry = self.__tracker.getCurrentEntry() duration = entry.getDuration() - + itm = self.entriesList.topLevelItem(0) - itm.setText(self.DurationColumn, - self.tr("{0} min").format(duration)) + itm.setText(self.DurationColumn, self.tr("{0} min").format(duration)) self.entriesList.resizeColumnToContents(self.DurationColumn) - + self.durationSpinBox.setValue(duration) else: self.__tracker.continueTrackerEntry() - + @pyqtSlot() def on_newButton_clicked(self): """ @@ -110,68 +110,73 @@ eid, duration = self.__tracker.stopTrackerEntry() if eid > -1: itm = self.entriesList.topLevelItem(0) - itm.setText(self.DurationColumn, - self.tr("{0} min").format(duration)) + itm.setText(self.DurationColumn, self.tr("{0} min").format(duration)) itm.setData(0, Qt.ItemDataRole.UserRole, eid) else: itm = self.entriesList.takeTopLevelItem(0) del itm self.__resizeColumns() - + # start a new one self.__tracker.startTrackerEntry() - + @pyqtSlot(QPoint) def on_entriesList_customContextMenuRequested(self, pos): """ Private slot to create the context menu and show it. - + @param pos position the menu should be shown at @type QPoint """ menu = QMenu() - + act = menu.addAction(self.tr("Edit"), self.__editEntry) act.setEnabled( - len(self.entriesList.selectedItems()) == 1 and - self.entriesList.selectedItems()[0].data( - 0, Qt.ItemDataRole.UserRole) > -1 + len(self.entriesList.selectedItems()) == 1 + and self.entriesList.selectedItems()[0].data(0, Qt.ItemDataRole.UserRole) + > -1 ) menu.addAction(self.tr("Add"), self.__addEntry) act = menu.addAction(self.tr("Delete"), self.__deleteSelectedEntries) act.setEnabled( - (len(self.entriesList.selectedItems()) == 1 and - self.entriesList.selectedItems()[0].data( - 0, Qt.ItemDataRole.UserRole) > -1) or - len(self.entriesList.selectedItems()) > 1 + ( + len(self.entriesList.selectedItems()) == 1 + and self.entriesList.selectedItems()[0].data( + 0, Qt.ItemDataRole.UserRole + ) + > -1 + ) + or len(self.entriesList.selectedItems()) > 1 ) menu.addSeparator() menu.addAction(self.tr("Save"), self.__saveEntries) menu.addSeparator() menu.addAction(self.tr("Import"), self.__importEntries) - act = menu.addAction(self.tr("Export Selected"), - self.__exportSelectedEntries) + act = menu.addAction(self.tr("Export Selected"), self.__exportSelectedEntries) act.setEnabled(len(self.entriesList.selectedItems()) > 0) menu.addAction(self.tr("Export All"), self.__exportEntries) menu.addSeparator() menu.addAction(self.tr("Remove duplicates"), self.__removeDuplicates) menu.addAction(self.tr("Merge duplicates"), self.__mergeDuplicates) menu.exec(QCursor.pos()) - + def __addEntry(self): """ Private slot to manually add an entry. """ from .TimeTrackerEntryDialog import TimeTrackerEntryDialog - - tasks = [self.taskCombo.itemText(index) - for index in range(self.taskCombo.count())] - comments = [self.commentCombo.itemText(index) - for index in range(self.commentCombo.count())] + + tasks = [ + self.taskCombo.itemText(index) for index in range(self.taskCombo.count()) + ] + comments = [ + self.commentCombo.itemText(index) + for index in range(self.commentCombo.count()) + ] dlg = TimeTrackerEntryDialog(self.__tracker, None, tasks, comments) if dlg.exec() == QDialog.DialogCode.Accepted: self.__tracker.addTrackerEntry(*dlg.getData()) - + def __editEntry(self): """ Private slot to edit the selected tracker entry. @@ -183,31 +188,37 @@ entry = self.__tracker.getEntry(eid) if entry is not None: from .TimeTrackerEntryDialog import TimeTrackerEntryDialog - - tasks = [self.taskCombo.itemText(index) - for index in range(self.taskCombo.count())] - comments = [self.commentCombo.itemText(index) - for index in range(self.commentCombo.count())] - dlg = TimeTrackerEntryDialog( - self.__tracker, entry, tasks, comments) + + tasks = [ + self.taskCombo.itemText(index) + for index in range(self.taskCombo.count()) + ] + comments = [ + self.commentCombo.itemText(index) + for index in range(self.commentCombo.count()) + ] + dlg = TimeTrackerEntryDialog(self.__tracker, entry, tasks, comments) if dlg.exec() == QDialog.DialogCode.Accepted: start, duration, task, comment = dlg.getData() - + entry.setStartDateTime(start) entry.setDuration(duration) entry.setTask(task) entry.setComment(comment) self.__tracker.entryChanged() - + data = entry.getEntryData() - itm.setText(0, self.tr("{0}, {1}", "date, time") - .format(data["start_date"], - data["start_time"])) + itm.setText( + 0, + self.tr("{0}, {1}", "date, time").format( + data["start_date"], data["start_time"] + ), + ) itm.setText(1, self.tr("{0} min").format(data["duration"])) itm.setText(2, data["task"]) itm.setText(3, data["comment"]) self.__resizeColumns() - + def __deleteSelectedEntries(self): """ Private slot to delete the selected tracker entries. @@ -215,67 +226,64 @@ res = EricMessageBox.yesNo( self, self.tr("Delete Selected Entries"), - self.tr("""Do you really want to delete the selected""" - """ entries?""")) + self.tr("""Do you really want to delete the selected""" """ entries?"""), + ) if res: for item in self.entriesList.selectedItems(): eid = item.data(0, Qt.ItemDataRole.UserRole) if eid > -1: # the current entry must not be deleted self.entriesList.takeTopLevelItem( - self.entriesList.indexOfTopLevelItem(item)) + self.entriesList.indexOfTopLevelItem(item) + ) self.__tracker.deleteTrackerEntry(eid) del item - + def __saveEntries(self): """ Private slot to save the tracker entries. """ self.__tracker.saveTrackerEntries() - + def __importEntries(self): """ Private slot to import tracker entries. """ - path = ( - Preferences.getMultiProject("Workspace") or - Utilities.getHomeDir() - ) + path = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir() fname = EricFileDialog.getOpenFileName( None, self.tr("Import Time Tracker Entries"), path, - self.tr("Time Tracker Files (*.ttj);;All Files (*)")) + self.tr("Time Tracker Files (*.ttj);;All Files (*)"), + ) if fname: fname = Utilities.toNativeSeparators(fname) if not os.path.exists(fname): EricMessageBox.critical( self, self.tr("Import Time Tracker Entries"), - self.tr("<p>The file <b>{0}</b> does not exist.</p>") - .format(fname)) + self.tr("<p>The file <b>{0}</b> does not exist.</p>").format(fname), + ) return - + self.__tracker.importTrackerEntries(fname) - + def __exportEntries(self, ids=None): """ Private method to export all or selected entries. - + @param ids list of IDs to export or all if empty @type list of int """ - path = ( - Preferences.getMultiProject("Workspace") or - Utilities.getHomeDir() - ) + path = Preferences.getMultiProject("Workspace") or Utilities.getHomeDir() fname, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( self, self.tr("Export Time Tracker Entries"), path, self.tr("Time Tracker Files (*.ttj);;All Files (*)"), None, - EricFileDialog.Options(EricFileDialog.DontConfirmOverwrite)) + EricFileDialog.Options(EricFileDialog.DontConfirmOverwrite), + ) if fname: ext = QFileInfo(fname).suffix() if not ext: @@ -286,14 +294,16 @@ res = EricMessageBox.yesNo( self, self.tr("Export Time Tracker Entries"), - self.tr("<p>The file <b>{0}</b> already exists." - " Overwrite it?</p>").format(fname), - icon=EricMessageBox.Warning) + self.tr( + "<p>The file <b>{0}</b> already exists." " Overwrite it?</p>" + ).format(fname), + icon=EricMessageBox.Warning, + ) if not res: return fname = Utilities.toNativeSeparators(fname) self.__tracker.saveTrackerEntries(filePath=fname, ids=ids) - + def __exportSelectedEntries(self): """ Private slot to export the selected tracker entries. @@ -303,10 +313,10 @@ eid = itm.data(0, Qt.ItemDataRole.UserRole) if eid > -1: ids.append(eid) - + if ids: self.__exportEntries(ids=ids) - + def __removeDuplicates(self): """ Private slot to remove duplicate entries. @@ -314,12 +324,15 @@ res = EricMessageBox.yesNo( self, self.tr("Remove Duplicate Tracker Entries"), - self.tr("""Are you sure you want to remove duplicate""" - """ tracker entries? Only the one with the longest""" - """ duration will be kept.""")) + self.tr( + """Are you sure you want to remove duplicate""" + """ tracker entries? Only the one with the longest""" + """ duration will be kept.""" + ), + ) if res: self.__tracker.removeDuplicateTrackerEntries() - + def __mergeDuplicates(self): """ Private slot to merge duplicate entries. @@ -327,16 +340,19 @@ res = EricMessageBox.yesNo( self, self.tr("Merge Duplicate Tracker Entries"), - self.tr("""Are you sure you want to merge duplicate""" - """ tracker entries? The durations of duplicate""" - """ ones will be added.""")) + self.tr( + """Are you sure you want to merge duplicate""" + """ tracker entries? The durations of duplicate""" + """ ones will be added.""" + ), + ) if res: self.__tracker.mergeDuplicateTrackerEntries() - + def __insertEntry(self, entry, index=-1): """ Private method to insert a tracker entry into the list. - + @param entry reference to the tracker entry @type TimeTrackEntry @param index index the entry is to be inserted; -1 for at the end @@ -344,11 +360,14 @@ """ data = entry.getEntryData() itm = QTreeWidgetItem( - [self.tr("{0}, {1}", "date, time").format(data["start_date"], - data["start_time"]), - self.tr("{0} min").format(data["duration"]), - data["task"], - data["comment"]] + [ + self.tr("{0}, {1}", "date, time").format( + data["start_date"], data["start_time"] + ), + self.tr("{0} min").format(data["duration"]), + data["task"], + data["comment"], + ] ) itm.setTextAlignment(1, Qt.AlignmentFlag.AlignRight) itm.setData(0, Qt.ItemDataRole.UserRole, data["id"]) @@ -356,27 +375,27 @@ self.entriesList.addTopLevelItem(itm) else: self.entriesList.insertTopLevelItem(index, itm) - + def __resizeColumns(self): """ Private slot to resize the columns of the entries list. """ for column in range(self.entriesList.columnCount()): self.entriesList.resizeColumnToContents(column) - + def showTrackerEntries(self, entries): """ Public method to show the tracker entries of the current project. - + @param entries list of tracker entries @type list of TimeTrackEntry """ self.taskCombo.addItem("") self.commentCombo.addItem("") - + tasks = [] comments = [] - + for entry in entries: self.__insertEntry(entry) task = entry.getTask() @@ -385,29 +404,29 @@ comment = entry.getComment() if comment and comment not in comments: comments.append(comment) - + self.__resizeColumns() if tasks: self.taskCombo.addItems(sorted(tasks)) if comments: self.commentCombo.addItems(sorted(comments)) - + def setCurrentEntry(self, entry): """ Public method to set the current entry. - + @param entry current entry @type TimeTrackEntry """ self.__insertEntry(entry, 0) self.__resizeColumns() - + data = entry.getEntryData() self.startDateTimeEdit.setDateTime(entry.getStartDateTime()) self.durationSpinBox.setValue(data["duration"]) self.taskCombo.setEditText(data["task"]) self.commentCombo.setEditText(data["comment"]) - + def clear(self): """ Public method to clear all the data.