42 @param parent reference to the parent widget |
43 @param parent reference to the parent widget |
43 @type QWidget |
44 @type QWidget |
44 """ |
45 """ |
45 super().__init__(parent) |
46 super().__init__(parent) |
46 self.setupUi(self) |
47 self.setupUi(self) |
47 |
48 |
48 self.tlsCertsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
49 self.tlsCertsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) |
49 self.tlsCertsFilePicker.setFilters( |
50 self.tlsCertsFilePicker.setFilters( |
50 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) |
51 self.tr("Certificate Files (*.crt *.pem);;All Files (*)") |
51 |
52 ) |
52 self.willPropertiesButton.setIcon( |
53 |
53 UI.PixmapCache.getIcon("listSelection")) |
54 self.willPropertiesButton.setIcon(UI.PixmapCache.getIcon("listSelection")) |
54 |
55 |
55 self.optionsWidget.setCurrentIndex(0) |
56 self.optionsWidget.setCurrentIndex(0) |
56 |
57 |
57 # initialize MQTTv5 related stuff |
58 # initialize MQTTv5 related stuff |
58 self.on_mqttv5Button_toggled(False) |
59 self.on_mqttv5Button_toggled(False) |
59 |
60 |
60 self.__populateDefaults(options=options) |
61 self.__populateDefaults(options=options) |
61 |
62 |
62 self.connectPropertiesButton.clicked[bool].connect( |
63 self.connectPropertiesButton.clicked[bool].connect( |
63 self.__propertiesTypeSelected) |
64 self.__propertiesTypeSelected |
|
65 ) |
64 self.disconnectPropertiesButton.clicked[bool].connect( |
66 self.disconnectPropertiesButton.clicked[bool].connect( |
65 self.__propertiesTypeSelected) |
67 self.__propertiesTypeSelected |
66 |
68 ) |
|
69 |
67 self.__updateOkButton() |
70 self.__updateOkButton() |
68 |
71 |
69 def __updateOkButton(self): |
72 def __updateOkButton(self): |
70 """ |
73 """ |
71 Private method to update the enabled state of the OK button. |
74 Private method to update the enabled state of the OK button. |
72 """ |
75 """ |
73 if ( |
76 if self.clientIdEdit.text() == "" and not self.cleanSessionCheckBox.isChecked(): |
74 self.clientIdEdit.text() == "" and |
|
75 not self.cleanSessionCheckBox.isChecked() |
|
76 ): |
|
77 enable = False |
77 enable = False |
78 EricMessageBox.critical( |
78 EricMessageBox.critical( |
79 self, |
79 self, |
80 self.tr("Invalid Connection Parameters"), |
80 self.tr("Invalid Connection Parameters"), |
81 self.tr("""An empty Client ID requires a clean session.""")) |
81 self.tr("""An empty Client ID requires a clean session."""), |
|
82 ) |
82 else: |
83 else: |
83 enable = True |
84 enable = True |
84 |
85 |
85 self.buttonBox.button( |
86 self.buttonBox.button(QDialogButtonBox.StandardButton.Ok).setEnabled(enable) |
86 QDialogButtonBox.StandardButton.Ok).setEnabled(enable) |
87 |
87 |
|
88 @pyqtSlot() |
88 @pyqtSlot() |
89 def on_generateIdButton_clicked(self): |
89 def on_generateIdButton_clicked(self): |
90 """ |
90 """ |
91 Private slot to generate a client ID. |
91 Private slot to generate a client ID. |
92 """ |
92 """ |
93 uuid = QUuid.createUuid() |
93 uuid = QUuid.createUuid() |
94 self.clientIdEdit.setText( |
94 self.clientIdEdit.setText(uuid.toString(QUuid.StringFormat.WithoutBraces)) |
95 uuid.toString(QUuid.StringFormat.WithoutBraces)) |
95 |
96 |
|
97 @pyqtSlot(str) |
96 @pyqtSlot(str) |
98 def on_clientIdEdit_textChanged(self, clientId): |
97 def on_clientIdEdit_textChanged(self, clientId): |
99 """ |
98 """ |
100 Private slot handling a change of the client ID string. |
99 Private slot handling a change of the client ID string. |
101 |
100 |
102 @param clientId client ID |
101 @param clientId client ID |
103 @type str |
102 @type str |
104 """ |
103 """ |
105 self.__updateOkButton() |
104 self.__updateOkButton() |
106 |
105 |
107 @pyqtSlot(bool) |
106 @pyqtSlot(bool) |
108 def on_cleanSessionCheckBox_clicked(self, checked): |
107 def on_cleanSessionCheckBox_clicked(self, checked): |
109 """ |
108 """ |
110 Private slot to handle a change of the clean session selection. |
109 Private slot to handle a change of the clean session selection. |
111 |
110 |
112 @param checked current state of the clean session selection |
111 @param checked current state of the clean session selection |
113 @type bool |
112 @type bool |
114 """ |
113 """ |
115 self.__updateOkButton() |
114 self.__updateOkButton() |
116 |
115 |
117 @pyqtSlot(bool) |
116 @pyqtSlot(bool) |
118 def on_mqttv5Button_toggled(self, checked): |
117 def on_mqttv5Button_toggled(self, checked): |
119 """ |
118 """ |
120 Private slot to handle the selection of the MQTT protocol. |
119 Private slot to handle the selection of the MQTT protocol. |
121 |
120 |
122 @param checked state of the button |
121 @param checked state of the button |
123 @type bool |
122 @type bool |
124 """ |
123 """ |
125 self.optionsWidget.setTabEnabled( |
124 self.optionsWidget.setTabEnabled( |
126 self.optionsWidget.indexOf(self.propertiesTab), |
125 self.optionsWidget.indexOf(self.propertiesTab), checked |
127 checked |
|
128 ) |
126 ) |
129 self.willPropertiesButton.setEnabled(checked) |
127 self.willPropertiesButton.setEnabled(checked) |
130 self.willPropertiesButton.setVisible(checked) |
128 self.willPropertiesButton.setVisible(checked) |
131 |
129 |
132 @pyqtSlot(QAbstractButton) |
130 @pyqtSlot(QAbstractButton) |
133 def on_buttonBox_clicked(self, button): |
131 def on_buttonBox_clicked(self, button): |
134 """ |
132 """ |
135 Private slot to handle the press of a button box button. |
133 Private slot to handle the press of a button box button. |
136 |
134 |
137 @param button button that has been pressed |
135 @param button button that has been pressed |
138 @type QAbstractButton |
136 @type QAbstractButton |
139 """ |
137 """ |
140 if button == self.buttonBox.button( |
138 if button == self.buttonBox.button( |
141 QDialogButtonBox.StandardButton.RestoreDefaults |
139 QDialogButtonBox.StandardButton.RestoreDefaults |
142 ): |
140 ): |
143 self.__populateDefaults(options=None) |
141 self.__populateDefaults(options=None) |
144 |
142 |
145 @pyqtSlot(bool) |
143 @pyqtSlot(bool) |
146 def on_samePropertiesCheckBox_toggled(self, checked): |
144 def on_samePropertiesCheckBox_toggled(self, checked): |
147 """ |
145 """ |
148 Private slot to handle a change of the properties usage. |
146 Private slot to handle a change of the properties usage. |
149 |
147 |
150 @param checked flag indicating to use the same user properties for |
148 @param checked flag indicating to use the same user properties for |
151 CONNECT and DISCONNECT |
149 CONNECT and DISCONNECT |
152 @type bool |
150 @type bool |
153 """ |
151 """ |
154 if checked and not self.connectPropertiesButton.isChecked(): |
152 if checked and not self.connectPropertiesButton.isChecked(): |
155 self.connectPropertiesButton.click() |
153 self.connectPropertiesButton.click() |
156 self.disconnectPropertiesButton.setEnabled(not checked) |
154 self.disconnectPropertiesButton.setEnabled(not checked) |
157 |
155 |
158 @pyqtSlot(bool) |
156 @pyqtSlot(bool) |
159 def __propertiesTypeSelected(self, checked): |
157 def __propertiesTypeSelected(self, checked): |
160 """ |
158 """ |
161 Private slot to handle the switching of the user properties type. |
159 Private slot to handle the switching of the user properties type. |
162 |
160 |
163 @param checked state of the buttons |
161 @param checked state of the buttons |
164 @type bool |
162 @type bool |
165 """ |
163 """ |
166 if checked: |
164 if checked: |
167 # handle the selection only |
165 # handle the selection only |
168 if self.connectPropertiesButton.isChecked(): |
166 if self.connectPropertiesButton.isChecked(): |
169 self.__userProperties["disconnect"] = ( |
167 self.__userProperties[ |
170 self.propertiesWidget.getProperties()) |
168 "disconnect" |
171 self.propertiesWidget.setProperties( |
169 ] = self.propertiesWidget.getProperties() |
172 self.__userProperties["connect"]) |
170 self.propertiesWidget.setProperties(self.__userProperties["connect"]) |
173 else: |
171 else: |
174 self.__userProperties["connect"] = ( |
172 self.__userProperties["connect"] = self.propertiesWidget.getProperties() |
175 self.propertiesWidget.getProperties()) |
173 self.propertiesWidget.setProperties(self.__userProperties["disconnect"]) |
176 self.propertiesWidget.setProperties( |
174 |
177 self.__userProperties["disconnect"]) |
|
178 |
|
179 @pyqtSlot() |
175 @pyqtSlot() |
180 def on_willPropertiesButton_clicked(self): |
176 def on_willPropertiesButton_clicked(self): |
181 """ |
177 """ |
182 Private slot to edit the last will user properties. |
178 Private slot to edit the last will user properties. |
183 """ |
179 """ |
184 from .MqttUserPropertiesEditor import MqttUserPropertiesEditorDialog |
180 from .MqttUserPropertiesEditor import MqttUserPropertiesEditorDialog |
185 |
181 |
186 dlg = MqttUserPropertiesEditorDialog( |
182 dlg = MqttUserPropertiesEditorDialog( |
187 self.tr("Last Will User Properties"), self.__willProperties, self) |
183 self.tr("Last Will User Properties"), self.__willProperties, self |
|
184 ) |
188 if dlg.exec() == QDialog.DialogCode.Accepted: |
185 if dlg.exec() == QDialog.DialogCode.Accepted: |
189 self.__willProperties = dlg.getProperties() |
186 self.__willProperties = dlg.getProperties() |
190 |
187 |
191 def __populateDefaults(self, options=None): |
188 def __populateDefaults(self, options=None): |
192 """ |
189 """ |
193 Private method to populate the dialog. |
190 Private method to populate the dialog. |
194 |
191 |
195 If no options dictionary is given, the dialog will be populated with |
192 If no options dictionary is given, the dialog will be populated with |
196 default values. |
193 default values. |
197 |
194 |
198 @param options dictionary containing the connection options to populate |
195 @param options dictionary containing the connection options to populate |
199 the dialog with. It must have the keys "ClientId", "Protocol", |
196 the dialog with. It must have the keys "ClientId", "Protocol", |
200 "ConnectionTimeout", "Keepalive", "CleanSession", "Username", |
197 "ConnectionTimeout", "Keepalive", "CleanSession", "Username", |
201 "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain", |
198 "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain", |
202 "WillProperties", "TlsEnable", "TlsCaCert", "UserProperties". |
199 "WillProperties", "TlsEnable", "TlsCaCert", "UserProperties". |
203 @type dict |
200 @type dict |
204 """ |
201 """ |
205 if options is None: |
202 if options is None: |
206 options = MqttClient.defaultConnectionOptions() |
203 options = MqttClient.defaultConnectionOptions() |
207 |
204 |
208 # general |
205 # general |
209 self.clientIdEdit.setText(options["ClientId"]) |
206 self.clientIdEdit.setText(options["ClientId"]) |
210 self.mqttv31Button.setChecked( |
207 self.mqttv31Button.setChecked(options["Protocol"] == MqttProtocols.MQTTv31) |
211 options["Protocol"] == MqttProtocols.MQTTv31) |
208 self.mqttv311Button.setChecked(options["Protocol"] == MqttProtocols.MQTTv311) |
212 self.mqttv311Button.setChecked( |
209 self.mqttv5Button.setChecked(options["Protocol"] == MqttProtocols.MQTTv5) |
213 options["Protocol"] == MqttProtocols.MQTTv311) |
|
214 self.mqttv5Button.setChecked( |
|
215 options["Protocol"] == MqttProtocols.MQTTv5) |
|
216 self.connectionTimeoutSpinBox.setValue(options["ConnectionTimeout"]) |
210 self.connectionTimeoutSpinBox.setValue(options["ConnectionTimeout"]) |
217 self.keepaliveSpinBox.setValue(options["Keepalive"]) |
211 self.keepaliveSpinBox.setValue(options["Keepalive"]) |
218 self.cleanSessionCheckBox.setChecked(options["CleanSession"]) |
212 self.cleanSessionCheckBox.setChecked(options["CleanSession"]) |
219 |
213 |
220 # user credentials |
214 # user credentials |
221 self.usernameEdit.setText(options["Username"]) |
215 self.usernameEdit.setText(options["Username"]) |
222 self.passwordEdit.setText(pwConvert(options["Password"], encode=False)) |
216 self.passwordEdit.setText(pwConvert(options["Password"], encode=False)) |
223 |
217 |
224 # last will and testament |
218 # last will and testament |
225 self.willQosSpinBox.setValue(options["WillQos"]) |
219 self.willQosSpinBox.setValue(options["WillQos"]) |
226 self.willRetainCheckBox.setChecked(options["WillRetain"]) |
220 self.willRetainCheckBox.setChecked(options["WillRetain"]) |
227 self.willTopicEdit.setText(options["WillTopic"]) |
221 self.willTopicEdit.setText(options["WillTopic"]) |
228 self.willMessageEdit.setPlainText(options["WillMessage"]) |
222 self.willMessageEdit.setPlainText(options["WillMessage"]) |
229 self.__willProperties = copy.deepcopy( |
223 self.__willProperties = copy.deepcopy(options.get("WillProperties", [])) |
230 options.get("WillProperties", [])) |
224 |
231 |
|
232 # TLS parameters |
225 # TLS parameters |
233 self.tlsEnableCheckBox.setChecked(options["TlsEnable"]) |
226 self.tlsEnableCheckBox.setChecked(options["TlsEnable"]) |
234 self.tlsCertsFilePicker.setText(options["TlsCaCert"]) |
227 self.tlsCertsFilePicker.setText(options["TlsCaCert"]) |
235 |
228 |
236 # user properties |
229 # user properties |
237 self.__userProperties = copy.deepcopy( |
230 self.__userProperties = copy.deepcopy(options.get("UserProperties", {})) |
238 options.get("UserProperties", {})) |
|
239 if not self.__userProperties: |
231 if not self.__userProperties: |
240 self.__userProperties = { |
232 self.__userProperties = { |
241 "connect": [], |
233 "connect": [], |
242 "disconnect": [], |
234 "disconnect": [], |
243 "use_connect": True, |
235 "use_connect": True, |
244 } |
236 } |
245 |
237 |
246 if options["Protocol"] == MqttProtocols.MQTTv5: |
238 if options["Protocol"] == MqttProtocols.MQTTv5: |
247 self.connectPropertiesButton.setChecked(True) |
239 self.connectPropertiesButton.setChecked(True) |
248 self.propertiesWidget.setProperties( |
240 self.propertiesWidget.setProperties(self.__userProperties["connect"]) |
249 self.__userProperties["connect"]) |
241 self.samePropertiesCheckBox.setChecked(self.__userProperties["use_connect"]) |
250 self.samePropertiesCheckBox.setChecked( |
|
251 self.__userProperties["use_connect"]) |
|
252 self.disconnectPropertiesButton.setEnabled( |
242 self.disconnectPropertiesButton.setEnabled( |
253 not self.__userProperties["use_connect"]) |
243 not self.__userProperties["use_connect"] |
|
244 ) |
254 else: |
245 else: |
255 self.propertiesWidget.clear() |
246 self.propertiesWidget.clear() |
256 |
247 |
257 def getConnectionOptions(self): |
248 def getConnectionOptions(self): |
258 """ |
249 """ |
259 Public method get the entered connection options. |
250 Public method get the entered connection options. |
260 |
251 |
261 @return dictionary containing the connection options. It has the keys |
252 @return dictionary containing the connection options. It has the keys |
262 "ClientId", "Protocol", "ConnectionTimeout", "Keepalive", |
253 "ClientId", "Protocol", "ConnectionTimeout", "Keepalive", |
263 "CleanSession", "Username", "Password", "WillTopic", "WillMessage", |
254 "CleanSession", "Username", "Password", "WillTopic", "WillMessage", |
264 "WillQos", "WillRetain", "WillProperties", "TlsEnable", |
255 "WillQos", "WillRetain", "WillProperties", "TlsEnable", |
265 "TlsCaCert", "UserProperties". |
256 "TlsCaCert", "UserProperties". |