MicroPython mpy_network

Wed, 03 May 2023 10:12:03 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 03 May 2023 10:12:03 +0200
branch
mpy_network
changeset 10010
8a68a7a7ab88
parent 10009
61e5fe703818
child 10011
26a7d607b8f6

MicroPython
- Added a dialog for manual configuration of the WebREPL connection parameters.

eric7.epj file | annotate | diff | comparison | revisions
src/eric7/MicroPython/MicroPythonWebreplConnectionDialog.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/MicroPythonWebreplConnectionDialog.ui file | annotate | diff | comparison | revisions
src/eric7/MicroPython/MicroPythonWebreplUrlAddEditDialog.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/MicroPythonWebreplUrlsConfigDialog.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/MicroPythonWidget.py file | annotate | diff | comparison | revisions
--- a/eric7.epj	Tue May 02 18:01:34 2023 +0200
+++ b/eric7.epj	Wed May 03 10:12:03 2023 +0200
@@ -352,6 +352,7 @@
       "src/eric7/MicroPython/IgnoredDevicesDialog.ui",
       "src/eric7/MicroPython/MicroPythonFileManagerWidget.ui",
       "src/eric7/MicroPython/MicroPythonProgressInfoDialog.ui",
+      "src/eric7/MicroPython/MicroPythonWebreplConnectionDialog.ui",
       "src/eric7/MicroPython/MicroPythonWebreplUrlAddEditDialog.ui",
       "src/eric7/MicroPython/MicroPythonWebreplUrlsConfigDialog.ui",
       "src/eric7/MicroPython/MicroPythonWidget.ui",
@@ -1351,6 +1352,7 @@
       "src/eric7/MicroPython/MicroPythonProgressInfoDialog.py",
       "src/eric7/MicroPython/MicroPythonSerialDeviceInterface.py",
       "src/eric7/MicroPython/MicroPythonSerialPort.py",
+      "src/eric7/MicroPython/MicroPythonWebreplConnectionDialog.py",
       "src/eric7/MicroPython/MicroPythonWebreplDeviceInterface.py",
       "src/eric7/MicroPython/MicroPythonWebreplSocket.py",
       "src/eric7/MicroPython/MicroPythonWebreplUrlAddEditDialog.py",
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/MicroPythonWebreplConnectionDialog.py	Wed May 03 10:12:03 2023 +0200
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a dialog to enter the WebREPL connection parameters.
+"""
+
+from PyQt6.QtCore import pyqtSlot
+from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QLineEdit
+
+from eric7.EricGui import EricPixmapCache
+
+from .Devices import getSupportedDevices
+from .Ui_MicroPythonWebreplConnectionDialog import Ui_MicroPythonWebreplConnectionDialog
+
+
+class MicroPythonWebreplConnectionDialog(
+    QDialog, Ui_MicroPythonWebreplConnectionDialog
+):
+    """
+    Class implementing a dialog to enter the WebREPL connection parameters.
+    """
+
+    def __init__(self, currentWebreplUrl, currentType, parent=None):
+        """
+        Constructor
+
+        @param currentWebreplUrl WebREPL URL most recently configured
+        @type str
+        @param currentType device type most recently selected
+        @type str
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        self.deviceTypeComboBox.addItem("", "")
+        for board, description in sorted(getSupportedDevices(), key=lambda x: x[1]):
+            self.deviceTypeComboBox.addItem(description, board)
+
+        self.showPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+
+        self.hostEdit.textChanged.connect(self.__updateOkButton)
+        self.portEdit.textChanged.connect(self.__updateOkButton)
+        self.deviceTypeComboBox.currentIndexChanged.connect(self.__updateOkButton)
+
+        if currentWebreplUrl:
+            url = currentWebreplUrl.replace("ws://", "")
+            password, hostPort = url.split("@", 1) if "@" in url else ("", url)
+            host, port = hostPort.split(":", 1) if ":" in hostPort else (hostPort, "")
+            self.hostEdit.setText(host)
+            self.portEdit.setText(port)
+            self.passwordEdit.setText(password)
+
+            typeIndex = self.deviceTypeComboBox.findData(currentType)
+            self.deviceTypeComboBox.setCurrentIndex(typeIndex)
+        else:
+            self.__updateOkButton()
+
+        msh = self.minimumSizeHint()
+        self.resize(max(self.width(), msh.width()), msh.height())
+
+    @pyqtSlot()
+    def __updateOkButton(self):
+        """
+        Private slot to update the enabled state of the OK button.
+        """
+        port = self.portEdit.text()
+        if port == "":
+            portOk = True
+        else:
+            try:
+                portNo = int(port)
+                portOk = 1024 < portNo <= 65535
+            except ValueError:
+                portOk = False
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
+            bool(self.hostEdit.text())
+            and portOk
+            and bool(self.deviceTypeComboBox.currentData())
+        )
+
+    @pyqtSlot(bool)
+    def on_showPasswordButton_clicked(self, checked):
+        """
+        Private slot to show or hide the password.
+
+        @param checked state of the button
+        @type bool
+        """
+        if checked:
+            self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Normal)
+            self.showPasswordButton.setIcon(EricPixmapCache.getIcon("hidePassword"))
+            self.showPasswordButton.setToolTip(self.tr("Press to hide the password."))
+        else:
+            self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Password)
+            self.showPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+            self.showPasswordButton.setToolTip(self.tr("Press to show the password."))
+
+    def getWebreplConnectionParameters(self):
+        """
+        Public method to retrieve the entered WebREPL connection data.
+
+        @return tuple containing the URL and device type for the WebREPL connection
+        @rtype tuple of (str, str)
+        """
+        password = self.passwordEdit.text()
+        host = self.hostEdit.text()
+        port = self.portEdit.text()
+
+        if password and port:
+            url = f"ws://{password}@{host}:{port}"
+        elif password:
+            url = f"ws://{password}@{host}"
+        elif port:
+            url = f"ws://{host}:{port}"
+        else:
+            url = f"ws://{host}"
+
+        return (url, self.deviceTypeComboBox.currentData())
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/MicroPythonWebreplConnectionDialog.ui	Wed May 03 10:12:03 2023 +0200
@@ -0,0 +1,157 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MicroPythonWebreplConnectionDialog</class>
+ <widget class="QDialog" name="MicroPythonWebreplConnectionDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>400</width>
+    <height>172</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>WebREPL Connection</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label_3">
+     <property name="text">
+      <string>Host:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1" colspan="2">
+    <widget class="QLineEdit" name="hostEdit">
+     <property name="toolTip">
+      <string>Enter the host name or IPv4 address of the device.</string>
+     </property>
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="0">
+    <widget class="QLabel" name="label_4">
+     <property name="text">
+      <string>Port:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="1" column="1" colspan="2">
+    <widget class="QLineEdit" name="portEdit">
+     <property name="toolTip">
+      <string>Enter the port of the WebREPL (empty for default port 8266).</string>
+     </property>
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="0">
+    <widget class="QLabel" name="label_5">
+     <property name="text">
+      <string>Password:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="1">
+    <widget class="QLineEdit" name="passwordEdit">
+     <property name="toolTip">
+      <string>Enter the password for this device connection.</string>
+     </property>
+     <property name="echoMode">
+      <enum>QLineEdit::Password</enum>
+     </property>
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="2" column="2">
+    <widget class="QToolButton" name="showPasswordButton">
+     <property name="toolTip">
+      <string>Press to show the password.</string>
+     </property>
+     <property name="checkable">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="0">
+    <widget class="QLabel" name="label_6">
+     <property name="text">
+      <string>Device Type:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="3" column="1" colspan="2">
+    <widget class="QComboBox" name="deviceTypeComboBox">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="toolTip">
+      <string>Select the device type</string>
+     </property>
+    </widget>
+   </item>
+   <item row="4" column="0" colspan="3">
+    <widget class="QDialogButtonBox" name="buttonBox">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="standardButtons">
+      <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <tabstops>
+  <tabstop>hostEdit</tabstop>
+  <tabstop>portEdit</tabstop>
+  <tabstop>passwordEdit</tabstop>
+  <tabstop>deviceTypeComboBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>MicroPythonWebreplConnectionDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>248</x>
+     <y>254</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>157</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>MicroPythonWebreplConnectionDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>316</x>
+     <y>260</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>286</x>
+     <y>274</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
--- a/src/eric7/MicroPython/MicroPythonWebreplUrlAddEditDialog.py	Tue May 02 18:01:34 2023 +0200
+++ b/src/eric7/MicroPython/MicroPythonWebreplUrlAddEditDialog.py	Wed May 03 10:12:03 2023 +0200
@@ -53,6 +53,7 @@
             self.__populateFields(connectionParams)
         else:
             self.__editName = ""
+            self.__updateOkButton()
 
         msh = self.minimumSizeHint()
         self.resize(max(self.width(), msh.width()), msh.height())
@@ -68,14 +69,8 @@
         self.descriptionEdit.setText(params[1])
 
         url = params[2].replace("ws://", "")
-        if "@" in url:
-            password, hostPort = url.split("@", 1)
-        else:
-            password, hostPort = "", url
-        if ":" in hostPort:
-            host, port = hostPort.split(":", 1)
-        else:
-            host, port = hostPort, ""
+        password, hostPort = url.split("@", 1) if "@" in url else ("", url)
+        host, port = hostPort.split(":", 1) if ":" in hostPort else (hostPort, "")
         self.hostEdit.setText(host)
         self.portEdit.setText(port)
         self.passwordEdit.setText(password)
@@ -115,9 +110,9 @@
         """
         Public method to retrieve the entered WebREPL connection data.
 
-        @return tuple containing the name, description and URL for the WebREPL
-            connection
-        @rtype tuple of (str, str, str)
+        @return tuple containing the name, description, URL and device type for
+            the WebREPL connection
+        @rtype tuple of (str, str, str, str)
         """
         password = self.passwordEdit.text()
         host = self.hostEdit.text()
--- a/src/eric7/MicroPython/MicroPythonWebreplUrlsConfigDialog.py	Tue May 02 18:01:34 2023 +0200
+++ b/src/eric7/MicroPython/MicroPythonWebreplUrlsConfigDialog.py	Wed May 03 10:12:03 2023 +0200
@@ -35,12 +35,12 @@
         super().__init__(parent)
         self.setupUi(self)
 
-        for name in webreplDict:
+        for name, data in webreplDict.items():
             itm = QTreeWidgetItem(
                 self.webreplUrlsList,
-                [name, webreplDict[name]["description"], webreplDict[name]["url"]],
+                [name, data["description"], data["url"]],
             )
-            itm.setData(0, Qt.ItemDataRole.UserRole, webreplDict["device_type"])
+            itm.setData(0, Qt.ItemDataRole.UserRole, data["device_type"])
 
         self.__sortItems()
         self.__resizeColumns()
--- a/src/eric7/MicroPython/MicroPythonWidget.py	Tue May 02 18:01:34 2023 +0200
+++ b/src/eric7/MicroPython/MicroPythonWidget.py	Wed May 03 10:12:03 2023 +0200
@@ -298,6 +298,8 @@
         self.__lastPort = None
         self.__lastDeviceType = None
 
+        self.__lastWebreplUrl = None
+
         self.__interface = None
         self.__device = None
         self.__connected = False
@@ -428,12 +430,13 @@
             self.deviceTypeComboBox.setItemData(
                 index, webreplUrlsDict[name]["url"], self.DeviceWebreplUrlRole
             )
-        if webreplUrlsDict:
-            webreplMessage = self.tr(
+        webreplMessage = (
+            self.tr(
                 "\n%n WebREPL connection(s) defined.", "", len(webreplUrlsDict)
             )
-        else:
-            webreplMessage = ""
+            if webreplUrlsDict
+            else ""
+        )
 
         self.deviceInfoLabel.setText(supportedMessage + unknownMessage + webreplMessage)
 
@@ -527,7 +530,7 @@
         Private slot to configure the list of selectable WebREPL URLs.
         """
         from .MicroPythonWebreplUrlsConfigDialog import (
-            MicroPythonWebreplUrlsConfigDialog
+            MicroPythonWebreplUrlsConfigDialog,
         )
 
         webreplUrlsDict = Preferences.getMicroPython("WebreplUrls")
@@ -808,7 +811,7 @@
         """
         self.replEdit.clear()
         if bool(self.__interface) and self.__interface.isConnected():
-           self.__interface.write(b"\r")
+            self.__interface.write(b"\r")
 
     @pyqtSlot()
     def __paste(self, mode=QClipboard.Mode.Clipboard):
@@ -891,7 +894,7 @@
                 tc.movePosition(QTextCursor.MoveOperation.EndOfLine)
                 self.replEdit.setTextCursor(tc)
             if bool(self.__interface) and self.__interface.isConnected():
-               self.__interface.write(msg)
+                self.__interface.write(msg)
             return True
         else:
             # standard event processing
@@ -1228,6 +1231,9 @@
         @exception ValueError raised to indicate an unsupported interface type
         """
         from .ConnectionSelectionDialog import ConnectionSelectionDialog
+        from .MicroPythonWebreplConnectionDialog import (
+            MicroPythonWebreplConnectionDialog,
+        )
 
         interfaceType = (
             self.deviceTypeComboBox.currentData(self.DeviceInterfaceTypeRole)
@@ -1263,8 +1269,22 @@
         elif interfaceType == "webrepl":
             port = self.deviceTypeComboBox.currentData(self.DeviceWebreplUrlRole)
             if not port:
-                # TODO: implement Webrepl parameter dialog (ws:// URL)
-                return
+                with EricOverridenCursor():
+                    dlg = MicroPythonWebreplConnectionDialog(
+                        self.__lastWebreplUrl, self.__lastDeviceType
+                    )
+                    if dlg.exec() == QDialog.DialogCode.Accepted:
+                        port, deviceType = dlg.getWebreplConnectionParameters()
+
+                        self.deviceIconLabel.setPixmap(
+                            Devices.getDeviceIcon(deviceType, False)
+                        )
+                        self.__device = Devices.getDevice(deviceType, self, None, None)
+
+                        self.__lastWebreplUrl = port
+                        self.__lastDeviceType = deviceType
+                    else:
+                        return
 
             self.__interface = MicroPythonWebreplDeviceInterface(self)
 

eric ide

mercurial