MqttMonitor/MqttConnectionProfilesDialog.py

branch
eric7
changeset 92
2fb5c08019fd
parent 86
620022b14cb4
child 95
d830314cca87
equal deleted inserted replaced
91:3cb08e5db764 92:2fb5c08019fd
7 Module implementing a dialog to edit the MQTT connection profiles. 7 Module implementing a dialog to edit the MQTT connection profiles.
8 """ 8 """
9 9
10 import collections 10 import collections
11 11
12 from PyQt5.QtCore import pyqtSlot, Qt, QUuid 12 from PyQt6.QtCore import pyqtSlot, Qt, QUuid
13 from PyQt5.QtWidgets import ( 13 from PyQt6.QtWidgets import (
14 QDialog, QDialogButtonBox, QAbstractButton, QListWidgetItem, QInputDialog, 14 QDialog, QDialogButtonBox, QAbstractButton, QListWidgetItem, QInputDialog,
15 QLineEdit 15 QLineEdit
16 ) 16 )
17 17
18 from E5Gui import E5MessageBox 18 from EricWidgets import EricMessageBox
19 from E5Gui.E5PathPicker import E5PathPickerModes 19 from EricWidgets.EricPathPicker import EricPathPickerModes
20 20
21 from .Ui_MqttConnectionProfilesDialog import Ui_MqttConnectionProfilesDialog 21 from .Ui_MqttConnectionProfilesDialog import Ui_MqttConnectionProfilesDialog
22 22
23 import UI.PixmapCache 23 import UI.PixmapCache
24 from Utilities.crypto import pwConvert 24 from Utilities.crypto import pwConvert
51 51
52 self.__profiles = collections.defaultdict(self.__defaultProfile) 52 self.__profiles = collections.defaultdict(self.__defaultProfile)
53 self.__profiles.update(profiles) 53 self.__profiles.update(profiles)
54 self.__profilesChanged = False 54 self.__profilesChanged = False
55 55
56 self.plusButton.setIcon(UI.PixmapCache.getIcon("plus.png")) 56 self.plusButton.setIcon(UI.PixmapCache.getIcon("plus"))
57 self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy.png")) 57 self.copyButton.setIcon(UI.PixmapCache.getIcon("editCopy"))
58 self.minusButton.setIcon(UI.PixmapCache.getIcon("minus.png")) 58 self.minusButton.setIcon(UI.PixmapCache.getIcon("minus"))
59 59
60 self.tlsCertsFilePicker.setMode(E5PathPickerModes.OpenFileMode) 60 self.tlsCertsFilePicker.setMode(EricPathPickerModes.OPEN_FILE_MODE)
61 self.tlsCertsFilePicker.setFilters( 61 self.tlsCertsFilePicker.setFilters(
62 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) 62 self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
63 self.tlsSelfSignedCertsFilePicker.setMode( 63 self.tlsSelfSignedCertsFilePicker.setMode(
64 E5PathPickerModes.OpenFileMode) 64 EricPathPickerModes.OPEN_FILE_MODE)
65 self.tlsSelfSignedCertsFilePicker.setFilters( 65 self.tlsSelfSignedCertsFilePicker.setFilters(
66 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) 66 self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
67 self.tlsSelfSignedClientCertFilePicker.setMode( 67 self.tlsSelfSignedClientCertFilePicker.setMode(
68 E5PathPickerModes.OpenFileMode) 68 EricPathPickerModes.OPEN_FILE_MODE)
69 self.tlsSelfSignedClientCertFilePicker.setFilters( 69 self.tlsSelfSignedClientCertFilePicker.setFilters(
70 self.tr("Certificate Files (*.crt *.pem);;All Files (*)")) 70 self.tr("Certificate Files (*.crt *.pem);;All Files (*)"))
71 self.tlsSelfSignedClientKeyFilePicker.setMode( 71 self.tlsSelfSignedClientKeyFilePicker.setMode(
72 E5PathPickerModes.OpenFileMode) 72 EricPathPickerModes.OPEN_FILE_MODE)
73 self.tlsSelfSignedClientKeyFilePicker.setFilters( 73 self.tlsSelfSignedClientKeyFilePicker.setFilters(
74 self.tr("Key Files (*.key *.pem);;All Files (*)")) 74 self.tr("Key Files (*.key *.pem);;All Files (*)"))
75 75
76 self.profileTabWidget.setCurrentIndex(0) 76 self.profileTabWidget.setCurrentIndex(0)
77 77
101 Private slot handling presses of the profile buttons. 101 Private slot handling presses of the profile buttons.
102 102
103 @param button reference to the pressed button 103 @param button reference to the pressed button
104 @type QAbstractButton 104 @type QAbstractButton
105 """ 105 """
106 if button == self.profileButtonBox.button(QDialogButtonBox.Apply): 106 if button == self.profileButtonBox.button(
107 QDialogButtonBox.StandardButton.Apply
108 ):
107 currentProfile = self.__applyProfile() 109 currentProfile = self.__applyProfile()
108 self.__populateProfilesList(currentProfile) 110 self.__populateProfilesList(currentProfile)
109 111
110 elif button == self.profileButtonBox.button(QDialogButtonBox.Reset): 112 elif button == self.profileButtonBox.button(
113 QDialogButtonBox.StandardButton.Reset
114 ):
111 self.__resetProfile() 115 self.__resetProfile()
112 116
113 elif button == self.profileButtonBox.button( 117 elif button == self.profileButtonBox.button(
114 QDialogButtonBox.RestoreDefaults): 118 QDialogButtonBox.StandardButton.RestoreDefaults
119 ):
115 self.__populateProfileDefault() 120 self.__populateProfileDefault()
116 121
117 @pyqtSlot(QListWidgetItem, QListWidgetItem) 122 @pyqtSlot(QListWidgetItem, QListWidgetItem)
118 def on_profilesList_currentItemChanged(self, current, previous): 123 def on_profilesList_currentItemChanged(self, current, previous):
119 """ 124 """
131 current is not previous and 136 current is not previous and
132 not self.__deletingProfile and 137 not self.__deletingProfile and
133 self.__isChangedProfile() 138 self.__isChangedProfile()
134 ): 139 ):
135 # modified profile belongs to previous 140 # modified profile belongs to previous
136 yes = E5MessageBox.yesNo( 141 yes = EricMessageBox.yesNo(
137 self, 142 self,
138 self.tr("Changed Connection Profile"), 143 self.tr("Changed Connection Profile"),
139 self.tr("""The current profile has unsaved changes.""" 144 self.tr("""The current profile has unsaved changes."""
140 """ Shall these be saved?"""), 145 """ Shall these be saved?"""),
141 icon=E5MessageBox.Warning, 146 icon=EricMessageBox.Warning,
142 yesDefault=True) 147 yesDefault=True)
143 if yes: 148 if yes:
144 self.__applyProfile() 149 self.__applyProfile()
145 150
146 if current: 151 if current:
156 """ 161 """
157 profileName, ok = QInputDialog.getText( 162 profileName, ok = QInputDialog.getText(
158 self, 163 self,
159 self.tr("New Connection Profile"), 164 self.tr("New Connection Profile"),
160 self.tr("Enter name for the new Connection Profile:"), 165 self.tr("Enter name for the new Connection Profile:"),
161 QLineEdit.Normal) 166 QLineEdit.EchoMode.Normal)
162 if ok and bool(profileName): 167 if ok and bool(profileName):
163 if profileName in self.__profiles: 168 if profileName in self.__profiles:
164 E5MessageBox.warning( 169 EricMessageBox.warning(
165 self, 170 self,
166 self.tr("New Connection Profile"), 171 self.tr("New Connection Profile"),
167 self.tr("""<p>A connection named <b>{0}</b> exists""" 172 self.tr("""<p>A connection named <b>{0}</b> exists"""
168 """ already. Aborting...</p>""").format( 173 """ already. Aborting...</p>""").format(
169 profileName)) 174 profileName))
170 else: 175 else:
171 itm = QListWidgetItem(profileName, self.profilesList) 176 itm = QListWidgetItem(profileName, self.profilesList)
172 self.profilesList.setCurrentItem(itm) 177 self.profilesList.setCurrentItem(itm)
173 self.brokerAddressEdit.setFocus(Qt.OtherFocusReason) 178 self.brokerAddressEdit.setFocus(
179 Qt.FocusReason.OtherFocusReason)
174 180
175 @pyqtSlot() 181 @pyqtSlot()
176 def on_copyButton_clicked(self): 182 def on_copyButton_clicked(self):
177 """ 183 """
178 Private slot to copy the selected profile entry. 184 Private slot to copy the selected profile entry.
182 profileName = itm.text() 188 profileName = itm.text()
183 newProfileName, ok = QInputDialog.getText( 189 newProfileName, ok = QInputDialog.getText(
184 self, 190 self,
185 self.tr("Copy Connection Profile"), 191 self.tr("Copy Connection Profile"),
186 self.tr("Enter name for the copied Connection Profile:"), 192 self.tr("Enter name for the copied Connection Profile:"),
187 QLineEdit.Normal) 193 QLineEdit.EchoMode.Normal)
188 if ok and bool(newProfileName): 194 if ok and bool(newProfileName):
189 if newProfileName in self.__profiles: 195 if newProfileName in self.__profiles:
190 E5MessageBox.warning( 196 EricMessageBox.warning(
191 self, 197 self,
192 self.tr("Copy Connection Profile"), 198 self.tr("Copy Connection Profile"),
193 self.tr("""<p>A connection named <b>{0}</b> exists""" 199 self.tr("""<p>A connection named <b>{0}</b> exists"""
194 """ already. Aborting...</p>""").format( 200 """ already. Aborting...</p>""").format(
195 newProfileName)) 201 newProfileName))
198 profile.update(self.__profiles[profileName]) 204 profile.update(self.__profiles[profileName])
199 self.__profiles[newProfileName] = profile 205 self.__profiles[newProfileName] = profile
200 206
201 itm = QListWidgetItem(newProfileName, self.profilesList) 207 itm = QListWidgetItem(newProfileName, self.profilesList)
202 self.profilesList.setCurrentItem(itm) 208 self.profilesList.setCurrentItem(itm)
203 self.brokerAddressEdit.setFocus(Qt.OtherFocusReason) 209 self.brokerAddressEdit.setFocus(
210 Qt.FocusReason.OtherFocusReason)
204 211
205 @pyqtSlot() 212 @pyqtSlot()
206 def on_minusButton_clicked(self): 213 def on_minusButton_clicked(self):
207 """ 214 """
208 Private slot to delete the selected entry. 215 Private slot to delete the selected entry.
209 """ 216 """
210 itm = self.profilesList.currentItem() 217 itm = self.profilesList.currentItem()
211 if itm: 218 if itm:
212 profileName = itm.text() 219 profileName = itm.text()
213 yes = E5MessageBox.yesNo( 220 yes = EricMessageBox.yesNo(
214 self, 221 self,
215 self.tr("Delete Connection Profile"), 222 self.tr("Delete Connection Profile"),
216 self.tr("""<p>Shall the Connection Profile <b>{0}</b>""" 223 self.tr("""<p>Shall the Connection Profile <b>{0}</b>"""
217 """ really be deleted?</p>""").format(profileName) 224 """ really be deleted?</p>""").format(profileName)
218 ) 225 )
221 del self.__profiles[profileName] 228 del self.__profiles[profileName]
222 self.__profilesChanged = True 229 self.__profilesChanged = True
223 self.__populateProfilesList() 230 self.__populateProfilesList()
224 self.__deletingProfile = False 231 self.__deletingProfile = False
225 232
226 self.profilesList.setFocus(Qt.OtherFocusReason) 233 self.profilesList.setFocus(Qt.FocusReason.OtherFocusReason)
227 234
228 def getProfiles(self): 235 def getProfiles(self):
229 """ 236 """
230 Public method to return a dictionary of profiles. 237 Public method to return a dictionary of profiles.
231 238
314 self.profilesList.clear() 321 self.profilesList.clear()
315 self.profilesList.addItems(sorted(self.__profiles.keys())) 322 self.profilesList.addItems(sorted(self.__profiles.keys()))
316 323
317 if currentProfile: 324 if currentProfile:
318 items = self.profilesList.findItems( 325 items = self.profilesList.findItems(
319 currentProfile, Qt.MatchExactly) 326 currentProfile, Qt.MatchFlag.MatchExactly)
320 if items: 327 if items:
321 self.profilesList.setCurrentItem(items[0]) 328 self.profilesList.setCurrentItem(items[0])
322 329
323 if len(self.__profiles) == 0: 330 if len(self.__profiles) == 0:
324 self.profileFrame.setEnabled(False) 331 self.profileFrame.setEnabled(False)
479 not self.__populatingProfile and 486 not self.__populatingProfile and
480 self.clientIdEdit.text() == "" and 487 self.clientIdEdit.text() == "" and
481 not self.cleanSessionCheckBox.isChecked() 488 not self.cleanSessionCheckBox.isChecked()
482 ): 489 ):
483 enable = False 490 enable = False
484 E5MessageBox.critical( 491 EricMessageBox.critical(
485 self, 492 self,
486 self.tr("Invalid Connection Parameters"), 493 self.tr("Invalid Connection Parameters"),
487 self.tr("An empty Client ID requires a clean session.")) 494 self.tr("An empty Client ID requires a clean session."))
488 495
489 if self.tlsGroupBox.isChecked(): 496 if self.tlsGroupBox.isChecked():
498 bool(self.tlsSelfSignedCertsFilePicker.text()) and 505 bool(self.tlsSelfSignedCertsFilePicker.text()) and
499 bool(self.tlsSelfSignedClientCertFilePicker.text()) and 506 bool(self.tlsSelfSignedClientCertFilePicker.text()) and
500 bool(self.tlsSelfSignedClientKeyFilePicker.text()) 507 bool(self.tlsSelfSignedClientKeyFilePicker.text())
501 ) 508 )
502 509
503 self.profileButtonBox.button(QDialogButtonBox.Apply).setEnabled(enable) 510 self.profileButtonBox.button(
511 QDialogButtonBox.StandardButton.Apply).setEnabled(enable)
504 512
505 @pyqtSlot(str) 513 @pyqtSlot(str)
506 def on_brokerAddressEdit_textChanged(self, address): 514 def on_brokerAddressEdit_textChanged(self, address):
507 """ 515 """
508 Private slot handling a change of the broker address. 516 Private slot handling a change of the broker address.
516 def on_generateIdButton_clicked(self): 524 def on_generateIdButton_clicked(self):
517 """ 525 """
518 Private slot to generate a client ID. 526 Private slot to generate a client ID.
519 """ 527 """
520 uuid = QUuid.createUuid() 528 uuid = QUuid.createUuid()
521 self.clientIdEdit.setText(uuid.toString(QUuid.WithoutBraces)) 529 self.clientIdEdit.setText(
530 uuid.toString(QUuid.StringFormat.WithoutBraces))
522 531
523 @pyqtSlot(str) 532 @pyqtSlot(str)
524 def on_clientIdEdit_textChanged(self, clientId): 533 def on_clientIdEdit_textChanged(self, clientId):
525 """ 534 """
526 Private slot handling a change of the client ID string. 535 Private slot handling a change of the client ID string.
588 @param checked state of the selection 597 @param checked state of the selection
589 @type bool 598 @type bool
590 """ 599 """
591 if checked and self.brokerPortSpinBox.value() == 1883: 600 if checked and self.brokerPortSpinBox.value() == 1883:
592 # port is still standard non-TLS port 601 # port is still standard non-TLS port
593 yes = E5MessageBox.yesNo( 602 yes = EricMessageBox.yesNo(
594 self, 603 self,
595 self.tr("SSL/TLS Enabled"), 604 self.tr("SSL/TLS Enabled"),
596 self.tr( 605 self.tr(
597 """Encrypted connection using SSL/TLS has been enabled.""" 606 """Encrypted connection using SSL/TLS has been enabled."""
598 """ However, the broker port is still the default""" 607 """ However, the broker port is still the default"""
599 """ unencrypted port (port 1883). Shall this be""" 608 """ unencrypted port (port 1883). Shall this be"""
600 """ changed?"""), 609 """ changed?"""),
601 icon=E5MessageBox.Warning, 610 icon=EricMessageBox.Warning,
602 yesDefault=True) 611 yesDefault=True)
603 if yes: 612 if yes:
604 self.brokerPortSpinBox.setValue(8883) 613 self.brokerPortSpinBox.setValue(8883)
605 elif not checked and self.brokerPortSpinBox.value() == 8883: 614 elif not checked and self.brokerPortSpinBox.value() == 8883:
606 # port is still standard TLS port 615 # port is still standard TLS port
607 yes = E5MessageBox.yesNo( 616 yes = EricMessageBox.yesNo(
608 self, 617 self,
609 self.tr("SSL/TLS Disabled"), 618 self.tr("SSL/TLS Disabled"),
610 self.tr( 619 self.tr(
611 """Encrypted connection using SSL/TLS has been disabled.""" 620 """Encrypted connection using SSL/TLS has been disabled."""
612 """ However, the broker port is still the default""" 621 """ However, the broker port is still the default"""
613 """ encrypted port (port 8883). Shall this be""" 622 """ encrypted port (port 8883). Shall this be"""
614 """ changed?"""), 623 """ changed?"""),
615 icon=E5MessageBox.Warning, 624 icon=EricMessageBox.Warning,
616 yesDefault=True) 625 yesDefault=True)
617 if yes: 626 if yes:
618 self.brokerPortSpinBox.setValue(1883) 627 self.brokerPortSpinBox.setValue(1883)
619 628
620 self.__updateApplyButton() 629 self.__updateApplyButton()
656 def reject(self): 665 def reject(self):
657 """ 666 """
658 Public slot to reject the dialog changes. 667 Public slot to reject the dialog changes.
659 """ 668 """
660 if self.__isChangedProfile(): 669 if self.__isChangedProfile():
661 button = E5MessageBox.warning( 670 button = EricMessageBox.warning(
662 self, 671 self,
663 self.tr("Changed Connection Profile"), 672 self.tr("Changed Connection Profile"),
664 self.tr("""The current profile has unsaved changes. Shall""" 673 self.tr("""The current profile has unsaved changes. Shall"""
665 """ these be saved?"""), 674 """ these be saved?"""),
666 E5MessageBox.StandardButtons( 675 EricMessageBox.Discard |
667 E5MessageBox.Discard | 676 EricMessageBox.Save,
668 E5MessageBox.Save), 677 EricMessageBox.Save)
669 E5MessageBox.Save) 678 if button == EricMessageBox.Save:
670 if button == E5MessageBox.Save:
671 self.__applyProfile() 679 self.__applyProfile()
672 return 680 return
673 681
674 if self.__profilesChanged: 682 if self.__profilesChanged:
675 button = E5MessageBox.warning( 683 button = EricMessageBox.warning(
676 self, 684 self,
677 self.tr("Changed Connection Profiles"), 685 self.tr("Changed Connection Profiles"),
678 self.tr("""The list of connection profiles has unsaved""" 686 self.tr("""The list of connection profiles has unsaved"""
679 """ changes."""), 687 """ changes."""),
680 E5MessageBox.StandardButtons( 688 EricMessageBox.Abort |
681 E5MessageBox.Abort | 689 EricMessageBox.Discard |
682 E5MessageBox.Discard | 690 EricMessageBox.Save,
683 E5MessageBox.Save), 691 EricMessageBox.Save)
684 E5MessageBox.Save) 692 if button == EricMessageBox.Save:
685 if button == E5MessageBox.Save:
686 super().accept() 693 super().accept()
687 return 694 return
688 elif button == E5MessageBox.Abort: 695 elif button == EricMessageBox.Abort:
689 return 696 return
690 697
691 super().reject() 698 super().reject()
692 699
693 @pyqtSlot() 700 @pyqtSlot()
694 def accept(self): 701 def accept(self):
695 """ 702 """
696 Public slot to accept the dialog. 703 Public slot to accept the dialog.
697 """ 704 """
698 if self.__isChangedProfile(): 705 if self.__isChangedProfile():
699 yes = E5MessageBox.yesNo( 706 yes = EricMessageBox.yesNo(
700 self, 707 self,
701 self.tr("Changed Connection Profile"), 708 self.tr("Changed Connection Profile"),
702 self.tr("""The current profile has unsaved changes. Shall""" 709 self.tr("""The current profile has unsaved changes. Shall"""
703 """ these be saved?"""), 710 """ these be saved?"""),
704 icon=E5MessageBox.Warning, 711 icon=EricMessageBox.Warning,
705 yesDefault=True) 712 yesDefault=True)
706 if yes: 713 if yes:
707 self.__applyProfile() 714 self.__applyProfile()
708 715
709 super().accept() 716 super().accept()

eric ide

mercurial