Continued implementing WiFi functionality for RP2040 based devices (set country, menu hierarchy). mpy_network

Sun, 19 Feb 2023 14:45:16 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sun, 19 Feb 2023 14:45:16 +0100
branch
mpy_network
changeset 9779
8d3c7c991085
parent 9776
210bf87ae5c7
child 9781
3112f77f722b

Continued implementing WiFi functionality for RP2040 based devices (set country, menu hierarchy).

eric7.epj file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/DeviceBase.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/Devices/RP2040Devices.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/WifiDialogs/WifiController.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.py file | annotate | diff | comparison | revisions
src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.ui file | annotate | diff | comparison | revisions
src/eric7/MicroPython/WifiDialogs/WifiStatusDialog.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/MicroPythonPage.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/MicroPythonPage.ui file | annotate | diff | comparison | revisions
src/eric7/Preferences/__init__.py file | annotate | diff | comparison | revisions
--- a/eric7.epj	Sat Feb 18 18:12:32 2023 +0100
+++ b/eric7.epj	Sun Feb 19 14:45:16 2023 +0100
@@ -348,6 +348,7 @@
       "src/eric7/MicroPython/UF2FlashDialog.ui",
       "src/eric7/MicroPython/UnknownDevicesDialog.ui",
       "src/eric7/MicroPython/WifiDialogs/WifiConnectionDialog.ui",
+      "src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.ui",
       "src/eric7/MicroPython/WifiDialogs/WifiStatusDialog.ui",
       "src/eric7/MultiProject/AddProjectDialog.ui",
       "src/eric7/MultiProject/PropertiesDialog.ui",
@@ -1316,6 +1317,7 @@
       "src/eric7/MicroPython/UnknownDevicesDialog.py",
       "src/eric7/MicroPython/WifiDialogs/WifiConnectionDialog.py",
       "src/eric7/MicroPython/WifiDialogs/WifiController.py",
+      "src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.py",
       "src/eric7/MicroPython/WifiDialogs/WifiStatusDialog.py",
       "src/eric7/MicroPython/WifiDialogs/__init__.py",
       "src/eric7/MicroPython/__init__.py",
--- a/src/eric7/MicroPython/Devices/DeviceBase.py	Sat Feb 18 18:12:32 2023 +0100
+++ b/src/eric7/MicroPython/Devices/DeviceBase.py	Sun Feb 19 14:45:16 2023 +0100
@@ -417,9 +417,24 @@
         """
         return []
 
-    ##################################################################
-    ## Methods below implement the file system commands
-    ##################################################################
+    def _showError(self, method, error):
+        """
+        Protected method to show some error message.
+
+        @param method name of the method the error occured in
+        @type str
+        @param error error message
+        @type str
+        """
+        EricMessageBox.warning(
+            self,
+            self.tr("Error handling device"),
+            self.tr(
+                "<p>There was an error communicating with the"
+                " connected device.</p><p>Method: {0}</p>"
+                "<p>Message: {1}</p>"
+            ).format(method, error),
+        )
 
     def _shortError(self, error):
         """
@@ -439,6 +454,10 @@
 
         return self.tr("Detected an error without indications.")
 
+    ##################################################################
+    ## Methods below implement the file system commands
+    ##################################################################
+
     def ls(self, dirname=""):
         """
         Public method to get a directory listing of the connected device.
--- a/src/eric7/MicroPython/Devices/RP2040Devices.py	Sat Feb 18 18:12:32 2023 +0100
+++ b/src/eric7/MicroPython/Devices/RP2040Devices.py	Sun Feb 19 14:45:16 2023 +0100
@@ -13,7 +13,7 @@
 
 from PyQt6.QtCore import QUrl, pyqtSlot
 from PyQt6.QtNetwork import QNetworkRequest
-from PyQt6.QtWidgets import QMenu
+from PyQt6.QtWidgets import QDialog, QMenu
 
 from eric7 import Globals, Preferences
 from eric7.EricGui.EricOverrideCursor import EricOverrideCursor
@@ -360,9 +360,21 @@
 """
 
     ##################################################################
-    ## Methods below implement network related methods
+    ## Methods below implement WiFi related methods
     ##################################################################
 
+    def addDeviceWifiEntries(self, menu):
+        """
+        Public method to add device specific entries to the given menu.
+
+        @param menu reference to the context menu
+        @type QMenu
+        """
+        menu.addSeparator()
+        menu.addAction(self.tr("Set Country"), self.__setCountry).setEnabled(
+            self._deviceData["wifi_type"] == "picow"
+        )
+
     def hasWifi(self):
         """
         Public method to check the availability of WiFi.
@@ -410,6 +422,7 @@
     import ubinascii
     import ujson
     import network
+    import rp2
 
     wifi = network.WLAN(network.STA_IF)
     station = {
@@ -420,6 +433,7 @@
         'mac': ubinascii.hexlify(wifi.config('mac'), ':').decode(),
         'channel': wifi.config('channel'),
         'txpower': wifi.config('txpower'),
+        'country': rp2.country(),
     }
     print(ujson.dumps(station))
 
@@ -433,6 +447,7 @@
         'channel': wifi.config('channel'),
         'txpower': wifi.config('txpower'),
         'essid': wifi.config('essid'),
+        'country': rp2.country(),
     }
     print(ujson.dumps(ap))
 
@@ -478,17 +493,21 @@
         @rtype tuple of (bool, str)
         """
         if self._deviceData["wifi_type"] == "picow":
+            country = Preferences.getMicroPython("WifiCountry").upper()
             command = """
 def connect_wifi(ssid, password):
     import network
+    import rp2
+    import ujson
     from time import sleep
-    import ujson
+
+    rp2.country({2})
 
     wifi = network.WLAN(network.STA_IF)
     wifi.active(False)
     wifi.active(True)
     wifi.connect(ssid, password)
-    max_wait = 100
+    max_wait = 140
     while max_wait:
         if wifi.status() < 0 or wifi.status() >= 3:
             break
@@ -499,7 +518,11 @@
 
 connect_wifi({0}, {1})
 del connect_wifi
-""".format(repr(ssid), repr(password if password else ""))
+""".format(
+            repr(ssid),
+            repr(password if password else ""),
+            repr(country if country else "XX"),
+        )
         elif self._deviceData["wifi_type"] == "pimoroni":
             # TODO: not yet implemented
             pass
@@ -558,6 +581,30 @@
 
         return out.decode("utf-8").strip() == "True", ""
 
+    @pyqtSlot()
+    def __setCountry(self):
+        """
+        Private slot to configure the country of the connected RP2040 device.
+
+        The country is the two letter country code.
+        """
+        from ..WifiDialogs.WifiCountryDialog import WifiCountryDialog
+
+        dlg = WifiCountryDialog()
+        if dlg.exec() == QDialog.DialogCode.Accepted:
+            country, remember = dlg.getCountry()
+            if remember:
+                Preferences.setMicroPython("WifiCountry", country)
+
+            command = """
+import rp2
+rp2.country({0})
+""".format(repr(country))
+
+            out, err = self._interface.execute(command)
+            if err:
+                self._showError("rp2.country()", err)
+
 
 def createDevice(microPythonWidget, deviceType, vid, pid, boardName, serialNumber):
     """
--- a/src/eric7/MicroPython/WifiDialogs/WifiController.py	Sat Feb 18 18:12:32 2023 +0100
+++ b/src/eric7/MicroPython/WifiDialogs/WifiController.py	Sun Feb 19 14:45:16 2023 +0100
@@ -42,13 +42,32 @@
         @rtype QMenu
         """
         wifiMenu = QMenu(self.tr("WiFi Functions"), menu)
+        wifiMenu.setTearOffEnabled(True)
         wifiMenu.addAction(self.tr("Show WiFi Status"), self.__showWifiStatus)
         wifiMenu.addSeparator()
         wifiMenu.addAction(self.tr("Connect WiFi"), self.__connectWifi)
+        wifiMenu.addAction(self.tr("Check Internet Connection"), self.__checkInternet)
         wifiMenu.addAction(self.tr("Disconnect WiFi"), self.__disconnectWifi)
+        wifiMenu.addSeparator()
+        wifiMenu.addAction(self.tr("Scan Networks"), self.__scanNetwork)
+        wifiMenu.addSeparator()
+        wifiMenu.addAction(self.tr("Write WiFi Credentials"), self.__writeCredentials)
+        wifiMenu.addAction(self.tr("Remove WiFi Credentials"), self.__removeCredentials)
+        wifiMenu.addSeparator()
+        wifiMenu.addAction(self.tr("Start WiFi Access Point"), self.__startAccessPoint)
+        wifiMenu.addAction(self.tr("Stop WiFi Access Point"), self.__stopAccessPoint)
+        wifiMenu.addSeparator()
+        wifiMenu.addAction(
+            self.tr("Deactivate Client Interface"),
+            lambda: self.__deactivateInterface("STA")
+        )
+        wifiMenu.addAction(
+            self.tr("Deactivate Access Point Interface"),
+            lambda: self.__deactivateInterface("AP")
+        )
 
         # add device specific entries (if there are any)
-        self.__device.addDeviceWifiEntries(wifiMenu)
+        self.__mpy.getDevice().addDeviceWifiEntries(wifiMenu)
 
         return wifiMenu
 
@@ -123,3 +142,68 @@
                     "<p>Reason: {0}</p>"
                 ).format(error if error else self.tr("unknown")),
             )
+
+    @pyqtSlot()
+    def __checkInternet(self):
+        """
+        Private slot to check the availability of an internet connection.
+        """
+        # TODO: not implemented yet
+        pass
+
+    @pyqtSlot()
+    def __scanNetwork(self):
+        """
+        Private slot to scan for visible WiFi networks.
+        """
+        # TODO: not implemented yet
+        pass
+
+    @pyqtSlot()
+    def __writeCredentials(self):
+        """
+        Private slot to save the WiFi login credentials to the connected device.
+
+        This will also modify the boot script to perform an automatic WiFi connection.
+        """
+        # TODO: not implemented yet
+        pass
+
+    @pyqtSlot()
+    def __removeCredentials(self):
+        """
+        Private slot to remove the saved WiFi credentials from the connected device.
+
+        This will not remove the auto-connect part of the boot script. This needs to be
+        done manually if desired.
+        """
+        # TODO: not implemented yet
+        pass
+
+    @pyqtSlot()
+    def __startAccessPoint(self):
+        """
+        Private slot to start the Access Point interface of the connected device.
+        """
+        # TODO: not implemented yet
+        pass
+
+    @pyqtSlot()
+    def __stopAccessPoint(self):
+        """
+        Private slot to stop the Access Point interface of the connected device.
+        """
+        # TODO: not implemented yet
+        pass
+
+    def __deactivateInterface(self, interface):
+        """
+        Private method to deactivate a given WiFi interface of the connected device.
+
+        @param interface designation of the interface to be deactivated (one of 'AP'
+            or 'STA')
+        @type str
+        """
+        # TODO: not implemented yet
+        pass
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.py	Sun Feb 19 14:45:16 2023 +0100
@@ -0,0 +1,61 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2023 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+
+"""
+Module implementing a dialog to enter the country code for the WiFi interface.
+"""
+
+from PyQt6.QtCore import pyqtSlot
+from PyQt6.QtWidgets import QDialog, QDialogButtonBox
+
+from eric7 import Preferences
+
+from .Ui_WifiCountryDialog import Ui_WifiCountryDialog
+
+
+class WifiCountryDialog(QDialog, Ui_WifiCountryDialog):
+    """
+    Class implementing a dialog to enter the country code for the WiFi interface.
+    """
+
+    def __init__(self, parent=None):
+        """
+        Constructor
+
+        @param parent reference to the parent widget (defaults to None)
+        @type QWidget (optional)
+        """
+        super().__init__(parent)
+        self.setupUi(self)
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(False)
+
+        self.countryEdit.setText(Preferences.getMicroPython("WifiCountry").upper())
+
+        msh = self.minimumSizeHint()
+        self.resize(max(self.width(), msh.width()), msh.height())
+
+    @pyqtSlot(str)
+    def on_countryEdit_textChanged(self, country):
+        """
+        Private slot handling a change of the country.
+
+        @param country entered country code
+        @type str
+        """
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(
+            bool(country)
+        )
+
+    def getCountry(self):
+        """
+        Public method to get the entered country code.
+
+        @return tuple containing the country code and a flag indicating to save it to
+            the settings
+        @rtype tuple of (str, bool)
+        """
+        return self.countryEdit.text().upper(), self.rememberCheckBox.isChecked()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/eric7/MicroPython/WifiDialogs/WifiCountryDialog.ui	Sun Feb 19 14:45:16 2023 +0100
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>WifiCountryDialog</class>
+ <widget class="QDialog" name="WifiCountryDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>353</width>
+    <height>106</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <property name="sizeGripEnabled">
+   <bool>true</bool>
+  </property>
+  <layout class="QGridLayout" name="gridLayout">
+   <item row="0" column="0">
+    <widget class="QLabel" name="label_13">
+     <property name="text">
+      <string>Country:</string>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="1">
+    <widget class="QLineEdit" name="countryEdit">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+       <horstretch>0</horstretch>
+       <verstretch>0</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="toolTip">
+      <string>Enter the country code for the WiFi interface</string>
+     </property>
+     <property name="maxLength">
+      <number>3</number>
+     </property>
+     <property name="clearButtonEnabled">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item row="0" column="2">
+    <spacer name="horizontalSpacer">
+     <property name="orientation">
+      <enum>Qt::Horizontal</enum>
+     </property>
+     <property name="sizeHint" stdset="0">
+      <size>
+       <width>142</width>
+       <height>20</height>
+      </size>
+     </property>
+    </spacer>
+   </item>
+   <item row="1" column="0" colspan="3">
+    <widget class="QCheckBox" name="rememberCheckBox">
+     <property name="toolTip">
+      <string>Select to remember the entered connection parameters</string>
+     </property>
+     <property name="text">
+      <string>Remember Parameters</string>
+     </property>
+    </widget>
+   </item>
+   <item row="2" 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>countryEdit</tabstop>
+  <tabstop>rememberCheckBox</tabstop>
+ </tabstops>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>WifiCountryDialog</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>WifiCountryDialog</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/WifiDialogs/WifiStatusDialog.py	Sat Feb 18 18:12:32 2023 +0100
+++ b/src/eric7/MicroPython/WifiDialogs/WifiStatusDialog.py	Sun Feb 19 14:45:16 2023 +0100
@@ -7,6 +7,8 @@
 Module implementing a dialog to show the WiFi status of the connected device.
 """
 
+import contextlib
+
 from PyQt6.QtWidgets import QDialog, QTreeWidgetItem
 
 from .Ui_WifiStatusDialog import Ui_WifiStatusDialog
@@ -68,6 +70,10 @@
                 QTreeWidgetItem(
                     header, [self.tr("Channel"), str(clientStatus["channel"])]
                 )
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(
+                        header, [self.tr("Country"), clientStatus["country"]]
+                    )
                 QTreeWidgetItem(
                     header,
                     [
@@ -104,6 +110,10 @@
                 QTreeWidgetItem(header, [self.tr("SSID"), apStatus["essid"]])
                 QTreeWidgetItem(header, [self.tr("MAC-Address"), apStatus["mac"]])
                 QTreeWidgetItem(header, [self.tr("Channel"), str(apStatus["channel"])])
+                with contextlib.suppress(KeyError):
+                    QTreeWidgetItem(
+                        header, [self.tr("Country"), apStatus["country"]]
+                    )
                 QTreeWidgetItem(
                     header,
                     [
--- a/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.py	Sat Feb 18 18:12:32 2023 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.py	Sun Feb 19 14:45:16 2023 +0100
@@ -119,13 +119,16 @@
             index = 0
         self.chartThemeComboBox.setCurrentIndex(index)
 
+        # WiFi
+        self.countryEdit.setText(Preferences.getMicroPython("WifiCountry").upper())
+        self.ssidEdit.setText(Preferences.getMicroPython("WifiName"))
+        self.passwordEdit.setText(Preferences.getMicroPython("WifiPassword"))
+        self.apSsidEdit.setText(Preferences.getMicroPython("WifiApName"))
+        self.apPasswordEdit.setText(Preferences.getMicroPython("WifiApPassword"))
+
         # MPY Cross Compiler
         self.mpyCrossPicker.setText(Preferences.getMicroPython("MpyCrossCompiler"))
 
-        # WiFi
-        self.ssidEdit.setText(Preferences.getMicroPython("WifiName"))
-        self.passwordEdit.setText(Preferences.getMicroPython("WifiPassword"))
-
         # PyBoard specifics
         self.dfuUtilPathPicker.setText(Preferences.getMicroPython("DfuUtilPath"))
 
@@ -203,13 +206,16 @@
             "ChartColorTheme", self.chartThemeComboBox.currentData()
         )
 
+        # WiFi
+        Preferences.setMicroPython("WifiCountry", self.countryEdit.text().upper())
+        Preferences.setMicroPython("WifiName", self.ssidEdit.text())
+        Preferences.setMicroPython("WifiPassword", self.passwordEdit.text())
+        Preferences.setMicroPython("WifiApName", self.apSsidEdit.text())
+        Preferences.setMicroPython("WifiApPassword", self.apPasswordEdit.text())
+
         # MPY Cross Compiler
         Preferences.setMicroPython("MpyCrossCompiler", self.mpyCrossPicker.text())
 
-        # WiFi
-        Preferences.setMicroPython("WifiName", self.ssidEdit.text())
-        Preferences.setMicroPython("WifiPassword", self.passwordEdit.text())
-
         # PyBoard specifics
         Preferences.setMicroPython("DfuUtilPath", self.dfuUtilPathPicker.text())
 
@@ -260,7 +266,7 @@
     @pyqtSlot(bool)
     def on_showPasswordButton_clicked(self, checked):
         """
-        Private slot to show or hide the password.
+        Private slot to show or hide the WiFi client password.
 
         @param checked state of the button
         @type bool
@@ -274,6 +280,23 @@
             self.showPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
             self.showPasswordButton.setToolTip(self.tr("Press to show the password"))
 
+    @pyqtSlot(bool)
+    def on_apShowPasswordButton_clicked(self, checked):
+        """
+        Private slot to show or hide the WiFi Access Point password.
+
+        @param checked state of the button
+        @type bool
+        """
+        if checked:
+            self.apPasswordEdit.setEchoMode(QLineEdit.EchoMode.Normal)
+            self.apShowPasswordButton.setIcon(EricPixmapCache.getIcon("hidePassword"))
+            self.apShowPasswordButton.setToolTip(self.tr("Press to hide the password"))
+        else:
+            self.apPasswordEdit.setEchoMode(QLineEdit.EchoMode.Password)
+            self.apShowPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword"))
+            self.apShowPasswordButton.setToolTip(self.tr("Press to show the password"))
+
 
 def create(dlg):
     """
--- a/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.ui	Sat Feb 18 18:12:32 2023 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/MicroPythonPage.ui	Sun Feb 19 14:45:16 2023 +0100
@@ -7,10 +7,10 @@
     <x>0</x>
     <y>0</y>
     <width>541</width>
-    <height>1407</height>
+    <height>1551</height>
    </rect>
   </property>
-  <layout class="QVBoxLayout" name="verticalLayout_2">
+  <layout class="QVBoxLayout" name="verticalLayout_3">
    <item>
     <widget class="QLabel" name="headerLabel">
      <property name="text">
@@ -208,6 +208,170 @@
     </widget>
    </item>
    <item>
+    <widget class="QGroupBox" name="groupBox_13">
+     <property name="title">
+      <string>WiFi</string>
+     </property>
+     <layout class="QVBoxLayout" name="verticalLayout_2">
+      <item>
+       <layout class="QHBoxLayout" name="horizontalLayout_5">
+        <item>
+         <widget class="QLabel" name="label_13">
+          <property name="text">
+           <string>Country:</string>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <widget class="QLineEdit" name="countryEdit">
+          <property name="sizePolicy">
+           <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+            <horstretch>0</horstretch>
+            <verstretch>0</verstretch>
+           </sizepolicy>
+          </property>
+          <property name="toolTip">
+           <string>Enter the country code for the WiFi interface</string>
+          </property>
+          <property name="maxLength">
+           <number>3</number>
+          </property>
+          <property name="clearButtonEnabled">
+           <bool>true</bool>
+          </property>
+         </widget>
+        </item>
+        <item>
+         <spacer name="horizontalSpacer_2">
+          <property name="orientation">
+           <enum>Qt::Horizontal</enum>
+          </property>
+          <property name="sizeHint" stdset="0">
+           <size>
+            <width>40</width>
+            <height>20</height>
+           </size>
+          </property>
+         </spacer>
+        </item>
+       </layout>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="groupBox_14">
+        <property name="title">
+         <string>Client</string>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_8">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_8">
+           <property name="text">
+            <string>Name:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1" colspan="2">
+          <widget class="QLineEdit" name="ssidEdit">
+           <property name="toolTip">
+            <string>Enter the network name (SSID) to connect to</string>
+           </property>
+           <property name="clearButtonEnabled">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_9">
+           <property name="text">
+            <string>Password:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="passwordEdit">
+           <property name="toolTip">
+            <string>Enter the network password</string>
+           </property>
+           <property name="echoMode">
+            <enum>QLineEdit::Password</enum>
+           </property>
+           <property name="clearButtonEnabled">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" 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>
+        </layout>
+       </widget>
+      </item>
+      <item>
+       <widget class="QGroupBox" name="groupBox_15">
+        <property name="title">
+         <string>Access Point</string>
+        </property>
+        <layout class="QGridLayout" name="gridLayout_9">
+         <item row="0" column="0">
+          <widget class="QLabel" name="label_10">
+           <property name="text">
+            <string>Name:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="0" column="1" colspan="2">
+          <widget class="QLineEdit" name="apSsidEdit">
+           <property name="toolTip">
+            <string>Enter the network name (SSID) to publih</string>
+           </property>
+           <property name="clearButtonEnabled">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="0">
+          <widget class="QLabel" name="label_12">
+           <property name="text">
+            <string>Password:</string>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="1">
+          <widget class="QLineEdit" name="apPasswordEdit">
+           <property name="toolTip">
+            <string>Enter the network password</string>
+           </property>
+           <property name="echoMode">
+            <enum>QLineEdit::Password</enum>
+           </property>
+           <property name="clearButtonEnabled">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+         <item row="1" column="2">
+          <widget class="QToolButton" name="apShowPasswordButton">
+           <property name="toolTip">
+            <string>Press to show the password</string>
+           </property>
+           <property name="checkable">
+            <bool>true</bool>
+           </property>
+          </widget>
+         </item>
+        </layout>
+       </widget>
+      </item>
+     </layout>
+    </widget>
+   </item>
+   <item>
     <widget class="QGroupBox" name="groupBox_3">
      <property name="title">
       <string>MPY Cross Compiler</string>
@@ -240,62 +404,6 @@
     </widget>
    </item>
    <item>
-    <widget class="QGroupBox" name="groupBox_13">
-     <property name="title">
-      <string>WiFi</string>
-     </property>
-     <layout class="QGridLayout" name="gridLayout_8">
-      <item row="0" column="0">
-       <widget class="QLabel" name="label_8">
-        <property name="text">
-         <string>Name:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="0" column="1" colspan="2">
-       <widget class="QLineEdit" name="ssidEdit">
-        <property name="toolTip">
-         <string>Enter the network name (SSID) to connect to</string>
-        </property>
-        <property name="clearButtonEnabled">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="0">
-       <widget class="QLabel" name="label_9">
-        <property name="text">
-         <string>Password:</string>
-        </property>
-       </widget>
-      </item>
-      <item row="1" column="1">
-       <widget class="QLineEdit" name="passwordEdit">
-        <property name="toolTip">
-         <string>Enter the network password</string>
-        </property>
-        <property name="echoMode">
-         <enum>QLineEdit::Password</enum>
-        </property>
-        <property name="clearButtonEnabled">
-         <bool>true</bool>
-        </property>
-       </widget>
-      </item>
-      <item row="1" 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>
-     </layout>
-    </widget>
-   </item>
-   <item>
     <widget class="QGroupBox" name="groupBox_5">
      <property name="title">
       <string>PyBoard</string>
@@ -610,10 +718,14 @@
   <tabstop>colorSchemeComboBox</tabstop>
   <tabstop>replWrapCheckBox</tabstop>
   <tabstop>chartThemeComboBox</tabstop>
-  <tabstop>mpyCrossPicker</tabstop>
+  <tabstop>countryEdit</tabstop>
   <tabstop>ssidEdit</tabstop>
   <tabstop>passwordEdit</tabstop>
   <tabstop>showPasswordButton</tabstop>
+  <tabstop>apSsidEdit</tabstop>
+  <tabstop>apPasswordEdit</tabstop>
+  <tabstop>apShowPasswordButton</tabstop>
+  <tabstop>mpyCrossPicker</tabstop>
   <tabstop>dfuUtilPathPicker</tabstop>
   <tabstop>micropythonFirmwareUrlLineEdit</tabstop>
   <tabstop>micropythonDocuUrlLineEdit</tabstop>
--- a/src/eric7/Preferences/__init__.py	Sat Feb 18 18:12:32 2023 +0100
+++ b/src/eric7/Preferences/__init__.py	Sun Feb 19 14:45:16 2023 +0100
@@ -1578,6 +1578,9 @@
         "ManualDevices": "[]",  # empty list encoded as JSON
         "WifiName": "",
         "WifiPassword": "",
+        "WifiApName": "",
+        "WifiApPassword": "",
+        "WifiCountry": "",
         # MicroPython URLs
         "MicroPythonDocuUrl": "https://docs.micropython.org/en/latest/",
         "MicroPythonFirmwareUrl": "http://micropython.org/download/",
@@ -3801,7 +3804,7 @@
             return json.loads(jsonStr)
         else:
             return None
-    elif key == "WifiPassword":
+    elif key in ("WifiPassword", "WifiApPassword"):
         return pwConvert(
             Prefs.settings.value(
                 "MicroPython/" + key, Prefs.microPythonDefaults[key]
@@ -3822,7 +3825,7 @@
     """
     if key in ["IgnoredUnknownDevices", "ManualDevices"]:
         Prefs.settings.setValue("MicroPython/" + key, json.dumps(value))
-    elif key == "WifiPassword":
+    elif key in ("WifiPassword", "WifiApPassword"):
         Prefs.settings.setValue("MicroPython/" + key, pwConvert(value, encode=True))
     else:
         Prefs.settings.setValue("MicroPython/" + key, value)

eric ide

mercurial