|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2014 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a dialog to enter some user data. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 import os |
|
13 |
|
14 from PyQt5.QtCore import pyqtSlot, Qt, QEvent |
|
15 from PyQt5.QtWidgets import QDialog, QTreeWidgetItem |
|
16 |
|
17 from E5Gui.E5PathPicker import E5PathPickerModes |
|
18 from E5Gui import E5MessageBox |
|
19 |
|
20 import Globals |
|
21 from Globals.E5ConfigParser import E5ConfigParser |
|
22 |
|
23 from .HgUtilities import getConfigPath |
|
24 from .HgUserConfigHostFingerprintDialog import \ |
|
25 HgUserConfigHostFingerprintDialog |
|
26 from .HgUserConfigHostMinimumProtocolDialog import \ |
|
27 HgUserConfigHostMinimumProtocolDialog |
|
28 |
|
29 from .Ui_HgUserConfigDialog import Ui_HgUserConfigDialog |
|
30 |
|
31 import UI.PixmapCache |
|
32 |
|
33 |
|
34 class HgUserConfigDialog(QDialog, Ui_HgUserConfigDialog): |
|
35 """ |
|
36 Class implementing a dialog to enter some user data. |
|
37 """ |
|
38 def __init__(self, version=(0, 0, 0), parent=None): |
|
39 """ |
|
40 Constructor |
|
41 |
|
42 @param version Mercurial version info |
|
43 @type tuple of three integers |
|
44 @param parent reference to the parent widget |
|
45 @type QWidget |
|
46 """ |
|
47 super(HgUserConfigDialog, self).__init__(parent) |
|
48 self.setupUi(self) |
|
49 |
|
50 self.__version = version |
|
51 |
|
52 self.__minimumProtocols = { |
|
53 "tls1.0": self.tr("TLS 1.0"), |
|
54 "tls1.1": self.tr("TLS 1.1"), |
|
55 "tls1.2": self.tr("TLS 1.2"), |
|
56 } |
|
57 |
|
58 self.lfUserCachePicker.setMode(E5PathPickerModes.DirectoryMode) |
|
59 if Globals.isLinuxPlatform(): |
|
60 self.lfUserCachePicker.setDefaultDirectory(os.path.expanduser( |
|
61 "~/.cache/largefiles")) |
|
62 elif Globals.isMacPlatform(): |
|
63 self.lfUserCachePicker.setDefaultDirectory(os.path.expanduser( |
|
64 "~/Library/Caches/largefiles")) |
|
65 else: |
|
66 self.lfUserCachePicker.setDefaultDirectory(os.path.expanduser( |
|
67 "~\\AppData\\Local\\largefiles")) |
|
68 |
|
69 self.fpAddButton.setIcon(UI.PixmapCache.getIcon("plus.png")) |
|
70 self.fpDeleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) |
|
71 self.fpEditButton.setIcon(UI.PixmapCache.getIcon("edit.png")) |
|
72 |
|
73 self.protocolAddButton.setIcon(UI.PixmapCache.getIcon("plus.png")) |
|
74 self.protocolDeleteButton.setIcon(UI.PixmapCache.getIcon("minus.png")) |
|
75 self.protocolEditButton.setIcon(UI.PixmapCache.getIcon("edit.png")) |
|
76 |
|
77 self.minimumProtocolComboBox.addItem(self.tr("Default"), "") |
|
78 for protocol in sorted(self.__minimumProtocols.keys()): |
|
79 self.minimumProtocolComboBox.addItem( |
|
80 self.__minimumProtocols[protocol], protocol) |
|
81 |
|
82 self.fingerprintsList.headerItem().setText( |
|
83 self.fingerprintsList.columnCount(), "") |
|
84 self.protocolsList.headerItem().setText( |
|
85 self.protocolsList.columnCount(), "") |
|
86 |
|
87 if self.__version < (3, 9, 0): |
|
88 self.disableTls10WarningCheckBox.setEnabled(False) |
|
89 self.minimumProtocolComboBox.setEnabled(False) |
|
90 self.minimumProtcolGroupBox.setEnabled(False) |
|
91 |
|
92 self.tabWidget.setCurrentIndex(0) |
|
93 |
|
94 self.__editor = None |
|
95 |
|
96 self.__config = None |
|
97 self.readUserConfig() |
|
98 |
|
99 self.__updateFingerprintsButtons() |
|
100 self.__updateProtocolsButtons() |
|
101 |
|
102 def writeUserConfig(self): |
|
103 """ |
|
104 Public method to write the user configuration file. |
|
105 """ |
|
106 if self.__config is None: |
|
107 self.__config = E5ConfigParser() |
|
108 |
|
109 ################################################################### |
|
110 ## ui section |
|
111 ################################################################### |
|
112 if "ui" not in self.__config: |
|
113 self.__config["ui"] = {} |
|
114 self.__config["ui"]["username"] = "{0} <{1}>".format( |
|
115 self.userNameEdit.text(), |
|
116 self.emailEdit.text(), |
|
117 ) |
|
118 ################################################################### |
|
119 ## extensions section |
|
120 ################################################################### |
|
121 if "extensions" not in self.__config: |
|
122 self.__config["extensions"] = {} |
|
123 if self.fetchCheckBox.isChecked(): |
|
124 self.__config["extensions"]["fetch"] = "" |
|
125 else: |
|
126 if "fetch" in self.__config["extensions"]: |
|
127 del self.__config["extensions"]["fetch"] |
|
128 self.__config["extensions"]["#fetch"] = "" |
|
129 |
|
130 if self.gpgCheckBox.isChecked(): |
|
131 self.__config["extensions"]["gpg"] = "" |
|
132 else: |
|
133 if "gpg" in self.__config["extensions"]: |
|
134 del self.__config["extensions"]["gpg"] |
|
135 self.__config["extensions"]["#gpg"] = "" |
|
136 |
|
137 if self.purgeCheckBox.isChecked(): |
|
138 self.__config["extensions"]["purge"] = "" |
|
139 else: |
|
140 if "purge" in self.__config["extensions"]: |
|
141 del self.__config["extensions"]["purge"] |
|
142 self.__config["extensions"]["#purge"] = "" |
|
143 |
|
144 if self.queuesCheckBox.isChecked(): |
|
145 self.__config["extensions"]["mq"] = "" |
|
146 else: |
|
147 if "mq" in self.__config["extensions"]: |
|
148 del self.__config["extensions"]["mq"] |
|
149 self.__config["extensions"]["#mq"] = "" |
|
150 |
|
151 if self.rebaseCheckBox.isChecked(): |
|
152 self.__config["extensions"]["rebase"] = "" |
|
153 else: |
|
154 if "rebase" in self.__config["extensions"]: |
|
155 del self.__config["extensions"]["rebase"] |
|
156 self.__config["extensions"]["#rebase"] = "" |
|
157 |
|
158 if self.shelveCheckBox.isChecked(): |
|
159 self.__config["extensions"]["shelve"] = "" |
|
160 else: |
|
161 if "shelve" in self.__config["extensions"]: |
|
162 del self.__config["extensions"]["shelve"] |
|
163 self.__config["extensions"]["#shelve"] = "" |
|
164 |
|
165 if self.stripCheckBox.isChecked(): |
|
166 self.__config["extensions"]["strip"] = "" |
|
167 else: |
|
168 if "strip" in self.__config["extensions"]: |
|
169 del self.__config["extensions"]["strip"] |
|
170 self.__config["extensions"]["#strip"] = "" |
|
171 |
|
172 if self.histeditCheckBox.isChecked(): |
|
173 self.__config["extensions"]["histedit"] = "" |
|
174 else: |
|
175 if "histedit" in self.__config["extensions"]: |
|
176 del self.__config["extensions"]["histedit"] |
|
177 self.__config["extensions"]["#histedit"] = "" |
|
178 |
|
179 if self.largefilesCheckBox.isChecked(): |
|
180 self.__config["extensions"]["largefiles"] = "" |
|
181 ############################################################### |
|
182 ## largefiles section |
|
183 ############################################################### |
|
184 if "largefiles" not in self.__config: |
|
185 self.__config["largefiles"] = {} |
|
186 self.__config["largefiles"]["minsize"] = \ |
|
187 str(self.lfFileSizeSpinBox.value()) |
|
188 lfFilePatterns = self.lfFilePatternsEdit.text() |
|
189 if lfFilePatterns: |
|
190 self.__config["largefiles"]["patterns"] = lfFilePatterns |
|
191 elif "patterns" in self.__config["largefiles"]: |
|
192 del self.__config["largefiles"]["patterns"] |
|
193 lfUserCache = self.lfUserCachePicker.text() |
|
194 if lfUserCache: |
|
195 self.__config["largefiles"]["usercache"] = lfUserCache |
|
196 elif "usercache" in self.__config["largefiles"]: |
|
197 del self.__config["largefiles"]["usercache"] |
|
198 else: |
|
199 if "largefiles" in self.__config["extensions"]: |
|
200 del self.__config["extensions"]["largefiles"] |
|
201 self.__config["extensions"]["#largefiles"] = "" |
|
202 ################################################################### |
|
203 ## http_proxy section |
|
204 ################################################################### |
|
205 if self.proxyHostEdit.text(): |
|
206 self.__config["http_proxy"] = { |
|
207 "host": self.proxyHostEdit.text(), |
|
208 "user": self.proxyUserEdit.text(), |
|
209 "passwd": self.proxyPasswordEdit.text() |
|
210 } |
|
211 if self.proxyBypassEdit.text(): |
|
212 self.__config["http_proxy"]["no"] = \ |
|
213 self.proxyBypassEdit.text() |
|
214 else: |
|
215 if "http_proxy" in self.__config: |
|
216 del self.__config["http_proxy"] |
|
217 ################################################################### |
|
218 ## hostfingerprints/hostsecurity section |
|
219 ################################################################### |
|
220 if self.__version < (3, 9, 0): |
|
221 # |
|
222 # delete hostsecurity section |
|
223 # |
|
224 if "hostsecurity" in self.__config: |
|
225 del self.__config["hostsecurity"] |
|
226 |
|
227 # |
|
228 # hostfingerprints section |
|
229 # |
|
230 if self.fingerprintsList.topLevelItemCount() > 0: |
|
231 self.__config["hostfingerprints"] = {} |
|
232 for row in range(self.fingerprintsList.topLevelItemCount()): |
|
233 itm = self.fingerprintsList.topLevelItem(row) |
|
234 fingerprint = itm.text(1) |
|
235 if fingerprint.startswith("sha1:"): |
|
236 fingerprint = fingerprint[5:] |
|
237 self.__config["hostfingerprints"][itm.text(0)] = \ |
|
238 fingerprint |
|
239 else: |
|
240 if "hostfingerprints" in self.__config: |
|
241 del self.__config["hostfingerprints"] |
|
242 else: |
|
243 # |
|
244 # delete hostfingerprints section |
|
245 # |
|
246 if "hostfingerprints" in self.__config: |
|
247 del self.__config["hostfingerprints"] |
|
248 |
|
249 # |
|
250 # hostsecurity section |
|
251 # |
|
252 if "hostsecurity" not in self.__config: |
|
253 self.__config["hostsecurity"] = {} |
|
254 |
|
255 if self.fingerprintsList.topLevelItemCount() > 0: |
|
256 self.__clearFingerprints() |
|
257 fingerprints = self.__assembleFingerprints() |
|
258 for host in fingerprints: |
|
259 key = "{0}:fingerprints".format(host) |
|
260 self.__config["hostsecurity"][key] = \ |
|
261 ", ".join(fingerprints[host]) |
|
262 else: |
|
263 self.__clearFingerprints() |
|
264 |
|
265 if self.disableTls10WarningCheckBox.isChecked(): |
|
266 disabletls10warning = "true" |
|
267 else: |
|
268 disabletls10warning = "false" |
|
269 self.__config["hostsecurity"]["disabletls10warning"] = \ |
|
270 disabletls10warning |
|
271 |
|
272 if self.minimumProtocolComboBox.currentIndex() == 0: |
|
273 self.__config.remove_option("hostsecurity", "minimumprotocol") |
|
274 else: |
|
275 minimumProtocol = self.minimumProtocolComboBox.itemData( |
|
276 self.minimumProtocolComboBox.currentIndex()) |
|
277 self.__config["hostsecurity"]["minimumprotocol"] = \ |
|
278 minimumProtocol |
|
279 |
|
280 if self.protocolsList.topLevelItemCount() > 0: |
|
281 self.__clearMinimumProtocols() |
|
282 minimumProtocols = self.__assembleMinimumProtocols() |
|
283 for host in minimumProtocols: |
|
284 key = "{0}:minimumprotocol".format(host) |
|
285 self.__config["hostsecurity"][key] = minimumProtocols[host] |
|
286 else: |
|
287 self.__clearMinimumProtocols() |
|
288 |
|
289 if len(self.__config.options("hostsecurity")) == 0: |
|
290 del self.__config["hostsecurity"] |
|
291 ################################################################### |
|
292 |
|
293 cfgFile = getConfigPath() |
|
294 with open(cfgFile, "w") as configFile: |
|
295 self.__config.write(configFile) |
|
296 |
|
297 def readUserConfig(self): |
|
298 """ |
|
299 Public method to read the user configuration file. |
|
300 """ |
|
301 cfgFile = getConfigPath() |
|
302 |
|
303 self.__config = E5ConfigParser(delimiters=("=",)) |
|
304 if self.__config.read(cfgFile): |
|
305 # step 1: extract user name and email |
|
306 try: |
|
307 username = self.__config["ui"]["username"].strip() |
|
308 if "<" in username and username.endswith(">"): |
|
309 name, email = username[:-1].rsplit("<", 1) |
|
310 else: |
|
311 name = username |
|
312 email = "" |
|
313 self.userNameEdit.setText(name.strip()), |
|
314 self.emailEdit.setText(email.strip()), |
|
315 except KeyError: |
|
316 pass |
|
317 |
|
318 # step 2: extract extensions information |
|
319 if "extensions" in self.__config: |
|
320 self.fetchCheckBox.setChecked( |
|
321 "fetch" in self.__config["extensions"]) |
|
322 self.gpgCheckBox.setChecked( |
|
323 "gpg" in self.__config["extensions"]) |
|
324 self.purgeCheckBox.setChecked( |
|
325 "purge" in self.__config["extensions"]) |
|
326 self.queuesCheckBox.setChecked( |
|
327 "mq" in self.__config["extensions"]) |
|
328 self.rebaseCheckBox.setChecked( |
|
329 "rebase" in self.__config["extensions"]) |
|
330 self.shelveCheckBox.setChecked( |
|
331 "shelve" in self.__config["extensions"]) |
|
332 self.largefilesCheckBox.setChecked( |
|
333 "largefiles" in self.__config["extensions"]) |
|
334 self.stripCheckBox.setChecked( |
|
335 "strip" in self.__config["extensions"]) |
|
336 self.histeditCheckBox.setChecked( |
|
337 "histedit" in self.__config["extensions"]) |
|
338 |
|
339 # step 3: extract large files information |
|
340 if "largefiles" in self.__config: |
|
341 if "minsize" in self.__config["largefiles"]: |
|
342 self.lfFileSizeSpinBox.setValue( |
|
343 self.__config.getint("largefiles", "minsize")) |
|
344 if "patterns" in self.__config["largefiles"]: |
|
345 self.lfFilePatternsEdit.setText( |
|
346 self.__config["largefiles"]["patterns"]) |
|
347 if "usercache" in self.__config["largefiles"]: |
|
348 self.lfUserCachePicker.setText( |
|
349 self.__config["largefiles"]["usercache"]) |
|
350 |
|
351 # step 4: extract http proxy information |
|
352 if "http_proxy" in self.__config: |
|
353 if "host" in self.__config["http_proxy"]: |
|
354 self.proxyHostEdit.setText( |
|
355 self.__config["http_proxy"]["host"]) |
|
356 if "user" in self.__config["http_proxy"]: |
|
357 self.proxyUserEdit.setText( |
|
358 self.__config["http_proxy"]["user"]) |
|
359 if "passwd" in self.__config["http_proxy"]: |
|
360 self.proxyPasswordEdit.setText( |
|
361 self.__config["http_proxy"]["passwd"]) |
|
362 if "no" in self.__config["http_proxy"]: |
|
363 self.proxyBypassEdit.setText( |
|
364 self.__config["http_proxy"]["no"]) |
|
365 |
|
366 # step 5a: extract host fingerprints |
|
367 if "hostfingerprints" in self.__config: |
|
368 for host in self.__config.options("hostfingerprints"): |
|
369 if self.__version < (3, 9, 0): |
|
370 QTreeWidgetItem(self.fingerprintsList, [ |
|
371 host, |
|
372 self.__config["hostfingerprints"][host] |
|
373 ]) |
|
374 else: |
|
375 # convert to hostsecurity fingerprint |
|
376 QTreeWidgetItem(self.fingerprintsList, [ |
|
377 host, |
|
378 "sha1:" + self.__config["hostfingerprints"][host] |
|
379 ]) |
|
380 |
|
381 # step 5b: extract hostsecurity fingerprints |
|
382 if "hostsecurity" in self.__config: |
|
383 for key in self.__config.options("hostsecurity"): |
|
384 if key.endswith(":fingerprints"): |
|
385 host = key.replace(":fingerprints", "") |
|
386 fingerprints = \ |
|
387 self.__config["hostsecurity"][key].split(",") |
|
388 for fingerprint in fingerprints: |
|
389 if self.__version < (3, 9, 0): |
|
390 # downgrade from a newer version |
|
391 if fingerprint.startswith("sha1:"): |
|
392 fingerprint = fingerprint[5:] |
|
393 else: |
|
394 # Mercurial < 3.9.0 supports sha1 |
|
395 # fingerprints only |
|
396 continue |
|
397 QTreeWidgetItem(self.fingerprintsList, [ |
|
398 host, |
|
399 fingerprint.replace("\\", "").strip() |
|
400 ]) |
|
401 |
|
402 elif key == "disabletls10warning": |
|
403 self.disableTls10WarningCheckBox.setChecked( |
|
404 self.__config.getboolean( |
|
405 "hostsecurity", "disabletls10warning")) |
|
406 |
|
407 elif key == "minimumprotocol": |
|
408 minimumProtocol = self.__config["hostsecurity"][key] |
|
409 index = self.minimumProtocolComboBox.findData( |
|
410 minimumProtocol) |
|
411 if index == -1: |
|
412 index = 0 |
|
413 self.minimumProtocolComboBox.setCurrentIndex(index) |
|
414 |
|
415 elif key.endswith(":minimumprotocol"): |
|
416 host = key.replace(":minimumprotocol", "") |
|
417 protocol = self.__config["hostsecurity"][key].strip() |
|
418 if protocol in self.__minimumProtocols: |
|
419 itm = QTreeWidgetItem(self.protocolsList, [ |
|
420 host, |
|
421 self.__minimumProtocols[protocol] |
|
422 ]) |
|
423 itm.setData(1, Qt.UserRole, protocol) |
|
424 |
|
425 self.__finalizeFingerprintsColumns() |
|
426 self.__finalizeProtocolsColumns() |
|
427 |
|
428 @pyqtSlot() |
|
429 def accept(self): |
|
430 """ |
|
431 Public slot to accept the dialog. |
|
432 """ |
|
433 self.writeUserConfig() |
|
434 |
|
435 super(HgUserConfigDialog, self).accept() |
|
436 |
|
437 def __clearDialog(self): |
|
438 """ |
|
439 Private method to clear the data of the dialog. |
|
440 """ |
|
441 self.userNameEdit.clear() |
|
442 self.emailEdit.clear() |
|
443 |
|
444 self.fetchCheckBox.setChecked(False) |
|
445 self.gpgCheckBox.setChecked(False) |
|
446 self.purgeCheckBox.setChecked(False) |
|
447 self.queuesCheckBox.setChecked(False) |
|
448 self.rebaseCheckBox.setChecked(False) |
|
449 self.shelveCheckBox.setChecked(False) |
|
450 self.stripCheckBox.setChecked(False) |
|
451 self.largefilesCheckBox.setChecked(False) |
|
452 self.lfFileSizeSpinBox.setValue(10) |
|
453 self.lfFilePatternsEdit.clear() |
|
454 self.lfUserCachePicker.clear() |
|
455 |
|
456 self.proxyHostEdit.clear() |
|
457 self.proxyUserEdit.clear() |
|
458 self.proxyPasswordEdit.clear() |
|
459 self.proxyBypassEdit.clear() |
|
460 |
|
461 self.fingerprintsList.clear() |
|
462 self.__finalizeFingerprintsColumns() |
|
463 self.__updateFingerprintsButtons() |
|
464 |
|
465 self.protocolsList.clear() |
|
466 self.__finalizeProtocolsColumns() |
|
467 self.__updateProtocolsButtons() |
|
468 |
|
469 ####################################################################### |
|
470 ## Methods and slots for the host fingerprint handling below |
|
471 ####################################################################### |
|
472 |
|
473 def __clearFingerprints(self): |
|
474 """ |
|
475 Private method to clear the fingerprints from the hostsecurity section. |
|
476 """ |
|
477 if "hostsecurity" in self.__config: |
|
478 for key in self.__config.options("hostsecurity"): |
|
479 if key.endswith(":fingerprints"): |
|
480 self.__config.remove_option("hostsecurity", key) |
|
481 |
|
482 def __assembleFingerprints(self): |
|
483 """ |
|
484 Private method to assemble a list of host fingerprints. |
|
485 |
|
486 @return dictionary with list of fingerprints per host |
|
487 @rtype dict with str as key and list of str as value |
|
488 """ |
|
489 hostFingerprints = {} |
|
490 for row in range(self.fingerprintsList.topLevelItemCount()): |
|
491 itm = self.fingerprintsList.topLevelItem(row) |
|
492 host = itm.text(0) |
|
493 fingerprint = itm.text(1) |
|
494 if host in hostFingerprints: |
|
495 hostFingerprints[host].append(fingerprint) |
|
496 else: |
|
497 hostFingerprints[host] = [fingerprint] |
|
498 return hostFingerprints |
|
499 |
|
500 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) |
|
501 def on_fingerprintsList_currentItemChanged(self, current, previous): |
|
502 """ |
|
503 Private slot handling a change of the current fingerprints item. |
|
504 |
|
505 @param current reference to the current item |
|
506 @type QTreeWidgetItem |
|
507 @param previous reference to the previous current item |
|
508 @type QTreeWidgetItem |
|
509 """ |
|
510 self.__updateFingerprintsButtons() |
|
511 |
|
512 @pyqtSlot() |
|
513 def on_fpAddButton_clicked(self): |
|
514 """ |
|
515 Private slot to add a fingerprints entry. |
|
516 """ |
|
517 dlg = HgUserConfigHostFingerprintDialog(self, version=self.__version) |
|
518 if dlg.exec_() == QDialog.Accepted: |
|
519 host, fingerprint = dlg.getData() |
|
520 itm = QTreeWidgetItem(self.fingerprintsList, [host, fingerprint]) |
|
521 self.__finalizeFingerprintsColumns() |
|
522 self.fingerprintsList.setCurrentItem(itm) |
|
523 self.fingerprintsList.scrollToItem(itm) |
|
524 |
|
525 @pyqtSlot() |
|
526 def on_fpDeleteButton_clicked(self): |
|
527 """ |
|
528 Private slot to delete the current fingerprints item. |
|
529 """ |
|
530 itm = self.fingerprintsList.currentItem() |
|
531 if itm is not None: |
|
532 host = itm.text(0) |
|
533 yes = E5MessageBox.yesNo( |
|
534 self, |
|
535 self.tr("Delete Host Fingerprint"), |
|
536 self.tr("""<p>Shall the fingerprint for host <b>{0}</b>""" |
|
537 """ really be deleted?</p>""").format(host)) |
|
538 if yes: |
|
539 self.fingerprintsList.takeTopLevelItem( |
|
540 self.fingerprintsList.indexOfTopLevelItem(itm)) |
|
541 del itm |
|
542 self.__finalizeFingerprintsColumns() |
|
543 |
|
544 @pyqtSlot() |
|
545 def on_fpEditButton_clicked(self): |
|
546 """ |
|
547 Private slot to edit the current fingerprints item. |
|
548 """ |
|
549 itm = self.fingerprintsList.currentItem() |
|
550 if itm is not None: |
|
551 host = itm.text(0) |
|
552 fingerprint = itm.text(1) |
|
553 dlg = HgUserConfigHostFingerprintDialog(self, host, fingerprint, |
|
554 version=self.__version) |
|
555 if dlg.exec_() == QDialog.Accepted: |
|
556 host, fingerprint = dlg.getData() |
|
557 itm.setText(0, host) |
|
558 itm.setText(1, fingerprint) |
|
559 self.__finalizeFingerprintsColumns() |
|
560 self.fingerprintsList.scrollToItem(itm) |
|
561 |
|
562 def __finalizeFingerprintsColumns(self): |
|
563 """ |
|
564 Private method to resize and sort the host fingerprints columns. |
|
565 """ |
|
566 for col in range(self.fingerprintsList.columnCount()): |
|
567 self.fingerprintsList.resizeColumnToContents(col) |
|
568 self.fingerprintsList.sortItems(0, Qt.AscendingOrder) |
|
569 |
|
570 def __updateFingerprintsButtons(self): |
|
571 """ |
|
572 Private slot to update the host fingerprints edit buttons. |
|
573 """ |
|
574 enable = self.fingerprintsList.currentItem() is not None |
|
575 self.fpDeleteButton.setEnabled(enable) |
|
576 self.fpEditButton.setEnabled(enable) |
|
577 |
|
578 ####################################################################### |
|
579 ## Methods and slots for the host minimum protocol handling below |
|
580 ####################################################################### |
|
581 |
|
582 def __clearMinimumProtocols(self): |
|
583 """ |
|
584 Private method to clear the minimum protocols from the hostsecurity |
|
585 section. |
|
586 """ |
|
587 if "hostsecurity" in self.__config: |
|
588 for key in self.__config.options("hostsecurity"): |
|
589 if key.endswith(":minimumprotocol"): |
|
590 self.__config.remove_option("hostsecurity", key) |
|
591 |
|
592 def __assembleMinimumProtocols(self): |
|
593 """ |
|
594 Private method to assemble a list of host minimum protocols. |
|
595 |
|
596 @return dictionary with list of minimum protocol per host |
|
597 @rtype dict with str as key and str as value |
|
598 """ |
|
599 minimumProtocols = {} |
|
600 for row in range(self.protocolsList.topLevelItemCount()): |
|
601 itm = self.protocolsList.topLevelItem(row) |
|
602 host = itm.text(0) |
|
603 minimumProtocol = itm.data(1, Qt.UserRole) |
|
604 minimumProtocols[host] = minimumProtocol |
|
605 return minimumProtocols |
|
606 |
|
607 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) |
|
608 def on_protocolsList_currentItemChanged(self, current, previous): |
|
609 """ |
|
610 Private slot handling a change of the current minimum protocol item. |
|
611 |
|
612 @param current reference to the current item |
|
613 @type QTreeWidgetItem |
|
614 @param previous reference to the previous current item |
|
615 @type QTreeWidgetItem |
|
616 """ |
|
617 self.__updateProtocolsButtons() |
|
618 |
|
619 @pyqtSlot() |
|
620 def on_protocolAddButton_clicked(self): |
|
621 """ |
|
622 Private slot to add a minimum protocol entry. |
|
623 """ |
|
624 dlg = HgUserConfigHostMinimumProtocolDialog(self.__minimumProtocols, |
|
625 self) |
|
626 if dlg.exec_() == QDialog.Accepted: |
|
627 host, protocol = dlg.getData() |
|
628 itm = QTreeWidgetItem(self.protocolsList, [ |
|
629 host, |
|
630 self.__minimumProtocols[protocol] |
|
631 ]) |
|
632 itm.setData(1, Qt.UserRole, protocol) |
|
633 self.__finalizeProtocolsColumns() |
|
634 self.protocolsList.setCurrentItem(itm) |
|
635 self.protocolsList.scrollToItem(itm) |
|
636 |
|
637 @pyqtSlot() |
|
638 def on_protocolDeleteButton_clicked(self): |
|
639 """ |
|
640 Private slot to delete the current minimum protocol item. |
|
641 """ |
|
642 itm = self.protocolsList.currentItem() |
|
643 if itm is not None: |
|
644 host = itm.text(0) |
|
645 yes = E5MessageBox.yesNo( |
|
646 self, |
|
647 self.tr("Delete Host Minimum Protocol"), |
|
648 self.tr("""<p>Shall the minimum protocol entry for host""" |
|
649 """ <b>{0}</b> really be deleted?</p>""").format(host)) |
|
650 if yes: |
|
651 self.protocolsList.takeTopLevelItem( |
|
652 self.protocolsList.indexOfTopLevelItem(itm)) |
|
653 del itm |
|
654 self.__finalizeProtocolsColumns() |
|
655 |
|
656 @pyqtSlot() |
|
657 def on_protocolEditButton_clicked(self): |
|
658 """ |
|
659 Private slot to edit the current minimum protocol item. |
|
660 """ |
|
661 itm = self.protocolsList.currentItem() |
|
662 if itm is not None: |
|
663 host = itm.text(0) |
|
664 protocol = itm.data(1, Qt.UserRole) |
|
665 dlg = HgUserConfigHostMinimumProtocolDialog( |
|
666 self.__minimumProtocols, self, host, protocol) |
|
667 if dlg.exec_() == QDialog.Accepted: |
|
668 host, protocol = dlg.getData() |
|
669 itm.setText(0, host) |
|
670 itm.setText(1, self.__minimumProtocols[protocol]) |
|
671 itm.setData(1, Qt.UserRole, protocol) |
|
672 self.__finalizeProtocolsColumns() |
|
673 self.protocolsList.scrollToItem(itm) |
|
674 |
|
675 def __finalizeProtocolsColumns(self): |
|
676 """ |
|
677 Private method to resize and sort the host fingerprints columns. |
|
678 """ |
|
679 for col in range(self.protocolsList.columnCount()): |
|
680 self.protocolsList.resizeColumnToContents(col) |
|
681 self.protocolsList.sortItems(0, Qt.AscendingOrder) |
|
682 |
|
683 def __updateProtocolsButtons(self): |
|
684 """ |
|
685 Private slot to update the host minimum protocol edit buttons. |
|
686 """ |
|
687 enable = self.protocolsList.currentItem() is not None |
|
688 self.protocolDeleteButton.setEnabled(enable) |
|
689 self.protocolEditButton.setEnabled(enable) |
|
690 |
|
691 ####################################################################### |
|
692 ## Slot to edit the user configuration in an editor below |
|
693 ####################################################################### |
|
694 |
|
695 @pyqtSlot() |
|
696 def on_editorButton_clicked(self): |
|
697 """ |
|
698 Private slot to open the user configuration file in a text editor. |
|
699 """ |
|
700 from QScintilla.MiniEditor import MiniEditor |
|
701 cfgFile = getConfigPath() |
|
702 |
|
703 yes = E5MessageBox.yesNo( |
|
704 self, |
|
705 self.tr("Edit User Configuration"), |
|
706 self.tr("""You will loose all changes made in this dialog.""" |
|
707 """ Shall the data be saved first?"""), |
|
708 icon=E5MessageBox.Warning, |
|
709 yesDefault=True) |
|
710 if yes: |
|
711 self.writeUserConfig() |
|
712 |
|
713 self.__editor = MiniEditor(cfgFile, "Properties", self) |
|
714 self.__editor.setWindowModality(Qt.WindowModal) |
|
715 self.__editor.installEventFilter(self) |
|
716 self.__editor.show() |
|
717 |
|
718 def eventFilter(self, watched, event): |
|
719 """ |
|
720 Public method called to filter the event queue. |
|
721 |
|
722 @param watched reference to the object being watched |
|
723 @type QObject |
|
724 @param event event to be handled |
|
725 @type QEvent |
|
726 @return flag indicating, if we handled the event |
|
727 @rtype bool |
|
728 """ |
|
729 if watched is self.__editor and event.type() == QEvent.Close: |
|
730 self.__editor.closeEvent(event) |
|
731 if event.isAccepted(): |
|
732 self.__clearDialog() |
|
733 self.readUserConfig() |
|
734 return True |
|
735 |
|
736 return False |