eric6/Plugins/VcsPlugins/vcsMercurial/QueuesExtension/HgQueuesListDialog.py

changeset 7370
5fb53279f2df
parent 7360
9190402e4505
child 7780
41420f82c0ac
equal deleted inserted replaced
7369:dbeeed55df08 7370:5fb53279f2df
8 """ 8 """
9 9
10 10
11 import os 11 import os
12 12
13 from PyQt5.QtCore import pyqtSlot, QProcess, Qt, QTimer, QCoreApplication 13 from PyQt5.QtCore import Qt, QCoreApplication
14 from PyQt5.QtWidgets import ( 14 from PyQt5.QtWidgets import (
15 QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem, QLineEdit 15 QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem
16 ) 16 )
17 17
18 from E5Gui import E5MessageBox
19
20 from .Ui_HgQueuesListDialog import Ui_HgQueuesListDialog 18 from .Ui_HgQueuesListDialog import Ui_HgQueuesListDialog
21
22 from Globals import strToQByteArray
23 19
24 20
25 class HgQueuesListDialog(QDialog, Ui_HgQueuesListDialog): 21 class HgQueuesListDialog(QDialog, Ui_HgQueuesListDialog):
26 """ 22 """
27 Class implementing a dialog to show a list of applied and unapplied 23 Class implementing a dialog to show a list of applied and unapplied
44 self.vcs = vcs 40 self.vcs = vcs
45 self.__hgClient = vcs.getClient() 41 self.__hgClient = vcs.getClient()
46 42
47 self.patchesList.header().setSortIndicator(0, Qt.AscendingOrder) 43 self.patchesList.header().setSortIndicator(0, Qt.AscendingOrder)
48 44
49 if self.__hgClient:
50 self.process = None
51 else:
52 self.process = QProcess()
53 self.process.finished.connect(self.__procFinished)
54 self.process.readyReadStandardOutput.connect(self.__readStdout)
55 self.process.readyReadStandardError.connect(self.__readStderr)
56
57 self.__statusDict = { 45 self.__statusDict = {
58 "A": self.tr("applied"), 46 "A": self.tr("applied"),
59 "U": self.tr("not applied"), 47 "U": self.tr("not applied"),
60 "G": self.tr("guarded"), 48 "G": self.tr("guarded"),
61 "D": self.tr("missing"), 49 "D": self.tr("missing"),
68 """ 56 """
69 Protected slot implementing a close event handler. 57 Protected slot implementing a close event handler.
70 58
71 @param e close event (QCloseEvent) 59 @param e close event (QCloseEvent)
72 """ 60 """
73 if self.__hgClient: 61 if self.__hgClient.isExecuting():
74 if self.__hgClient.isExecuting(): 62 self.__hgClient.cancel()
75 self.__hgClient.cancel()
76 else:
77 if (
78 self.process is not None and
79 self.process.state() != QProcess.NotRunning
80 ):
81 self.process.terminate()
82 QTimer.singleShot(2000, self.process.kill)
83 self.process.waitForFinished(3000)
84 63
85 e.accept() 64 e.accept()
86 65
87 def start(self, path): 66 def start(self, path):
88 """ 67 """
124 args.append('--summary') 103 args.append('--summary')
125 args.append('--verbose') 104 args.append('--verbose')
126 if missing: 105 if missing:
127 args.append('--missing') 106 args.append('--missing')
128 107
129 if self.__hgClient: 108 out, err = self.__hgClient.runcommand(args)
130 self.inputGroup.setEnabled(False) 109 if err:
131 self.inputGroup.hide() 110 self.__showError(err)
132 111 if out:
133 out, err = self.__hgClient.runcommand(args) 112 for line in out.splitlines():
134 if err: 113 self.__processOutputLine(line)
135 self.__showError(err) 114 if self.__hgClient.wasCanceled():
136 if out: 115 self.__mode = ""
137 for line in out.splitlines(): 116 break
138 self.__processOutputLine(line) 117 if self.__mode == "qseries":
139 if self.__hgClient.wasCanceled(): 118 self.__getSeries(True)
140 self.__mode = "" 119 elif self.__mode == "missing":
141 break 120 self.__getTop()
142 if self.__mode == "qseries": 121 else:
143 self.__getSeries(True) 122 self.__finish()
144 elif self.__mode == "missing":
145 self.__getTop()
146 else:
147 self.__finish()
148 else:
149 self.process.kill()
150 self.process.setWorkingDirectory(self.__repodir)
151
152 self.process.start('hg', args)
153 procStarted = self.process.waitForStarted(5000)
154 if not procStarted:
155 self.inputGroup.setEnabled(False)
156 self.inputGroup.hide()
157 E5MessageBox.critical(
158 self,
159 self.tr('Process Generation Error'),
160 self.tr(
161 'The process {0} could not be started. '
162 'Ensure, that it is in the search path.'
163 ).format('hg'))
164 else:
165 self.inputGroup.setEnabled(True)
166 self.inputGroup.show()
167 123
168 def __getTop(self): 124 def __getTop(self):
169 """ 125 """
170 Private slot to get patch at the top of the stack. 126 Private slot to get patch at the top of the stack.
171 """ 127 """
172 self.__mode = "qtop" 128 self.__mode = "qtop"
173 129
174 args = self.vcs.initCommand("qtop") 130 args = self.vcs.initCommand("qtop")
175 131
176 if self.__hgClient: 132 out, err = self.__hgClient.runcommand(args)
177 self.inputGroup.setEnabled(False) 133 if err:
178 self.inputGroup.hide() 134 self.__showError(err)
179 135 if out:
180 out, err = self.__hgClient.runcommand(args) 136 for line in out.splitlines():
181 if err: 137 self.__processOutputLine(line)
182 self.__showError(err) 138 if self.__hgClient.wasCanceled():
183 if out: 139 break
184 for line in out.splitlines(): 140 self.__finish()
185 self.__processOutputLine(line)
186 if self.__hgClient.wasCanceled():
187 break
188 self.__finish()
189 else:
190 self.process.kill()
191 self.process.setWorkingDirectory(self.__repodir)
192
193 self.process.start('hg', args)
194 procStarted = self.process.waitForStarted(5000)
195 if not procStarted:
196 self.inputGroup.setEnabled(False)
197 self.inputGroup.hide()
198 E5MessageBox.critical(
199 self,
200 self.tr('Process Generation Error'),
201 self.tr(
202 'The process {0} could not be started. '
203 'Ensure, that it is in the search path.'
204 ).format('hg'))
205 else:
206 self.inputGroup.setEnabled(True)
207 self.inputGroup.show()
208 141
209 def __finish(self): 142 def __finish(self):
210 """ 143 """
211 Private slot called when the process finished or the user pressed 144 Private slot called when the process finished or the user pressed
212 the button. 145 the button.
213 """ 146 """
214 if (
215 self.process is not None and
216 self.process.state() != QProcess.NotRunning
217 ):
218 self.process.terminate()
219 QTimer.singleShot(2000, self.process.kill)
220 self.process.waitForFinished(3000)
221
222 self.inputGroup.setEnabled(False)
223 self.inputGroup.hide()
224
225 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) 147 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
226 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) 148 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
227 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) 149 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
228 self.buttonBox.button(QDialogButtonBox.Close).setFocus( 150 self.buttonBox.button(QDialogButtonBox.Close).setFocus(
229 Qt.OtherFocusReason) 151 Qt.OtherFocusReason)
243 """ 165 """
244 if button == self.buttonBox.button(QDialogButtonBox.Close): 166 if button == self.buttonBox.button(QDialogButtonBox.Close):
245 self.close() 167 self.close()
246 elif button == self.buttonBox.button(QDialogButtonBox.Cancel): 168 elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
247 self.__mode = "" 169 self.__mode = ""
248 if self.__hgClient: 170 self.__hgClient.cancel()
249 self.__hgClient.cancel()
250 else:
251 self.__finish()
252
253 def __procFinished(self, exitCode, exitStatus):
254 """
255 Private slot connected to the finished signal.
256
257 @param exitCode exit code of the process (integer)
258 @param exitStatus exit status of the process (QProcess.ExitStatus)
259 """
260 if self.__mode == "qseries":
261 self.__getSeries(True)
262 elif self.__mode == "missing":
263 self.__getTop()
264 else:
265 self.__finish()
266 171
267 def __resort(self): 172 def __resort(self):
268 """ 173 """
269 Private method to resort the tree. 174 Private method to resort the tree.
270 """ 175 """
332 for column in range(itm.columnCount()): 237 for column in range(itm.columnCount()):
333 font = itm.font(column) 238 font = itm.font(column)
334 font.setBold(True) 239 font.setBold(True)
335 itm.setFont(column, font) 240 itm.setFont(column, font)
336 241
337 def __readStdout(self):
338 """
339 Private slot to handle the readyReadStdout signal.
340
341 It reads the output of the process, formats it and inserts it into
342 the contents pane.
343 """
344 self.process.setReadChannel(QProcess.StandardOutput)
345
346 while self.process.canReadLine():
347 s = str(self.process.readLine(), self.vcs.getEncoding(),
348 'replace').strip()
349 self.__processOutputLine(s)
350
351 def __processOutputLine(self, line): 242 def __processOutputLine(self, line):
352 """ 243 """
353 Private method to process the lines of output. 244 Private method to process the lines of output.
354 245
355 @param line output line to be processed (string) 246 @param line output line to be processed (string)
370 index, status, name = li[:3] 261 index, status, name = li[:3]
371 else: 262 else:
372 return 263 return
373 self.__generateItem(index, status, name, summary) 264 self.__generateItem(index, status, name, summary)
374 265
375 def __readStderr(self):
376 """
377 Private slot to handle the readyReadStderr signal.
378
379 It reads the error output of the process and inserts it into the
380 error pane.
381 """
382 if self.process is not None:
383 s = str(self.process.readAllStandardError(),
384 self.vcs.getEncoding(), 'replace')
385 self.__showError(s)
386
387 def __showError(self, out): 266 def __showError(self, out):
388 """ 267 """
389 Private slot to show some error. 268 Private slot to show some error.
390 269
391 @param out error to be shown (string) 270 @param out error to be shown (string)
392 """ 271 """
393 self.errorGroup.show() 272 self.errorGroup.show()
394 self.errors.insertPlainText(out) 273 self.errors.insertPlainText(out)
395 self.errors.ensureCursorVisible() 274 self.errors.ensureCursorVisible()
396
397 def on_passwordCheckBox_toggled(self, isOn):
398 """
399 Private slot to handle the password checkbox toggled.
400
401 @param isOn flag indicating the status of the check box (boolean)
402 """
403 if isOn:
404 self.input.setEchoMode(QLineEdit.Password)
405 else:
406 self.input.setEchoMode(QLineEdit.Normal)
407
408 @pyqtSlot()
409 def on_sendButton_clicked(self):
410 """
411 Private slot to send the input to the subversion process.
412 """
413 inputTxt = self.input.text()
414 inputTxt += os.linesep
415
416 if self.passwordCheckBox.isChecked():
417 self.errors.insertPlainText(os.linesep)
418 self.errors.ensureCursorVisible()
419 else:
420 self.errors.insertPlainText(inputTxt)
421 self.errors.ensureCursorVisible()
422
423 self.process.write(strToQByteArray(inputTxt))
424
425 self.passwordCheckBox.setChecked(False)
426 self.input.clear()
427
428 def on_input_returnPressed(self):
429 """
430 Private slot to handle the press of the return key in the input field.
431 """
432 self.intercept = True
433 self.on_sendButton_clicked()
434
435 def keyPressEvent(self, evt):
436 """
437 Protected slot to handle a key press event.
438
439 @param evt the key press event (QKeyEvent)
440 """
441 if self.intercept:
442 self.intercept = False
443 evt.accept()
444 return
445 super(HgQueuesListDialog, self).keyPressEvent(evt)

eric ide

mercurial