15 pass |
15 pass |
16 |
16 |
17 import os |
17 import os |
18 |
18 |
19 from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer |
19 from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer |
|
20 from PyQt5.QtGui import QTextCursor |
20 from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QMenu, QHeaderView, \ |
21 from PyQt5.QtWidgets import QWidget, QDialogButtonBox, QMenu, QHeaderView, \ |
21 QTreeWidgetItem, QLineEdit |
22 QTreeWidgetItem, QLineEdit |
22 |
23 |
23 from E5Gui.E5Application import e5App |
24 from E5Gui.E5Application import e5App |
24 from E5Gui import E5MessageBox |
25 from E5Gui import E5MessageBox |
25 |
26 |
26 from .Ui_HgStatusDialog import Ui_HgStatusDialog |
27 from .Ui_HgStatusDialog import Ui_HgStatusDialog |
|
28 |
|
29 from .HgDiffHighlighter import HgDiffHighlighter |
|
30 from .HgDiffGenerator import HgDiffGenerator |
27 |
31 |
28 import Preferences |
32 import Preferences |
29 |
33 |
30 |
34 |
31 class HgStatusDialog(QWidget, Ui_HgStatusDialog): |
35 class HgStatusDialog(QWidget, Ui_HgStatusDialog): |
68 self.process = QProcess() |
72 self.process = QProcess() |
69 self.process.finished.connect(self.__procFinished) |
73 self.process.finished.connect(self.__procFinished) |
70 self.process.readyReadStandardOutput.connect(self.__readStdout) |
74 self.process.readyReadStandardOutput.connect(self.__readStdout) |
71 self.process.readyReadStandardError.connect(self.__readStderr) |
75 self.process.readyReadStandardError.connect(self.__readStderr) |
72 |
76 |
|
77 self.__hDiffSplitterState = None |
|
78 |
73 self.statusList.headerItem().setText(self.__lastColumn, "") |
79 self.statusList.headerItem().setText(self.__lastColumn, "") |
74 self.statusList.header().setSortIndicator( |
80 self.statusList.header().setSortIndicator( |
75 self.__pathColumn, Qt.AscendingOrder) |
81 self.__pathColumn, Qt.AscendingOrder) |
|
82 |
|
83 font = Preferences.getEditorOtherFonts("MonospacedFont") |
|
84 self.diffEdit.setFontFamily(font.family()) |
|
85 self.diffEdit.setFontPointSize(font.pointSize()) |
|
86 |
|
87 self.diffHighlighter = HgDiffHighlighter(self.diffEdit.document()) |
|
88 self.__diffGenerator = HgDiffGenerator(vcs, self) |
|
89 self.__diffGenerator.finished.connect(self.__generatorFinished) |
|
90 |
|
91 self.__selectedName = "" |
76 |
92 |
77 if mq: |
93 if mq: |
78 self.buttonsLine.setVisible(False) |
94 self.buttonsLine.setVisible(False) |
79 self.addButton.setVisible(False) |
95 self.addButton.setVisible(False) |
80 self.diffButton.setVisible(False) |
96 self.diffButton.setVisible(False) |
81 self.sbsDiffButton.setVisible(False) |
97 self.sbsDiffButton.setVisible(False) |
82 self.revertButton.setVisible(False) |
98 self.revertButton.setVisible(False) |
83 self.forgetButton.setVisible(False) |
99 self.forgetButton.setVisible(False) |
84 self.restoreButton.setVisible(False) |
100 self.restoreButton.setVisible(False) |
|
101 |
|
102 self.diffEdit.setVisible(False) |
85 |
103 |
86 self.menuactions = [] |
104 self.menuactions = [] |
87 self.lfActions = [] |
105 self.lfActions = [] |
88 self.menu = QMenu() |
106 self.menu = QMenu() |
89 if not mq: |
107 if not mq: |
168 'R': self.tr('removed'), |
186 'R': self.tr('removed'), |
169 '?': self.tr('not tracked'), |
187 '?': self.tr('not tracked'), |
170 '!': self.tr('missing'), |
188 '!': self.tr('missing'), |
171 } |
189 } |
172 |
190 |
|
191 def show(self): |
|
192 """ |
|
193 Public slot to show the dialog. |
|
194 """ |
|
195 super(HgStatusDialog, self).show() |
|
196 |
|
197 if not self.__mq and self.__hDiffSplitterState: |
|
198 self.diffSplitter.restoreState(self.__hDiffSplitterState) |
|
199 |
173 def __resort(self): |
200 def __resort(self): |
174 """ |
201 """ |
175 Private method to resort the tree. |
202 Private method to resort the tree. |
176 """ |
203 """ |
177 self.statusList.sortItems( |
204 self.statusList.sortItems( |
224 if self.process is not None and \ |
251 if self.process is not None and \ |
225 self.process.state() != QProcess.NotRunning: |
252 self.process.state() != QProcess.NotRunning: |
226 self.process.terminate() |
253 self.process.terminate() |
227 QTimer.singleShot(2000, self.process.kill) |
254 QTimer.singleShot(2000, self.process.kill) |
228 self.process.waitForFinished(3000) |
255 self.process.waitForFinished(3000) |
|
256 |
|
257 if not self.__mq: |
|
258 self.__hDiffSplitterState = self.diffSplitter.saveState() |
229 |
259 |
230 e.accept() |
260 e.accept() |
231 |
261 |
232 def start(self, fn): |
262 def start(self, fn): |
233 """ |
263 """ |
360 self.__resort() |
390 self.__resort() |
361 self.__resizeColumns() |
391 self.__resizeColumns() |
362 |
392 |
363 self.__updateButtons() |
393 self.__updateButtons() |
364 self.__updateCommitButton() |
394 self.__updateCommitButton() |
|
395 |
|
396 self.__refreshDiff() |
365 |
397 |
366 def on_buttonBox_clicked(self, button): |
398 def on_buttonBox_clicked(self, button): |
367 """ |
399 """ |
368 Private slot called by a button of the button box clicked. |
400 Private slot called by a button of the button box clicked. |
369 |
401 |
488 @pyqtSlot() |
520 @pyqtSlot() |
489 def on_refreshButton_clicked(self): |
521 def on_refreshButton_clicked(self): |
490 """ |
522 """ |
491 Private slot to refresh the status display. |
523 Private slot to refresh the status display. |
492 """ |
524 """ |
|
525 selectedItems = self.statusList.selectedItems() |
|
526 if len(selectedItems) == 1: |
|
527 self.__selectedName = selectedItems[0].text(self.__pathColumn) |
|
528 else: |
|
529 self.__selectedName = "" |
|
530 |
493 self.start(self.args) |
531 self.start(self.args) |
494 |
532 |
495 def __updateButtons(self): |
533 def __updateButtons(self): |
496 """ |
534 """ |
497 Private method to update the VCS buttons status. |
535 Private method to update the VCS buttons status. |
545 def on_statusList_itemSelectionChanged(self): |
583 def on_statusList_itemSelectionChanged(self): |
546 """ |
584 """ |
547 Private slot to act upon changes of selected items. |
585 Private slot to act upon changes of selected items. |
548 """ |
586 """ |
549 self.__updateButtons() |
587 self.__updateButtons() |
|
588 self.__generateDiffs() |
550 |
589 |
551 @pyqtSlot() |
590 @pyqtSlot() |
552 def on_commitButton_clicked(self): |
591 def on_commitButton_clicked(self): |
553 """ |
592 """ |
554 Private slot to handle the press of the Commit button. |
593 Private slot to handle the press of the Commit button. |
889 if itm.flags() & Qt.ItemIsUserCheckable: |
928 if itm.flags() & Qt.ItemIsUserCheckable: |
890 if selected: |
929 if selected: |
891 itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) |
930 itm.setCheckState(self.__toBeCommittedColumn, Qt.Checked) |
892 else: |
931 else: |
893 itm.setCheckState(self.__toBeCommittedColumn, Qt.Unchecked) |
932 itm.setCheckState(self.__toBeCommittedColumn, Qt.Unchecked) |
|
933 |
|
934 ########################################################################### |
|
935 ## Diff handling methods below |
|
936 ########################################################################### |
|
937 |
|
938 def __generateDiffs(self): |
|
939 """ |
|
940 Private slot to generate diff outputs for the selected item. |
|
941 """ |
|
942 self.diffEdit.clear() |
|
943 |
|
944 if not self.__mq: |
|
945 selectedItems = self.statusList.selectedItems() |
|
946 if len(selectedItems) == 1: |
|
947 fn = os.path.join(self.dname, |
|
948 selectedItems[0].text(self.__pathColumn)) |
|
949 self.__diffGenerator.start(fn) |
|
950 |
|
951 def __generatorFinished(self): |
|
952 """ |
|
953 Private slot connected to the finished signal of the diff generator. |
|
954 """ |
|
955 diff = self.__diffGenerator.getResult()[0] |
|
956 |
|
957 if diff: |
|
958 for line in diff[:]: |
|
959 if line.startswith("@@ "): |
|
960 break |
|
961 else: |
|
962 diff.pop(0) |
|
963 self.diffEdit.setPlainText("".join(diff)) |
|
964 |
|
965 tc = self.diffEdit.textCursor() |
|
966 tc.movePosition(QTextCursor.Start) |
|
967 self.diffEdit.setTextCursor(tc) |
|
968 self.diffEdit.ensureCursorVisible() |
|
969 |
|
970 def __refreshDiff(self): |
|
971 """ |
|
972 Private method to refresh the diff output after a refresh. |
|
973 """ |
|
974 if self.__selectedName and not self.__mq: |
|
975 for index in range(self.statusList.topLevelItemCount()): |
|
976 itm = self.statusList.topLevelItem(index) |
|
977 if itm.text(self.__pathColumn) == self.__selectedName: |
|
978 itm.setSelected(True) |
|
979 break |
|
980 |
|
981 self.__selectedName = "" |