--- a/src/eric7/MicroPython/MicroPythonWidget.py Thu Apr 27 17:59:09 2023 +0200 +++ b/src/eric7/MicroPython/MicroPythonWidget.py Fri Apr 28 12:07:41 2023 +0200 @@ -7,6 +7,10 @@ Module implementing the MicroPython REPL widget. """ +# TODO: refactor the code such to have the MicroPythonWidget as the top level +# container and a MicroPythonReplWidget containing the REPL related stuff +# (incl. device status line and zoom widget ?) + import contextlib import functools import os @@ -57,7 +61,7 @@ HAS_QTCHART = False try: - from .MicroPythonDeviceInterface import MicroPythonDeviceInterface + from .MicroPythonSerialDeviceInterface import MicroPythonSerialDeviceInterface HAS_QTSERIALPORT = True except ImportError: @@ -211,6 +215,7 @@ DeviceVidRole = Qt.ItemDataRole.UserRole + 3 DevicePidRole = Qt.ItemDataRole.UserRole + 4 DeviceSerNoRole = Qt.ItemDataRole.UserRole + 5 + DeviceInterfaceTypeRole = Qt.ItemDataRole.UserRole + 6 dataReceived = pyqtSignal(bytes) @@ -290,10 +295,7 @@ self.__lastPort = None self.__lastDeviceType = None - if HAS_QTSERIALPORT: - self.__interface = MicroPythonDeviceInterface(self) - else: - self.__interface = None + self.__interface = None self.__device = None self.__connected = False self.__linkConnected = False @@ -324,7 +326,6 @@ self.replEdit.customContextMenuRequested.connect(self.__showContextMenu) self.__ui.preferencesChanged.connect(self.__handlePreferencesChanged) - self.__ui.preferencesChanged.connect(self.__interface.handlePreferencesChanged) self.__handlePreferencesChanged() @@ -376,6 +377,9 @@ self.deviceTypeComboBox.setItemData( index, serialNumber, self.DeviceSerNoRole ) + self.deviceTypeComboBox.setItemData( + index, "serial", self.DeviceInterfaceTypeRole + ) else: supportedMessage = self.tr("No supported devices detected.") @@ -478,6 +482,9 @@ else: self.replEdit.setLineWrapMode(QTextEdit.LineWrapMode.NoWrap) + if self.__interface is not None: + self.__interface.handlePreferencesChanged + if self.__chartWidget is not None: self.__chartWidget.preferencesChanged() @@ -622,7 +629,7 @@ @type bool """ self.__connected = connected - self.__linkConnected = self.__interface.isConnected() + self.__linkConnected = bool(self.__interface) and self.__interface.isConnected() self.deviceConnectedLed.setOn(self.__linkConnected) if self.__fileManagerWidget: @@ -723,7 +730,8 @@ self.replEdit.setFocus(Qt.FocusReason.OtherFocusReason) else: with contextlib.suppress(TypeError): - self.__interface.dataReceived.disconnect(self.__processData) + if self.__interface is not None: + self.__interface.dataReceived.disconnect(self.__processData) if not self.chartButton.isChecked() and not self.filesButton.isChecked(): self.__disconnectFromDevice() self.__device.setRepl(False) @@ -1134,16 +1142,6 @@ else: return "" - def getCurrentBoard(self): - """ - Public method to get the board name of the selected device. - - @return board name of the selected device - @rtype str - """ - boardName = self.deviceTypeComboBox.currentData(self.DeviceBoardRole) - return boardName - def getDevice(self): """ Public method to get a reference to the current device. @@ -1182,27 +1180,44 @@ @param withAutostart flag indicating to start the repl and file manager automatically @type bool + @exception ValueError raised to indicate an unsupported interface type """ from .ConnectionSelectionDialog import ConnectionSelectionDialog - port = self.getCurrentPort() - if not port: - with EricOverridenCursor(): - dlg = ConnectionSelectionDialog( - self.__unknownPorts, self.__lastPort, self.__lastDeviceType - ) - if dlg.exec() == QDialog.DialogCode.Accepted: - vid, pid, port, deviceType = dlg.getData() + interfaceType = ( + self.deviceTypeComboBox.currentData(self.DeviceInterfaceTypeRole) + or "serial" + ) # 'serial' is the default + + if interfaceType not in ("serial", "webrepl"): + raise ValueError( + "Unsupported interface type detected ('{0}')".format(interfaceType) + ) - self.deviceIconLabel.setPixmap( - Devices.getDeviceIcon(deviceType, False) + if interfaceType == "serial": + port = self.getCurrentPort() + if not port: + with EricOverridenCursor(): + dlg = ConnectionSelectionDialog( + self.__unknownPorts, self.__lastPort, self.__lastDeviceType ) - self.__device = Devices.getDevice(deviceType, self, vid, pid) + if dlg.exec() == QDialog.DialogCode.Accepted: + vid, pid, port, deviceType = dlg.getData() - self.__lastPort = port - self.__lastDeviceType = deviceType - else: - return + self.deviceIconLabel.setPixmap( + Devices.getDeviceIcon(deviceType, False) + ) + self.__device = Devices.getDevice(deviceType, self, vid, pid) + + self.__lastPort = port + self.__lastDeviceType = deviceType + else: + return + + self.__interface = MicroPythonSerialDeviceInterface(self) + elif interfaceType == "webrepl": + # TODO: not yet implemented + return if self.__interface.connectToDevice(port): deviceResponding = self.__interface.probeDevice() @@ -1250,9 +1265,13 @@ Private method to disconnect from the device. """ self.__device and self.__device.setConnected(False) - self.__interface.disconnectFromDevice() self.__setConnected(False) + if self.__interface is not None: + self.__interface.disconnectFromDevice() + self.__interface.deleteLater() + self.__interface = None + @pyqtSlot() def on_runButton_clicked(self): """