eric6/Plugins/VcsPlugins/vcsMercurial/HgConflictsListDialog.py

changeset 7370
5fb53279f2df
parent 7360
9190402e4505
child 7771
787a6b3f8c9f
equal deleted inserted replaced
7369:dbeeed55df08 7370:5fb53279f2df
6 """ 6 """
7 Module implementing a dialog to show a list of files which had or still have 7 Module implementing a dialog to show a list of files which had or still have
8 conflicts. 8 conflicts.
9 """ 9 """
10 10
11
12 import os 11 import os
13 12
14 from PyQt5.QtCore import pyqtSlot, Qt, QPoint, QProcess, QTimer 13 from PyQt5.QtCore import pyqtSlot, Qt, QPoint
15 from PyQt5.QtWidgets import ( 14 from PyQt5.QtWidgets import (
16 QAbstractButton, QDialogButtonBox, QHeaderView, QTreeWidgetItem, QLineEdit, 15 QAbstractButton, QDialogButtonBox, QHeaderView, QTreeWidgetItem,
17 QApplication, QWidget 16 QApplication, QWidget
18 ) 17 )
19 18
20 from E5Gui import E5MessageBox
21 from E5Gui.E5Application import e5App 19 from E5Gui.E5Application import e5App
22 20
23 from .Ui_HgConflictsListDialog import Ui_HgConflictsListDialog 21 from .Ui_HgConflictsListDialog import Ui_HgConflictsListDialog
24 22
25 import Utilities.MimeTypes 23 import Utilities.MimeTypes
26 from Globals import strToQByteArray
27 24
28 25
29 class HgConflictsListDialog(QWidget, Ui_HgConflictsListDialog): 26 class HgConflictsListDialog(QWidget, Ui_HgConflictsListDialog):
30 """ 27 """
31 Class implementing a dialog to show a list of files which had or still 28 Class implementing a dialog to show a list of files which had or still
61 58
62 self.vcs = vcs 59 self.vcs = vcs
63 self.project = e5App().getObject("Project") 60 self.project = e5App().getObject("Project")
64 61
65 self.__hgClient = vcs.getClient() 62 self.__hgClient = vcs.getClient()
66 if self.__hgClient:
67 self.process = None
68 else:
69 self.process = QProcess()
70 self.process.finished.connect(self.__procFinished)
71 self.process.readyReadStandardOutput.connect(self.__readStdout)
72 self.process.readyReadStandardError.connect(self.__readStderr)
73 63
74 def closeEvent(self, e): 64 def closeEvent(self, e):
75 """ 65 """
76 Protected slot implementing a close event handler. 66 Protected slot implementing a close event handler.
77 67
78 @param e close event (QCloseEvent) 68 @param e close event (QCloseEvent)
79 """ 69 """
80 if self.__hgClient: 70 if self.__hgClient.isExecuting():
81 if self.__hgClient.isExecuting(): 71 self.__hgClient.cancel()
82 self.__hgClient.cancel()
83 else:
84 if (
85 self.process is not None and
86 self.process.state() != QProcess.NotRunning
87 ):
88 self.process.terminate()
89 QTimer.singleShot(2000, self.process.kill)
90 self.process.waitForFinished(3000)
91 72
92 self.__position = self.pos() 73 self.__position = self.pos()
93 74
94 e.accept() 75 e.accept()
95 76
134 Private method to get the conflict entries. 115 Private method to get the conflict entries.
135 """ 116 """
136 args = self.vcs.initCommand("resolve") 117 args = self.vcs.initCommand("resolve")
137 args.append('--list') 118 args.append('--list')
138 119
139 if self.__hgClient: 120 out, err = self.__hgClient.runcommand(args)
140 self.inputGroup.setEnabled(False) 121 if err:
141 self.inputGroup.hide() 122 self.__showError(err)
142 123 if out:
143 out, err = self.__hgClient.runcommand(args) 124 for line in out.splitlines():
144 if err: 125 self.__processOutputLine(line)
145 self.__showError(err) 126 if self.__hgClient.wasCanceled():
146 if out: 127 break
147 for line in out.splitlines(): 128 self.__finish()
148 self.__processOutputLine(line)
149 if self.__hgClient.wasCanceled():
150 break
151 self.__finish()
152 else:
153 self.process.kill()
154 self.process.setWorkingDirectory(self.__repodir)
155
156 self.process.start('hg', args)
157 procStarted = self.process.waitForStarted(5000)
158 if not procStarted:
159 self.inputGroup.setEnabled(False)
160 self.inputGroup.hide()
161 E5MessageBox.critical(
162 self,
163 self.tr('Process Generation Error'),
164 self.tr(
165 'The process {0} could not be started. '
166 'Ensure, that it is in the search path.'
167 ).format('hg'))
168 else:
169 self.inputGroup.setEnabled(True)
170 self.inputGroup.show()
171 129
172 def __finish(self): 130 def __finish(self):
173 """ 131 """
174 Private slot called when the process finished or the user pressed 132 Private slot called when the process finished or the user pressed
175 the button. 133 the button.
176 """ 134 """
177 if (
178 self.process is not None and
179 self.process.state() != QProcess.NotRunning
180 ):
181 self.process.terminate()
182 QTimer.singleShot(2000, self.process.kill)
183 self.process.waitForFinished(3000)
184
185 QApplication.restoreOverrideCursor() 135 QApplication.restoreOverrideCursor()
186 136
187 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) 137 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True)
188 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) 138 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False)
189 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) 139 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True)
190 140
191 self.inputGroup.setEnabled(False)
192 self.inputGroup.hide()
193 self.refreshButton.setEnabled(True) 141 self.refreshButton.setEnabled(True)
194 142
195 self.__resizeColumns() 143 self.__resizeColumns()
196 self.__resort() 144 self.__resort()
197 self.on_conflictsList_itemSelectionChanged() 145 self.on_conflictsList_itemSelectionChanged()
204 @param button button that was clicked (QAbstractButton) 152 @param button button that was clicked (QAbstractButton)
205 """ 153 """
206 if button == self.buttonBox.button(QDialogButtonBox.Close): 154 if button == self.buttonBox.button(QDialogButtonBox.Close):
207 self.close() 155 self.close()
208 elif button == self.buttonBox.button(QDialogButtonBox.Cancel): 156 elif button == self.buttonBox.button(QDialogButtonBox.Cancel):
209 if self.__hgClient: 157 self.__hgClient.cancel()
210 self.__hgClient.cancel()
211 else:
212 self.__finish()
213 elif button == self.refreshButton: 158 elif button == self.refreshButton:
214 self.on_refreshButton_clicked() 159 self.on_refreshButton_clicked()
215
216 def __procFinished(self, exitCode, exitStatus):
217 """
218 Private slot connected to the finished signal.
219
220 @param exitCode exit code of the process (integer)
221 @param exitStatus exit status of the process (QProcess.ExitStatus)
222 """
223 self.__finish()
224 160
225 def __resort(self): 161 def __resort(self):
226 """ 162 """
227 Private method to resort the tree. 163 Private method to resort the tree.
228 """ 164 """
255 itm.setText(1, name) 191 itm.setText(1, name)
256 192
257 itm.setData(0, self.StatusRole, status) 193 itm.setData(0, self.StatusRole, status)
258 itm.setData(0, self.FilenameRole, self.project.getAbsolutePath(name)) 194 itm.setData(0, self.FilenameRole, self.project.getAbsolutePath(name))
259 195
260 def __readStdout(self):
261 """
262 Private slot to handle the readyReadStdout signal.
263
264 It reads the output of the process, formats it and inserts it into
265 the contents pane.
266 """
267 self.process.setReadChannel(QProcess.StandardOutput)
268
269 while self.process.canReadLine():
270 s = str(self.process.readLine(), self.vcs.getEncoding(),
271 'replace').strip()
272 self.__processOutputLine(s)
273
274 def __processOutputLine(self, line): 196 def __processOutputLine(self, line):
275 """ 197 """
276 Private method to process the lines of output. 198 Private method to process the lines of output.
277 199
278 @param line output line to be processed (string) 200 @param line output line to be processed (string)
279 """ 201 """
280 status, filename = line.strip().split(None, 1) 202 status, filename = line.strip().split(None, 1)
281 self.__generateItem(status, filename) 203 self.__generateItem(status, filename)
204
205 def __showError(self, out):
206 """
207 Private slot to show some error.
208
209 @param out error to be shown (string)
210 """
211 self.errorGroup.show()
212 self.errors.insertPlainText(out)
213 self.errors.ensureCursorVisible()
282 214
283 @pyqtSlot() 215 @pyqtSlot()
284 def on_refreshButton_clicked(self): 216 def on_refreshButton_clicked(self):
285 """ 217 """
286 Private slot to refresh the log. 218 Private slot to refresh the log.
287 """ 219 """
288 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) 220 self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False)
289 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) 221 self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True)
290 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) 222 self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True)
291 223
292 self.inputGroup.setEnabled(True)
293 self.inputGroup.show()
294 self.refreshButton.setEnabled(False) 224 self.refreshButton.setEnabled(False)
295 self.start(self.__repodir) 225 self.start(self.__repodir)
296
297 def __readStderr(self):
298 """
299 Private slot to handle the readyReadStderr signal.
300
301 It reads the error output of the process and inserts it into the
302 error pane.
303 """
304 if self.process is not None:
305 s = str(self.process.readAllStandardError(),
306 self.vcs.getEncoding(), 'replace')
307 self.__showError(s)
308
309 def __showError(self, out):
310 """
311 Private slot to show some error.
312
313 @param out error to be shown (string)
314 """
315 self.errorGroup.show()
316 self.errors.insertPlainText(out)
317 self.errors.ensureCursorVisible()
318
319 def on_passwordCheckBox_toggled(self, isOn):
320 """
321 Private slot to handle the password checkbox toggled.
322
323 @param isOn flag indicating the status of the check box (boolean)
324 """
325 if isOn:
326 self.input.setEchoMode(QLineEdit.Password)
327 else:
328 self.input.setEchoMode(QLineEdit.Normal)
329
330 @pyqtSlot()
331 def on_sendButton_clicked(self):
332 """
333 Private slot to send the input to the subversion process.
334 """
335 inputTxt = self.input.text()
336 inputTxt += os.linesep
337
338 if self.passwordCheckBox.isChecked():
339 self.errors.insertPlainText(os.linesep)
340 self.errors.ensureCursorVisible()
341 else:
342 self.errors.insertPlainText(inputTxt)
343 self.errors.ensureCursorVisible()
344
345 self.process.write(strToQByteArray(inputTxt))
346
347 self.passwordCheckBox.setChecked(False)
348 self.input.clear()
349
350 def on_input_returnPressed(self):
351 """
352 Private slot to handle the press of the return key in the input field.
353 """
354 self.intercept = True
355 self.on_sendButton_clicked()
356
357 def keyPressEvent(self, evt):
358 """
359 Protected slot to handle a key press event.
360
361 @param evt the key press event (QKeyEvent)
362 """
363 if self.intercept:
364 self.intercept = False
365 evt.accept()
366 return
367 super(HgConflictsListDialog, self).keyPressEvent(evt)
368 226
369 @pyqtSlot(QTreeWidgetItem, int) 227 @pyqtSlot(QTreeWidgetItem, int)
370 def on_conflictsList_itemDoubleClicked(self, item, column): 228 def on_conflictsList_itemDoubleClicked(self, item, column):
371 """ 229 """
372 Private slot to open the double clicked entry. 230 Private slot to open the double clicked entry.

eric ide

mercurial