Sat, 23 Dec 2023 19:45:41 +0100
Corrected some code style issues.
# -*- coding: utf-8 -*- # Copyright (c) 2018 - 2024 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing a dialog to edit the MQTT connection profiles. """ import collections import copy from PyQt6.QtCore import Qt, QUuid, pyqtSlot from PyQt6.QtWidgets import ( QAbstractButton, QDialog, QDialogButtonBox, QInputDialog, QLineEdit, QListWidgetItem, ) try: from eric7.EricGui import EricPixmapCache except ImportError: from UI import PixmapCache as EricPixmapCache from eric7.EricWidgets import EricMessageBox from eric7.EricWidgets.EricPathPicker import EricPathPickerModes from eric7.Utilities.crypto import pwConvert from .MqttClient import MqttClient from .MqttProtocols import MqttProtocols from .Ui_MqttConnectionProfilesDialog import Ui_MqttConnectionProfilesDialog class MqttConnectionProfilesDialog(QDialog, Ui_MqttConnectionProfilesDialog): """ 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", "ConnectionTimeout", "Keepalive", "CleanSession", "Username", "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain", "WillProperties", "TlsEnable", "TlsCaCert", "TlsClientCert", "TlsClientKey", "UserProperties". @type dict @param currentProfile name of the currently selected profile @type str @param parent reference to the parent widget @type QWidget """ super().__init__(parent) self.setupUi(self) self.__profiles = collections.defaultdict(self.__defaultProfile) self.__profiles.update(copy.deepcopy(profiles)) self.__profilesChanged = False self.plusButton.setIcon(EricPixmapCache.getIcon("plus")) self.copyButton.setIcon(EricPixmapCache.getIcon("editCopy")) self.minusButton.setIcon(EricPixmapCache.getIcon("minus")) self.showPasswordButton.setIcon(EricPixmapCache.getIcon("showPassword")) self.willPropertiesButton.setIcon(EricPixmapCache.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.tlsSelfSignedCertsFilePicker.setFilters( self.tr("Certificate Files (*.crt *.pem);;All Files (*)") ) self.tlsSelfSignedClientCertFilePicker.setMode( EricPathPickerModes.OPEN_FILE_MODE ) self.tlsSelfSignedClientCertFilePicker.setFilters( self.tr("Certificate Files (*.crt *.pem);;All Files (*)") ) self.tlsSelfSignedClientKeyFilePicker.setMode( EricPathPickerModes.OPEN_FILE_MODE ) self.tlsSelfSignedClientKeyFilePicker.setFilters( self.tr("Key Files (*.key *.pem);;All Files (*)") ) self.profileTabWidget.setCurrentIndex(0) self.connectPropertiesButton.clicked[bool].connect( self.__propertiesTypeSelected ) self.disconnectPropertiesButton.clicked[bool].connect( 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 """ if button == self.profileButtonBox.button( QDialogButtonBox.StandardButton.Apply ): 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 ): 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 @type QListWidgetItem """ 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() ): # 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?""" ), icon=EricMessageBox.Warning, yesDefault=True, ) if yes: self.__applyProfile() if current: profileName = current.text() self.__populateProfile(profileName) else: self.__clearProfile() @pyqtSlot() def on_plusButton_clicked(self): """ Private slot to add a new empty profile entry. """ profileName, ok = QInputDialog.getText( self, self.tr("New Connection Profile"), self.tr("Enter name for the new Connection Profile:"), 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), ) else: itm = QListWidgetItem(profileName, self.profilesList) self.profilesList.setCurrentItem(itm) self.brokerAddressEdit.setFocus(Qt.FocusReason.OtherFocusReason) @pyqtSlot() def on_copyButton_clicked(self): """ Private slot to copy the selected profile entry. """ itm = self.profilesList.currentItem() if itm: profileName = itm.text() newProfileName, ok = QInputDialog.getText( self, self.tr("Copy Connection Profile"), self.tr("Enter name for the copied Connection Profile:"), 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), ) else: connectionProfile = self.__defaultProfile() connectionProfile.update( 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) @pyqtSlot() def on_minusButton_clicked(self): """ Private slot to delete the selected entry. """ itm = self.profilesList.currentItem() if itm: profileName = itm.text() 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), ) if yes: self.__deletingProfile = True del self.__profiles[profileName] 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", "Keepalive", "CleanSession", "Username", "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain", "WillProperties", "TlsEnable", "TlsCaCert", "TlsClientCert", "TlsClientKey", "UserProperties". @rtype dict """ 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 """ if self.mqttv31Button.isChecked(): protocol = MqttProtocols.MQTTv31 elif self.mqttv311Button.isChecked(): protocol = MqttProtocols.MQTTv311 elif self.mqttv5Button.isChecked(): protocol = MqttProtocols.MQTTv5 else: # should never happen protocol = MqttProtocols.MQTTv311 if protocol == MqttProtocols.MQTTv5: if self.connectPropertiesButton.isChecked(): self.__userProperties["connect"] = self.propertiesWidget.getProperties() else: 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(), "BrokerPort": self.brokerPortSpinBox.value(), "ClientId": self.clientIdEdit.text(), "Protocol": protocol, "ConnectionTimeout": self.connectionTimeoutSpinBox.value(), "Keepalive": self.keepaliveSpinBox.value(), "CleanSession": self.cleanSessionCheckBox.isChecked(), "Username": self.usernameEdit.text(), "Password": pwConvert(self.passwordEdit.text(), encode=True), "WillTopic": self.willTopicEdit.text(), "WillMessage": self.willMessageEdit.toPlainText(), "WillQos": self.willQosSpinBox.value(), "WillRetain": self.willRetainCheckBox.isChecked(), "WillProperties": copy.deepcopy(self.__willProperties), "TlsEnable": self.tlsGroupBox.isChecked(), "TlsCaCert": "", "TlsClientCert": "", "TlsClientKey": "", "UserProperties": copy.deepcopy(self.__userProperties), } if connectionProfile["TlsEnable"]: 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() 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 """ defaultProfile = MqttClient.defaultConnectionOptions() defaultProfile["BrokerAddress"] = "" if defaultProfile["TlsEnable"]: 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 """ if not currentProfile: 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 ) 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 ) self.mqttv311Button.setChecked( connectionProfile["Protocol"] == MqttProtocols.MQTTv311 ) self.mqttv5Button.setChecked( connectionProfile["Protocol"] == MqttProtocols.MQTTv5 ) self.on_mqttv5Button_toggled(self.mqttv5Button.isChecked()) 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) ) # 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", []) ) # SSL/TLS tab self.tlsGroupBox.setChecked(connectionProfile["TlsEnable"]) if connectionProfile["TlsCaCert"] and connectionProfile["TlsClientCert"]: self.tlsSelfSignedCertsButton.setChecked(True) self.tlsSelfSignedCertsFilePicker.setText(connectionProfile["TlsCaCert"]) self.tlsSelfSignedClientCertFilePicker.setText( connectionProfile["TlsClientCert"] ) self.tlsSelfSignedClientKeyFilePicker.setText( 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", {}) ) 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.disconnectPropertiesButton.setEnabled( 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. """ self.__populatingProfile = True self.profileEdit.setText("") self.brokerAddressEdit.setText("") self.brokerPortSpinBox.setValue(1883) self.clientIdEdit.setText("") self.mqttv311Button.setChecked(True) self.keepaliveSpinBox.setValue(60) self.cleanSessionCheckBox.setChecked(True) self.usernameEdit.setText("") self.passwordEdit.setText("") self.willTopicEdit.setText("") self.willMessageEdit.setPlainText("") self.willQosSpinBox.setValue(0) self.willRetainCheckBox.setChecked(False) self.__willProperties = [] self.tlsGroupBox.setChecked(False) self.tlsDefaultCertsButton.setChecked(True) self.tlsCertsFileButton.setChecked(True) self.tlsCertsFilePicker.setText("") self.tlsSelfSignedCertsButton.setChecked(False) self.tlsSelfSignedCertsFilePicker.setText("") self.tlsSelfSignedClientCertFilePicker.setText("") self.tlsSelfSignedClientKeyFilePicker.setText("") self.__userProperties = { "connect": [], "disconnect": [], "use_connect": True, } self.propertiesWidget.clear() 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 values. """ 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 elif self.mqttv311Button.isChecked(): protocol = MqttProtocols.MQTTv311 elif self.mqttv5Button.isChecked(): protocol = MqttProtocols.MQTTv5 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"] ) # check will properties only, ig not yet changed if not changed and protocol == MqttProtocols.MQTTv5: 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"] ) elif self.tlsSelfSignedCertsButton.isChecked(): changed |= ( 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(), } ) changed |= ( 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()) # 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() ): enable = False EricMessageBox.critical( self, self.tr("Invalid Connection Parameters"), 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 # be given enable &= bool(self.tlsCertsFilePicker.text()) elif self.tlsSelfSignedCertsButton.isChecked(): # 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()) ) 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)) @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.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) ) @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 ) 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 """ if checked and self.brokerPortSpinBox.value() == 1883: # port is still standard non-TLS port yes = EricMessageBox.yesNo( self, self.tr("SSL/TLS Enabled"), self.tr( """Encrypted connection using SSL/TLS has been enabled.""" """ However, the broker port is still the default""" """ unencrypted port (port 1883). Shall this be""" """ changed?""" ), icon=EricMessageBox.Warning, yesDefault=True, ) if yes: self.brokerPortSpinBox.setValue(8883) elif not checked and self.brokerPortSpinBox.value() == 8883: # port is still standard TLS port yes = EricMessageBox.yesNo( self, self.tr("SSL/TLS Disabled"), self.tr( """Encrypted connection using SSL/TLS has been disabled.""" """ However, the broker port is still the default""" """ encrypted port (port 8883). Shall this be""" """ changed?""" ), icon=EricMessageBox.Warning, 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 """ 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"]) else: self.__userProperties["connect"] = self.propertiesWidget.getProperties() self.propertiesWidget.setProperties(self.__userProperties["disconnect"]) @pyqtSlot() def reject(self): """ Public slot to reject the dialog changes. """ if self.__isChangedProfile(): button = EricMessageBox.warning( self, self.tr("Changed Connection Profile"), self.tr( """The current profile has unsaved changes. Shall""" """ these be saved?""" ), EricMessageBox.Discard | 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 | EricMessageBox.Save, EricMessageBox.Save, ) if button == EricMessageBox.Save: super().accept() return elif button == EricMessageBox.Abort: return super().reject() @pyqtSlot() def accept(self): """ Public slot to accept the dialog. """ if self.__isChangedProfile(): yes = EricMessageBox.yesNo( self, self.tr("Changed Connection Profile"), self.tr( """The current profile has unsaved changes. Shall""" """ these be saved?""" ), icon=EricMessageBox.Warning, yesDefault=True, ) if yes: self.__applyProfile() super().accept()