14 from PyQt5.QtCore import pyqtSlot, Qt, QUuid |
14 from PyQt5.QtCore import pyqtSlot, Qt, QUuid |
15 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ |
15 from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton, \ |
16 QListWidgetItem, QInputDialog, QLineEdit |
16 QListWidgetItem, QInputDialog, QLineEdit |
17 |
17 |
18 from E5Gui import E5MessageBox |
18 from E5Gui import E5MessageBox |
|
19 from E5Gui.E5PathPicker import E5PathPickerModes |
19 |
20 |
20 from .Ui_MqttConnectionProfilesDialog import Ui_MqttConnectionProfilesDialog |
21 from .Ui_MqttConnectionProfilesDialog import Ui_MqttConnectionProfilesDialog |
21 |
22 |
22 import UI.PixmapCache |
23 import UI.PixmapCache |
23 from Utilities.crypto import pwConvert |
24 from Utilities.crypto import pwConvert |
35 @type MqttClient |
36 @type MqttClient |
36 @param profiles dictionary containing dictionaries containing the |
37 @param profiles dictionary containing dictionaries containing the |
37 connection parameters. Each entry must have the keys |
38 connection parameters. Each entry must have the keys |
38 "BrokerAddress", "BrokerPort", "ClientId", |
39 "BrokerAddress", "BrokerPort", "ClientId", |
39 "Keepalive", "CleanSession", "Username", "Password", "WillTopic", |
40 "Keepalive", "CleanSession", "Username", "Password", "WillTopic", |
40 "WillMessage", "WillQos", "WillRetain". |
41 "WillMessage", "WillQos", "WillRetain", "TlsEnable", "TlsCaCert", |
|
42 "TlsClientCert", "TlsClientKey". |
41 @type dict |
43 @type dict |
42 @param parent reference to the parent widget |
44 @param parent reference to the parent widget |
43 @type QWidget |
45 @type QWidget |
44 """ |
46 """ |
45 super(MqttConnectionProfilesDialog, self).__init__(parent) |
47 super(MqttConnectionProfilesDialog, self).__init__(parent) |
50 self.__profiles = collections.defaultdict(self.__defaultProfile) |
52 self.__profiles = collections.defaultdict(self.__defaultProfile) |
51 self.__profiles.update(profiles) |
53 self.__profiles.update(profiles) |
52 self.__profilesChanged = False |
54 self.__profilesChanged = False |
53 |
55 |
54 self.plusButton.setIcon(UI.PixmapCache.getIcon("plus.png")) |
56 self.plusButton.setIcon(UI.PixmapCache.getIcon("plus.png")) |
|
57 self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png")) |
55 self.minusButton.setIcon(UI.PixmapCache.getIcon("minus.png")) |
58 self.minusButton.setIcon(UI.PixmapCache.getIcon("minus.png")) |
|
59 |
|
60 self.tlsCertsFilePicker.setMode(E5PathPickerModes.OpenFileMode) |
|
61 self.tlsCertsFilePicker.setFilters( |
|
62 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) |
|
63 self.tlsSelfSignedCertsFilePicker.setMode( |
|
64 E5PathPickerModes.OpenFileMode) |
|
65 self.tlsSelfSignedCertsFilePicker.setFilters( |
|
66 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) |
|
67 self.tlsSelfSignedClientCertFilePicker.setMode( |
|
68 E5PathPickerModes.OpenFileMode) |
|
69 self.tlsSelfSignedClientCertFilePicker.setFilters( |
|
70 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) |
|
71 self.tlsSelfSignedClientKeyFilePicker.setMode( |
|
72 E5PathPickerModes.OpenFileMode) |
|
73 self.tlsSelfSignedClientKeyFilePicker.setFilters( |
|
74 self.tr("Key Files (*.key *.pem);;All Files (*)")) |
56 |
75 |
57 self.profileTabWidget.setCurrentIndex(0) |
76 self.profileTabWidget.setCurrentIndex(0) |
58 |
77 |
59 if len(self.__profiles) == 0: |
78 if len(self.__profiles) == 0: |
60 self.minusButton.setEnabled(False) |
79 self.minusButton.setEnabled(False) |
|
80 self.copyButton.setEnabled(False) |
61 |
81 |
62 self.profileFrame.setEnabled(False) |
82 self.profileFrame.setEnabled(False) |
63 self.__populatingProfile = False |
83 self.__populatingProfile = False |
64 self.__deletingProfile = False |
84 self.__deletingProfile = False |
65 |
85 |
103 @type QListWidgetItem |
123 @type QListWidgetItem |
104 @param previous previous current item |
124 @param previous previous current item |
105 @type QListWidgetItem |
125 @type QListWidgetItem |
106 """ |
126 """ |
107 self.minusButton.setEnabled(current is not None) |
127 self.minusButton.setEnabled(current is not None) |
|
128 self.copyButton.setEnabled(current is not None) |
108 |
129 |
109 if current is not previous: |
130 if current is not previous: |
110 if not self.__deletingProfile and self.__isChangedProfile(): |
131 if not self.__deletingProfile and self.__isChangedProfile(): |
111 # modified profile belongs to previous |
132 # modified profile belongs to previous |
112 yes = E5MessageBox.yesNo( |
133 yes = E5MessageBox.yesNo( |
133 profileName, ok = QInputDialog.getText( |
154 profileName, ok = QInputDialog.getText( |
134 self, |
155 self, |
135 self.tr("New Connection Profile"), |
156 self.tr("New Connection Profile"), |
136 self.tr("Enter name for the new Connection Profile:"), |
157 self.tr("Enter name for the new Connection Profile:"), |
137 QLineEdit.Normal) |
158 QLineEdit.Normal) |
138 if ok and bool(profileName) and profileName not in self.__profiles: |
159 if ok and bool(profileName): |
139 itm = QListWidgetItem(profileName, self.profilesList) |
160 if profileName in self.__profiles: |
140 self.profilesList.setCurrentItem(itm) |
161 E5MessageBox.warning( |
141 self.brokerAddressEdit.setFocus(Qt.OtherFocusReason) |
162 self, |
|
163 self.tr("New Connection Profile"), |
|
164 self.tr("""<p>A connection named <b>{0}</b> exists""" |
|
165 """ already. Aborting...</p>""").format( |
|
166 profileName)) |
|
167 else: |
|
168 itm = QListWidgetItem(profileName, self.profilesList) |
|
169 self.profilesList.setCurrentItem(itm) |
|
170 self.brokerAddressEdit.setFocus(Qt.OtherFocusReason) |
|
171 |
|
172 @pyqtSlot() |
|
173 def on_copyButton_clicked(self): |
|
174 """ |
|
175 Private slot to copy the selected profile entry. |
|
176 """ |
|
177 itm = self.profilesList.currentItem() |
|
178 if itm: |
|
179 profileName = itm.text() |
|
180 newProfileName, ok = QInputDialog.getText( |
|
181 self, |
|
182 self.tr("Copy Connection Profile"), |
|
183 self.tr("Enter name for the copied Connection Profile:"), |
|
184 QLineEdit.Normal) |
|
185 if ok and bool(newProfileName): |
|
186 if newProfileName in self.__profiles: |
|
187 E5MessageBox.warning( |
|
188 self, |
|
189 self.tr("Copy Connection Profile"), |
|
190 self.tr("""<p>A connection named <b>{0}</b> exists""" |
|
191 """ already. Aborting...</p>""").format( |
|
192 newProfileName)) |
|
193 else: |
|
194 profile = self.__defaultProfile() |
|
195 profile.update(self.__profiles[profileName]) |
|
196 self.__profiles[newProfileName] = profile |
|
197 |
|
198 itm = QListWidgetItem(newProfileName, self.profilesList) |
|
199 self.profilesList.setCurrentItem(itm) |
|
200 self.brokerAddressEdit.setFocus(Qt.OtherFocusReason) |
142 |
201 |
143 @pyqtSlot() |
202 @pyqtSlot() |
144 def on_minusButton_clicked(self): |
203 def on_minusButton_clicked(self): |
145 """ |
204 """ |
146 Private slot to delete the selected entry. |
205 Private slot to delete the selected entry. |
168 Public method to return a dictionary of profiles. |
227 Public method to return a dictionary of profiles. |
169 |
228 |
170 @return dictionary containing dictionaries containing the defined |
229 @return dictionary containing dictionaries containing the defined |
171 connection profiles. Each entry have the keys "BrokerAddress", |
230 connection profiles. Each entry have the keys "BrokerAddress", |
172 "BrokerPort", "ClientId", "Keepalive", "CleanSession", "Username", |
231 "BrokerPort", "ClientId", "Keepalive", "CleanSession", "Username", |
173 "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain". |
232 "Password", "WillTopic", "WillMessage", "WillQos", "WillRetain", |
|
233 "TlsEnable", "TlsCaCert", "TlsClientCert", "TlsClientKey". |
174 @rtype dict |
234 @rtype dict |
175 """ |
235 """ |
176 profilesDict = {} |
236 profilesDict = {} |
177 profilesDict.update(self.__profiles) |
237 profilesDict.update(self.__profiles) |
178 return profilesDict |
238 return profilesDict |
195 "Password": pwConvert(self.passwordEdit.text(), encode=True), |
255 "Password": pwConvert(self.passwordEdit.text(), encode=True), |
196 "WillTopic": self.willTopicEdit.text(), |
256 "WillTopic": self.willTopicEdit.text(), |
197 "WillMessage": self.willMessageEdit.toPlainText(), |
257 "WillMessage": self.willMessageEdit.toPlainText(), |
198 "WillQos": self.willQosSpinBox.value(), |
258 "WillQos": self.willQosSpinBox.value(), |
199 "WillRetain": self.willRetainCheckBox.isChecked(), |
259 "WillRetain": self.willRetainCheckBox.isChecked(), |
|
260 "TlsEnable": self.tlsGroupBox.isChecked(), |
|
261 "TlsCaCert": "", |
|
262 "TlsClientCert": "", |
|
263 "TlsClientKey": "", |
200 } |
264 } |
|
265 if profile["TlsEnable"]: |
|
266 if self.tlsCertsFileButton.isChecked(): |
|
267 profile["TlsCaCert"] = self.tlsCertsFilePicker.text() |
|
268 elif self.tlsSelfSignedCertsButton.isChecked(): |
|
269 profile["TlsCaCert"] = \ |
|
270 self.tlsSelfSignedCertsFilePicker.text() |
|
271 profile["TlsClientCert"] = \ |
|
272 self.tlsSelfSignedClientCertFilePicker.text() |
|
273 profile["TlsClientKey"] = \ |
|
274 self.tlsSelfSignedClientKeyFilePicker.text() |
|
275 |
201 self.__profiles[profileName] = profile |
276 self.__profiles[profileName] = profile |
202 self.__profilesChanged = True |
277 self.__profilesChanged = True |
203 |
278 |
204 return profileName |
279 return profileName |
205 |
280 |
245 Private method to populate the profile data entry fields. |
323 Private method to populate the profile data entry fields. |
246 |
324 |
247 @param profileName name of the profile to get data from |
325 @param profileName name of the profile to get data from |
248 @type str |
326 @type str |
249 """ |
327 """ |
|
328 profile = self.__defaultProfile() |
250 if profileName: |
329 if profileName: |
251 profile = self.__profiles[profileName] |
330 profile.update(self.__profiles[profileName]) |
252 else: |
|
253 profile = self.__defaultProfile() |
|
254 |
331 |
255 self.__populatingProfile = True |
332 self.__populatingProfile = True |
256 if profileName is not None: |
333 if profileName is not None: |
257 self.profileEdit.setText(profileName) |
334 self.profileEdit.setText(profileName) |
258 self.brokerAddressEdit.setText(profile["BrokerAddress"]) |
335 self.brokerAddressEdit.setText(profile["BrokerAddress"]) |
264 self.passwordEdit.setText(pwConvert(profile["Password"], encode=False)) |
341 self.passwordEdit.setText(pwConvert(profile["Password"], encode=False)) |
265 self.willTopicEdit.setText(profile["WillTopic"]) |
342 self.willTopicEdit.setText(profile["WillTopic"]) |
266 self.willMessageEdit.setPlainText(profile["WillMessage"]) |
343 self.willMessageEdit.setPlainText(profile["WillMessage"]) |
267 self.willQosSpinBox.setValue(profile["WillQos"]) |
344 self.willQosSpinBox.setValue(profile["WillQos"]) |
268 self.willRetainCheckBox.setChecked(profile["WillRetain"]) |
345 self.willRetainCheckBox.setChecked(profile["WillRetain"]) |
|
346 self.tlsGroupBox.setChecked(profile["TlsEnable"]) |
|
347 if profile["TlsCaCert"] and profile["TlsClientCert"]: |
|
348 self.tlsSelfSignedCertsButton.setChecked(True) |
|
349 self.tlsSelfSignedCertsFilePicker.setText(profile["TlsCaCert"]) |
|
350 self.tlsSelfSignedClientCertFilePicker.setText( |
|
351 profile["TlsClientCert"]) |
|
352 self.tlsSelfSignedClientKeyFilePicker.setText( |
|
353 profile["TlsClientKey"]) |
|
354 elif profile["TlsCaCert"]: |
|
355 self.tlsCertsFileButton.setChecked(True) |
|
356 self.tlsCertsFilePicker.setText(profile["TlsCaCert"]) |
|
357 else: |
|
358 self.tlsDefaultCertsButton.setChecked(True) |
269 self.__populatingProfile = False |
359 self.__populatingProfile = False |
270 |
360 |
271 self.profileFrame.setEnabled(True) |
361 self.profileFrame.setEnabled(True) |
272 self.__updateApplyButton() |
362 self.__updateApplyButton() |
273 |
363 |
286 self.passwordEdit.setText("") |
376 self.passwordEdit.setText("") |
287 self.willTopicEdit.setText("") |
377 self.willTopicEdit.setText("") |
288 self.willMessageEdit.setPlainText("") |
378 self.willMessageEdit.setPlainText("") |
289 self.willQosSpinBox.setValue(0) |
379 self.willQosSpinBox.setValue(0) |
290 self.willRetainCheckBox.setChecked(False) |
380 self.willRetainCheckBox.setChecked(False) |
|
381 self.tlsGroupBox.setChecked(False) |
|
382 self.tlsDefaultCertsButton.setChecked(True) |
|
383 self.tlsCertsFileButton.setChecked(True) |
|
384 self.tlsCertsFilePicker.setText("") |
|
385 self.tlsSelfSignedCertsButton.setChecked(False) |
|
386 self.tlsSelfSignedCertsFilePicker.setText("") |
|
387 self.tlsSelfSignedClientCertFilePicker.setText("") |
|
388 self.tlsSelfSignedClientKeyFilePicker.setText("") |
291 self.__populatingProfile = False |
389 self.__populatingProfile = False |
292 |
390 |
293 self.profileFrame.setEnabled(False) |
391 self.profileFrame.setEnabled(False) |
294 self.__updateApplyButton() |
392 self.__updateApplyButton() |
295 |
393 |
320 profileName = self.profileEdit.text() |
418 profileName = self.profileEdit.text() |
321 if profileName == "": |
419 if profileName == "": |
322 return False |
420 return False |
323 |
421 |
324 elif profileName in self.__profiles: |
422 elif profileName in self.__profiles: |
325 profile = self.__profiles[profileName] |
423 profile = self.__defaultProfile() |
326 return ( |
424 profile.update(self.__profiles[profileName]) |
|
425 changed = ( |
327 self.brokerAddressEdit.text() != profile["BrokerAddress"] or |
426 self.brokerAddressEdit.text() != profile["BrokerAddress"] or |
328 self.brokerPortSpinBox.value() != profile["BrokerPort"] or |
427 self.brokerPortSpinBox.value() != profile["BrokerPort"] or |
329 self.clientIdEdit.text() != profile["ClientId"] or |
428 self.clientIdEdit.text() != profile["ClientId"] or |
330 self.keepaliveSpinBox.value() != profile["Keepalive"] or |
429 self.keepaliveSpinBox.value() != profile["Keepalive"] or |
331 self.cleanSessionCheckBox.isChecked() != |
430 self.cleanSessionCheckBox.isChecked() != |
334 self.passwordEdit.text() != |
433 self.passwordEdit.text() != |
335 pwConvert(profile["Password"], encode=False) or |
434 pwConvert(profile["Password"], encode=False) or |
336 self.willTopicEdit.text() != profile["WillTopic"] or |
435 self.willTopicEdit.text() != profile["WillTopic"] or |
337 self.willMessageEdit.toPlainText() != profile["WillMessage"] or |
436 self.willMessageEdit.toPlainText() != profile["WillMessage"] or |
338 self.willQosSpinBox.value() != profile["WillQos"] or |
437 self.willQosSpinBox.value() != profile["WillQos"] or |
339 self.willRetainCheckBox.isChecked() != profile["WillRetain"] |
438 self.willRetainCheckBox.isChecked() != profile["WillRetain"] or |
|
439 self.tlsGroupBox.isChecked() != profile["TlsEnable"] |
340 ) |
440 ) |
|
441 # check TLS stuff only, if not yet changed |
|
442 if not changed: |
|
443 if self.tlsCertsFileButton.isChecked(): |
|
444 changed |= ( |
|
445 self.tlsCertsFilePicker.text() != profile["TlsCaCert"] |
|
446 ) |
|
447 elif self.tlsSelfSignedCertsButton.isChecked(): |
|
448 changed |= ( |
|
449 self.tlsSelfSignedCertsFilePicker.text() != |
|
450 profile["TlsCaCert"] or |
|
451 self.tlsSelfSignedClientCertFilePicker.text() != |
|
452 profile["TlsClientCert"] or |
|
453 self.tlsSelfSignedClientKeyFilePicker.text() != |
|
454 profile["TlsClientKey"] |
|
455 ) |
|
456 return changed |
341 |
457 |
342 else: |
458 else: |
343 return True |
459 return True |
344 |
460 |
345 def __updateApplyButton(self): |
461 def __updateApplyButton(self): |
358 E5MessageBox.critical( |
474 E5MessageBox.critical( |
359 self, |
475 self, |
360 self.tr("Invalid Connection Parameters"), |
476 self.tr("Invalid Connection Parameters"), |
361 self.tr("An empty Client ID requires a clean session.")) |
477 self.tr("An empty Client ID requires a clean session.")) |
362 |
478 |
|
479 if self.tlsGroupBox.isChecked(): |
|
480 if self.tlsCertsFileButton.isChecked(): |
|
481 # condition 3a: if CA certificates file shall be used, it must |
|
482 # be given |
|
483 enable &= bool(self.tlsCertsFilePicker.text()) |
|
484 elif self.tlsSelfSignedCertsButton.isChecked(): |
|
485 # condition 3b: if client certificates shall be used, all files |
|
486 # must be given |
|
487 enable &= ( |
|
488 bool(self.tlsSelfSignedCertsFilePicker.text()) and |
|
489 bool(self.tlsSelfSignedClientCertFilePicker.text()) and |
|
490 bool(self.tlsSelfSignedClientKeyFilePicker.text()) |
|
491 ) |
|
492 |
363 self.profileButtonBox.button(QDialogButtonBox.Apply).setEnabled(enable) |
493 self.profileButtonBox.button(QDialogButtonBox.Apply).setEnabled(enable) |
364 |
494 |
365 @pyqtSlot(str) |
495 @pyqtSlot(str) |
366 def on_brokerAddressEdit_textChanged(self, address): |
496 def on_brokerAddressEdit_textChanged(self, address): |
367 """ |
497 """ |
377 """ |
507 """ |
378 Private slot to generate a client ID. |
508 Private slot to generate a client ID. |
379 """ |
509 """ |
380 uuid = QUuid.createUuid() |
510 uuid = QUuid.createUuid() |
381 self.clientIdEdit.setText(uuid.toString(QUuid.WithoutBraces)) |
511 self.clientIdEdit.setText(uuid.toString(QUuid.WithoutBraces)) |
|
512 |
|
513 @pyqtSlot(str) |
|
514 def on_clientIdEdit_textChanged(self, clientId): |
|
515 """ |
|
516 Private slot handling a change of the client ID string. |
|
517 |
|
518 @param clientId client ID |
|
519 @type str |
|
520 """ |
|
521 self.__updateApplyButton() |
|
522 |
|
523 @pyqtSlot(bool) |
|
524 def on_cleanSessionCheckBox_clicked(self, checked): |
|
525 """ |
|
526 Private slot to handle a change of the clean session selection. |
|
527 |
|
528 @param checked current state of the clean session selection |
|
529 @type bool |
|
530 """ |
|
531 self.__updateApplyButton() |
|
532 |
|
533 @pyqtSlot(str) |
|
534 def on_tlsCertsFilePicker_textChanged(self, path): |
|
535 """ |
|
536 Private slot handling a change of the TLS CA certificates file. |
|
537 |
|
538 @param path file path |
|
539 @type str |
|
540 """ |
|
541 self.__updateApplyButton() |
|
542 |
|
543 @pyqtSlot(str) |
|
544 def on_tlsSelfSignedCertsFilePicker_textChanged(self, path): |
|
545 """ |
|
546 Private slot handling a change of the TLS CA certificates file. |
|
547 |
|
548 @param path file path |
|
549 @type str |
|
550 """ |
|
551 self.__updateApplyButton() |
|
552 |
|
553 @pyqtSlot(str) |
|
554 def on_tlsSelfSignedClientCertFilePicker_textChanged(self, path): |
|
555 """ |
|
556 Private slot handling a change of the TLS client certificate file. |
|
557 |
|
558 @param path file path |
|
559 @type str |
|
560 """ |
|
561 self.__updateApplyButton() |
|
562 |
|
563 @pyqtSlot(str) |
|
564 def on_tlsSelfSignedClientKeyFilePicker_textChanged(self, path): |
|
565 """ |
|
566 Private slot handling a change of the TLS client key file. |
|
567 |
|
568 @param path file path |
|
569 @type str |
|
570 """ |
|
571 self.__updateApplyButton() |
|
572 |
|
573 @pyqtSlot(bool) |
|
574 def on_tlsGroupBox_toggled(self, checked): |
|
575 """ |
|
576 Private slot handling the selection of TLS mode. |
|
577 |
|
578 @param checked state of the selection |
|
579 @type bool |
|
580 """ |
|
581 if checked and self.brokerPortSpinBox.value() == 1883: |
|
582 # port is still standard non-TLS port |
|
583 yes = E5MessageBox.yesNo( |
|
584 self, |
|
585 self.tr("SSL/TLS Enabled"), |
|
586 self.tr( |
|
587 """Encrypted connection using SSL/TLS has been enabled.""" |
|
588 """ However, the broker port is still the default""" |
|
589 """ unencrypted port (port 1883). Shall this be""" |
|
590 """ changed?"""), |
|
591 icon=E5MessageBox.Warning, |
|
592 yesDefault=True) |
|
593 if yes: |
|
594 self.brokerPortSpinBox.setValue(8883) |
|
595 elif not checked and self.brokerPortSpinBox.value() == 8883: |
|
596 # port is still standard TLS port |
|
597 yes = E5MessageBox.yesNo( |
|
598 self, |
|
599 self.tr("SSL/TLS Disabled"), |
|
600 self.tr( |
|
601 """Encrypted connection using SSL/TLS has been disabled.""" |
|
602 """ However, the broker port is still the default""" |
|
603 """ encrypted port (port 8883). Shall this be""" |
|
604 """ changed?"""), |
|
605 icon=E5MessageBox.Warning, |
|
606 yesDefault=True) |
|
607 if yes: |
|
608 self.brokerPortSpinBox.setValue(1883) |
|
609 |
|
610 self.__updateApplyButton() |
|
611 |
|
612 @pyqtSlot(bool) |
|
613 def on_tlsDefaultCertsButton_toggled(self, checked): |
|
614 """ |
|
615 Private slot handling the selection of using the default |
|
616 certificates file. |
|
617 |
|
618 @param checked state of the selection |
|
619 @type bool |
|
620 """ |
|
621 self.__updateApplyButton() |
|
622 |
|
623 @pyqtSlot(bool) |
|
624 def on_tlsCertsFileButton_toggled(self, checked): |
|
625 """ |
|
626 Private slot handling the selection of using a non-default |
|
627 certificates file. |
|
628 |
|
629 @param checked state of the selection |
|
630 @type bool |
|
631 """ |
|
632 self.__updateApplyButton() |
|
633 |
|
634 @pyqtSlot(bool) |
|
635 def on_tlsSelfSignedCertsButton_toggled(self, checked): |
|
636 """ |
|
637 Private slot handling the selection of using self signed |
|
638 client certificate and key files. |
|
639 |
|
640 @param checked state of the selection |
|
641 @type bool |
|
642 """ |
|
643 self.__updateApplyButton() |
382 |
644 |
383 @pyqtSlot() |
645 @pyqtSlot() |
384 def reject(self): |
646 def reject(self): |
385 """ |
647 """ |
386 Public slot to reject the dialog changes. |
648 Public slot to reject the dialog changes. |