eric6/Plugins/VcsPlugins/vcsMercurial/ShelveExtension/HgShelveBrowserDialog.py

changeset 7370
5fb53279f2df
parent 7360
9190402e4505
child 7771
787a6b3f8c9f
equal deleted inserted replaced
7369:dbeeed55df08 7370:5fb53279f2df
5 5
6 """ 6 """
7 Module implementing Mercurial shelve browser dialog. 7 Module implementing Mercurial shelve browser dialog.
8 """ 8 """
9 9
10
11 import os 10 import os
12 11
13 from PyQt5.QtCore import pyqtSlot, Qt, QPoint, QProcess, QTimer 12 from PyQt5.QtCore import pyqtSlot, Qt, QPoint
14 from PyQt5.QtGui import QCursor 13 from PyQt5.QtGui import QCursor
15 from PyQt5.QtWidgets import ( 14 from PyQt5.QtWidgets import (
16 QWidget, QDialogButtonBox, QTreeWidgetItem, QAbstractButton, QMenu, 15 QWidget, QDialogButtonBox, QTreeWidgetItem, QAbstractButton, QMenu,
17 QHeaderView, QApplication, QLineEdit 16 QHeaderView, QApplication
18 ) 17 )
19 18
20 from E5Gui import E5MessageBox
21
22 from .Ui_HgShelveBrowserDialog import Ui_HgShelveBrowserDialog 19 from .Ui_HgShelveBrowserDialog import Ui_HgShelveBrowserDialog
23
24 from Globals import strToQByteArray
25 20
26 21
27 class HgShelveBrowserDialog(QWidget, Ui_HgShelveBrowserDialog): 22 class HgShelveBrowserDialog(QWidget, Ui_HgShelveBrowserDialog):
28 """ 23 """
29 Class implementing Mercurial shelve browser dialog. 24 Class implementing Mercurial shelve browser dialog.
60 55
61 self.vcs = vcs 56 self.vcs = vcs
62 self.__hgClient = vcs.getClient() 57 self.__hgClient = vcs.getClient()
63 self.__resetUI() 58 self.__resetUI()
64 59
65 if self.__hgClient:
66 self.process = None
67 else:
68 self.process = QProcess()
69 self.process.finished.connect(self.__procFinished)
70 self.process.readyReadStandardOutput.connect(self.__readStdout)
71 self.process.readyReadStandardError.connect(self.__readStderr)
72
73 self.__contextMenu = QMenu() 60 self.__contextMenu = QMenu()
74 self.__unshelveAct = self.__contextMenu.addAction( 61 self.__unshelveAct = self.__contextMenu.addAction(
75 self.tr("Restore selected shelve"), self.__unshelve) 62 self.tr("Restore selected shelve"), self.__unshelve)
76 self.__deleteAct = self.__contextMenu.addAction( 63 self.__deleteAct = self.__contextMenu.addAction(
77 self.tr("Delete selected shelves"), self.__deleteShelves) 64 self.tr("Delete selected shelves"), self.__deleteShelves)
82 """ 69 """
83 Protected slot implementing a close event handler. 70 Protected slot implementing a close event handler.
84 71
85 @param e close event (QCloseEvent) 72 @param e close event (QCloseEvent)
86 """ 73 """
87 if self.__hgClient: 74 if self.__hgClient.isExecuting():
88 if self.__hgClient.isExecuting(): 75 self.__hgClient.cancel()
89 self.__hgClient.cancel()
90 else:
91 if (
92 self.process is not None and
93 self.process.state() != QProcess.NotRunning
94 ):
95 self.process.terminate()
96 QTimer.singleShot(2000, self.process.kill)
97 self.process.waitForFinished(3000)
98 76
99 self.__position = self.pos() 77 self.__position = self.pos()
100 78
101 e.accept() 79 e.accept()
102 80
160 138
161 args = self.vcs.initCommand("shelve") 139 args = self.vcs.initCommand("shelve")
162 args.append("--list") 140 args.append("--list")
163 args.append("--stat") 141 args.append("--stat")
164 142
165 if self.__hgClient: 143 out, err = self.__hgClient.runcommand(args)
166 self.inputGroup.setEnabled(False) 144 self.buf = out.splitlines(True)
167 self.inputGroup.hide() 145 if err:
168 146 self.__showError(err)
169 out, err = self.__hgClient.runcommand(args) 147 self.__processBuffer()
170 self.buf = out.splitlines(True) 148 self.__finish()
171 if err:
172 self.__showError(err)
173 self.__processBuffer()
174 self.__finish()
175 else:
176 self.process.kill()
177
178 self.process.setWorkingDirectory(self.repodir)
179
180 self.inputGroup.setEnabled(True)
181 self.inputGroup.show()
182
183 self.process.start('hg', args)
184 procStarted = self.process.waitForStarted(5000)
185 if not procStarted:
186 self.inputGroup.setEnabled(False)
187 self.inputGroup.hide()
188 E5MessageBox.critical(
189 self,
190 self.tr('Process Generation Error'),
191 self.tr(
192 'The process {0} could not be started. '
193 'Ensure, that it is in the search path.'
194 ).format('hg'))
195 149
196 def start(self, projectDir): 150 def start(self, projectDir):
197 """ 151 """
198 Public slot to start the hg shelve command. 152 Public slot to start the hg shelve command.
199 153
216 170
217 self.shelveList.clear() 171 self.shelveList.clear()
218 self.__started = True 172 self.__started = True
219 self.__getShelveEntries() 173 self.__getShelveEntries()
220 174
221 def __procFinished(self, exitCode, exitStatus):
222 """
223 Private slot connected to the finished signal.
224
225 @param exitCode exit code of the process (integer)
226 @param exitStatus exit status of the process (QProcess.ExitStatus)
227 """
228 self.__processBuffer()
229 self.__finish()
230
231 def __finish(self): 175 def __finish(self):
232 """ 176 """
233 Private slot called when the process finished or the user pressed 177 Private slot called when the process finished or the user pressed
234 the button. 178 the button.
235 """ 179 """
236 if (
237 self.process is not None and
238 self.process.state() != QProcess.NotRunning
239 ):
240 self.process.terminate()
241 QTimer.singleShot(2000, self.process.kill)
242 self.process.waitForFinished(3000)
243
244 QApplication.restoreOverrideCursor() 180 QApplication.restoreOverrideCursor()
245 181
246 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) 182 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
247 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) 183 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
248 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) 184 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
249 185
250 self.inputGroup.setEnabled(False)
251 self.inputGroup.hide()
252 self.refreshButton.setEnabled(True) 186 self.refreshButton.setEnabled(True)
253 187
254 def __processBuffer(self): 188 def __processBuffer(self):
255 """ 189 """
256 Private method to process the buffered output of the hg shelve command. 190 Private method to process the buffered output of the hg shelve command.
301 235
302 if self.__started: 236 if self.__started:
303 self.shelveList.setCurrentItem(self.shelveList.topLevelItem(0)) 237 self.shelveList.setCurrentItem(self.shelveList.topLevelItem(0))
304 self.__started = False 238 self.__started = False
305 239
306 def __readStdout(self):
307 """
308 Private slot to handle the readyReadStandardOutput signal.
309
310 It reads the output of the process and inserts it into a buffer.
311 """
312 self.process.setReadChannel(QProcess.StandardOutput)
313
314 while self.process.canReadLine():
315 line = str(self.process.readLine(), self.vcs.getEncoding(),
316 'replace')
317 self.buf.append(line)
318
319 def __readStderr(self):
320 """
321 Private slot to handle the readyReadStandardError signal.
322
323 It reads the error output of the process and inserts it into the
324 error pane.
325 """
326 if self.process is not None:
327 s = str(self.process.readAllStandardError(),
328 self.vcs.getEncoding(), 'replace')
329 self.__showError(s)
330
331 def __showError(self, out): 240 def __showError(self, out):
332 """ 241 """
333 Private slot to show some error. 242 Private slot to show some error.
334 243
335 @param out error to be shown (string) 244 @param out error to be shown (string)
347 """ 256 """
348 if button == self.buttonBox.button(QDialogButtonBox.Close): 257 if button == self.buttonBox.button(QDialogButtonBox.Close):
349 self.close() 258 self.close()
350 elif button == self.buttonBox.button(QDialogButtonBox.Cancel): 259 elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
351 self.cancelled = True 260 self.cancelled = True
352 if self.__hgClient: 261 self.__hgClient.cancel()
353 self.__hgClient.cancel()
354 else:
355 self.__finish()
356 elif button == self.refreshButton: 262 elif button == self.refreshButton:
357 self.on_refreshButton_clicked() 263 self.on_refreshButton_clicked()
358 264
359 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem) 265 @pyqtSlot(QTreeWidgetItem, QTreeWidgetItem)
360 def on_shelveList_currentItemChanged(self, current, previous): 266 def on_shelveList_currentItemChanged(self, current, previous):
404 """ 310 """
405 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) 311 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
406 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) 312 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True)
407 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) 313 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
408 314
409 self.inputGroup.setEnabled(True)
410 self.inputGroup.show()
411 self.refreshButton.setEnabled(False) 315 self.refreshButton.setEnabled(False)
412 316
413 self.start(self.__projectDir) 317 self.start(self.__projectDir)
414
415 def on_passwordCheckBox_toggled(self, isOn):
416 """
417 Private slot to handle the password checkbox toggled.
418
419 @param isOn flag indicating the status of the check box (boolean)
420 """
421 if isOn:
422 self.input.setEchoMode(QLineEdit.Password)
423 else:
424 self.input.setEchoMode(QLineEdit.Normal)
425
426 @pyqtSlot()
427 def on_sendButton_clicked(self):
428 """
429 Private slot to send the input to the mercurial process.
430 """
431 inputTxt = self.input.text()
432 inputTxt += os.linesep
433
434 if self.passwordCheckBox.isChecked():
435 self.errors.insertPlainText(os.linesep)
436 self.errors.ensureCursorVisible()
437 else:
438 self.errors.insertPlainText(inputTxt)
439 self.errors.ensureCursorVisible()
440 self.errorGroup.show()
441
442 self.process.write(strToQByteArray(inputTxt))
443
444 self.passwordCheckBox.setChecked(False)
445 self.input.clear()
446
447 def on_input_returnPressed(self):
448 """
449 Private slot to handle the press of the return key in the input field.
450 """
451 self.intercept = True
452 self.on_sendButton_clicked()
453
454 def keyPressEvent(self, evt):
455 """
456 Protected slot to handle a key press event.
457
458 @param evt the key press event (QKeyEvent)
459 """
460 if self.intercept:
461 self.intercept = False
462 evt.accept()
463 return
464 super(HgShelveBrowserDialog, self).keyPressEvent(evt)
465 318
466 def __unshelve(self): 319 def __unshelve(self):
467 """ 320 """
468 Private slot to restore the selected shelve of changes. 321 Private slot to restore the selected shelve of changes.
469 """ 322 """

eric ide

mercurial