eric6/Plugins/VcsPlugins/vcsMercurial/GpgExtension/HgGpgSignaturesDialog.py

changeset 7370
5fb53279f2df
parent 7360
9190402e4505
child 7775
4a1db75550bd
equal deleted inserted replaced
7369:dbeeed55df08 7370:5fb53279f2df
5 5
6 """ 6 """
7 Module implementing a dialog showing signed changesets. 7 Module implementing a dialog showing signed changesets.
8 """ 8 """
9 9
10
11 import os 10 import os
12 11
13 from PyQt5.QtCore import ( 12 from PyQt5.QtCore import pyqtSlot, Qt, QRegExp, QCoreApplication
14 pyqtSlot, QProcess, QTimer, Qt, QRegExp, QCoreApplication 13 from PyQt5.QtWidgets import (
14 QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem
15 ) 15 )
16 from PyQt5.QtWidgets import (
17 QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem, QLineEdit
18 )
19
20 from E5Gui import E5MessageBox
21 16
22 from .Ui_HgGpgSignaturesDialog import Ui_HgGpgSignaturesDialog 17 from .Ui_HgGpgSignaturesDialog import Ui_HgGpgSignaturesDialog
23
24 from Globals import strToQByteArray
25 18
26 19
27 class HgGpgSignaturesDialog(QDialog, Ui_HgGpgSignaturesDialog): 20 class HgGpgSignaturesDialog(QDialog, Ui_HgGpgSignaturesDialog):
28 """ 21 """
29 Class implementing a dialog showing signed changesets. 22 Class implementing a dialog showing signed changesets.
40 self.setWindowFlags(Qt.Window) 33 self.setWindowFlags(Qt.Window)
41 34
42 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) 35 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
43 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) 36 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
44 37
45 self.process = QProcess()
46 self.vcs = vcs 38 self.vcs = vcs
47 self.__hgClient = vcs.getClient() 39 self.__hgClient = vcs.getClient()
48 40
49 self.process.finished.connect(self.__procFinished)
50 self.process.readyReadStandardOutput.connect(self.__readStdout)
51 self.process.readyReadStandardError.connect(self.__readStderr)
52
53 self.show() 41 self.show()
54 QCoreApplication.processEvents() 42 QCoreApplication.processEvents()
55 43
56 def closeEvent(self, e): 44 def closeEvent(self, e):
57 """ 45 """
58 Protected slot implementing a close event handler. 46 Protected slot implementing a close event handler.
59 47
60 @param e close event (QCloseEvent) 48 @param e close event (QCloseEvent)
61 """ 49 """
62 if self.__hgClient: 50 if self.__hgClient.isExecuting():
63 if self.__hgClient.isExecuting(): 51 self.__hgClient.cancel()
64 self.__hgClient.cancel()
65 else:
66 if (
67 self.process is not None and
68 self.process.state() != QProcess.NotRunning
69 ):
70 self.process.terminate()
71 QTimer.singleShot(2000, self.process.kill)
72 self.process.waitForFinished(3000)
73 52
74 e.accept() 53 e.accept()
75 54
76 def start(self, path): 55 def start(self, path):
77 """ 56 """
94 if os.path.splitdrive(repodir)[1] == os.sep: 73 if os.path.splitdrive(repodir)[1] == os.sep:
95 return 74 return
96 75
97 args = self.vcs.initCommand("sigs") 76 args = self.vcs.initCommand("sigs")
98 77
99 if self.__hgClient: 78 out, err = self.__hgClient.runcommand(args)
100 self.inputGroup.setEnabled(False) 79 if err:
101 self.inputGroup.hide() 80 self.__showError(err)
102 81 if out:
103 out, err = self.__hgClient.runcommand(args) 82 for line in out.splitlines():
104 if err: 83 self.__processOutputLine(line)
105 self.__showError(err) 84 if self.__hgClient.wasCanceled():
106 if out: 85 break
107 for line in out.splitlines(): 86 self.__finish()
108 self.__processOutputLine(line)
109 if self.__hgClient.wasCanceled():
110 break
111 self.__finish()
112 else:
113 self.process.kill()
114 self.process.setWorkingDirectory(repodir)
115
116 self.process.start('hg', args)
117 procStarted = self.process.waitForStarted(5000)
118 if not procStarted:
119 self.inputGroup.setEnabled(False)
120 self.inputGroup.hide()
121 E5MessageBox.critical(
122 self,
123 self.tr('Process Generation Error'),
124 self.tr(
125 'The process {0} could not be started. '
126 'Ensure, that it is in the search path.'
127 ).format('hg'))
128 else:
129 self.inputGroup.setEnabled(True)
130 self.inputGroup.show()
131 87
132 def __finish(self): 88 def __finish(self):
133 """ 89 """
134 Private slot called when the process finished or the user pressed 90 Private slot called when the process finished or the user pressed
135 the button. 91 the button.
136 """ 92 """
137 if (
138 self.process is not None and
139 self.process.state() != QProcess.NotRunning
140 ):
141 self.process.terminate()
142 QTimer.singleShot(2000, self.process.kill)
143 self.process.waitForFinished(3000)
144
145 self.inputGroup.setEnabled(False)
146 self.inputGroup.hide()
147
148 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) 93 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
149 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) 94 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
150 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) 95 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
151 self.buttonBox.button(QDialogButtonBox.Close).setFocus( 96 self.buttonBox.button(QDialogButtonBox.Close).setFocus(
152 Qt.OtherFocusReason) 97 Qt.OtherFocusReason)
164 @param button button that was clicked (QAbstractButton) 109 @param button button that was clicked (QAbstractButton)
165 """ 110 """
166 if button == self.buttonBox.button(QDialogButtonBox.Close): 111 if button == self.buttonBox.button(QDialogButtonBox.Close):
167 self.close() 112 self.close()
168 elif button == self.buttonBox.button(QDialogButtonBox.Cancel): 113 elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
169 if self.__hgClient: 114 self.__hgClient.cancel()
170 self.__hgClient.cancel()
171 else:
172 self.__finish()
173
174 def __procFinished(self, exitCode, exitStatus):
175 """
176 Private slot connected to the finished signal.
177
178 @param exitCode exit code of the process (integer)
179 @param exitStatus exit status of the process (QProcess.ExitStatus)
180 """
181 self.__finish()
182 115
183 def __resort(self): 116 def __resort(self):
184 """ 117 """
185 Private method to resort the tree. 118 Private method to resort the tree.
186 """ 119 """
220 topItm.setFont(0, font) 153 topItm.setFont(0, font)
221 else: 154 else:
222 topItm = topItems[0] 155 topItm = topItems[0]
223 QTreeWidgetItem(topItm, [signature]) 156 QTreeWidgetItem(topItm, [signature])
224 157
225 def __readStdout(self):
226 """
227 Private slot to handle the readyReadStdout signal.
228
229 It reads the output of the process, formats it and inserts it into
230 the contents pane.
231 """
232 self.process.setReadChannel(QProcess.StandardOutput)
233
234 while self.process.canReadLine():
235 s = str(self.process.readLine(), self.vcs.getEncoding(),
236 'replace').strip()
237 self.__processOutputLine(s)
238
239 def __processOutputLine(self, line): 158 def __processOutputLine(self, line):
240 """ 159 """
241 Private method to process the lines of output. 160 Private method to process the lines of output.
242 161
243 @param line output line to be processed (string) 162 @param line output line to be processed (string)
247 # last element is a rev:changeset 166 # last element is a rev:changeset
248 rev, changeset = li[-1].split(":", 1) 167 rev, changeset = li[-1].split(":", 1)
249 del li[-1] 168 del li[-1]
250 signature = " ".join(li) 169 signature = " ".join(li)
251 self.__generateItem(rev, changeset, signature) 170 self.__generateItem(rev, changeset, signature)
252
253 def __readStderr(self):
254 """
255 Private slot to handle the readyReadStderr signal.
256
257 It reads the error output of the process and inserts it into the
258 error pane.
259 """
260 if self.process is not None:
261 s = str(self.process.readAllStandardError(),
262 self.vcs.getEncoding(), 'replace')
263 self.__showError(s)
264 171
265 def __showError(self, out): 172 def __showError(self, out):
266 """ 173 """
267 Private slot to show some error. 174 Private slot to show some error.
268 175
340 childItem.setHidden(True) 247 childItem.setHidden(True)
341 visibleChildren -= 1 248 visibleChildren -= 1
342 else: 249 else:
343 childItem.setHidden(False) 250 childItem.setHidden(False)
344 topLevelItem.setHidden(visibleChildren == 0) 251 topLevelItem.setHidden(visibleChildren == 0)
345
346 def on_passwordCheckBox_toggled(self, isOn):
347 """
348 Private slot to handle the password checkbox toggled.
349
350 @param isOn flag indicating the status of the check box (boolean)
351 """
352 if isOn:
353 self.input.setEchoMode(QLineEdit.Password)
354 else:
355 self.input.setEchoMode(QLineEdit.Normal)
356
357 @pyqtSlot()
358 def on_sendButton_clicked(self):
359 """
360 Private slot to send the input to the subversion process.
361 """
362 inputTxt = self.input.text()
363 inputTxt += os.linesep
364
365 if self.passwordCheckBox.isChecked():
366 self.errors.insertPlainText(os.linesep)
367 self.errors.ensureCursorVisible()
368 else:
369 self.errors.insertPlainText(inputTxt)
370 self.errors.ensureCursorVisible()
371
372 self.process.write(strToQByteArray(inputTxt))
373
374 self.passwordCheckBox.setChecked(False)
375 self.input.clear()
376
377 def on_input_returnPressed(self):
378 """
379 Private slot to handle the press of the return key in the input field.
380 """
381 self.intercept = True
382 self.on_sendButton_clicked()
383
384 def keyPressEvent(self, evt):
385 """
386 Protected slot to handle a key press event.
387
388 @param evt the key press event (QKeyEvent)
389 """
390 if self.intercept:
391 self.intercept = False
392 evt.accept()
393 return
394 super(HgGpgSignaturesDialog, self).keyPressEvent(evt)

eric ide

mercurial