MqttMonitor/MqttConnectionProfilesDialog.py

Wed, 05 Sep 2018 19:52:30 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Wed, 05 Sep 2018 19:52:30 +0200
branch
connection_profiles
changeset 19
889a7c3c0e63
parent 18
bbfe5866b6aa
child 23
0b23bd856e43
permissions
-rw-r--r--

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))

eric ide

mercurial