MqttConnectionProfilesDialog: added support for TLS and added a button to copy the current profile. connection_profiles

Sat, 08 Sep 2018 15:29:39 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Sat, 08 Sep 2018 15:29:39 +0200
branch
connection_profiles
changeset 26
ad232a5129cc
parent 25
01d44a4decf5
child 28
0f02baed8308
child 29
e36374ad8271

MqttConnectionProfilesDialog: added support for TLS and added a button to copy the current profile.

MqttMonitor/MqttConnectionProfilesDialog.py file | annotate | diff | comparison | revisions
MqttMonitor/MqttConnectionProfilesDialog.ui file | annotate | diff | comparison | revisions
--- a/MqttMonitor/MqttConnectionProfilesDialog.py	Sat Sep 08 15:28:48 2018 +0200
+++ b/MqttMonitor/MqttConnectionProfilesDialog.py	Sat Sep 08 15:29:39 2018 +0200
@@ -16,6 +16,7 @@
     QListWidgetItem, QInputDialog, QLineEdit
 
 from E5Gui import E5MessageBox
+from E5Gui.E5PathPicker import E5PathPickerModes
 
 from .Ui_MqttConnectionProfilesDialog import Ui_MqttConnectionProfilesDialog
 
@@ -37,7 +38,8 @@
             connection parameters. Each entry must have the keys
             "BrokerAddress", "BrokerPort", "ClientId",
             "Keepalive", "CleanSession", "Username", "Password", "WillTopic",
-            "WillMessage", "WillQos", "WillRetain".
+            "WillMessage", "WillQos", "WillRetain", "TlsEnable", "TlsCaCert",
+            "TlsClientCert", "TlsClientKey".
         @type dict
         @param parent reference to the parent widget
         @type QWidget
@@ -52,12 +54,30 @@
         self.__profilesChanged = False
         
         self.plusButton.setIcon(UI.PixmapCache.getIcon("plus.png"))
+        self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png"))
         self.minusButton.setIcon(UI.PixmapCache.getIcon("minus.png"))
         
+        self.tlsCertsFilePicker.setMode(E5PathPickerModes.OpenFileMode)
+        self.tlsCertsFilePicker.setFilters(
+            self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
+        self.tlsSelfSignedCertsFilePicker.setMode(
+            E5PathPickerModes.OpenFileMode)
+        self.tlsSelfSignedCertsFilePicker.setFilters(
+            self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
+        self.tlsSelfSignedClientCertFilePicker.setMode(
+            E5PathPickerModes.OpenFileMode)
+        self.tlsSelfSignedClientCertFilePicker.setFilters(
+            self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
+        self.tlsSelfSignedClientKeyFilePicker.setMode(
+            E5PathPickerModes.OpenFileMode)
+        self.tlsSelfSignedClientKeyFilePicker.setFilters(
+            self.tr("Key Files (*.key *.pem);;All Files (*)"))
+        
         self.profileTabWidget.setCurrentIndex(0)
         
         if len(self.__profiles) == 0:
             self.minusButton.setEnabled(False)
+            self.copyButton.setEnabled(False)
         
         self.profileFrame.setEnabled(False)
         self.__populatingProfile = False
@@ -105,6 +125,7 @@
         @type QListWidgetItem
         """
         self.minusButton.setEnabled(current is not None)
+        self.copyButton.setEnabled(current is not None)
         
         if current is not previous:
             if not self.__deletingProfile and self.__isChangedProfile():
@@ -135,10 +156,48 @@
             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)
+        if ok and bool(profileName):
+            if profileName in self.__profiles:
+                E5MessageBox.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.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.Normal)
+            if ok and bool(newProfileName):
+                if newProfileName in self.__profiles:
+                    E5MessageBox.warning(
+                        self,
+                        self.tr("Copy Connection Profile"),
+                        self.tr("""<p>A connection named <b>{0}</b> exists"""
+                                """ already. Aborting...</p>""").format(
+                            newProfileName))
+                else:
+                    profile = self.__defaultProfile()
+                    profile.update(self.__profiles[profileName])
+                    self.__profiles[newProfileName] = profile
+                    
+                    itm = QListWidgetItem(newProfileName, self.profilesList)
+                    self.profilesList.setCurrentItem(itm)
+                    self.brokerAddressEdit.setFocus(Qt.OtherFocusReason)
     
     @pyqtSlot()
     def on_minusButton_clicked(self):
@@ -170,7 +229,8 @@
         @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".
+            "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain",
+            "TlsEnable", "TlsCaCert", "TlsClientCert", "TlsClientKey".
         @rtype dict
         """
         profilesDict = {}
@@ -197,7 +257,22 @@
             "WillMessage": self.willMessageEdit.toPlainText(),
             "WillQos": self.willQosSpinBox.value(),
             "WillRetain": self.willRetainCheckBox.isChecked(),
+            "TlsEnable": self.tlsGroupBox.isChecked(),
+            "TlsCaCert": "",
+            "TlsClientCert": "",
+            "TlsClientKey": "",
         }
+        if profile["TlsEnable"]:
+            if self.tlsCertsFileButton.isChecked():
+                profile["TlsCaCert"] = self.tlsCertsFilePicker.text()
+            elif self.tlsSelfSignedCertsButton.isChecked():
+                profile["TlsCaCert"] = \
+                    self.tlsSelfSignedCertsFilePicker.text()
+                profile["TlsClientCert"] = \
+                    self.tlsSelfSignedClientCertFilePicker.text()
+                profile["TlsClientKey"] = \
+                    self.tlsSelfSignedClientKeyFilePicker.text()
+        
         self.__profiles[profileName] = profile
         self.__profilesChanged = True
         
@@ -212,7 +287,10 @@
         """
         defaultProfile = self.__client.defaultConnectionOptions()
         defaultProfile["BrokerAddress"] = ""
-        defaultProfile["BrokerPort"] = 1883
+        if defaultProfile["TlsEnable"]:
+            defaultProfile["BrokerPort"] = 8883
+        else:
+            defaultProfile["BrokerPort"] = 1883
         
         return defaultProfile
     
@@ -247,10 +325,9 @@
         @param profileName name of the profile to get data from
         @type str
         """
+        profile = self.__defaultProfile()
         if profileName:
-            profile = self.__profiles[profileName]
-        else:
-            profile = self.__defaultProfile()
+            profile.update(self.__profiles[profileName])
         
         self.__populatingProfile = True
         if profileName is not None:
@@ -266,6 +343,19 @@
         self.willMessageEdit.setPlainText(profile["WillMessage"])
         self.willQosSpinBox.setValue(profile["WillQos"])
         self.willRetainCheckBox.setChecked(profile["WillRetain"])
+        self.tlsGroupBox.setChecked(profile["TlsEnable"])
+        if profile["TlsCaCert"] and profile["TlsClientCert"]:
+            self.tlsSelfSignedCertsButton.setChecked(True)
+            self.tlsSelfSignedCertsFilePicker.setText(profile["TlsCaCert"])
+            self.tlsSelfSignedClientCertFilePicker.setText(
+                profile["TlsClientCert"])
+            self.tlsSelfSignedClientKeyFilePicker.setText(
+                profile["TlsClientKey"])
+        elif profile["TlsCaCert"]:
+            self.tlsCertsFileButton.setChecked(True)
+            self.tlsCertsFilePicker.setText(profile["TlsCaCert"])
+        else:
+            self.tlsDefaultCertsButton.setChecked(True)
         self.__populatingProfile = False
         
         self.profileFrame.setEnabled(True)
@@ -288,6 +378,14 @@
         self.willMessageEdit.setPlainText("")
         self.willQosSpinBox.setValue(0)
         self.willRetainCheckBox.setChecked(False)
+        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.__populatingProfile = False
         
         self.profileFrame.setEnabled(False)
@@ -322,8 +420,9 @@
             return False
         
         elif profileName in self.__profiles:
-            profile = self.__profiles[profileName]
-            return (
+            profile = self.__defaultProfile()
+            profile.update(self.__profiles[profileName])
+            changed = (
                 self.brokerAddressEdit.text() != profile["BrokerAddress"] or
                 self.brokerPortSpinBox.value() != profile["BrokerPort"] or
                 self.clientIdEdit.text() != profile["ClientId"] or
@@ -336,8 +435,25 @@
                 self.willTopicEdit.text() != profile["WillTopic"] or
                 self.willMessageEdit.toPlainText() != profile["WillMessage"] or
                 self.willQosSpinBox.value() != profile["WillQos"] or
-                self.willRetainCheckBox.isChecked() != profile["WillRetain"]
+                self.willRetainCheckBox.isChecked() != profile["WillRetain"] or
+                self.tlsGroupBox.isChecked() != profile["TlsEnable"]
             )
+            # check TLS stuff only, if not yet changed
+            if not changed:
+                if self.tlsCertsFileButton.isChecked():
+                    changed |= (
+                        self.tlsCertsFilePicker.text() != profile["TlsCaCert"]
+                    )
+                elif self.tlsSelfSignedCertsButton.isChecked():
+                    changed |= (
+                        self.tlsSelfSignedCertsFilePicker.text() !=
+                        profile["TlsCaCert"] or
+                        self.tlsSelfSignedClientCertFilePicker.text() !=
+                        profile["TlsClientCert"] or
+                        self.tlsSelfSignedClientKeyFilePicker.text() !=
+                        profile["TlsClientKey"]
+                    )
+            return changed
         
         else:
             return True
@@ -360,6 +476,20 @@
                     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.Apply).setEnabled(enable)
     
     @pyqtSlot(str)
@@ -380,6 +510,138 @@
         uuid = QUuid.createUuid()
         self.clientIdEdit.setText(uuid.toString(QUuid.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(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 = E5MessageBox.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=E5MessageBox.Warning,
+                yesDefault=True)
+            if yes:
+                self.brokerPortSpinBox.setValue(8883)
+        elif not checked and self.brokerPortSpinBox.value() == 8883:
+            # port is still standard TLS port
+            yes = E5MessageBox.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=E5MessageBox.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()
     def reject(self):
         """
@@ -435,23 +697,3 @@
                 self.__applyProfile()
         
         super(MqttConnectionProfilesDialog, self).accept()
-    
-    @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()
--- a/MqttMonitor/MqttConnectionProfilesDialog.ui	Sat Sep 08 15:28:48 2018 +0200
+++ b/MqttMonitor/MqttConnectionProfilesDialog.ui	Sat Sep 08 15:29:39 2018 +0200
@@ -53,6 +53,13 @@
           </widget>
          </item>
          <item>
+          <widget class="QToolButton" name="copyButton">
+           <property name="toolTip">
+            <string>Press to copy the selected profile</string>
+           </property>
+          </widget>
+         </item>
+         <item>
           <widget class="QToolButton" name="minusButton">
            <property name="toolTip">
             <string>Press to delete the selected profile</string>
@@ -94,9 +101,9 @@
           </widget>
          </item>
          <item row="0" column="1">
-          <widget class="E5ClearableLineEdit" name="profileEdit">
-           <property name="toolTip">
-            <string>Enter the name of the profile</string>
+          <widget class="QLineEdit" name="profileEdit">
+           <property name="readOnly">
+            <bool>true</bool>
            </property>
           </widget>
          </item>
@@ -380,6 +387,243 @@
            </item>
           </layout>
          </widget>
+         <widget class="QWidget" name="tlsTab">
+          <attribute name="title">
+           <string>SSL/TLS</string>
+          </attribute>
+          <layout class="QVBoxLayout" name="verticalLayout_5">
+           <item>
+            <widget class="QGroupBox" name="tlsGroupBox">
+             <property name="toolTip">
+              <string>Select to enable SSL/TLS connections</string>
+             </property>
+             <property name="title">
+              <string>SSL/TLS Enabled</string>
+             </property>
+             <property name="checkable">
+              <bool>true</bool>
+             </property>
+             <property name="checked">
+              <bool>false</bool>
+             </property>
+             <layout class="QVBoxLayout" name="verticalLayout_4">
+              <item>
+               <widget class="QRadioButton" name="tlsDefaultCertsButton">
+                <property name="toolTip">
+                 <string>Select to use the default certificate file of the client</string>
+                </property>
+                <property name="text">
+                 <string>CA signed server certificate</string>
+                </property>
+                <property name="checked">
+                 <bool>true</bool>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QRadioButton" name="tlsCertsFileButton">
+                <property name="toolTip">
+                 <string>Select to use a specific certificate file</string>
+                </property>
+                <property name="text">
+                 <string>CA certificate file</string>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QWidget" name="tlsCertsFileWidget" native="true">
+                <property name="enabled">
+                 <bool>false</bool>
+                </property>
+                <layout class="QHBoxLayout" name="horizontalLayout_6">
+                 <property name="leftMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="topMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="rightMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="bottomMargin">
+                  <number>0</number>
+                 </property>
+                 <item>
+                  <spacer name="horizontalSpacer_4">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeType">
+                    <enum>QSizePolicy::Fixed</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>25</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                 <item>
+                  <widget class="QLabel" name="label_8">
+                   <property name="text">
+                    <string>CA File:</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item>
+                  <widget class="E5PathPicker" name="tlsCertsFilePicker" native="true">
+                   <property name="sizePolicy">
+                    <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="focusPolicy">
+                    <enum>Qt::StrongFocus</enum>
+                   </property>
+                   <property name="toolTip">
+                    <string>Enter the full path to the CA certificate file</string>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </widget>
+              </item>
+              <item>
+               <widget class="QRadioButton" name="tlsSelfSignedCertsButton">
+                <property name="toolTip">
+                 <string>Select to use a self signed client certificate</string>
+                </property>
+                <property name="text">
+                 <string>Self signed certificates</string>
+                </property>
+               </widget>
+              </item>
+              <item>
+               <widget class="QWidget" name="tlsSelfSignedFilesWidget" native="true">
+                <property name="enabled">
+                 <bool>false</bool>
+                </property>
+                <layout class="QGridLayout" name="gridLayout_5">
+                 <property name="leftMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="topMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="rightMargin">
+                  <number>0</number>
+                 </property>
+                 <property name="bottomMargin">
+                  <number>0</number>
+                 </property>
+                 <item row="0" column="0">
+                  <spacer name="horizontalSpacer_5">
+                   <property name="orientation">
+                    <enum>Qt::Horizontal</enum>
+                   </property>
+                   <property name="sizeType">
+                    <enum>QSizePolicy::Fixed</enum>
+                   </property>
+                   <property name="sizeHint" stdset="0">
+                    <size>
+                     <width>25</width>
+                     <height>20</height>
+                    </size>
+                   </property>
+                  </spacer>
+                 </item>
+                 <item row="0" column="1">
+                  <widget class="QLabel" name="label_9">
+                   <property name="text">
+                    <string>CA File:</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="0" column="2">
+                  <widget class="E5PathPicker" name="tlsSelfSignedCertsFilePicker" native="true">
+                   <property name="sizePolicy">
+                    <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="focusPolicy">
+                    <enum>Qt::StrongFocus</enum>
+                   </property>
+                   <property name="toolTip">
+                    <string>Enter the full path to the CA certificate file</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="1" column="1">
+                  <widget class="QLabel" name="label_10">
+                   <property name="text">
+                    <string>Client Certificate File:</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="1" column="2">
+                  <widget class="E5PathPicker" name="tlsSelfSignedClientCertFilePicker" native="true">
+                   <property name="sizePolicy">
+                    <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="focusPolicy">
+                    <enum>Qt::StrongFocus</enum>
+                   </property>
+                   <property name="toolTip">
+                    <string>Enter the full path to the client certificate file</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="2" column="1">
+                  <widget class="QLabel" name="label_11">
+                   <property name="text">
+                    <string>Client Key File:</string>
+                   </property>
+                  </widget>
+                 </item>
+                 <item row="2" column="2">
+                  <widget class="E5PathPicker" name="tlsSelfSignedClientKeyFilePicker" native="true">
+                   <property name="sizePolicy">
+                    <sizepolicy hsizetype="Expanding" vsizetype="Preferred">
+                     <horstretch>0</horstretch>
+                     <verstretch>0</verstretch>
+                    </sizepolicy>
+                   </property>
+                   <property name="focusPolicy">
+                    <enum>Qt::StrongFocus</enum>
+                   </property>
+                   <property name="toolTip">
+                    <string>Enter the full path to the client key file</string>
+                   </property>
+                  </widget>
+                 </item>
+                </layout>
+               </widget>
+              </item>
+             </layout>
+            </widget>
+           </item>
+           <item>
+            <spacer name="verticalSpacer_3">
+             <property name="orientation">
+              <enum>Qt::Vertical</enum>
+             </property>
+             <property name="sizeHint" stdset="0">
+              <size>
+               <width>20</width>
+               <height>128</height>
+              </size>
+             </property>
+            </spacer>
+           </item>
+          </layout>
+         </widget>
         </widget>
        </item>
        <item>
@@ -411,10 +655,17 @@
    <extends>QLineEdit</extends>
    <header>E5Gui/E5LineEdit.h</header>
   </customwidget>
+  <customwidget>
+   <class>E5PathPicker</class>
+   <extends>QWidget</extends>
+   <header>E5Gui/E5PathPicker.h</header>
+   <container>1</container>
+  </customwidget>
  </customwidgets>
  <tabstops>
   <tabstop>profilesList</tabstop>
   <tabstop>plusButton</tabstop>
+  <tabstop>copyButton</tabstop>
   <tabstop>minusButton</tabstop>
   <tabstop>profileEdit</tabstop>
   <tabstop>brokerAddressEdit</tabstop>
@@ -430,6 +681,14 @@
   <tabstop>willMessageEdit</tabstop>
   <tabstop>willQosSpinBox</tabstop>
   <tabstop>willRetainCheckBox</tabstop>
+  <tabstop>tlsGroupBox</tabstop>
+  <tabstop>tlsDefaultCertsButton</tabstop>
+  <tabstop>tlsCertsFileButton</tabstop>
+  <tabstop>tlsCertsFilePicker</tabstop>
+  <tabstop>tlsSelfSignedCertsButton</tabstop>
+  <tabstop>tlsSelfSignedCertsFilePicker</tabstop>
+  <tabstop>tlsSelfSignedClientCertFilePicker</tabstop>
+  <tabstop>tlsSelfSignedClientKeyFilePicker</tabstop>
  </tabstops>
  <resources/>
  <connections>
@@ -465,5 +724,37 @@
     </hint>
    </hints>
   </connection>
+  <connection>
+   <sender>tlsCertsFileButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>tlsCertsFileWidget</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>367</x>
+     <y>238</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>357</x>
+     <y>252</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>tlsSelfSignedCertsButton</sender>
+   <signal>toggled(bool)</signal>
+   <receiver>tlsSelfSignedFilesWidget</receiver>
+   <slot>setEnabled(bool)</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>387</x>
+     <y>287</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>466</x>
+     <y>305</y>
+    </hint>
+   </hints>
+  </connection>
  </connections>
 </ui>

eric ide

mercurial