MqttMonitor/MqttConnectionProfilesDialog.py

branch
eric7
changeset 123
3d7e63ed4fd1
parent 114
8c0e9e602124
child 127
8982ef7b7d67
--- a/MqttMonitor/MqttConnectionProfilesDialog.py	Thu Dec 30 16:36:40 2021 +0100
+++ b/MqttMonitor/MqttConnectionProfilesDialog.py	Wed Sep 21 09:42:33 2022 +0200
@@ -12,8 +12,12 @@
 
 from PyQt6.QtCore import pyqtSlot, Qt, QUuid
 from PyQt6.QtWidgets import (
-    QDialog, QDialogButtonBox, QAbstractButton, QListWidgetItem, QInputDialog,
-    QLineEdit
+    QDialog,
+    QDialogButtonBox,
+    QAbstractButton,
+    QListWidgetItem,
+    QInputDialog,
+    QLineEdit,
 )
 
 from EricWidgets import EricMessageBox
@@ -32,10 +36,11 @@
     """
     Class implementing a dialog to edit the MQTT connection profiles.
     """
+
     def __init__(self, profiles, currentProfile="", parent=None):
         """
         Constructor
-        
+
         @param profiles dictionary containing dictionaries containing the
             connection parameters. Each entry must have the keys
             "BrokerAddress", "BrokerPort", "ClientId", "Protocol",
@@ -51,66 +56,72 @@
         """
         super().__init__(parent)
         self.setupUi(self)
-        
+
         self.__profiles = collections.defaultdict(self.__defaultProfile)
         self.__profiles.update(copy.deepcopy(profiles))
         self.__profilesChanged = False
-        
+
         self.plusButton.setIcon(UI.PixmapCache.getIcon("plus"))
         self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy"))
         self.minusButton.setIcon(UI.PixmapCache.getIcon("minus"))
         self.showPasswordButton.setIcon(UI.PixmapCache.getIcon("showPassword"))
-        self.willPropertiesButton.setIcon(
-            UI.PixmapCache.getIcon("listSelection"))
-        
+        self.willPropertiesButton.setIcon(UI.PixmapCache.getIcon("listSelection"))
+
         self.tlsCertsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
         self.tlsCertsFilePicker.setFilters(
-            self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
-        self.tlsSelfSignedCertsFilePicker.setMode(
-            EricPathPickerModes.OPEN_FILE_MODE)
+            self.tr("Certificate Files (*.crt *.pem);;All Files (*)")
+        )
+        self.tlsSelfSignedCertsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
         self.tlsSelfSignedCertsFilePicker.setFilters(
-            self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
+            self.tr("Certificate Files (*.crt *.pem);;All Files (*)")
+        )
         self.tlsSelfSignedClientCertFilePicker.setMode(
-            EricPathPickerModes.OPEN_FILE_MODE)
+            EricPathPickerModes.OPEN_FILE_MODE
+        )
         self.tlsSelfSignedClientCertFilePicker.setFilters(
-            self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
+            self.tr("Certificate Files (*.crt *.pem);;All Files (*)")
+        )
         self.tlsSelfSignedClientKeyFilePicker.setMode(
-            EricPathPickerModes.OPEN_FILE_MODE)
+            EricPathPickerModes.OPEN_FILE_MODE
+        )
         self.tlsSelfSignedClientKeyFilePicker.setFilters(
-            self.tr("Key Files (*.key *.pem);;All Files (*)"))
-        
+            self.tr("Key Files (*.key *.pem);;All Files (*)")
+        )
+
         self.profileTabWidget.setCurrentIndex(0)
-        
+
         self.connectPropertiesButton.clicked[bool].connect(
-            self.__propertiesTypeSelected)
+            self.__propertiesTypeSelected
+        )
         self.disconnectPropertiesButton.clicked[bool].connect(
-            self.__propertiesTypeSelected)
-        
+            self.__propertiesTypeSelected
+        )
+
         if len(self.__profiles) == 0:
             self.minusButton.setEnabled(False)
             self.copyButton.setEnabled(False)
-        
+
         self.profileFrame.setEnabled(False)
         self.__populatingProfile = False
         self.__deletingProfile = False
-        
+
         self.__populateProfilesList(currentProfile=currentProfile)
-    
+
     @pyqtSlot(str)
     def on_profileEdit_textChanged(self, name):
         """
         Private slot to handle changes of the profile name.
-        
+
         @param name name of the profile
         @type str
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(QAbstractButton)
     def on_profileButtonBox_clicked(self, button):
         """
         Private slot handling presses of the profile buttons.
-        
+
         @param button reference to the pressed button
         @type QAbstractButton
         """
@@ -119,22 +130,22 @@
         ):
             currentProfile = self.__applyProfile()
             self.__populateProfilesList(currentProfile=currentProfile)
-        
+
         elif button == self.profileButtonBox.button(
             QDialogButtonBox.StandardButton.Reset
         ):
             self.__resetProfile()
-        
+
         elif button == self.profileButtonBox.button(
-                QDialogButtonBox.StandardButton.RestoreDefaults
+            QDialogButtonBox.StandardButton.RestoreDefaults
         ):
             self.__populateProfileDefault()
-    
+
     @pyqtSlot(QListWidgetItem, QListWidgetItem)
     def on_profilesList_currentItemChanged(self, current, previous):
         """
         Private slot to handle a change of the current profile.
-        
+
         @param current new current item
         @type QListWidgetItem
         @param previous previous current item
@@ -142,29 +153,32 @@
         """
         self.minusButton.setEnabled(current is not None)
         self.copyButton.setEnabled(current is not None)
-        
+
         if (
-            current is not previous and
-            not self.__deletingProfile and
-            self.__isChangedProfile()
+            current is not previous
+            and not self.__deletingProfile
+            and self.__isChangedProfile()
         ):
             # modified profile belongs to previous
             yes = EricMessageBox.yesNo(
                 self,
                 self.tr("Changed Connection Profile"),
-                self.tr("""The current profile has unsaved changes."""
-                        """ Shall these be saved?"""),
+                self.tr(
+                    """The current profile has unsaved changes."""
+                    """ Shall these be saved?"""
+                ),
                 icon=EricMessageBox.Warning,
-                yesDefault=True)
+                yesDefault=True,
+            )
             if yes:
                 self.__applyProfile()
-        
+
         if current:
             profileName = current.text()
             self.__populateProfile(profileName)
         else:
             self.__clearProfile()
-    
+
     @pyqtSlot()
     def on_plusButton_clicked(self):
         """
@@ -174,21 +188,23 @@
             self,
             self.tr("New Connection Profile"),
             self.tr("Enter name for the new Connection Profile:"),
-            QLineEdit.EchoMode.Normal)
+            QLineEdit.EchoMode.Normal,
+        )
         if ok and bool(profileName):
             if profileName in self.__profiles:
                 EricMessageBox.warning(
                     self,
                     self.tr("New Connection Profile"),
-                    self.tr("""<p>A connection named <b>{0}</b> exists"""
-                            """ already. Aborting...</p>""").format(
-                        profileName))
+                    self.tr(
+                        """<p>A connection named <b>{0}</b> exists"""
+                        """ already. Aborting...</p>"""
+                    ).format(profileName),
+                )
             else:
                 itm = QListWidgetItem(profileName, self.profilesList)
                 self.profilesList.setCurrentItem(itm)
-                self.brokerAddressEdit.setFocus(
-                    Qt.FocusReason.OtherFocusReason)
-    
+                self.brokerAddressEdit.setFocus(Qt.FocusReason.OtherFocusReason)
+
     @pyqtSlot()
     def on_copyButton_clicked(self):
         """
@@ -201,27 +217,30 @@
                 self,
                 self.tr("Copy Connection Profile"),
                 self.tr("Enter name for the copied Connection Profile:"),
-                QLineEdit.EchoMode.Normal)
+                QLineEdit.EchoMode.Normal,
+            )
             if ok and bool(newProfileName):
                 if newProfileName in self.__profiles:
                     EricMessageBox.warning(
                         self,
                         self.tr("Copy Connection Profile"),
-                        self.tr("""<p>A connection named <b>{0}</b> exists"""
-                                """ already. Aborting...</p>""").format(
-                            newProfileName))
+                        self.tr(
+                            """<p>A connection named <b>{0}</b> exists"""
+                            """ already. Aborting...</p>"""
+                        ).format(newProfileName),
+                    )
                 else:
                     connectionProfile = self.__defaultProfile()
                     connectionProfile.update(
-                        copy.deepcopy(self.__profiles[profileName]))
+                        copy.deepcopy(self.__profiles[profileName])
+                    )
                     self.__profiles[newProfileName] = connectionProfile
                     self.__profilesChanged = True
-                    
+
                     itm = QListWidgetItem(newProfileName, self.profilesList)
                     self.profilesList.setCurrentItem(itm)
-                    self.brokerAddressEdit.setFocus(
-                        Qt.FocusReason.OtherFocusReason)
-    
+                    self.brokerAddressEdit.setFocus(Qt.FocusReason.OtherFocusReason)
+
     @pyqtSlot()
     def on_minusButton_clicked(self):
         """
@@ -233,8 +252,10 @@
             yes = EricMessageBox.yesNo(
                 self,
                 self.tr("Delete Connection Profile"),
-                self.tr("""<p>Shall the Connection Profile <b>{0}</b>"""
-                        """ really be deleted?</p>""").format(profileName)
+                self.tr(
+                    """<p>Shall the Connection Profile <b>{0}</b>"""
+                    """ really be deleted?</p>"""
+                ).format(profileName),
             )
             if yes:
                 self.__deletingProfile = True
@@ -242,13 +263,13 @@
                 self.__profilesChanged = True
                 self.__populateProfilesList()
                 self.__deletingProfile = False
-        
+
         self.profilesList.setFocus(Qt.FocusReason.OtherFocusReason)
-    
+
     def getProfiles(self):
         """
         Public method to return a dictionary of profiles.
-        
+
         @return dictionary containing dictionaries containing the defined
             connection profiles. Each entry has the keys "BrokerAddress",
             "BrokerPort", "ClientId", "Protocol", "ConnectionTimeout",
@@ -261,11 +282,11 @@
         profilesDict = {}
         profilesDict.update(copy.deepcopy(dict(self.__profiles)))
         return profilesDict
-    
+
     def __applyProfile(self):
         """
         Private method to apply the entered data to the list of profiles.
-        
+
         @return name of the applied profile
         @rtype str
         """
@@ -278,20 +299,21 @@
         else:
             # should never happen
             protocol = MqttProtocols.MQTTv311
-        
+
         if protocol == MqttProtocols.MQTTv5:
             if self.connectPropertiesButton.isChecked():
-                self.__userProperties["connect"] = (
-                    self.propertiesWidget.getProperties())
+                self.__userProperties["connect"] = self.propertiesWidget.getProperties()
             else:
-                self.__userProperties["disconnect"] = (
-                    self.propertiesWidget.getProperties())
-            self.__userProperties["use_connect"] = (
-                self.samePropertiesCheckBox.isChecked())
+                self.__userProperties[
+                    "disconnect"
+                ] = self.propertiesWidget.getProperties()
+            self.__userProperties[
+                "use_connect"
+            ] = self.samePropertiesCheckBox.isChecked()
         else:
             self.__userProperties = {}
             self.__willProperties = []
-        
+
         profileName = self.profileEdit.text()
         connectionProfile = {
             "BrokerAddress": self.brokerAddressEdit.text(),
@@ -318,22 +340,25 @@
             if self.tlsCertsFileButton.isChecked():
                 connectionProfile["TlsCaCert"] = self.tlsCertsFilePicker.text()
             elif self.tlsSelfSignedCertsButton.isChecked():
-                connectionProfile["TlsCaCert"] = (
-                    self.tlsSelfSignedCertsFilePicker.text())
-                connectionProfile["TlsClientCert"] = (
-                    self.tlsSelfSignedClientCertFilePicker.text())
-                connectionProfile["TlsClientKey"] = (
-                    self.tlsSelfSignedClientKeyFilePicker.text())
-        
+                connectionProfile[
+                    "TlsCaCert"
+                ] = self.tlsSelfSignedCertsFilePicker.text()
+                connectionProfile[
+                    "TlsClientCert"
+                ] = self.tlsSelfSignedClientCertFilePicker.text()
+                connectionProfile[
+                    "TlsClientKey"
+                ] = self.tlsSelfSignedClientKeyFilePicker.text()
+
         self.__profiles[profileName] = connectionProfile
         self.__profilesChanged = True
-        
+
         return profileName
-    
+
     def __defaultProfile(self):
         """
         Private method to populate non-existing profile items.
-        
+
         @return default dictionary entry
         @rtype dict
         """
@@ -343,13 +368,13 @@
             defaultProfile["BrokerPort"] = 8883
         else:
             defaultProfile["BrokerPort"] = 1883
-        
+
         return defaultProfile
-    
+
     def __populateProfilesList(self, currentProfile=""):
         """
         Private method to populate the list of defined profiles.
-        
+
         @param currentProfile name of the current profile
         @type str
         """
@@ -357,111 +382,114 @@
             currentItem = self.profilesList.currentItem()
             if currentItem:
                 currentProfile = currentItem.text()
-        
+
         self.profilesList.clear()
         self.profilesList.addItems(sorted(self.__profiles.keys()))
-        
+
         if currentProfile:
             items = self.profilesList.findItems(
-                currentProfile, Qt.MatchFlag.MatchExactly)
+                currentProfile, Qt.MatchFlag.MatchExactly
+            )
             if items:
                 self.profilesList.setCurrentItem(items[0])
-        
+
         if len(self.__profiles) == 0:
             self.profileFrame.setEnabled(False)
-    
+
     def __populateProfile(self, profileName):
         """
         Private method to populate the profile data entry fields.
-        
+
         @param profileName name of the profile to get data from
         @type str
         """
         connectionProfile = self.__defaultProfile()
         if profileName:
             connectionProfile.update(self.__profiles[profileName])
-        
+
         self.__populatingProfile = True
         if profileName is not None:
             self.profileEdit.setText(profileName)
         self.brokerAddressEdit.setText(connectionProfile["BrokerAddress"])
         self.brokerPortSpinBox.setValue(connectionProfile["BrokerPort"])
         self.clientIdEdit.setText(connectionProfile["ClientId"])
-        
+
         # general tab
         self.mqttv31Button.setChecked(
-            connectionProfile["Protocol"] == MqttProtocols.MQTTv31)
+            connectionProfile["Protocol"] == MqttProtocols.MQTTv31
+        )
         self.mqttv311Button.setChecked(
-            connectionProfile["Protocol"] == MqttProtocols.MQTTv311)
+            connectionProfile["Protocol"] == MqttProtocols.MQTTv311
+        )
         self.mqttv5Button.setChecked(
-            connectionProfile["Protocol"] == MqttProtocols.MQTTv5)
+            connectionProfile["Protocol"] == MqttProtocols.MQTTv5
+        )
         self.on_mqttv5Button_toggled(self.mqttv5Button.isChecked())
-        self.connectionTimeoutSpinBox.setValue(
-            connectionProfile["ConnectionTimeout"])
+        self.connectionTimeoutSpinBox.setValue(connectionProfile["ConnectionTimeout"])
         self.keepaliveSpinBox.setValue(connectionProfile["Keepalive"])
         self.cleanSessionCheckBox.setChecked(connectionProfile["CleanSession"])
-        
+
         # user credentials tab
         self.usernameEdit.setText(connectionProfile["Username"])
         self.passwordEdit.setText(
-            pwConvert(connectionProfile["Password"], encode=False))
-        
+            pwConvert(connectionProfile["Password"], encode=False)
+        )
+
         # will tab
         self.willTopicEdit.setText(connectionProfile["WillTopic"])
         self.willMessageEdit.setPlainText(connectionProfile["WillMessage"])
         self.willQosSpinBox.setValue(connectionProfile["WillQos"])
         self.willRetainCheckBox.setChecked(connectionProfile["WillRetain"])
         self.__willProperties = copy.deepcopy(
-            connectionProfile.get("WillProperties", []))
-        
+            connectionProfile.get("WillProperties", [])
+        )
+
         # SSL/TLS tab
         self.tlsGroupBox.setChecked(connectionProfile["TlsEnable"])
-        if (
-            connectionProfile["TlsCaCert"] and
-            connectionProfile["TlsClientCert"]
-        ):
+        if connectionProfile["TlsCaCert"] and connectionProfile["TlsClientCert"]:
             self.tlsSelfSignedCertsButton.setChecked(True)
-            self.tlsSelfSignedCertsFilePicker.setText(
-                connectionProfile["TlsCaCert"])
+            self.tlsSelfSignedCertsFilePicker.setText(connectionProfile["TlsCaCert"])
             self.tlsSelfSignedClientCertFilePicker.setText(
-                connectionProfile["TlsClientCert"])
+                connectionProfile["TlsClientCert"]
+            )
             self.tlsSelfSignedClientKeyFilePicker.setText(
-                connectionProfile["TlsClientKey"])
+                connectionProfile["TlsClientKey"]
+            )
         elif connectionProfile["TlsCaCert"]:
             self.tlsCertsFileButton.setChecked(True)
             self.tlsCertsFilePicker.setText(connectionProfile["TlsCaCert"])
         else:
             self.tlsDefaultCertsButton.setChecked(True)
-        
+
         # user properties tab
         self.__userProperties = copy.deepcopy(
-            connectionProfile.get("UserProperties", {}))
+            connectionProfile.get("UserProperties", {})
+        )
         if not self.__userProperties:
             self.__userProperties = {
                 "connect": [],
                 "disconnect": [],
                 "use_connect": True,
             }
-        
+
         if connectionProfile["Protocol"] == MqttProtocols.MQTTv5:
             self.connectPropertiesButton.setChecked(True)
-            self.propertiesWidget.setProperties(
-                self.__userProperties["connect"])
-            self.samePropertiesCheckBox.setChecked(
-                self.__userProperties["use_connect"])
+            self.propertiesWidget.setProperties(self.__userProperties["connect"])
+            self.samePropertiesCheckBox.setChecked(self.__userProperties["use_connect"])
             self.disconnectPropertiesButton.setEnabled(
-                not self.__userProperties["use_connect"])
+                not self.__userProperties["use_connect"]
+            )
         else:
             self.propertiesWidget.clear()
-        
+
         self.__populatingProfile = False
-        
+
         self.showPasswordButton.setChecked(False)
         self.profileFrame.setEnabled(True)
         self.__updateApplyButton()
-        
+
         self.profileTabWidget.setCurrentIndex(0)
-    
+
     def __clearProfile(self):
         """
         Private method to clear the profile data entry fields.
@@ -489,7 +517,7 @@
         self.tlsSelfSignedCertsFilePicker.setText("")
         self.tlsSelfSignedClientCertFilePicker.setText("")
         self.tlsSelfSignedClientKeyFilePicker.setText("")
-        
+
         self.__userProperties = {
             "connect": [],
             "disconnect": [],
@@ -499,13 +527,13 @@
         self.samePropertiesCheckBox.setChecked(True)
         self.connectPropertiesButton.setChecked(True)
         self.disconnectPropertiesButton.setEnabled(False)
-        
+
         self.__populatingProfile = False
-        
+
         self.showPasswordButton.setChecked(False)
         self.profileFrame.setEnabled(False)
         self.__updateApplyButton()
-    
+
     def __resetProfile(self):
         """
         Private method to reset the profile data entry fields to their stored
@@ -514,26 +542,26 @@
         profileName = self.profileEdit.text()
         if profileName in self.__profiles:
             self.__populateProfile(profileName)
-    
+
     def __populateProfileDefault(self):
         """
         Private method to populate the profile data entry fields with default
         profile values.
         """
         self.__populateProfile(None)
-    
+
     def __isChangedProfile(self):
         """
         Private method to check, if the currently shown profile contains some
         changed data.
-        
+
         @return flag indicating changed data
         @rtype bool
         """
         profileName = self.profileEdit.text()
         if profileName == "":
             return False
-        
+
         elif profileName in self.__profiles:
             if self.mqttv31Button.isChecked():
                 protocol = MqttProtocols.MQTTv31
@@ -544,98 +572,97 @@
             else:
                 # should never happen
                 protocol = MqttProtocols.MQTTv311
-            
+
             connectionProfile = self.__defaultProfile()
             connectionProfile.update(self.__profiles[profileName])
             changed = (
-                self.brokerAddressEdit.text() !=
-                connectionProfile["BrokerAddress"] or
-                self.brokerPortSpinBox.value() !=
-                connectionProfile["BrokerPort"] or
-                self.clientIdEdit.text() != connectionProfile["ClientId"] or
-                protocol != connectionProfile["Protocol"] or
-                self.connectionTimeoutSpinBox.value() !=
-                connectionProfile["ConnectionTimeout"] or
-                self.keepaliveSpinBox.value() !=
-                connectionProfile["Keepalive"] or
-                self.cleanSessionCheckBox.isChecked() !=
-                connectionProfile["CleanSession"] or
-                self.usernameEdit.text() != connectionProfile["Username"] or
-                self.passwordEdit.text() !=
-                pwConvert(connectionProfile["Password"], encode=False) or
-                self.willTopicEdit.text() != connectionProfile["WillTopic"] or
-                self.willMessageEdit.toPlainText() !=
-                connectionProfile["WillMessage"] or
-                self.willQosSpinBox.value() != connectionProfile["WillQos"] or
-                self.willRetainCheckBox.isChecked() !=
-                connectionProfile["WillRetain"] or
-                self.tlsGroupBox.isChecked() != connectionProfile["TlsEnable"]
+                self.brokerAddressEdit.text() != connectionProfile["BrokerAddress"]
+                or self.brokerPortSpinBox.value() != connectionProfile["BrokerPort"]
+                or self.clientIdEdit.text() != connectionProfile["ClientId"]
+                or protocol != connectionProfile["Protocol"]
+                or self.connectionTimeoutSpinBox.value()
+                != connectionProfile["ConnectionTimeout"]
+                or self.keepaliveSpinBox.value() != connectionProfile["Keepalive"]
+                or self.cleanSessionCheckBox.isChecked()
+                != connectionProfile["CleanSession"]
+                or self.usernameEdit.text() != connectionProfile["Username"]
+                or self.passwordEdit.text()
+                != pwConvert(connectionProfile["Password"], encode=False)
+                or self.willTopicEdit.text() != connectionProfile["WillTopic"]
+                or self.willMessageEdit.toPlainText()
+                != connectionProfile["WillMessage"]
+                or self.willQosSpinBox.value() != connectionProfile["WillQos"]
+                or self.willRetainCheckBox.isChecked()
+                != connectionProfile["WillRetain"]
+                or self.tlsGroupBox.isChecked() != connectionProfile["TlsEnable"]
             )
             # check will properties only, ig not yet changed
             if not changed and protocol == MqttProtocols.MQTTv5:
-                changed |= (
-                    sorted(self.__willProperties) !=
-                    sorted(connectionProfile["WillProperties"])
+                changed |= sorted(self.__willProperties) != sorted(
+                    connectionProfile["WillProperties"]
                 )
             # check TLS stuff only, if not yet changed
             if not changed:
                 if self.tlsCertsFileButton.isChecked():
                     changed |= (
-                        self.tlsCertsFilePicker.text() !=
-                        connectionProfile["TlsCaCert"]
+                        self.tlsCertsFilePicker.text() != connectionProfile["TlsCaCert"]
                     )
                 elif self.tlsSelfSignedCertsButton.isChecked():
                     changed |= (
-                        self.tlsSelfSignedCertsFilePicker.text() !=
-                        connectionProfile["TlsCaCert"] or
-                        self.tlsSelfSignedClientCertFilePicker.text() !=
-                        connectionProfile["TlsClientCert"] or
-                        self.tlsSelfSignedClientKeyFilePicker.text() !=
-                        connectionProfile["TlsClientKey"]
+                        self.tlsSelfSignedCertsFilePicker.text()
+                        != connectionProfile["TlsCaCert"]
+                        or self.tlsSelfSignedClientCertFilePicker.text()
+                        != connectionProfile["TlsClientCert"]
+                        or self.tlsSelfSignedClientKeyFilePicker.text()
+                        != connectionProfile["TlsClientKey"]
                     )
             # check user properties only, if not yet changed
             if not changed and protocol == MqttProtocols.MQTTv5:
-                properties = {
-                    "connect": self.propertiesWidget.getProperties(),
-                    "disconnect": self.__userProperties["disconnect"],
-                } if self.connectPropertiesButton.isChecked() else {
-                    "connect": self.__userProperties["connect"],
-                    "disconnect": self.propertiesWidget.getProperties(),
-                }
+                properties = (
+                    {
+                        "connect": self.propertiesWidget.getProperties(),
+                        "disconnect": self.__userProperties["disconnect"],
+                    }
+                    if self.connectPropertiesButton.isChecked()
+                    else {
+                        "connect": self.__userProperties["connect"],
+                        "disconnect": self.propertiesWidget.getProperties(),
+                    }
+                )
                 changed |= (
-                    self.samePropertiesCheckBox.isChecked() !=
-                    connectionProfile["UserProperties"]["use_connect"] or
-                    sorted(properties["connect"]) !=
-                    sorted(connectionProfile["UserProperties"]["connect"]) or
-                    sorted(properties["disconnect"]) !=
-                    sorted(connectionProfile["UserProperties"]["disconnect"])
+                    self.samePropertiesCheckBox.isChecked()
+                    != connectionProfile["UserProperties"]["use_connect"]
+                    or sorted(properties["connect"])
+                    != sorted(connectionProfile["UserProperties"]["connect"])
+                    or sorted(properties["disconnect"])
+                    != sorted(connectionProfile["UserProperties"]["disconnect"])
                 )
-            
+
             return changed
-        
+
         else:
             return True
-    
+
     def __updateApplyButton(self):
         """
         Private method to set the state of the Apply button.
         """
         # condition 1: profile name and broker address need to be given
-        enable = (bool(self.profileEdit.text()) and
-                  bool(self.brokerAddressEdit.text()))
-        
+        enable = bool(self.profileEdit.text()) and bool(self.brokerAddressEdit.text())
+
         # condition 2: if client ID is empty, clean session must be selected
         if (
-            not self.__populatingProfile and
-            self.clientIdEdit.text() == "" and
-            not self.cleanSessionCheckBox.isChecked()
+            not self.__populatingProfile
+            and self.clientIdEdit.text() == ""
+            and not self.cleanSessionCheckBox.isChecked()
         ):
             enable = False
             EricMessageBox.critical(
                 self,
                 self.tr("Invalid Connection Parameters"),
-                self.tr("An empty Client ID requires a clean session."))
-        
+                self.tr("An empty Client ID requires a clean session."),
+            )
+
         if self.tlsGroupBox.isChecked():
             if self.tlsCertsFileButton.isChecked():
                 # condition 3a: if CA certificates file shall be used, it must
@@ -645,139 +672,139 @@
                 # condition 3b: if client certificates shall be used, all files
                 # must be given
                 enable &= (
-                    bool(self.tlsSelfSignedCertsFilePicker.text()) and
-                    bool(self.tlsSelfSignedClientCertFilePicker.text()) and
-                    bool(self.tlsSelfSignedClientKeyFilePicker.text())
+                    bool(self.tlsSelfSignedCertsFilePicker.text())
+                    and bool(self.tlsSelfSignedClientCertFilePicker.text())
+                    and bool(self.tlsSelfSignedClientKeyFilePicker.text())
                 )
-        
-        self.profileButtonBox.button(
-            QDialogButtonBox.StandardButton.Apply).setEnabled(enable)
-    
+
+        self.profileButtonBox.button(QDialogButtonBox.StandardButton.Apply).setEnabled(
+            enable
+        )
+
     @pyqtSlot(str)
     def on_brokerAddressEdit_textChanged(self, address):
         """
         Private slot handling a change of the broker address.
-        
+
         @param address broker address
         @type str
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot()
     def on_generateIdButton_clicked(self):
         """
         Private slot to generate a client ID.
         """
         uuid = QUuid.createUuid()
-        self.clientIdEdit.setText(
-            uuid.toString(QUuid.StringFormat.WithoutBraces))
-    
+        self.clientIdEdit.setText(uuid.toString(QUuid.StringFormat.WithoutBraces))
+
     @pyqtSlot(str)
     def on_clientIdEdit_textChanged(self, clientId):
         """
         Private slot handling a change of the client ID string.
-        
+
         @param clientId client ID
         @type str
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(bool)
     def on_cleanSessionCheckBox_clicked(self, checked):
         """
         Private slot to handle a change of the clean session selection.
-        
+
         @param checked current state of the clean session selection
         @type bool
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(bool)
     def on_mqttv5Button_toggled(self, checked):
         """
         Private slot to handle the selection of the MQTT protocol.
-        
+
         @param checked state of the button
         @type bool
         """
         self.profileTabWidget.setTabEnabled(
-            self.profileTabWidget.indexOf(self.propertiesTab),
-            checked
+            self.profileTabWidget.indexOf(self.propertiesTab), checked
         )
         self.willPropertiesButton.setEnabled(checked)
         self.willPropertiesButton.setVisible(checked)
-    
+
     @pyqtSlot(bool)
     def on_showPasswordButton_toggled(self, checked):
         """
         Private slot to show or hide the password.
-        
+
         @param checked flag indicating the button state
         @type bool
         """
         (
             self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Normal)
-            if checked else
-            self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Password)
+            if checked
+            else self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Password)
         )
-    
+
     @pyqtSlot()
     def on_willPropertiesButton_clicked(self):
         """
         Private slot to edit the last will user properties.
         """
         from .MqttUserPropertiesEditor import MqttUserPropertiesEditorDialog
-        
+
         dlg = MqttUserPropertiesEditorDialog(
-            self.tr("Last Will User Properties"), self.__willProperties, self)
+            self.tr("Last Will User Properties"), self.__willProperties, self
+        )
         if dlg.exec() == QDialog.DialogCode.Accepted:
             self.__willProperties = dlg.getProperties()
-    
+
     @pyqtSlot(str)
     def on_tlsCertsFilePicker_textChanged(self, path):
         """
         Private slot handling a change of the TLS CA certificates file.
-        
+
         @param path file path
         @type str
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(str)
     def on_tlsSelfSignedCertsFilePicker_textChanged(self, path):
         """
         Private slot handling a change of the TLS CA certificates file.
-        
+
         @param path file path
         @type str
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(str)
     def on_tlsSelfSignedClientCertFilePicker_textChanged(self, path):
         """
         Private slot handling a change of the TLS client certificate file.
-        
+
         @param path file path
         @type str
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(str)
     def on_tlsSelfSignedClientKeyFilePicker_textChanged(self, path):
         """
         Private slot handling a change of the TLS client key file.
-        
+
         @param path file path
         @type str
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(bool)
     def on_tlsGroupBox_toggled(self, checked):
         """
         Private slot handling the selection of TLS mode.
-        
+
         @param checked state of the selection
         @type bool
         """
@@ -790,9 +817,11 @@
                     """Encrypted connection using SSL/TLS has been enabled."""
                     """ However, the broker port is still the default"""
                     """ unencrypted port (port 1883). Shall this be"""
-                    """ changed?"""),
+                    """ changed?"""
+                ),
                 icon=EricMessageBox.Warning,
-                yesDefault=True)
+                yesDefault=True,
+            )
             if yes:
                 self.brokerPortSpinBox.setValue(8883)
         elif not checked and self.brokerPortSpinBox.value() == 8883:
@@ -804,52 +833,54 @@
                     """Encrypted connection using SSL/TLS has been disabled."""
                     """ However, the broker port is still the default"""
                     """ encrypted port (port 8883). Shall this be"""
-                    """ changed?"""),
+                    """ changed?"""
+                ),
                 icon=EricMessageBox.Warning,
-                yesDefault=True)
+                yesDefault=True,
+            )
             if yes:
                 self.brokerPortSpinBox.setValue(1883)
-        
+
         self.__updateApplyButton()
-    
+
     @pyqtSlot(bool)
     def on_tlsDefaultCertsButton_toggled(self, checked):
         """
         Private slot handling the selection of using the default
         certificates file.
-        
+
         @param checked state of the selection
         @type bool
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(bool)
     def on_tlsCertsFileButton_toggled(self, checked):
         """
         Private slot handling the selection of using a non-default
         certificates file.
-        
+
         @param checked state of the selection
         @type bool
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(bool)
     def on_tlsSelfSignedCertsButton_toggled(self, checked):
         """
         Private slot handling the selection of using self signed
         client certificate and key files.
-        
+
         @param checked state of the selection
         @type bool
         """
         self.__updateApplyButton()
-    
+
     @pyqtSlot(bool)
     def on_samePropertiesCheckBox_toggled(self, checked):
         """
         Private slot to handle a change of the properties usage.
-        
+
         @param checked flag indicating to use the same user properties for
             CONNECT and DISCONNECT
         @type bool
@@ -857,28 +888,26 @@
         if checked and not self.connectPropertiesButton.isChecked():
             self.connectPropertiesButton.click()
         self.disconnectPropertiesButton.setEnabled(not checked)
-    
+
     @pyqtSlot(bool)
     def __propertiesTypeSelected(self, checked):
         """
         Private slot to handle the switching of the user properties type.
-        
+
         @param checked state of the buttons
         @type bool
         """
         if checked:
             # handle the selection only
             if self.connectPropertiesButton.isChecked():
-                self.__userProperties["disconnect"] = (
-                    self.propertiesWidget.getProperties())
-                self.propertiesWidget.setProperties(
-                    self.__userProperties["connect"])
+                self.__userProperties[
+                    "disconnect"
+                ] = self.propertiesWidget.getProperties()
+                self.propertiesWidget.setProperties(self.__userProperties["connect"])
             else:
-                self.__userProperties["connect"] = (
-                    self.propertiesWidget.getProperties())
-                self.propertiesWidget.setProperties(
-                    self.__userProperties["disconnect"])
-    
+                self.__userProperties["connect"] = self.propertiesWidget.getProperties()
+                self.propertiesWidget.setProperties(self.__userProperties["disconnect"])
+
     @pyqtSlot()
     def reject(self):
         """
@@ -888,33 +917,35 @@
             button = EricMessageBox.warning(
                 self,
                 self.tr("Changed Connection Profile"),
-                self.tr("""The current profile has unsaved changes. Shall"""
-                        """ these be saved?"""),
-                EricMessageBox.Discard |
+                self.tr(
+                    """The current profile has unsaved changes. Shall"""
+                    """ these be saved?"""
+                ),
+                EricMessageBox.Discard | EricMessageBox.Save,
                 EricMessageBox.Save,
-                EricMessageBox.Save)
+            )
             if button == EricMessageBox.Save:
                 self.__applyProfile()
                 return
-        
+
         if self.__profilesChanged:
             button = EricMessageBox.warning(
                 self,
                 self.tr("Changed Connection Profiles"),
-                self.tr("""The list of connection profiles has unsaved"""
-                        """ changes."""),
-                EricMessageBox.Abort |
-                EricMessageBox.Discard |
+                self.tr(
+                    """The list of connection profiles has unsaved""" """ changes."""
+                ),
+                EricMessageBox.Abort | EricMessageBox.Discard | EricMessageBox.Save,
                 EricMessageBox.Save,
-                EricMessageBox.Save)
+            )
             if button == EricMessageBox.Save:
                 super().accept()
                 return
             elif button == EricMessageBox.Abort:
                 return
-        
+
         super().reject()
-    
+
     @pyqtSlot()
     def accept(self):
         """
@@ -924,11 +955,14 @@
             yes = EricMessageBox.yesNo(
                 self,
                 self.tr("Changed Connection Profile"),
-                self.tr("""The current profile has unsaved changes. Shall"""
-                        """ these be saved?"""),
+                self.tr(
+                    """The current profile has unsaved changes. Shall"""
+                    """ these be saved?"""
+                ),
                 icon=EricMessageBox.Warning,
-                yesDefault=True)
+                yesDefault=True,
+            )
             if yes:
                 self.__applyProfile()
-        
+
         super().accept()

eric ide

mercurial