Wed, 05 Sep 2018 19:52:30 +0200
MqttConnectionProfilesDialog: continued implementing the connections profile dialog.
# -*- coding: utf-8 -*- # Copyright (c) 2018 Detlev Offenbach <detlev@die-offenbachs.de> # """ Module implementing a dialog to edit the MQTT connection profiles. """ from __future__ import unicode_literals import collections from PyQt5.QtCore import pyqtSlot, Qt, QUuid from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ QListWidgetItem, QInputDialog, QLineEdit from E5Gui import E5MessageBox from .Ui_MqttConnectionProfilesDialog import Ui_MqttConnectionProfilesDialog import UI.PixmapCache class MqttConnectionProfilesDialog(QDialog, Ui_MqttConnectionProfilesDialog): """ Class implementing a dialog to edit the MQTT connection profiles. """ def __init__(self, client, profiles, parent=None): """ Constructor @param client reference to the MQTT client object @type MqttClient @param profiles dictionary containing dictionaries containing the connection parameters. Each entry must have the keys "BrokerAddress", "BrokerPort", "ClientId", "Keepalive", "CleanSession", "Username", "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain". @type dict @param parent reference to the parent widget @type QWidget """ super(MqttConnectionProfilesDialog, self).__init__(parent) self.setupUi(self) self.__client = client self.__profiles = collections.defaultdict(self.__defaultProfile) self.__profiles.update(profiles) self.plusButton.setIcon(UI.PixmapCache.getIcon("plus.png")) self.minusButton.setIcon(UI.PixmapCache.getIcon("minus.png")) self.__populateProfilesList() if len(self.__profiles) == 0: self.minusButton.setEnabled(False) self.__updateApplyButton() self.profileTabWidget.setCurrentIndex(0) @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.Apply): currentProfile = self.__applyProfile() self.__populateProfilesList(currentProfile) # TODO: not implemented other paths @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) if current: profileName = current.text() self.__populateProfile(profileName) @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.Normal) if ok and bool(profileName) and profileName not in self.__profiles: itm = QListWidgetItem(profileName, self.profilesList) self.profilesList.setCurrentItem(itm) self.brokerAddressEdit.setFocus(Qt.OtherFocusReason) @pyqtSlot() def on_minusButton_clicked(self): """ Private slot to delete the selected entry. """ itm = self.profilesList.currentItem() if itm: profileName = itm.text() yes = E5MessageBox.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: del self.__profiles[profileName] self.__populateProfilesList() def getProfiles(self): """ Public method to return a dictionary of profiles. @return dictionary containing dictionaries containing the defined connection profiles. Each entry have the keys "BrokerAddress", "BrokerPort", "ClientId", "Keepalive", "CleanSession", "Username", "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain". @rtype dict """ profilesDict = {} profilesDict.update(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 """ profileName = self.profileEdit.text() profile = { "BrokerAddress": self.brokerAddressEdit.text(), "BrokerPort": self.brokerPortSpinBox.value(), "ClientId": self.clientIdEdit.text(), "Keepalive": self.keepaliveSpinBox.value(), "CleanSession": self.cleanSessionCheckBox.isChecked(), "Username": self.usernameEdit.text(), "Password": self.passwordEdit.text(), "WillTopic": self.willTopicEdit.text(), "WillMessage": self.willMessageEdit.toPlainText(), "WillQos": self.willQosSpinBox.value(), "WillRetain": self.willRetainCheckBox.isChecked(), } self.__profiles[profileName] = profile return profileName def __defaultProfile(self): """ Private method to populate non-existing profile items. @return default dictionary entry @rtype dict """ defaultProfile = self.__client.defaultConnectionOptions() defaultProfile["BrokerAddress"] = "" 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.MatchExactly) if items: self.profilesList.setCurrentItem(items[0]) 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 """ if profileName: profile = self.__profiles[profileName] else: profile = self.__defaultProfile() self.profileEdit.setText(profileName) self.brokerAddressEdit.setText(profile["BrokerAddress"]) self.brokerPortSpinBox.setValue(profile["BrokerPort"]) self.clientIdEdit.setText(profile["ClientId"]) self.keepaliveSpinBox.setValue(profile["Keepalive"]) self.cleanSessionCheckBox.setChecked(profile["CleanSession"]) self.usernameEdit.setText(profile["Username"]) self.passwordEdit.setText(profile["Password"]) self.willTopicEdit.setText(profile["WillTopic"]) self.willMessageEdit.setPlainText(profile["WillMessage"]) self.willQosSpinBox.setValue(profile["WillQos"]) self.willRetainCheckBox.setChecked(profile["WillRetain"]) self.__updateApplyButton() def __updateApplyButton(self): """ Private method to set the state of the Apply button. """ enable = (bool(self.profileEdit.text()) and bool(self.brokerAddressEdit.text())) self.profileButtonBox.button(QDialogButtonBox.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.WithoutBraces))