8 """ |
8 """ |
9 |
9 |
10 import re |
10 import re |
11 |
11 |
12 from PyQt6.QtCore import Qt, QCoreApplication |
12 from PyQt6.QtCore import Qt, QCoreApplication |
13 from PyQt6.QtWidgets import ( |
13 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem |
14 QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem |
|
15 ) |
|
16 |
14 |
17 from .Ui_HgAnnotateDialog import Ui_HgAnnotateDialog |
15 from .Ui_HgAnnotateDialog import Ui_HgAnnotateDialog |
18 |
16 |
19 import Preferences |
17 import Preferences |
20 |
18 |
21 |
19 |
22 class HgAnnotateDialog(QDialog, Ui_HgAnnotateDialog): |
20 class HgAnnotateDialog(QDialog, Ui_HgAnnotateDialog): |
23 """ |
21 """ |
24 Class implementing a dialog to show the output of the hg annotate command. |
22 Class implementing a dialog to show the output of the hg annotate command. |
25 """ |
23 """ |
|
24 |
26 def __init__(self, vcs, parent=None): |
25 def __init__(self, vcs, parent=None): |
27 """ |
26 """ |
28 Constructor |
27 Constructor |
29 |
28 |
30 @param vcs reference to the vcs object |
29 @param vcs reference to the vcs object |
31 @param parent parent widget (QWidget) |
30 @param parent parent widget (QWidget) |
32 """ |
31 """ |
33 super().__init__(parent) |
32 super().__init__(parent) |
34 self.setupUi(self) |
33 self.setupUi(self) |
35 self.setWindowFlags(Qt.WindowType.Window) |
34 self.setWindowFlags(Qt.WindowType.Window) |
36 |
35 |
37 self.buttonBox.button( |
36 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False) |
38 QDialogButtonBox.StandardButton.Close).setEnabled(False) |
37 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
39 self.buttonBox.button( |
38 |
40 QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
|
41 |
|
42 self.vcs = vcs |
39 self.vcs = vcs |
43 self.__hgClient = vcs.getClient() |
40 self.__hgClient = vcs.getClient() |
44 |
41 |
45 self.__annotateRe = re.compile( |
42 self.__annotateRe = re.compile( |
46 r"""(.+)\s+(\d+)\s+([0-9a-fA-F]+)\s+([0-9-]+)\s+(.+)""") |
43 r"""(.+)\s+(\d+)\s+([0-9a-fA-F]+)\s+([0-9-]+)\s+(.+)""" |
47 |
44 ) |
48 self.annotateList.headerItem().setText( |
45 |
49 self.annotateList.columnCount(), "") |
46 self.annotateList.headerItem().setText(self.annotateList.columnCount(), "") |
50 font = Preferences.getEditorOtherFonts("MonospacedFont") |
47 font = Preferences.getEditorOtherFonts("MonospacedFont") |
51 self.annotateList.setFont(font) |
48 self.annotateList.setFont(font) |
52 |
49 |
53 self.show() |
50 self.show() |
54 QCoreApplication.processEvents() |
51 QCoreApplication.processEvents() |
55 |
52 |
56 def closeEvent(self, e): |
53 def closeEvent(self, e): |
57 """ |
54 """ |
58 Protected slot implementing a close event handler. |
55 Protected slot implementing a close event handler. |
59 |
56 |
60 @param e close event (QCloseEvent) |
57 @param e close event (QCloseEvent) |
61 """ |
58 """ |
62 if self.__hgClient.isExecuting(): |
59 if self.__hgClient.isExecuting(): |
63 self.__hgClient.cancel() |
60 self.__hgClient.cancel() |
64 |
61 |
65 e.accept() |
62 e.accept() |
66 |
63 |
67 def start(self, fn): |
64 def start(self, fn): |
68 """ |
65 """ |
69 Public slot to start the annotate command. |
66 Public slot to start the annotate command. |
70 |
67 |
71 @param fn filename to show the annotation for (string) |
68 @param fn filename to show the annotation for (string) |
72 """ |
69 """ |
73 self.annotateList.clear() |
70 self.annotateList.clear() |
74 self.errorGroup.hide() |
71 self.errorGroup.hide() |
75 self.intercept = False |
72 self.intercept = False |
76 self.activateWindow() |
73 self.activateWindow() |
77 self.lineno = 1 |
74 self.lineno = 1 |
78 |
75 |
79 args = self.vcs.initCommand("annotate") |
76 args = self.vcs.initCommand("annotate") |
80 args.append('--follow') |
77 args.append("--follow") |
81 args.append('--user') |
78 args.append("--user") |
82 args.append('--date') |
79 args.append("--date") |
83 args.append('--number') |
80 args.append("--number") |
84 args.append('--changeset') |
81 args.append("--changeset") |
85 args.append('--quiet') |
82 args.append("--quiet") |
86 args.append(fn) |
83 args.append(fn) |
87 |
84 |
88 out, err = self.__hgClient.runcommand(args) |
85 out, err = self.__hgClient.runcommand(args) |
89 if err: |
86 if err: |
90 self.__showError(err) |
87 self.__showError(err) |
91 if out: |
88 if out: |
92 for line in out.splitlines(): |
89 for line in out.splitlines(): |
93 self.__processOutputLine(line) |
90 self.__processOutputLine(line) |
94 if self.__hgClient.wasCanceled(): |
91 if self.__hgClient.wasCanceled(): |
95 break |
92 break |
96 self.__finish() |
93 self.__finish() |
97 |
94 |
98 def __finish(self): |
95 def __finish(self): |
99 """ |
96 """ |
100 Private slot called when the process finished or the user pressed |
97 Private slot called when the process finished or the user pressed |
101 the button. |
98 the button. |
102 """ |
99 """ |
103 self.buttonBox.button( |
100 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True) |
104 QDialogButtonBox.StandardButton.Close).setEnabled(True) |
101 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
105 self.buttonBox.button( |
102 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True) |
106 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
103 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setFocus( |
107 self.buttonBox.button( |
104 Qt.FocusReason.OtherFocusReason |
108 QDialogButtonBox.StandardButton.Close).setDefault(True) |
105 ) |
109 self.buttonBox.button( |
106 |
110 QDialogButtonBox.StandardButton.Close).setFocus( |
|
111 Qt.FocusReason.OtherFocusReason) |
|
112 |
|
113 self.__resizeColumns() |
107 self.__resizeColumns() |
114 |
108 |
115 def on_buttonBox_clicked(self, button): |
109 def on_buttonBox_clicked(self, button): |
116 """ |
110 """ |
117 Private slot called by a button of the button box clicked. |
111 Private slot called by a button of the button box clicked. |
118 |
112 |
119 @param button button that was clicked (QAbstractButton) |
113 @param button button that was clicked (QAbstractButton) |
120 """ |
114 """ |
121 if button == self.buttonBox.button( |
115 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close): |
122 QDialogButtonBox.StandardButton.Close |
|
123 ): |
|
124 self.close() |
116 self.close() |
125 elif button == self.buttonBox.button( |
117 elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel): |
126 QDialogButtonBox.StandardButton.Cancel |
|
127 ): |
|
128 if self.__hgClient: |
118 if self.__hgClient: |
129 self.__hgClient.cancel() |
119 self.__hgClient.cancel() |
130 else: |
120 else: |
131 self.__finish() |
121 self.__finish() |
132 |
122 |
133 def __resizeColumns(self): |
123 def __resizeColumns(self): |
134 """ |
124 """ |
135 Private method to resize the list columns. |
125 Private method to resize the list columns. |
136 """ |
126 """ |
137 self.annotateList.header().resizeSections( |
127 self.annotateList.header().resizeSections( |
138 QHeaderView.ResizeMode.ResizeToContents) |
128 QHeaderView.ResizeMode.ResizeToContents |
139 |
129 ) |
|
130 |
140 def __generateItem(self, revision, changeset, author, date, text): |
131 def __generateItem(self, revision, changeset, author, date, text): |
141 """ |
132 """ |
142 Private method to generate an annotate item in the annotation list. |
133 Private method to generate an annotate item in the annotation list. |
143 |
134 |
144 @param revision revision string (string) |
135 @param revision revision string (string) |
145 @param changeset changeset string (string) |
136 @param changeset changeset string (string) |
146 @param author author of the change (string) |
137 @param author author of the change (string) |
147 @param date date of the change (string) |
138 @param date date of the change (string) |
148 @param text text of the change (string) |
139 @param text text of the change (string) |
149 """ |
140 """ |
150 itm = QTreeWidgetItem( |
141 itm = QTreeWidgetItem( |
151 self.annotateList, |
142 self.annotateList, |
152 [revision, changeset, author, date, "{0:d}".format(self.lineno), |
143 [revision, changeset, author, date, "{0:d}".format(self.lineno), text], |
153 text]) |
144 ) |
154 self.lineno += 1 |
145 self.lineno += 1 |
155 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignRight) |
146 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignRight) |
156 itm.setTextAlignment(4, Qt.AlignmentFlag.AlignRight) |
147 itm.setTextAlignment(4, Qt.AlignmentFlag.AlignRight) |
157 |
148 |
158 def __processOutputLine(self, line): |
149 def __processOutputLine(self, line): |
159 """ |
150 """ |
160 Private method to process the lines of output. |
151 Private method to process the lines of output. |
161 |
152 |
162 @param line output line to be processed (string) |
153 @param line output line to be processed (string) |
163 """ |
154 """ |
164 try: |
155 try: |
165 info, text = line.split(": ", 1) |
156 info, text = line.split(": ", 1) |
166 except ValueError: |
157 except ValueError: |
167 info = line[:-2] |
158 info = line[:-2] |
168 text = "" |
159 text = "" |
169 match = self.__annotateRe.match(info) |
160 match = self.__annotateRe.match(info) |
170 author, rev, changeset, date, file = match.groups() |
161 author, rev, changeset, date, file = match.groups() |
171 self.__generateItem(rev.strip(), changeset.strip(), author.strip(), |
162 self.__generateItem( |
172 date.strip(), text) |
163 rev.strip(), changeset.strip(), author.strip(), date.strip(), text |
173 |
164 ) |
|
165 |
174 def __showError(self, out): |
166 def __showError(self, out): |
175 """ |
167 """ |
176 Private slot to show some error. |
168 Private slot to show some error. |
177 |
169 |
178 @param out error to be shown (string) |
170 @param out error to be shown (string) |
179 """ |
171 """ |
180 self.errorGroup.show() |
172 self.errorGroup.show() |
181 self.errors.insertPlainText(out) |
173 self.errors.insertPlainText(out) |
182 self.errors.ensureCursorVisible() |
174 self.errors.ensureCursorVisible() |