7 Module implementing a dialog to show the output of the hg diff command process. |
7 Module implementing a dialog to show the output of the hg diff command process. |
8 """ |
8 """ |
9 |
9 |
10 from __future__ import unicode_literals |
10 from __future__ import unicode_literals |
11 try: |
11 try: |
12 str = unicode # __IGNORE_WARNING__ |
12 str = unicode |
13 except (NameError): |
13 except NameError: |
14 pass |
14 pass |
15 |
15 |
16 import os |
16 import os |
17 |
17 |
18 from PyQt4.QtCore import pyqtSlot, QProcess, QTimer, QFileInfo, Qt |
18 from PyQt4.QtCore import pyqtSlot, QProcess, QTimer, QFileInfo, Qt |
114 self.contents.clear() |
114 self.contents.clear() |
115 self.paras = 0 |
115 self.paras = 0 |
116 |
116 |
117 self.filesCombo.clear() |
117 self.filesCombo.clear() |
118 |
118 |
119 args = [] |
|
120 if qdiff: |
119 if qdiff: |
121 args.append('qdiff') |
120 args = self.vcs.initCommand("qdiff") |
122 self.setWindowTitle(self.trUtf8("Patch Contents")) |
121 self.setWindowTitle(self.tr("Patch Contents")) |
123 else: |
122 else: |
124 args.append('diff') |
123 args = self.vcs.initCommand("diff") |
125 self.vcs.addArguments(args, self.vcs.options['global']) |
|
126 self.vcs.addArguments(args, self.vcs.options['diff']) |
|
127 |
124 |
128 if self.vcs.hasSubrepositories(): |
125 if self.vcs.hasSubrepositories(): |
129 args.append("--subrepos") |
126 args.append("--subrepos") |
130 |
127 |
131 if bundle: |
128 if bundle: |
198 QApplication.restoreOverrideCursor() |
195 QApplication.restoreOverrideCursor() |
199 self.inputGroup.setEnabled(False) |
196 self.inputGroup.setEnabled(False) |
200 self.inputGroup.hide() |
197 self.inputGroup.hide() |
201 E5MessageBox.critical( |
198 E5MessageBox.critical( |
202 self, |
199 self, |
203 self.trUtf8('Process Generation Error'), |
200 self.tr('Process Generation Error'), |
204 self.trUtf8( |
201 self.tr( |
205 'The process {0} could not be started. ' |
202 'The process {0} could not be started. ' |
206 'Ensure, that it is in the search path.' |
203 'Ensure, that it is in the search path.' |
207 ).format('hg')) |
204 ).format('hg')) |
208 |
205 |
209 def __procFinished(self, exitCode, exitStatus): |
206 def __procFinished(self, exitCode, exitStatus): |
224 self.inputGroup.setEnabled(False) |
221 self.inputGroup.setEnabled(False) |
225 self.inputGroup.hide() |
222 self.inputGroup.hide() |
226 |
223 |
227 if self.paras == 0: |
224 if self.paras == 0: |
228 self.contents.insertPlainText( |
225 self.contents.insertPlainText( |
229 self.trUtf8('There is no difference.')) |
226 self.tr('There is no difference.')) |
230 return |
227 return |
231 |
228 |
232 self.buttonBox.button(QDialogButtonBox.Save).setEnabled(True) |
229 self.buttonBox.button(QDialogButtonBox.Save).setEnabled(True) |
233 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) |
230 self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) |
234 self.buttonBox.button(QDialogButtonBox.Close).setFocus( |
231 self.buttonBox.button(QDialogButtonBox.Close).setFocus( |
237 tc = self.contents.textCursor() |
234 tc = self.contents.textCursor() |
238 tc.movePosition(QTextCursor.Start) |
235 tc.movePosition(QTextCursor.Start) |
239 self.contents.setTextCursor(tc) |
236 self.contents.setTextCursor(tc) |
240 self.contents.ensureCursorVisible() |
237 self.contents.ensureCursorVisible() |
241 |
238 |
242 self.filesCombo.addItem(self.trUtf8("<Start>"), 0) |
239 self.filesCombo.addItem(self.tr("<Start>"), 0) |
243 self.filesCombo.addItem(self.trUtf8("<End>"), -1) |
240 self.filesCombo.addItem(self.tr("<End>"), -1) |
244 for oldFile, newFile, pos in sorted(self.__fileSeparators): |
241 for oldFile, newFile, pos in sorted(self.__fileSeparators): |
245 if oldFile != newFile: |
242 if oldFile != newFile: |
246 self.filesCombo.addItem( |
243 self.filesCombo.addItem( |
247 "{0}\n{1}".format(oldFile, newFile), pos) |
244 "{0}\n{1}".format(oldFile, newFile), pos) |
248 else: |
245 else: |
316 the contents pane. |
313 the contents pane. |
317 """ |
314 """ |
318 self.process.setReadChannel(QProcess.StandardOutput) |
315 self.process.setReadChannel(QProcess.StandardOutput) |
319 |
316 |
320 while self.process.canReadLine(): |
317 while self.process.canReadLine(): |
321 line = str(self.process.readLine(), |
318 line = str(self.process.readLine(), self.vcs.getEncoding(), |
322 Preferences.getSystem("IOEncoding"), |
|
323 'replace') |
319 'replace') |
324 self.__processOutputLine(line) |
320 self.__processOutputLine(line) |
325 |
321 |
326 def __readStderr(self): |
322 def __readStderr(self): |
327 """ |
323 """ |
330 It reads the error output of the process and inserts it into the |
326 It reads the error output of the process and inserts it into the |
331 error pane. |
327 error pane. |
332 """ |
328 """ |
333 if self.process is not None: |
329 if self.process is not None: |
334 s = str(self.process.readAllStandardError(), |
330 s = str(self.process.readAllStandardError(), |
335 Preferences.getSystem("IOEncoding"), |
331 self.vcs.getEncoding(), 'replace') |
336 'replace') |
|
337 self.__showError(s) |
332 self.__showError(s) |
338 |
333 |
339 def __showError(self, out): |
334 def __showError(self, out): |
340 """ |
335 """ |
341 Private slot to show some error. |
336 Private slot to show some error. |
409 else: |
404 else: |
410 fname = self.vcs.splitPath(self.filename)[0] |
405 fname = self.vcs.splitPath(self.filename)[0] |
411 |
406 |
412 fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( |
407 fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( |
413 self, |
408 self, |
414 self.trUtf8("Save Diff"), |
409 self.tr("Save Diff"), |
415 fname, |
410 fname, |
416 self.trUtf8("Patch Files (*.diff)"), |
411 self.tr("Patch Files (*.diff)"), |
417 None, |
412 None, |
418 E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) |
413 E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) |
419 |
414 |
420 if not fname: |
415 if not fname: |
421 return # user aborted |
416 return # user aborted |
426 if ex: |
421 if ex: |
427 fname += ex |
422 fname += ex |
428 if QFileInfo(fname).exists(): |
423 if QFileInfo(fname).exists(): |
429 res = E5MessageBox.yesNo( |
424 res = E5MessageBox.yesNo( |
430 self, |
425 self, |
431 self.trUtf8("Save Diff"), |
426 self.tr("Save Diff"), |
432 self.trUtf8("<p>The patch file <b>{0}</b> already exists." |
427 self.tr("<p>The patch file <b>{0}</b> already exists." |
433 " Overwrite it?</p>").format(fname), |
428 " Overwrite it?</p>").format(fname), |
434 icon=E5MessageBox.Warning) |
429 icon=E5MessageBox.Warning) |
435 if not res: |
430 if not res: |
436 return |
431 return |
437 fname = Utilities.toNativeSeparators(fname) |
432 fname = Utilities.toNativeSeparators(fname) |
438 |
433 |
441 f = open(fname, "w", encoding="utf-8") |
436 f = open(fname, "w", encoding="utf-8") |
442 f.write(eol.join(self.contents.toPlainText().splitlines())) |
437 f.write(eol.join(self.contents.toPlainText().splitlines())) |
443 f.close() |
438 f.close() |
444 except IOError as why: |
439 except IOError as why: |
445 E5MessageBox.critical( |
440 E5MessageBox.critical( |
446 self, self.trUtf8('Save Diff'), |
441 self, self.tr('Save Diff'), |
447 self.trUtf8( |
442 self.tr( |
448 '<p>The patch file <b>{0}</b> could not be saved.' |
443 '<p>The patch file <b>{0}</b> could not be saved.' |
449 '<br>Reason: {1}</p>') |
444 '<br>Reason: {1}</p>') |
450 .format(fname, str(why))) |
445 .format(fname, str(why))) |
451 |
446 |
452 def on_passwordCheckBox_toggled(self, isOn): |
447 def on_passwordCheckBox_toggled(self, isOn): |