TimeTracker/TimeTracker.py

branch
eric7
changeset 98
693e42176007
parent 94
a3d936304e51
child 104
2ae9ad969598
--- a/TimeTracker/TimeTracker.py	Thu Jun 03 18:02:18 2021 +0200
+++ b/TimeTracker/TimeTracker.py	Fri Jun 04 16:40:54 2021 +0200
@@ -7,14 +7,15 @@
 Module implementing the time tracker object.
 """
 
+import json
 import os
 
-from PyQt5.QtCore import Qt, QObject
-from PyQt5.QtGui import QKeySequence
+from PyQt6.QtCore import Qt, QObject
+from PyQt6.QtGui import QKeySequence
 
-from E5Gui.E5Application import e5App
-from E5Gui import E5MessageBox
-from E5Gui.E5Action import E5Action
+from EricWidgets.EricApplication import ericApp
+from EricWidgets import EricMessageBox
+from EricGui.EricAction import EricAction
 
 import UI.PixmapCache
 
@@ -23,7 +24,7 @@
     """
     Class implementing the time tracker object.
     """
-    FileName = "TimeTracker.txt"
+    FileName = "TimeTracker.ttj"
     
     def __init__(self, plugin, iconSuffix, parent=None):
         """
@@ -42,7 +43,7 @@
         self.__iconSuffix = iconSuffix
         self.__ui = parent
         
-        self.__e5project = e5App().getObject("Project")
+        self.__ericProject = ericApp().getObject("Project")
     
     def __initialize(self):
         """
@@ -73,7 +74,7 @@
             ),
             self.tr("Time Tracker"))
         
-        self.__activateAct = E5Action(
+        self.__activateAct = EricAction(
             self.tr('Time Tracker'),
             self.tr('T&ime Tracker'),
             QKeySequence(self.tr("Alt+Shift+I")),
@@ -88,7 +89,7 @@
         ))
         self.__activateAct.triggered.connect(self.__activateWidget)
         
-        self.__ui.addE5Actions([self.__activateAct], 'ui')
+        self.__ui.addEricActions([self.__activateAct], 'ui')
         menu = self.__ui.getMenu("subwindow")
         menu.addAction(self.__activateAct)
         
@@ -100,7 +101,7 @@
         """
         menu = self.__ui.getMenu("subwindow")
         menu.removeAction(self.__activateAct)
-        self.__ui.removeE5Actions([self.__activateAct], 'ui')
+        self.__ui.removeEricActions([self.__activateAct], 'ui')
         self.__ui.removeSideWidget(self.__widget)
     
     def projectOpened(self):
@@ -111,9 +112,9 @@
             self.projectClosed()
         
         self.__projectOpen = True
-        self.__projectPath = self.__e5project.getProjectPath()
+        self.__projectPath = self.__ericProject.getProjectPath()
         self.__trackerFilePath = os.path.join(
-            self.__e5project.getProjectManagementDir(),
+            self.__ericProject.getProjectManagementDir(),
             TimeTracker.FileName)
         
         self.__readTrackerEntries()
@@ -138,10 +139,11 @@
         """
         if os.path.exists(self.__trackerFilePath):
             try:
-                with open(self.__trackerFilePath, "r", encoding="utf-8") as f:
-                    data = f.read()
-            except OSError as err:
-                E5MessageBox.critical(
+                with open(self.__trackerFilePath, "r") as f:
+                    jsonString = f.read()
+                entriesDataList = json.loads(jsonString)
+            except (OSError, json.JSONDecodeError) as err:
+                EricMessageBox.critical(
                     self.__ui,
                     self.tr("Read Time Tracker File"),
                     self.tr("""<p>The time tracker file <b>{0}</b> could"""
@@ -152,16 +154,16 @@
             from .TimeTrackEntry import TimeTrackEntry
             
             invalidCount = 0
-            for line in data.splitlines():
-                entry = TimeTrackEntry(self.__plugin)
-                eid = entry.fromString(line.strip())
+            for data in entriesDataList:
+                entry  = TimeTrackEntry(self.__plugin)
+                eid = entry.fromDict(data)
                 if eid > -1:
                     self.__entries[eid] = entry
                 else:
                     invalidCount += 1
             
             if invalidCount:
-                E5MessageBox.information(
+                EricMessageBox.information(
                     self.__ui,
                     self.tr("Read Time Tracker File"),
                     self.tr("""<p>The time tracker file <b>{0}</b>"""
@@ -173,24 +175,25 @@
         """
         Public slot to save the tracker entries to a file.
         
-        @keyparam filePath path and name of the file to write the entries to
-            (string)
-        @keyparam ids list of entry IDs to be written (list of integer)
+        @param filePath path and name of the file to write the entries to
+        @type str
+        @param ids list of entry IDs to be written
+        @type list of int
         """
         if not filePath:
             filePath = self.__trackerFilePath
-        entriesList = (
-            [self.__entries[eid] for eid in ids if eid in self.__entries]
+        entriesDataList = (
+            [self.__entries[eid].toDict()
+             for eid in ids if eid in self.__entries]
             if ids else
-            self.__entries.values()
+            [e.toDict() for e in self.__entries.values()]
         )
         try:
-            with open(filePath, "w", encoding="utf-8") as f:
-                for entry in entriesList:
-                    if entry.isValid():
-                        f.write(entry.toString() + "\n")
-        except OSError as err:
-            E5MessageBox.critical(
+            jsonString = json.dumps(entriesDataList, indent=2)
+            with open(filePath, "w") as f:
+                f.write(jsonString)
+        except (TypeError, OSError) as err:
+            EricMessageBox.critical(
                 self.__ui,
                 self.tr("Save Time Tracker File"),
                 self.tr("""<p>The time tracker file <b>{0}</b> could"""
@@ -205,9 +208,10 @@
         """
         try:
             with open(fname, "r", encoding="utf-8") as f:
-                data = f.read()
-        except OSError as err:
-            E5MessageBox.critical(
+                jsonString = f.read()
+            entriesDataList = json.loads(jsonString)
+        except (OSError, json.JSONDecodeError) as err:
+            EricMessageBox.critical(
                 self.__ui,
                 self.tr("Import Time Tracker File"),
                 self.tr("""<p>The time tracker file <b>{0}</b> could"""
@@ -220,9 +224,10 @@
         invalidCount = 0
         duplicateCount = 0
         entries = []
-        for line in data.splitlines():
+        
+        for data in entriesDataList:
             entry = TimeTrackEntry(self.__plugin)
-            eid = entry.fromString(line.strip())
+            eid = entry.fromDict(data)
             if eid > -1:
                 entries.append(entry)
             else:
@@ -270,7 +275,7 @@
             msg += " " + self.tr(
                 """ %n entries have been ignored.</p>""",
                 "", invalidCount + duplicateCount)
-            E5MessageBox.information(
+            EricMessageBox.information(
                 self.__ui,
                 self.tr("Import Time Tracker File"),
                 msg)
@@ -284,10 +289,14 @@
         """
         Public method to add a new tracker entry based on the given data.
         
-        @param startDateTime start date and time (QDateTime)
-        @param duration duration in minutes (integer)
-        @param task task description (string)
-        @param comment comment (string)
+        @param startDateTime start date and time
+        @type QDateTime
+        @param duration duration in minutes
+        @type int
+        @param task task description
+        @type str
+        @param comment comment
+        @type str
         """
         if not self.__plugin.getPreferences("AllowDuplicates"):
             startDateTimes = [
@@ -315,8 +324,8 @@
         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):
@@ -336,17 +345,19 @@
         Public method to stop the current tracker entry.
         
         @return tuple of the ID assigned to the stopped tracker entry and
-            the duration (integer, integer)
+            the duration
+        @rtype tuple of (int, int)
         """
         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
+                nextID = (
+                    max(self.__entries.keys()) + 1
+                    if len(self.__entries.keys()) else
+                    0
+                )
                 self.__currentEntry.setID(nextID)
                 self.__entries[nextID] = self.__currentEntry
                 if self.__plugin.getPreferences("AutoSave"):
@@ -370,7 +381,8 @@
         """
         Public method to get a reference to the current tracker entry.
         
-        @return reference to the current entry (TimeTrackEntry)
+        @return reference to the current entry
+        @rtype TimeTrackEntry
         """
         return self.__currentEntry
     
@@ -378,8 +390,10 @@
         """
         Public method to get a tracker entry given its ID.
         
-        @param eid ID of the tracker entry (integer)
-        @return entry for the given ID (TimeTrackEntry) or None
+        @param eid ID of the tracker entry
+        @type int
+        @return entry for the given ID or None
+        @rtype TimeTrackEntry
         """
         if eid in self.__entries:
             return self.__entries[eid]
@@ -390,7 +404,8 @@
         """
         Public method to delete a tracker entry given its ID.
         
-        @param eid ID of the tracker entry (integer)
+        @param eid ID of the tracker entry
+        @type int
         """
         if eid in self.__entries:
             del self.__entries[eid]
@@ -420,8 +435,8 @@
             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):
@@ -448,8 +463,8 @@
             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):
@@ -463,14 +478,16 @@
         """
         Public method to retrieve the various settings.
         
-        @param key the key of the value to get
-        @return the requested setting
+        @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 project browser.
+        Private slot to handle the activation of the time tracker widget.
         """
         uiLayoutType = self.__ui.getLayoutType()
         
@@ -482,4 +499,4 @@
             self.__ui.bottomSidebar.setCurrentWidget(self.__widget)
         else:
             self.__widget.show()
-        self.__widget.setFocus(Qt.ActiveWindowFocusReason)
+        self.__widget.setFocus(Qt.FocusReason.ActiveWindowFocusReason)

eric ide

mercurial