MqttMonitor/MqttConnectionProfilesDialog.py

branch
eric7
changeset 123
3d7e63ed4fd1
parent 114
8c0e9e602124
child 127
8982ef7b7d67
equal deleted inserted replaced
122:28d69b9e1b6a 123:3d7e63ed4fd1
10 import collections 10 import collections
11 import copy 11 import copy
12 12
13 from PyQt6.QtCore import pyqtSlot, Qt, QUuid 13 from PyQt6.QtCore import pyqtSlot, Qt, QUuid
14 from PyQt6.QtWidgets import ( 14 from PyQt6.QtWidgets import (
15 QDialog, QDialogButtonBox, QAbstractButton, QListWidgetItem, QInputDialog, 15 QDialog,
16 QLineEdit 16 QDialogButtonBox,
17 QAbstractButton,
18 QListWidgetItem,
19 QInputDialog,
20 QLineEdit,
17 ) 21 )
18 22
19 from EricWidgets import EricMessageBox 23 from EricWidgets import EricMessageBox
20 from EricWidgets.EricPathPicker import EricPathPickerModes 24 from EricWidgets.EricPathPicker import EricPathPickerModes
21 25
30 34
31 class MqttConnectionProfilesDialog(QDialog, Ui_MqttConnectionProfilesDialog): 35 class MqttConnectionProfilesDialog(QDialog, Ui_MqttConnectionProfilesDialog):
32 """ 36 """
33 Class implementing a dialog to edit the MQTT connection profiles. 37 Class implementing a dialog to edit the MQTT connection profiles.
34 """ 38 """
39
35 def __init__(self, profiles, currentProfile="", parent=None): 40 def __init__(self, profiles, currentProfile="", parent=None):
36 """ 41 """
37 Constructor 42 Constructor
38 43
39 @param profiles dictionary containing dictionaries containing the 44 @param profiles dictionary containing dictionaries containing the
40 connection parameters. Each entry must have the keys 45 connection parameters. Each entry must have the keys
41 "BrokerAddress", "BrokerPort", "ClientId", "Protocol", 46 "BrokerAddress", "BrokerPort", "ClientId", "Protocol",
42 "ConnectionTimeout", "Keepalive", "CleanSession", "Username", 47 "ConnectionTimeout", "Keepalive", "CleanSession", "Username",
43 "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain", 48 "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain",
49 @param parent reference to the parent widget 54 @param parent reference to the parent widget
50 @type QWidget 55 @type QWidget
51 """ 56 """
52 super().__init__(parent) 57 super().__init__(parent)
53 self.setupUi(self) 58 self.setupUi(self)
54 59
55 self.__profiles = collections.defaultdict(self.__defaultProfile) 60 self.__profiles = collections.defaultdict(self.__defaultProfile)
56 self.__profiles.update(copy.deepcopy(profiles)) 61 self.__profiles.update(copy.deepcopy(profiles))
57 self.__profilesChanged = False 62 self.__profilesChanged = False
58 63
59 self.plusButton.setIcon(UI.PixmapCache.getIcon("plus")) 64 self.plusButton.setIcon(UI.PixmapCache.getIcon("plus"))
60 self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy")) 65 self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy"))
61 self.minusButton.setIcon(UI.PixmapCache.getIcon("minus")) 66 self.minusButton.setIcon(UI.PixmapCache.getIcon("minus"))
62 self.showPasswordButton.setIcon(UI.PixmapCache.getIcon("showPassword")) 67 self.showPasswordButton.setIcon(UI.PixmapCache.getIcon("showPassword"))
63 self.willPropertiesButton.setIcon( 68 self.willPropertiesButton.setIcon(UI.PixmapCache.getIcon("listSelection"))
64 UI.PixmapCache.getIcon("listSelection")) 69
65
66 self.tlsCertsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE) 70 self.tlsCertsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
67 self.tlsCertsFilePicker.setFilters( 71 self.tlsCertsFilePicker.setFilters(
68 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) 72 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")
69 self.tlsSelfSignedCertsFilePicker.setMode( 73 )
70 EricPathPickerModes.OPEN_FILE_MODE) 74 self.tlsSelfSignedCertsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
71 self.tlsSelfSignedCertsFilePicker.setFilters( 75 self.tlsSelfSignedCertsFilePicker.setFilters(
72 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) 76 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")
77 )
73 self.tlsSelfSignedClientCertFilePicker.setMode( 78 self.tlsSelfSignedClientCertFilePicker.setMode(
74 EricPathPickerModes.OPEN_FILE_MODE) 79 EricPathPickerModes.OPEN_FILE_MODE
80 )
75 self.tlsSelfSignedClientCertFilePicker.setFilters( 81 self.tlsSelfSignedClientCertFilePicker.setFilters(
76 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) 82 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")
83 )
77 self.tlsSelfSignedClientKeyFilePicker.setMode( 84 self.tlsSelfSignedClientKeyFilePicker.setMode(
78 EricPathPickerModes.OPEN_FILE_MODE) 85 EricPathPickerModes.OPEN_FILE_MODE
86 )
79 self.tlsSelfSignedClientKeyFilePicker.setFilters( 87 self.tlsSelfSignedClientKeyFilePicker.setFilters(
80 self.tr("Key Files (*.key *.pem);;All Files (*)")) 88 self.tr("Key Files (*.key *.pem);;All Files (*)")
81 89 )
90
82 self.profileTabWidget.setCurrentIndex(0) 91 self.profileTabWidget.setCurrentIndex(0)
83 92
84 self.connectPropertiesButton.clicked[bool].connect( 93 self.connectPropertiesButton.clicked[bool].connect(
85 self.__propertiesTypeSelected) 94 self.__propertiesTypeSelected
95 )
86 self.disconnectPropertiesButton.clicked[bool].connect( 96 self.disconnectPropertiesButton.clicked[bool].connect(
87 self.__propertiesTypeSelected) 97 self.__propertiesTypeSelected
88 98 )
99
89 if len(self.__profiles) == 0: 100 if len(self.__profiles) == 0:
90 self.minusButton.setEnabled(False) 101 self.minusButton.setEnabled(False)
91 self.copyButton.setEnabled(False) 102 self.copyButton.setEnabled(False)
92 103
93 self.profileFrame.setEnabled(False) 104 self.profileFrame.setEnabled(False)
94 self.__populatingProfile = False 105 self.__populatingProfile = False
95 self.__deletingProfile = False 106 self.__deletingProfile = False
96 107
97 self.__populateProfilesList(currentProfile=currentProfile) 108 self.__populateProfilesList(currentProfile=currentProfile)
98 109
99 @pyqtSlot(str) 110 @pyqtSlot(str)
100 def on_profileEdit_textChanged(self, name): 111 def on_profileEdit_textChanged(self, name):
101 """ 112 """
102 Private slot to handle changes of the profile name. 113 Private slot to handle changes of the profile name.
103 114
104 @param name name of the profile 115 @param name name of the profile
105 @type str 116 @type str
106 """ 117 """
107 self.__updateApplyButton() 118 self.__updateApplyButton()
108 119
109 @pyqtSlot(QAbstractButton) 120 @pyqtSlot(QAbstractButton)
110 def on_profileButtonBox_clicked(self, button): 121 def on_profileButtonBox_clicked(self, button):
111 """ 122 """
112 Private slot handling presses of the profile buttons. 123 Private slot handling presses of the profile buttons.
113 124
114 @param button reference to the pressed button 125 @param button reference to the pressed button
115 @type QAbstractButton 126 @type QAbstractButton
116 """ 127 """
117 if button == self.profileButtonBox.button( 128 if button == self.profileButtonBox.button(
118 QDialogButtonBox.StandardButton.Apply 129 QDialogButtonBox.StandardButton.Apply
119 ): 130 ):
120 currentProfile = self.__applyProfile() 131 currentProfile = self.__applyProfile()
121 self.__populateProfilesList(currentProfile=currentProfile) 132 self.__populateProfilesList(currentProfile=currentProfile)
122 133
123 elif button == self.profileButtonBox.button( 134 elif button == self.profileButtonBox.button(
124 QDialogButtonBox.StandardButton.Reset 135 QDialogButtonBox.StandardButton.Reset
125 ): 136 ):
126 self.__resetProfile() 137 self.__resetProfile()
127 138
128 elif button == self.profileButtonBox.button( 139 elif button == self.profileButtonBox.button(
129 QDialogButtonBox.StandardButton.RestoreDefaults 140 QDialogButtonBox.StandardButton.RestoreDefaults
130 ): 141 ):
131 self.__populateProfileDefault() 142 self.__populateProfileDefault()
132 143
133 @pyqtSlot(QListWidgetItem, QListWidgetItem) 144 @pyqtSlot(QListWidgetItem, QListWidgetItem)
134 def on_profilesList_currentItemChanged(self, current, previous): 145 def on_profilesList_currentItemChanged(self, current, previous):
135 """ 146 """
136 Private slot to handle a change of the current profile. 147 Private slot to handle a change of the current profile.
137 148
138 @param current new current item 149 @param current new current item
139 @type QListWidgetItem 150 @type QListWidgetItem
140 @param previous previous current item 151 @param previous previous current item
141 @type QListWidgetItem 152 @type QListWidgetItem
142 """ 153 """
143 self.minusButton.setEnabled(current is not None) 154 self.minusButton.setEnabled(current is not None)
144 self.copyButton.setEnabled(current is not None) 155 self.copyButton.setEnabled(current is not None)
145 156
146 if ( 157 if (
147 current is not previous and 158 current is not previous
148 not self.__deletingProfile and 159 and not self.__deletingProfile
149 self.__isChangedProfile() 160 and self.__isChangedProfile()
150 ): 161 ):
151 # modified profile belongs to previous 162 # modified profile belongs to previous
152 yes = EricMessageBox.yesNo( 163 yes = EricMessageBox.yesNo(
153 self, 164 self,
154 self.tr("Changed Connection Profile"), 165 self.tr("Changed Connection Profile"),
155 self.tr("""The current profile has unsaved changes.""" 166 self.tr(
156 """ Shall these be saved?"""), 167 """The current profile has unsaved changes."""
168 """ Shall these be saved?"""
169 ),
157 icon=EricMessageBox.Warning, 170 icon=EricMessageBox.Warning,
158 yesDefault=True) 171 yesDefault=True,
172 )
159 if yes: 173 if yes:
160 self.__applyProfile() 174 self.__applyProfile()
161 175
162 if current: 176 if current:
163 profileName = current.text() 177 profileName = current.text()
164 self.__populateProfile(profileName) 178 self.__populateProfile(profileName)
165 else: 179 else:
166 self.__clearProfile() 180 self.__clearProfile()
167 181
168 @pyqtSlot() 182 @pyqtSlot()
169 def on_plusButton_clicked(self): 183 def on_plusButton_clicked(self):
170 """ 184 """
171 Private slot to add a new empty profile entry. 185 Private slot to add a new empty profile entry.
172 """ 186 """
173 profileName, ok = QInputDialog.getText( 187 profileName, ok = QInputDialog.getText(
174 self, 188 self,
175 self.tr("New Connection Profile"), 189 self.tr("New Connection Profile"),
176 self.tr("Enter name for the new Connection Profile:"), 190 self.tr("Enter name for the new Connection Profile:"),
177 QLineEdit.EchoMode.Normal) 191 QLineEdit.EchoMode.Normal,
192 )
178 if ok and bool(profileName): 193 if ok and bool(profileName):
179 if profileName in self.__profiles: 194 if profileName in self.__profiles:
180 EricMessageBox.warning( 195 EricMessageBox.warning(
181 self, 196 self,
182 self.tr("New Connection Profile"), 197 self.tr("New Connection Profile"),
183 self.tr("""<p>A connection named <b>{0}</b> exists""" 198 self.tr(
184 """ already. Aborting...</p>""").format( 199 """<p>A connection named <b>{0}</b> exists"""
185 profileName)) 200 """ already. Aborting...</p>"""
201 ).format(profileName),
202 )
186 else: 203 else:
187 itm = QListWidgetItem(profileName, self.profilesList) 204 itm = QListWidgetItem(profileName, self.profilesList)
188 self.profilesList.setCurrentItem(itm) 205 self.profilesList.setCurrentItem(itm)
189 self.brokerAddressEdit.setFocus( 206 self.brokerAddressEdit.setFocus(Qt.FocusReason.OtherFocusReason)
190 Qt.FocusReason.OtherFocusReason) 207
191
192 @pyqtSlot() 208 @pyqtSlot()
193 def on_copyButton_clicked(self): 209 def on_copyButton_clicked(self):
194 """ 210 """
195 Private slot to copy the selected profile entry. 211 Private slot to copy the selected profile entry.
196 """ 212 """
199 profileName = itm.text() 215 profileName = itm.text()
200 newProfileName, ok = QInputDialog.getText( 216 newProfileName, ok = QInputDialog.getText(
201 self, 217 self,
202 self.tr("Copy Connection Profile"), 218 self.tr("Copy Connection Profile"),
203 self.tr("Enter name for the copied Connection Profile:"), 219 self.tr("Enter name for the copied Connection Profile:"),
204 QLineEdit.EchoMode.Normal) 220 QLineEdit.EchoMode.Normal,
221 )
205 if ok and bool(newProfileName): 222 if ok and bool(newProfileName):
206 if newProfileName in self.__profiles: 223 if newProfileName in self.__profiles:
207 EricMessageBox.warning( 224 EricMessageBox.warning(
208 self, 225 self,
209 self.tr("Copy Connection Profile"), 226 self.tr("Copy Connection Profile"),
210 self.tr("""<p>A connection named <b>{0}</b> exists""" 227 self.tr(
211 """ already. Aborting...</p>""").format( 228 """<p>A connection named <b>{0}</b> exists"""
212 newProfileName)) 229 """ already. Aborting...</p>"""
230 ).format(newProfileName),
231 )
213 else: 232 else:
214 connectionProfile = self.__defaultProfile() 233 connectionProfile = self.__defaultProfile()
215 connectionProfile.update( 234 connectionProfile.update(
216 copy.deepcopy(self.__profiles[profileName])) 235 copy.deepcopy(self.__profiles[profileName])
236 )
217 self.__profiles[newProfileName] = connectionProfile 237 self.__profiles[newProfileName] = connectionProfile
218 self.__profilesChanged = True 238 self.__profilesChanged = True
219 239
220 itm = QListWidgetItem(newProfileName, self.profilesList) 240 itm = QListWidgetItem(newProfileName, self.profilesList)
221 self.profilesList.setCurrentItem(itm) 241 self.profilesList.setCurrentItem(itm)
222 self.brokerAddressEdit.setFocus( 242 self.brokerAddressEdit.setFocus(Qt.FocusReason.OtherFocusReason)
223 Qt.FocusReason.OtherFocusReason) 243
224
225 @pyqtSlot() 244 @pyqtSlot()
226 def on_minusButton_clicked(self): 245 def on_minusButton_clicked(self):
227 """ 246 """
228 Private slot to delete the selected entry. 247 Private slot to delete the selected entry.
229 """ 248 """
231 if itm: 250 if itm:
232 profileName = itm.text() 251 profileName = itm.text()
233 yes = EricMessageBox.yesNo( 252 yes = EricMessageBox.yesNo(
234 self, 253 self,
235 self.tr("Delete Connection Profile"), 254 self.tr("Delete Connection Profile"),
236 self.tr("""<p>Shall the Connection Profile <b>{0}</b>""" 255 self.tr(
237 """ really be deleted?</p>""").format(profileName) 256 """<p>Shall the Connection Profile <b>{0}</b>"""
257 """ really be deleted?</p>"""
258 ).format(profileName),
238 ) 259 )
239 if yes: 260 if yes:
240 self.__deletingProfile = True 261 self.__deletingProfile = True
241 del self.__profiles[profileName] 262 del self.__profiles[profileName]
242 self.__profilesChanged = True 263 self.__profilesChanged = True
243 self.__populateProfilesList() 264 self.__populateProfilesList()
244 self.__deletingProfile = False 265 self.__deletingProfile = False
245 266
246 self.profilesList.setFocus(Qt.FocusReason.OtherFocusReason) 267 self.profilesList.setFocus(Qt.FocusReason.OtherFocusReason)
247 268
248 def getProfiles(self): 269 def getProfiles(self):
249 """ 270 """
250 Public method to return a dictionary of profiles. 271 Public method to return a dictionary of profiles.
251 272
252 @return dictionary containing dictionaries containing the defined 273 @return dictionary containing dictionaries containing the defined
253 connection profiles. Each entry has the keys "BrokerAddress", 274 connection profiles. Each entry has the keys "BrokerAddress",
254 "BrokerPort", "ClientId", "Protocol", "ConnectionTimeout", 275 "BrokerPort", "ClientId", "Protocol", "ConnectionTimeout",
255 "Keepalive", "CleanSession", "Username", "Password", "WillTopic", 276 "Keepalive", "CleanSession", "Username", "Password", "WillTopic",
256 "WillMessage", "WillQos", "WillRetain", "WillProperties", 277 "WillMessage", "WillQos", "WillRetain", "WillProperties",
259 @rtype dict 280 @rtype dict
260 """ 281 """
261 profilesDict = {} 282 profilesDict = {}
262 profilesDict.update(copy.deepcopy(dict(self.__profiles))) 283 profilesDict.update(copy.deepcopy(dict(self.__profiles)))
263 return profilesDict 284 return profilesDict
264 285
265 def __applyProfile(self): 286 def __applyProfile(self):
266 """ 287 """
267 Private method to apply the entered data to the list of profiles. 288 Private method to apply the entered data to the list of profiles.
268 289
269 @return name of the applied profile 290 @return name of the applied profile
270 @rtype str 291 @rtype str
271 """ 292 """
272 if self.mqttv31Button.isChecked(): 293 if self.mqttv31Button.isChecked():
273 protocol = MqttProtocols.MQTTv31 294 protocol = MqttProtocols.MQTTv31
276 elif self.mqttv5Button.isChecked(): 297 elif self.mqttv5Button.isChecked():
277 protocol = MqttProtocols.MQTTv5 298 protocol = MqttProtocols.MQTTv5
278 else: 299 else:
279 # should never happen 300 # should never happen
280 protocol = MqttProtocols.MQTTv311 301 protocol = MqttProtocols.MQTTv311
281 302
282 if protocol == MqttProtocols.MQTTv5: 303 if protocol == MqttProtocols.MQTTv5:
283 if self.connectPropertiesButton.isChecked(): 304 if self.connectPropertiesButton.isChecked():
284 self.__userProperties["connect"] = ( 305 self.__userProperties["connect"] = self.propertiesWidget.getProperties()
285 self.propertiesWidget.getProperties())
286 else: 306 else:
287 self.__userProperties["disconnect"] = ( 307 self.__userProperties[
288 self.propertiesWidget.getProperties()) 308 "disconnect"
289 self.__userProperties["use_connect"] = ( 309 ] = self.propertiesWidget.getProperties()
290 self.samePropertiesCheckBox.isChecked()) 310 self.__userProperties[
311 "use_connect"
312 ] = self.samePropertiesCheckBox.isChecked()
291 else: 313 else:
292 self.__userProperties = {} 314 self.__userProperties = {}
293 self.__willProperties = [] 315 self.__willProperties = []
294 316
295 profileName = self.profileEdit.text() 317 profileName = self.profileEdit.text()
296 connectionProfile = { 318 connectionProfile = {
297 "BrokerAddress": self.brokerAddressEdit.text(), 319 "BrokerAddress": self.brokerAddressEdit.text(),
298 "BrokerPort": self.brokerPortSpinBox.value(), 320 "BrokerPort": self.brokerPortSpinBox.value(),
299 "ClientId": self.clientIdEdit.text(), 321 "ClientId": self.clientIdEdit.text(),
316 } 338 }
317 if connectionProfile["TlsEnable"]: 339 if connectionProfile["TlsEnable"]:
318 if self.tlsCertsFileButton.isChecked(): 340 if self.tlsCertsFileButton.isChecked():
319 connectionProfile["TlsCaCert"] = self.tlsCertsFilePicker.text() 341 connectionProfile["TlsCaCert"] = self.tlsCertsFilePicker.text()
320 elif self.tlsSelfSignedCertsButton.isChecked(): 342 elif self.tlsSelfSignedCertsButton.isChecked():
321 connectionProfile["TlsCaCert"] = ( 343 connectionProfile[
322 self.tlsSelfSignedCertsFilePicker.text()) 344 "TlsCaCert"
323 connectionProfile["TlsClientCert"] = ( 345 ] = self.tlsSelfSignedCertsFilePicker.text()
324 self.tlsSelfSignedClientCertFilePicker.text()) 346 connectionProfile[
325 connectionProfile["TlsClientKey"] = ( 347 "TlsClientCert"
326 self.tlsSelfSignedClientKeyFilePicker.text()) 348 ] = self.tlsSelfSignedClientCertFilePicker.text()
327 349 connectionProfile[
350 "TlsClientKey"
351 ] = self.tlsSelfSignedClientKeyFilePicker.text()
352
328 self.__profiles[profileName] = connectionProfile 353 self.__profiles[profileName] = connectionProfile
329 self.__profilesChanged = True 354 self.__profilesChanged = True
330 355
331 return profileName 356 return profileName
332 357
333 def __defaultProfile(self): 358 def __defaultProfile(self):
334 """ 359 """
335 Private method to populate non-existing profile items. 360 Private method to populate non-existing profile items.
336 361
337 @return default dictionary entry 362 @return default dictionary entry
338 @rtype dict 363 @rtype dict
339 """ 364 """
340 defaultProfile = MqttClient.defaultConnectionOptions() 365 defaultProfile = MqttClient.defaultConnectionOptions()
341 defaultProfile["BrokerAddress"] = "" 366 defaultProfile["BrokerAddress"] = ""
342 if defaultProfile["TlsEnable"]: 367 if defaultProfile["TlsEnable"]:
343 defaultProfile["BrokerPort"] = 8883 368 defaultProfile["BrokerPort"] = 8883
344 else: 369 else:
345 defaultProfile["BrokerPort"] = 1883 370 defaultProfile["BrokerPort"] = 1883
346 371
347 return defaultProfile 372 return defaultProfile
348 373
349 def __populateProfilesList(self, currentProfile=""): 374 def __populateProfilesList(self, currentProfile=""):
350 """ 375 """
351 Private method to populate the list of defined profiles. 376 Private method to populate the list of defined profiles.
352 377
353 @param currentProfile name of the current profile 378 @param currentProfile name of the current profile
354 @type str 379 @type str
355 """ 380 """
356 if not currentProfile: 381 if not currentProfile:
357 currentItem = self.profilesList.currentItem() 382 currentItem = self.profilesList.currentItem()
358 if currentItem: 383 if currentItem:
359 currentProfile = currentItem.text() 384 currentProfile = currentItem.text()
360 385
361 self.profilesList.clear() 386 self.profilesList.clear()
362 self.profilesList.addItems(sorted(self.__profiles.keys())) 387 self.profilesList.addItems(sorted(self.__profiles.keys()))
363 388
364 if currentProfile: 389 if currentProfile:
365 items = self.profilesList.findItems( 390 items = self.profilesList.findItems(
366 currentProfile, Qt.MatchFlag.MatchExactly) 391 currentProfile, Qt.MatchFlag.MatchExactly
392 )
367 if items: 393 if items:
368 self.profilesList.setCurrentItem(items[0]) 394 self.profilesList.setCurrentItem(items[0])
369 395
370 if len(self.__profiles) == 0: 396 if len(self.__profiles) == 0:
371 self.profileFrame.setEnabled(False) 397 self.profileFrame.setEnabled(False)
372 398
373 def __populateProfile(self, profileName): 399 def __populateProfile(self, profileName):
374 """ 400 """
375 Private method to populate the profile data entry fields. 401 Private method to populate the profile data entry fields.
376 402
377 @param profileName name of the profile to get data from 403 @param profileName name of the profile to get data from
378 @type str 404 @type str
379 """ 405 """
380 connectionProfile = self.__defaultProfile() 406 connectionProfile = self.__defaultProfile()
381 if profileName: 407 if profileName:
382 connectionProfile.update(self.__profiles[profileName]) 408 connectionProfile.update(self.__profiles[profileName])
383 409
384 self.__populatingProfile = True 410 self.__populatingProfile = True
385 if profileName is not None: 411 if profileName is not None:
386 self.profileEdit.setText(profileName) 412 self.profileEdit.setText(profileName)
387 self.brokerAddressEdit.setText(connectionProfile["BrokerAddress"]) 413 self.brokerAddressEdit.setText(connectionProfile["BrokerAddress"])
388 self.brokerPortSpinBox.setValue(connectionProfile["BrokerPort"]) 414 self.brokerPortSpinBox.setValue(connectionProfile["BrokerPort"])
389 self.clientIdEdit.setText(connectionProfile["ClientId"]) 415 self.clientIdEdit.setText(connectionProfile["ClientId"])
390 416
391 # general tab 417 # general tab
392 self.mqttv31Button.setChecked( 418 self.mqttv31Button.setChecked(
393 connectionProfile["Protocol"] == MqttProtocols.MQTTv31) 419 connectionProfile["Protocol"] == MqttProtocols.MQTTv31
420 )
394 self.mqttv311Button.setChecked( 421 self.mqttv311Button.setChecked(
395 connectionProfile["Protocol"] == MqttProtocols.MQTTv311) 422 connectionProfile["Protocol"] == MqttProtocols.MQTTv311
423 )
396 self.mqttv5Button.setChecked( 424 self.mqttv5Button.setChecked(
397 connectionProfile["Protocol"] == MqttProtocols.MQTTv5) 425 connectionProfile["Protocol"] == MqttProtocols.MQTTv5
426 )
398 self.on_mqttv5Button_toggled(self.mqttv5Button.isChecked()) 427 self.on_mqttv5Button_toggled(self.mqttv5Button.isChecked())
399 self.connectionTimeoutSpinBox.setValue( 428 self.connectionTimeoutSpinBox.setValue(connectionProfile["ConnectionTimeout"])
400 connectionProfile["ConnectionTimeout"])
401 self.keepaliveSpinBox.setValue(connectionProfile["Keepalive"]) 429 self.keepaliveSpinBox.setValue(connectionProfile["Keepalive"])
402 self.cleanSessionCheckBox.setChecked(connectionProfile["CleanSession"]) 430 self.cleanSessionCheckBox.setChecked(connectionProfile["CleanSession"])
403 431
404 # user credentials tab 432 # user credentials tab
405 self.usernameEdit.setText(connectionProfile["Username"]) 433 self.usernameEdit.setText(connectionProfile["Username"])
406 self.passwordEdit.setText( 434 self.passwordEdit.setText(
407 pwConvert(connectionProfile["Password"], encode=False)) 435 pwConvert(connectionProfile["Password"], encode=False)
408 436 )
437
409 # will tab 438 # will tab
410 self.willTopicEdit.setText(connectionProfile["WillTopic"]) 439 self.willTopicEdit.setText(connectionProfile["WillTopic"])
411 self.willMessageEdit.setPlainText(connectionProfile["WillMessage"]) 440 self.willMessageEdit.setPlainText(connectionProfile["WillMessage"])
412 self.willQosSpinBox.setValue(connectionProfile["WillQos"]) 441 self.willQosSpinBox.setValue(connectionProfile["WillQos"])
413 self.willRetainCheckBox.setChecked(connectionProfile["WillRetain"]) 442 self.willRetainCheckBox.setChecked(connectionProfile["WillRetain"])
414 self.__willProperties = copy.deepcopy( 443 self.__willProperties = copy.deepcopy(
415 connectionProfile.get("WillProperties", [])) 444 connectionProfile.get("WillProperties", [])
416 445 )
446
417 # SSL/TLS tab 447 # SSL/TLS tab
418 self.tlsGroupBox.setChecked(connectionProfile["TlsEnable"]) 448 self.tlsGroupBox.setChecked(connectionProfile["TlsEnable"])
419 if ( 449 if connectionProfile["TlsCaCert"] and connectionProfile["TlsClientCert"]:
420 connectionProfile["TlsCaCert"] and
421 connectionProfile["TlsClientCert"]
422 ):
423 self.tlsSelfSignedCertsButton.setChecked(True) 450 self.tlsSelfSignedCertsButton.setChecked(True)
424 self.tlsSelfSignedCertsFilePicker.setText( 451 self.tlsSelfSignedCertsFilePicker.setText(connectionProfile["TlsCaCert"])
425 connectionProfile["TlsCaCert"])
426 self.tlsSelfSignedClientCertFilePicker.setText( 452 self.tlsSelfSignedClientCertFilePicker.setText(
427 connectionProfile["TlsClientCert"]) 453 connectionProfile["TlsClientCert"]
454 )
428 self.tlsSelfSignedClientKeyFilePicker.setText( 455 self.tlsSelfSignedClientKeyFilePicker.setText(
429 connectionProfile["TlsClientKey"]) 456 connectionProfile["TlsClientKey"]
457 )
430 elif connectionProfile["TlsCaCert"]: 458 elif connectionProfile["TlsCaCert"]:
431 self.tlsCertsFileButton.setChecked(True) 459 self.tlsCertsFileButton.setChecked(True)
432 self.tlsCertsFilePicker.setText(connectionProfile["TlsCaCert"]) 460 self.tlsCertsFilePicker.setText(connectionProfile["TlsCaCert"])
433 else: 461 else:
434 self.tlsDefaultCertsButton.setChecked(True) 462 self.tlsDefaultCertsButton.setChecked(True)
435 463
436 # user properties tab 464 # user properties tab
437 self.__userProperties = copy.deepcopy( 465 self.__userProperties = copy.deepcopy(
438 connectionProfile.get("UserProperties", {})) 466 connectionProfile.get("UserProperties", {})
467 )
439 if not self.__userProperties: 468 if not self.__userProperties:
440 self.__userProperties = { 469 self.__userProperties = {
441 "connect": [], 470 "connect": [],
442 "disconnect": [], 471 "disconnect": [],
443 "use_connect": True, 472 "use_connect": True,
444 } 473 }
445 474
446 if connectionProfile["Protocol"] == MqttProtocols.MQTTv5: 475 if connectionProfile["Protocol"] == MqttProtocols.MQTTv5:
447 self.connectPropertiesButton.setChecked(True) 476 self.connectPropertiesButton.setChecked(True)
448 self.propertiesWidget.setProperties( 477 self.propertiesWidget.setProperties(self.__userProperties["connect"])
449 self.__userProperties["connect"]) 478 self.samePropertiesCheckBox.setChecked(self.__userProperties["use_connect"])
450 self.samePropertiesCheckBox.setChecked(
451 self.__userProperties["use_connect"])
452 self.disconnectPropertiesButton.setEnabled( 479 self.disconnectPropertiesButton.setEnabled(
453 not self.__userProperties["use_connect"]) 480 not self.__userProperties["use_connect"]
481 )
454 else: 482 else:
455 self.propertiesWidget.clear() 483 self.propertiesWidget.clear()
456 484
457 self.__populatingProfile = False 485 self.__populatingProfile = False
458 486
459 self.showPasswordButton.setChecked(False) 487 self.showPasswordButton.setChecked(False)
460 self.profileFrame.setEnabled(True) 488 self.profileFrame.setEnabled(True)
461 self.__updateApplyButton() 489 self.__updateApplyButton()
462 490
463 self.profileTabWidget.setCurrentIndex(0) 491 self.profileTabWidget.setCurrentIndex(0)
464 492
465 def __clearProfile(self): 493 def __clearProfile(self):
466 """ 494 """
467 Private method to clear the profile data entry fields. 495 Private method to clear the profile data entry fields.
468 """ 496 """
469 self.__populatingProfile = True 497 self.__populatingProfile = True
487 self.tlsCertsFilePicker.setText("") 515 self.tlsCertsFilePicker.setText("")
488 self.tlsSelfSignedCertsButton.setChecked(False) 516 self.tlsSelfSignedCertsButton.setChecked(False)
489 self.tlsSelfSignedCertsFilePicker.setText("") 517 self.tlsSelfSignedCertsFilePicker.setText("")
490 self.tlsSelfSignedClientCertFilePicker.setText("") 518 self.tlsSelfSignedClientCertFilePicker.setText("")
491 self.tlsSelfSignedClientKeyFilePicker.setText("") 519 self.tlsSelfSignedClientKeyFilePicker.setText("")
492 520
493 self.__userProperties = { 521 self.__userProperties = {
494 "connect": [], 522 "connect": [],
495 "disconnect": [], 523 "disconnect": [],
496 "use_connect": True, 524 "use_connect": True,
497 } 525 }
498 self.propertiesWidget.clear() 526 self.propertiesWidget.clear()
499 self.samePropertiesCheckBox.setChecked(True) 527 self.samePropertiesCheckBox.setChecked(True)
500 self.connectPropertiesButton.setChecked(True) 528 self.connectPropertiesButton.setChecked(True)
501 self.disconnectPropertiesButton.setEnabled(False) 529 self.disconnectPropertiesButton.setEnabled(False)
502 530
503 self.__populatingProfile = False 531 self.__populatingProfile = False
504 532
505 self.showPasswordButton.setChecked(False) 533 self.showPasswordButton.setChecked(False)
506 self.profileFrame.setEnabled(False) 534 self.profileFrame.setEnabled(False)
507 self.__updateApplyButton() 535 self.__updateApplyButton()
508 536
509 def __resetProfile(self): 537 def __resetProfile(self):
510 """ 538 """
511 Private method to reset the profile data entry fields to their stored 539 Private method to reset the profile data entry fields to their stored
512 values. 540 values.
513 """ 541 """
514 profileName = self.profileEdit.text() 542 profileName = self.profileEdit.text()
515 if profileName in self.__profiles: 543 if profileName in self.__profiles:
516 self.__populateProfile(profileName) 544 self.__populateProfile(profileName)
517 545
518 def __populateProfileDefault(self): 546 def __populateProfileDefault(self):
519 """ 547 """
520 Private method to populate the profile data entry fields with default 548 Private method to populate the profile data entry fields with default
521 profile values. 549 profile values.
522 """ 550 """
523 self.__populateProfile(None) 551 self.__populateProfile(None)
524 552
525 def __isChangedProfile(self): 553 def __isChangedProfile(self):
526 """ 554 """
527 Private method to check, if the currently shown profile contains some 555 Private method to check, if the currently shown profile contains some
528 changed data. 556 changed data.
529 557
530 @return flag indicating changed data 558 @return flag indicating changed data
531 @rtype bool 559 @rtype bool
532 """ 560 """
533 profileName = self.profileEdit.text() 561 profileName = self.profileEdit.text()
534 if profileName == "": 562 if profileName == "":
535 return False 563 return False
536 564
537 elif profileName in self.__profiles: 565 elif profileName in self.__profiles:
538 if self.mqttv31Button.isChecked(): 566 if self.mqttv31Button.isChecked():
539 protocol = MqttProtocols.MQTTv31 567 protocol = MqttProtocols.MQTTv31
540 elif self.mqttv311Button.isChecked(): 568 elif self.mqttv311Button.isChecked():
541 protocol = MqttProtocols.MQTTv311 569 protocol = MqttProtocols.MQTTv311
542 elif self.mqttv5Button.isChecked(): 570 elif self.mqttv5Button.isChecked():
543 protocol = MqttProtocols.MQTTv5 571 protocol = MqttProtocols.MQTTv5
544 else: 572 else:
545 # should never happen 573 # should never happen
546 protocol = MqttProtocols.MQTTv311 574 protocol = MqttProtocols.MQTTv311
547 575
548 connectionProfile = self.__defaultProfile() 576 connectionProfile = self.__defaultProfile()
549 connectionProfile.update(self.__profiles[profileName]) 577 connectionProfile.update(self.__profiles[profileName])
550 changed = ( 578 changed = (
551 self.brokerAddressEdit.text() != 579 self.brokerAddressEdit.text() != connectionProfile["BrokerAddress"]
552 connectionProfile["BrokerAddress"] or 580 or self.brokerPortSpinBox.value() != connectionProfile["BrokerPort"]
553 self.brokerPortSpinBox.value() != 581 or self.clientIdEdit.text() != connectionProfile["ClientId"]
554 connectionProfile["BrokerPort"] or 582 or protocol != connectionProfile["Protocol"]
555 self.clientIdEdit.text() != connectionProfile["ClientId"] or 583 or self.connectionTimeoutSpinBox.value()
556 protocol != connectionProfile["Protocol"] or 584 != connectionProfile["ConnectionTimeout"]
557 self.connectionTimeoutSpinBox.value() != 585 or self.keepaliveSpinBox.value() != connectionProfile["Keepalive"]
558 connectionProfile["ConnectionTimeout"] or 586 or self.cleanSessionCheckBox.isChecked()
559 self.keepaliveSpinBox.value() != 587 != connectionProfile["CleanSession"]
560 connectionProfile["Keepalive"] or 588 or self.usernameEdit.text() != connectionProfile["Username"]
561 self.cleanSessionCheckBox.isChecked() != 589 or self.passwordEdit.text()
562 connectionProfile["CleanSession"] or 590 != pwConvert(connectionProfile["Password"], encode=False)
563 self.usernameEdit.text() != connectionProfile["Username"] or 591 or self.willTopicEdit.text() != connectionProfile["WillTopic"]
564 self.passwordEdit.text() != 592 or self.willMessageEdit.toPlainText()
565 pwConvert(connectionProfile["Password"], encode=False) or 593 != connectionProfile["WillMessage"]
566 self.willTopicEdit.text() != connectionProfile["WillTopic"] or 594 or self.willQosSpinBox.value() != connectionProfile["WillQos"]
567 self.willMessageEdit.toPlainText() != 595 or self.willRetainCheckBox.isChecked()
568 connectionProfile["WillMessage"] or 596 != connectionProfile["WillRetain"]
569 self.willQosSpinBox.value() != connectionProfile["WillQos"] or 597 or self.tlsGroupBox.isChecked() != connectionProfile["TlsEnable"]
570 self.willRetainCheckBox.isChecked() !=
571 connectionProfile["WillRetain"] or
572 self.tlsGroupBox.isChecked() != connectionProfile["TlsEnable"]
573 ) 598 )
574 # check will properties only, ig not yet changed 599 # check will properties only, ig not yet changed
575 if not changed and protocol == MqttProtocols.MQTTv5: 600 if not changed and protocol == MqttProtocols.MQTTv5:
576 changed |= ( 601 changed |= sorted(self.__willProperties) != sorted(
577 sorted(self.__willProperties) != 602 connectionProfile["WillProperties"]
578 sorted(connectionProfile["WillProperties"])
579 ) 603 )
580 # check TLS stuff only, if not yet changed 604 # check TLS stuff only, if not yet changed
581 if not changed: 605 if not changed:
582 if self.tlsCertsFileButton.isChecked(): 606 if self.tlsCertsFileButton.isChecked():
583 changed |= ( 607 changed |= (
584 self.tlsCertsFilePicker.text() != 608 self.tlsCertsFilePicker.text() != connectionProfile["TlsCaCert"]
585 connectionProfile["TlsCaCert"]
586 ) 609 )
587 elif self.tlsSelfSignedCertsButton.isChecked(): 610 elif self.tlsSelfSignedCertsButton.isChecked():
588 changed |= ( 611 changed |= (
589 self.tlsSelfSignedCertsFilePicker.text() != 612 self.tlsSelfSignedCertsFilePicker.text()
590 connectionProfile["TlsCaCert"] or 613 != connectionProfile["TlsCaCert"]
591 self.tlsSelfSignedClientCertFilePicker.text() != 614 or self.tlsSelfSignedClientCertFilePicker.text()
592 connectionProfile["TlsClientCert"] or 615 != connectionProfile["TlsClientCert"]
593 self.tlsSelfSignedClientKeyFilePicker.text() != 616 or self.tlsSelfSignedClientKeyFilePicker.text()
594 connectionProfile["TlsClientKey"] 617 != connectionProfile["TlsClientKey"]
595 ) 618 )
596 # check user properties only, if not yet changed 619 # check user properties only, if not yet changed
597 if not changed and protocol == MqttProtocols.MQTTv5: 620 if not changed and protocol == MqttProtocols.MQTTv5:
598 properties = { 621 properties = (
599 "connect": self.propertiesWidget.getProperties(), 622 {
600 "disconnect": self.__userProperties["disconnect"], 623 "connect": self.propertiesWidget.getProperties(),
601 } if self.connectPropertiesButton.isChecked() else { 624 "disconnect": self.__userProperties["disconnect"],
602 "connect": self.__userProperties["connect"], 625 }
603 "disconnect": self.propertiesWidget.getProperties(), 626 if self.connectPropertiesButton.isChecked()
604 } 627 else {
628 "connect": self.__userProperties["connect"],
629 "disconnect": self.propertiesWidget.getProperties(),
630 }
631 )
605 changed |= ( 632 changed |= (
606 self.samePropertiesCheckBox.isChecked() != 633 self.samePropertiesCheckBox.isChecked()
607 connectionProfile["UserProperties"]["use_connect"] or 634 != connectionProfile["UserProperties"]["use_connect"]
608 sorted(properties["connect"]) != 635 or sorted(properties["connect"])
609 sorted(connectionProfile["UserProperties"]["connect"]) or 636 != sorted(connectionProfile["UserProperties"]["connect"])
610 sorted(properties["disconnect"]) != 637 or sorted(properties["disconnect"])
611 sorted(connectionProfile["UserProperties"]["disconnect"]) 638 != sorted(connectionProfile["UserProperties"]["disconnect"])
612 ) 639 )
613 640
614 return changed 641 return changed
615 642
616 else: 643 else:
617 return True 644 return True
618 645
619 def __updateApplyButton(self): 646 def __updateApplyButton(self):
620 """ 647 """
621 Private method to set the state of the Apply button. 648 Private method to set the state of the Apply button.
622 """ 649 """
623 # condition 1: profile name and broker address need to be given 650 # condition 1: profile name and broker address need to be given
624 enable = (bool(self.profileEdit.text()) and 651 enable = bool(self.profileEdit.text()) and bool(self.brokerAddressEdit.text())
625 bool(self.brokerAddressEdit.text())) 652
626
627 # condition 2: if client ID is empty, clean session must be selected 653 # condition 2: if client ID is empty, clean session must be selected
628 if ( 654 if (
629 not self.__populatingProfile and 655 not self.__populatingProfile
630 self.clientIdEdit.text() == "" and 656 and self.clientIdEdit.text() == ""
631 not self.cleanSessionCheckBox.isChecked() 657 and not self.cleanSessionCheckBox.isChecked()
632 ): 658 ):
633 enable = False 659 enable = False
634 EricMessageBox.critical( 660 EricMessageBox.critical(
635 self, 661 self,
636 self.tr("Invalid Connection Parameters"), 662 self.tr("Invalid Connection Parameters"),
637 self.tr("An empty Client ID requires a clean session.")) 663 self.tr("An empty Client ID requires a clean session."),
638 664 )
665
639 if self.tlsGroupBox.isChecked(): 666 if self.tlsGroupBox.isChecked():
640 if self.tlsCertsFileButton.isChecked(): 667 if self.tlsCertsFileButton.isChecked():
641 # condition 3a: if CA certificates file shall be used, it must 668 # condition 3a: if CA certificates file shall be used, it must
642 # be given 669 # be given
643 enable &= bool(self.tlsCertsFilePicker.text()) 670 enable &= bool(self.tlsCertsFilePicker.text())
644 elif self.tlsSelfSignedCertsButton.isChecked(): 671 elif self.tlsSelfSignedCertsButton.isChecked():
645 # condition 3b: if client certificates shall be used, all files 672 # condition 3b: if client certificates shall be used, all files
646 # must be given 673 # must be given
647 enable &= ( 674 enable &= (
648 bool(self.tlsSelfSignedCertsFilePicker.text()) and 675 bool(self.tlsSelfSignedCertsFilePicker.text())
649 bool(self.tlsSelfSignedClientCertFilePicker.text()) and 676 and bool(self.tlsSelfSignedClientCertFilePicker.text())
650 bool(self.tlsSelfSignedClientKeyFilePicker.text()) 677 and bool(self.tlsSelfSignedClientKeyFilePicker.text())
651 ) 678 )
652 679
653 self.profileButtonBox.button( 680 self.profileButtonBox.button(QDialogButtonBox.StandardButton.Apply).setEnabled(
654 QDialogButtonBox.StandardButton.Apply).setEnabled(enable) 681 enable
655 682 )
683
656 @pyqtSlot(str) 684 @pyqtSlot(str)
657 def on_brokerAddressEdit_textChanged(self, address): 685 def on_brokerAddressEdit_textChanged(self, address):
658 """ 686 """
659 Private slot handling a change of the broker address. 687 Private slot handling a change of the broker address.
660 688
661 @param address broker address 689 @param address broker address
662 @type str 690 @type str
663 """ 691 """
664 self.__updateApplyButton() 692 self.__updateApplyButton()
665 693
666 @pyqtSlot() 694 @pyqtSlot()
667 def on_generateIdButton_clicked(self): 695 def on_generateIdButton_clicked(self):
668 """ 696 """
669 Private slot to generate a client ID. 697 Private slot to generate a client ID.
670 """ 698 """
671 uuid = QUuid.createUuid() 699 uuid = QUuid.createUuid()
672 self.clientIdEdit.setText( 700 self.clientIdEdit.setText(uuid.toString(QUuid.StringFormat.WithoutBraces))
673 uuid.toString(QUuid.StringFormat.WithoutBraces)) 701
674
675 @pyqtSlot(str) 702 @pyqtSlot(str)
676 def on_clientIdEdit_textChanged(self, clientId): 703 def on_clientIdEdit_textChanged(self, clientId):
677 """ 704 """
678 Private slot handling a change of the client ID string. 705 Private slot handling a change of the client ID string.
679 706
680 @param clientId client ID 707 @param clientId client ID
681 @type str 708 @type str
682 """ 709 """
683 self.__updateApplyButton() 710 self.__updateApplyButton()
684 711
685 @pyqtSlot(bool) 712 @pyqtSlot(bool)
686 def on_cleanSessionCheckBox_clicked(self, checked): 713 def on_cleanSessionCheckBox_clicked(self, checked):
687 """ 714 """
688 Private slot to handle a change of the clean session selection. 715 Private slot to handle a change of the clean session selection.
689 716
690 @param checked current state of the clean session selection 717 @param checked current state of the clean session selection
691 @type bool 718 @type bool
692 """ 719 """
693 self.__updateApplyButton() 720 self.__updateApplyButton()
694 721
695 @pyqtSlot(bool) 722 @pyqtSlot(bool)
696 def on_mqttv5Button_toggled(self, checked): 723 def on_mqttv5Button_toggled(self, checked):
697 """ 724 """
698 Private slot to handle the selection of the MQTT protocol. 725 Private slot to handle the selection of the MQTT protocol.
699 726
700 @param checked state of the button 727 @param checked state of the button
701 @type bool 728 @type bool
702 """ 729 """
703 self.profileTabWidget.setTabEnabled( 730 self.profileTabWidget.setTabEnabled(
704 self.profileTabWidget.indexOf(self.propertiesTab), 731 self.profileTabWidget.indexOf(self.propertiesTab), checked
705 checked
706 ) 732 )
707 self.willPropertiesButton.setEnabled(checked) 733 self.willPropertiesButton.setEnabled(checked)
708 self.willPropertiesButton.setVisible(checked) 734 self.willPropertiesButton.setVisible(checked)
709 735
710 @pyqtSlot(bool) 736 @pyqtSlot(bool)
711 def on_showPasswordButton_toggled(self, checked): 737 def on_showPasswordButton_toggled(self, checked):
712 """ 738 """
713 Private slot to show or hide the password. 739 Private slot to show or hide the password.
714 740
715 @param checked flag indicating the button state 741 @param checked flag indicating the button state
716 @type bool 742 @type bool
717 """ 743 """
718 ( 744 (
719 self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Normal) 745 self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Normal)
720 if checked else 746 if checked
721 self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Password) 747 else self.passwordEdit.setEchoMode(QLineEdit.EchoMode.Password)
722 ) 748 )
723 749
724 @pyqtSlot() 750 @pyqtSlot()
725 def on_willPropertiesButton_clicked(self): 751 def on_willPropertiesButton_clicked(self):
726 """ 752 """
727 Private slot to edit the last will user properties. 753 Private slot to edit the last will user properties.
728 """ 754 """
729 from .MqttUserPropertiesEditor import MqttUserPropertiesEditorDialog 755 from .MqttUserPropertiesEditor import MqttUserPropertiesEditorDialog
730 756
731 dlg = MqttUserPropertiesEditorDialog( 757 dlg = MqttUserPropertiesEditorDialog(
732 self.tr("Last Will User Properties"), self.__willProperties, self) 758 self.tr("Last Will User Properties"), self.__willProperties, self
759 )
733 if dlg.exec() == QDialog.DialogCode.Accepted: 760 if dlg.exec() == QDialog.DialogCode.Accepted:
734 self.__willProperties = dlg.getProperties() 761 self.__willProperties = dlg.getProperties()
735 762
736 @pyqtSlot(str) 763 @pyqtSlot(str)
737 def on_tlsCertsFilePicker_textChanged(self, path): 764 def on_tlsCertsFilePicker_textChanged(self, path):
738 """ 765 """
739 Private slot handling a change of the TLS CA certificates file. 766 Private slot handling a change of the TLS CA certificates file.
740 767
741 @param path file path 768 @param path file path
742 @type str 769 @type str
743 """ 770 """
744 self.__updateApplyButton() 771 self.__updateApplyButton()
745 772
746 @pyqtSlot(str) 773 @pyqtSlot(str)
747 def on_tlsSelfSignedCertsFilePicker_textChanged(self, path): 774 def on_tlsSelfSignedCertsFilePicker_textChanged(self, path):
748 """ 775 """
749 Private slot handling a change of the TLS CA certificates file. 776 Private slot handling a change of the TLS CA certificates file.
750 777
751 @param path file path 778 @param path file path
752 @type str 779 @type str
753 """ 780 """
754 self.__updateApplyButton() 781 self.__updateApplyButton()
755 782
756 @pyqtSlot(str) 783 @pyqtSlot(str)
757 def on_tlsSelfSignedClientCertFilePicker_textChanged(self, path): 784 def on_tlsSelfSignedClientCertFilePicker_textChanged(self, path):
758 """ 785 """
759 Private slot handling a change of the TLS client certificate file. 786 Private slot handling a change of the TLS client certificate file.
760 787
761 @param path file path 788 @param path file path
762 @type str 789 @type str
763 """ 790 """
764 self.__updateApplyButton() 791 self.__updateApplyButton()
765 792
766 @pyqtSlot(str) 793 @pyqtSlot(str)
767 def on_tlsSelfSignedClientKeyFilePicker_textChanged(self, path): 794 def on_tlsSelfSignedClientKeyFilePicker_textChanged(self, path):
768 """ 795 """
769 Private slot handling a change of the TLS client key file. 796 Private slot handling a change of the TLS client key file.
770 797
771 @param path file path 798 @param path file path
772 @type str 799 @type str
773 """ 800 """
774 self.__updateApplyButton() 801 self.__updateApplyButton()
775 802
776 @pyqtSlot(bool) 803 @pyqtSlot(bool)
777 def on_tlsGroupBox_toggled(self, checked): 804 def on_tlsGroupBox_toggled(self, checked):
778 """ 805 """
779 Private slot handling the selection of TLS mode. 806 Private slot handling the selection of TLS mode.
780 807
781 @param checked state of the selection 808 @param checked state of the selection
782 @type bool 809 @type bool
783 """ 810 """
784 if checked and self.brokerPortSpinBox.value() == 1883: 811 if checked and self.brokerPortSpinBox.value() == 1883:
785 # port is still standard non-TLS port 812 # port is still standard non-TLS port
788 self.tr("SSL/TLS Enabled"), 815 self.tr("SSL/TLS Enabled"),
789 self.tr( 816 self.tr(
790 """Encrypted connection using SSL/TLS has been enabled.""" 817 """Encrypted connection using SSL/TLS has been enabled."""
791 """ However, the broker port is still the default""" 818 """ However, the broker port is still the default"""
792 """ unencrypted port (port 1883). Shall this be""" 819 """ unencrypted port (port 1883). Shall this be"""
793 """ changed?"""), 820 """ changed?"""
821 ),
794 icon=EricMessageBox.Warning, 822 icon=EricMessageBox.Warning,
795 yesDefault=True) 823 yesDefault=True,
824 )
796 if yes: 825 if yes:
797 self.brokerPortSpinBox.setValue(8883) 826 self.brokerPortSpinBox.setValue(8883)
798 elif not checked and self.brokerPortSpinBox.value() == 8883: 827 elif not checked and self.brokerPortSpinBox.value() == 8883:
799 # port is still standard TLS port 828 # port is still standard TLS port
800 yes = EricMessageBox.yesNo( 829 yes = EricMessageBox.yesNo(
802 self.tr("SSL/TLS Disabled"), 831 self.tr("SSL/TLS Disabled"),
803 self.tr( 832 self.tr(
804 """Encrypted connection using SSL/TLS has been disabled.""" 833 """Encrypted connection using SSL/TLS has been disabled."""
805 """ However, the broker port is still the default""" 834 """ However, the broker port is still the default"""
806 """ encrypted port (port 8883). Shall this be""" 835 """ encrypted port (port 8883). Shall this be"""
807 """ changed?"""), 836 """ changed?"""
837 ),
808 icon=EricMessageBox.Warning, 838 icon=EricMessageBox.Warning,
809 yesDefault=True) 839 yesDefault=True,
840 )
810 if yes: 841 if yes:
811 self.brokerPortSpinBox.setValue(1883) 842 self.brokerPortSpinBox.setValue(1883)
812 843
813 self.__updateApplyButton() 844 self.__updateApplyButton()
814 845
815 @pyqtSlot(bool) 846 @pyqtSlot(bool)
816 def on_tlsDefaultCertsButton_toggled(self, checked): 847 def on_tlsDefaultCertsButton_toggled(self, checked):
817 """ 848 """
818 Private slot handling the selection of using the default 849 Private slot handling the selection of using the default
819 certificates file. 850 certificates file.
820 851
821 @param checked state of the selection 852 @param checked state of the selection
822 @type bool 853 @type bool
823 """ 854 """
824 self.__updateApplyButton() 855 self.__updateApplyButton()
825 856
826 @pyqtSlot(bool) 857 @pyqtSlot(bool)
827 def on_tlsCertsFileButton_toggled(self, checked): 858 def on_tlsCertsFileButton_toggled(self, checked):
828 """ 859 """
829 Private slot handling the selection of using a non-default 860 Private slot handling the selection of using a non-default
830 certificates file. 861 certificates file.
831 862
832 @param checked state of the selection 863 @param checked state of the selection
833 @type bool 864 @type bool
834 """ 865 """
835 self.__updateApplyButton() 866 self.__updateApplyButton()
836 867
837 @pyqtSlot(bool) 868 @pyqtSlot(bool)
838 def on_tlsSelfSignedCertsButton_toggled(self, checked): 869 def on_tlsSelfSignedCertsButton_toggled(self, checked):
839 """ 870 """
840 Private slot handling the selection of using self signed 871 Private slot handling the selection of using self signed
841 client certificate and key files. 872 client certificate and key files.
842 873
843 @param checked state of the selection 874 @param checked state of the selection
844 @type bool 875 @type bool
845 """ 876 """
846 self.__updateApplyButton() 877 self.__updateApplyButton()
847 878
848 @pyqtSlot(bool) 879 @pyqtSlot(bool)
849 def on_samePropertiesCheckBox_toggled(self, checked): 880 def on_samePropertiesCheckBox_toggled(self, checked):
850 """ 881 """
851 Private slot to handle a change of the properties usage. 882 Private slot to handle a change of the properties usage.
852 883
853 @param checked flag indicating to use the same user properties for 884 @param checked flag indicating to use the same user properties for
854 CONNECT and DISCONNECT 885 CONNECT and DISCONNECT
855 @type bool 886 @type bool
856 """ 887 """
857 if checked and not self.connectPropertiesButton.isChecked(): 888 if checked and not self.connectPropertiesButton.isChecked():
858 self.connectPropertiesButton.click() 889 self.connectPropertiesButton.click()
859 self.disconnectPropertiesButton.setEnabled(not checked) 890 self.disconnectPropertiesButton.setEnabled(not checked)
860 891
861 @pyqtSlot(bool) 892 @pyqtSlot(bool)
862 def __propertiesTypeSelected(self, checked): 893 def __propertiesTypeSelected(self, checked):
863 """ 894 """
864 Private slot to handle the switching of the user properties type. 895 Private slot to handle the switching of the user properties type.
865 896
866 @param checked state of the buttons 897 @param checked state of the buttons
867 @type bool 898 @type bool
868 """ 899 """
869 if checked: 900 if checked:
870 # handle the selection only 901 # handle the selection only
871 if self.connectPropertiesButton.isChecked(): 902 if self.connectPropertiesButton.isChecked():
872 self.__userProperties["disconnect"] = ( 903 self.__userProperties[
873 self.propertiesWidget.getProperties()) 904 "disconnect"
874 self.propertiesWidget.setProperties( 905 ] = self.propertiesWidget.getProperties()
875 self.__userProperties["connect"]) 906 self.propertiesWidget.setProperties(self.__userProperties["connect"])
876 else: 907 else:
877 self.__userProperties["connect"] = ( 908 self.__userProperties["connect"] = self.propertiesWidget.getProperties()
878 self.propertiesWidget.getProperties()) 909 self.propertiesWidget.setProperties(self.__userProperties["disconnect"])
879 self.propertiesWidget.setProperties( 910
880 self.__userProperties["disconnect"])
881
882 @pyqtSlot() 911 @pyqtSlot()
883 def reject(self): 912 def reject(self):
884 """ 913 """
885 Public slot to reject the dialog changes. 914 Public slot to reject the dialog changes.
886 """ 915 """
887 if self.__isChangedProfile(): 916 if self.__isChangedProfile():
888 button = EricMessageBox.warning( 917 button = EricMessageBox.warning(
889 self, 918 self,
890 self.tr("Changed Connection Profile"), 919 self.tr("Changed Connection Profile"),
891 self.tr("""The current profile has unsaved changes. Shall""" 920 self.tr(
892 """ these be saved?"""), 921 """The current profile has unsaved changes. Shall"""
893 EricMessageBox.Discard | 922 """ these be saved?"""
923 ),
924 EricMessageBox.Discard | EricMessageBox.Save,
894 EricMessageBox.Save, 925 EricMessageBox.Save,
895 EricMessageBox.Save) 926 )
896 if button == EricMessageBox.Save: 927 if button == EricMessageBox.Save:
897 self.__applyProfile() 928 self.__applyProfile()
898 return 929 return
899 930
900 if self.__profilesChanged: 931 if self.__profilesChanged:
901 button = EricMessageBox.warning( 932 button = EricMessageBox.warning(
902 self, 933 self,
903 self.tr("Changed Connection Profiles"), 934 self.tr("Changed Connection Profiles"),
904 self.tr("""The list of connection profiles has unsaved""" 935 self.tr(
905 """ changes."""), 936 """The list of connection profiles has unsaved""" """ changes."""
906 EricMessageBox.Abort | 937 ),
907 EricMessageBox.Discard | 938 EricMessageBox.Abort | EricMessageBox.Discard | EricMessageBox.Save,
908 EricMessageBox.Save, 939 EricMessageBox.Save,
909 EricMessageBox.Save) 940 )
910 if button == EricMessageBox.Save: 941 if button == EricMessageBox.Save:
911 super().accept() 942 super().accept()
912 return 943 return
913 elif button == EricMessageBox.Abort: 944 elif button == EricMessageBox.Abort:
914 return 945 return
915 946
916 super().reject() 947 super().reject()
917 948
918 @pyqtSlot() 949 @pyqtSlot()
919 def accept(self): 950 def accept(self):
920 """ 951 """
921 Public slot to accept the dialog. 952 Public slot to accept the dialog.
922 """ 953 """
923 if self.__isChangedProfile(): 954 if self.__isChangedProfile():
924 yes = EricMessageBox.yesNo( 955 yes = EricMessageBox.yesNo(
925 self, 956 self,
926 self.tr("Changed Connection Profile"), 957 self.tr("Changed Connection Profile"),
927 self.tr("""The current profile has unsaved changes. Shall""" 958 self.tr(
928 """ these be saved?"""), 959 """The current profile has unsaved changes. Shall"""
960 """ these be saved?"""
961 ),
929 icon=EricMessageBox.Warning, 962 icon=EricMessageBox.Warning,
930 yesDefault=True) 963 yesDefault=True,
964 )
931 if yes: 965 if yes:
932 self.__applyProfile() 966 self.__applyProfile()
933 967
934 super().accept() 968 super().accept()

eric ide

mercurial