src/eric7/MicroPython/MicroPythonWidget.py

branch
eric7
changeset 9751
606ac0e26533
parent 9749
5d409223cf3f
child 9752
2b9546c0cbd9
--- a/src/eric7/MicroPython/MicroPythonWidget.py	Thu Feb 09 09:55:57 2023 +0100
+++ b/src/eric7/MicroPython/MicroPythonWidget.py	Sat Feb 11 16:59:50 2023 +0100
@@ -202,6 +202,7 @@
     DevicePortRole = Qt.ItemDataRole.UserRole + 2
     DeviceVidRole = Qt.ItemDataRole.UserRole + 3
     DevicePidRole = Qt.ItemDataRole.UserRole + 4
+    DeviceSerNoRole = Qt.ItemDataRole.UserRole + 5
 
     dataReceived = pyqtSignal(bytes)
 
@@ -282,6 +283,8 @@
         self.__linkConnected = False
         self.__setConnected(False)
 
+        self.__replBuffer = b""
+
         if not HAS_QTSERIALPORT:
             self.replEdit.setHtml(
                 self.tr(
@@ -336,6 +339,7 @@
                 portName,
                 vid,
                 pid,
+                serialNumber,
             ) in enumerate(sorted(devices), 1):
                 self.deviceTypeComboBox.addItem(
                     self.tr(
@@ -353,6 +357,9 @@
                 )
                 self.deviceTypeComboBox.setItemData(index, vid, self.DeviceVidRole)
                 self.deviceTypeComboBox.setItemData(index, pid, self.DevicePidRole)
+                self.deviceTypeComboBox.setItemData(
+                    index, serialNumber, self.DeviceSerNoRole
+                )
 
         else:
             supportedMessage = self.tr("No supported devices detected.")
@@ -386,6 +393,7 @@
             if self.__linkConnected:
                 # we are still connected, so disconnect
                 self.on_connectButton_clicked()
+            self.__device = None
 
         self.on_deviceTypeComboBox_activated(index)
         self.deviceTypeComboBox.setCurrentIndex(index)
@@ -500,14 +508,17 @@
             boardName = self.deviceTypeComboBox.itemData(index, self.DeviceBoardRole)
             vid = self.deviceTypeComboBox.itemData(index, self.DeviceVidRole)
             pid = self.deviceTypeComboBox.itemData(index, self.DevicePidRole)
+            serNo = self.deviceTypeComboBox.itemData(index, self.DeviceSerNoRole)
 
             if deviceType or (pid is not None and pid is not None):
                 self.__device = MicroPythonDevices.getDevice(
-                    deviceType, self, vid, pid, boardName
+                    deviceType, self, vid, pid, boardName=boardName, serialNumber=serNo
                 )
                 self.__device.setButtons()
 
                 self.connectButton.setEnabled(bool(deviceType))
+            else:
+                self.__device = None
 
     @pyqtSlot()
     def on_checkButton_clicked(self):
@@ -844,6 +855,9 @@
         charFormat.setFontPointSize(self.__font.pointSize())
         tc.setCharFormat(charFormat)
 
+        # add received data to the buffered one
+        data = self.__replBuffer + data
+
         index = 0
         while index < len(data):
             if data[index] == 8:  # \b
@@ -891,7 +905,7 @@
                             tc.removeSelectedText()
                             self.replEdit.setTextCursor(tc)
                         elif match.group("count") == "1":
-                            # delete to beinning of line
+                            # delete to beginning of line
                             tc.movePosition(
                                 QTextCursor.MoveOperation.StartOfLine,
                                 mode=QTextCursor.MoveMode.KeepAnchor,
@@ -909,6 +923,24 @@
                             self.replEdit.setTextCursor(tc)
                     elif action == "m":
                         self.__setCharFormat(match.group(0)[:-1].split(";"), tc)
+            elif (
+                len(data) > index + 1
+                and data[index] == 27
+                and data[index + 1 : index + 4] == b"]0;"
+            ):
+                if b"\x1b\\" in data[index + 4 :]:
+                    # 'set window title' command detected: <Esc>]0;...<Esc>\
+                    # __IGNORE_WARNING_M891__
+                    titleData = data[index + 4 :].split(b"\x1b\\")[0]
+                    title = titleData.decode()
+                    index += len(titleData) + 5  # one more is done at the end
+                    tc.deleteChar()
+                    self.replEdit.setTextCursor(tc)
+                    self.replEdit.insertPlainText(title)
+                else:
+                    # data is incomplete; buffer and stop processing
+                    self.__replBuffer = data[index:]
+                    return
             else:
                 tc.deleteChar()
                 self.replEdit.setTextCursor(tc)
@@ -917,6 +949,7 @@
             index += 1
 
         self.replEdit.ensureCursorVisible()
+        self.__replBuffer = b""
 
     def __setCharFormat(self, formatCodes, textCursor):
         """
@@ -1127,6 +1160,7 @@
         if self.__interface.connectToDevice(port):
             deviceResponding = self.__interface.probeDevice()
             self.__setConnected(deviceResponding)
+            self.__device.setConnected(deviceResponding)
             if deviceResponding:
                 if (
                     Preferences.getMicroPython("SyncTimeAfterConnect")
@@ -1161,6 +1195,7 @@
         """
         Private method to disconnect from the device.
         """
+        self.__device.setConnected(False)
         self.__interface.disconnectFromDevice()
         self.__setConnected(False)
 
@@ -1423,34 +1458,28 @@
         # populate the super menu
         hasTime = self.__device.hasTimeCommands() if self.__device else False
 
-        act = self.__superMenu.addAction(
+        self.__superMenu.addAction(
             self.tr("Show Version"), self.__showDeviceVersion
-        )
-        act.setEnabled(self.__connected)
-        act = self.__superMenu.addAction(
+        ).setEnabled(self.__connected)
+        self.__superMenu.addAction(
             self.tr("Show Implementation"), self.__showImplementation
-        )
-        act.setEnabled(self.__connected)
-        act = self.__superMenu.addAction(
+        ).setEnabled(self.__connected)
+        self.__superMenu.addAction(
             self.tr("Show Board Data"), self.__showBoardInformation
-        )
-        act.setEnabled(self.__connected)
+        ).setEnabled(self.__connected)
         self.__superMenu.addSeparator()
         if hasTime:
-            act = self.__superMenu.addAction(
+            self.__superMenu.addAction(
                 self.tr("Synchronize Time"), self.__synchronizeTime
-            )
-            act.setEnabled(self.__connected)
-            act = self.__superMenu.addAction(
+            ).setEnabled(self.__connected)
+            self.__superMenu.addAction(
                 self.tr("Show Device Time"), self.__showDeviceTime
-            )
-            act.setEnabled(self.__connected)
+            ).setEnabled(self.__connected)
         self.__superMenu.addAction(self.tr("Show Local Time"), self.__showLocalTime)
         if hasTime:
-            act = self.__superMenu.addAction(
+            self.__superMenu.addAction(
                 self.tr("Show Time"), self.__showLocalAndDeviceTime
-            )
-            act.setEnabled(self.__connected)
+            ).setEnabled(self.__connected)
         self.__superMenu.addSeparator()
         self.__superMenu.addAction(
             self.tr("Show Builtin Modules"), self.__showBuiltinModules
@@ -1458,35 +1487,32 @@
         self.__superMenu.addSeparator()
         if not OSUtilities.isWindowsPlatform():
             available = self.__mpyCrossAvailable()
-            act = self.__superMenu.addAction(
+            self.__superMenu.addAction(
                 self.tr("Compile Python File"), self.__compileFile2Mpy
-            )
-            act.setEnabled(available)
-            act = self.__superMenu.addAction(
+            ).setEnabled(available)
+            aw = ericApp().getObject("ViewManager").activeWindow()
+            self.__superMenu.addAction(
                 self.tr("Compile Current Editor"), self.__compileEditor2Mpy
-            )
-            aw = ericApp().getObject("ViewManager").activeWindow()
-            act.setEnabled(available and bool(aw))
+            ).setEnabled(available and bool(aw))
             self.__superMenu.addSeparator()
         if self.__device:
             self.__device.addDeviceMenuEntries(self.__superMenu)
             self.__superMenu.addSeparator()
             if downloadMenu is None:
                 # generic download action
-                act = self.__superMenu.addAction(
+                self.__superMenu.addAction(
                     self.tr("Download Firmware"), self.__downloadFirmware
-                )
-                act.setEnabled(self.__device.hasFirmwareUrl())
+                ).setEnabled(self.__device.hasFirmwareUrl())
             else:
                 # download sub-menu
                 self.__superMenu.addMenu(downloadMenu)
             self.__superMenu.addSeparator()
-            act = self.__superMenu.addAction(
+            self.__superMenu.addAction(
                 self.tr("Show Documentation"), self.__showDocumentation
-            )
-            act.setEnabled(self.__device.hasDocumentationUrl())
+            ).setEnabled(self.__device.hasDocumentationUrl())
             self.__superMenu.addSeparator()
-        if self.__device is not None and not self.__device.hasFlashMenuEntry():
+        ##if self.__device is not None and not self.__device.hasFlashMenuEntry():
+        if bool(UF2FlashDialog.getFoundDevices()):
             self.__superMenu.addAction(self.tr("Flash UF2 Device"), self.__flashUF2)
             self.__superMenu.addSeparator()
         self.__superMenu.addAction(
@@ -1503,46 +1529,46 @@
         """
         Private slot to show some version info about MicroPython of the device.
         """
-        try:
-            versionInfo = self.__interface.version()
-            if versionInfo:
-                msg = self.tr("<h3>Device Version Information</h3>")
-                msg += "<table>"
-                for key, value in versionInfo.items():
-                    msg += "<tr><td><b>{0}</b></td><td>{1}</td></tr>".format(
-                        key.capitalize(), value
-                    )
-                msg += "</table>"
-            else:
-                msg = self.tr("No version information available.")
-
+        data = self.__device.getDeviceData()
+        if data:
+            msg = self.tr("<h3>Device Version Information</h3>")
+            msg += "<table>"
+            for key in ("sysname", "nodename", "release", "version", "machine"):
+                msg += "<tr><td><b>{0}</b></td><td>{1}</td></tr>".format(
+                    key.capitalize(), data[key]
+                )
+            msg += "</table>"
             EricMessageBox.information(self, self.tr("Device Version Information"), msg)
-        except Exception as exc:
-            self.__showError("version()", str(exc))
+        else:
+            EricMessageBox.critical(
+                self,
+                self.tr("Device Version Information"),
+                self.tr("No version information available."),
+            )
 
     @pyqtSlot()
     def __showImplementation(self):
         """
         Private slot to show some implementation related information.
         """
-        try:
-            impInfo = self.__interface.getImplementation()
-            if impInfo["name"] == "micropython":
+        data = self.__device.getDeviceData()
+        if data:
+            if data["mpy_name"] == "micropython":
                 name = "MicroPython"
-            elif impInfo["name"] == "circuitpython":
+            elif data["mpy_name"] == "circuitpython":
                 name = "CircuitPython"
-            elif impInfo["name"] == "unknown":
+            elif data["mpy_name"] == "unknown":
                 name = self.tr("unknown")
             else:
-                name = impInfo["name"]
+                name = data["mpy_name"]
             version = (
                 self.tr("unknown")
-                if impInfo["version"] == "unknown"
-                else impInfo["version"]
+                if data["mpy_version"] == "unknown"
+                else data["mpy_version"]
             )
             variant = (
-                self.tr(" ({0})").format(impInfo["variant"])
-                if impInfo["variant"]
+                self.tr(" ({0})").format(data["mpy_variant"])
+                if data["mpy_variant"]
                 else ""
             )
 
@@ -1554,8 +1580,12 @@
                     "<p>This device contains <b>{0} {1}{2}</b>.</p>"
                 ).format(name, version, variant),
             )
-        except Exception as exc:
-            self.__showError("getImplementation()", str(exc))
+        else:
+            EricMessageBox.critical(
+                self,
+                self.tr("Device Implementation Information"),
+                self.tr("No device implementation information available."),
+            )
 
     @pyqtSlot()
     def __showBoardInformation(self):
@@ -1582,8 +1612,12 @@
         @type bool
         """
         if self.__device and self.__device.hasTimeCommands():
+            hasCPy = (
+                self.__device.checkDeviceData()
+                and self.__device.getDeviceData()["mpy_name"] == "circuitpython"
+            )
             try:
-                self.__interface.syncTime(self.__device.getDeviceType())
+                self.__interface.syncTime(self.__device.getDeviceType(), hasCPy=hasCPy)
 
                 if not quiet:
                     with EricOverridenCursor():

eric ide

mercurial