6 """ |
6 """ |
7 Module implementing a dialog to show a list of applied and unapplied patches. |
7 Module implementing a dialog to show a list of applied and unapplied patches. |
8 """ |
8 """ |
9 |
9 |
10 from PyQt6.QtCore import Qt, QCoreApplication |
10 from PyQt6.QtCore import Qt, QCoreApplication |
11 from PyQt6.QtWidgets import ( |
11 from PyQt6.QtWidgets import QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem |
12 QDialog, QDialogButtonBox, QHeaderView, QTreeWidgetItem |
|
13 ) |
|
14 |
12 |
15 from .Ui_HgQueuesListDialog import Ui_HgQueuesListDialog |
13 from .Ui_HgQueuesListDialog import Ui_HgQueuesListDialog |
16 |
14 |
17 |
15 |
18 class HgQueuesListDialog(QDialog, Ui_HgQueuesListDialog): |
16 class HgQueuesListDialog(QDialog, Ui_HgQueuesListDialog): |
19 """ |
17 """ |
20 Class implementing a dialog to show a list of applied and unapplied |
18 Class implementing a dialog to show a list of applied and unapplied |
21 patches. |
19 patches. |
22 """ |
20 """ |
|
21 |
23 def __init__(self, vcs, parent=None): |
22 def __init__(self, vcs, parent=None): |
24 """ |
23 """ |
25 Constructor |
24 Constructor |
26 |
25 |
27 @param vcs reference to the vcs object |
26 @param vcs reference to the vcs object |
28 @param parent parent widget (QWidget) |
27 @param parent parent widget (QWidget) |
29 """ |
28 """ |
30 super().__init__(parent) |
29 super().__init__(parent) |
31 self.setupUi(self) |
30 self.setupUi(self) |
32 self.setWindowFlags(Qt.WindowType.Window) |
31 self.setWindowFlags(Qt.WindowType.Window) |
33 |
32 |
34 self.buttonBox.button( |
33 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False) |
35 QDialogButtonBox.StandardButton.Close).setEnabled(False) |
34 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
36 self.buttonBox.button( |
35 |
37 QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
|
38 |
|
39 self.vcs = vcs |
36 self.vcs = vcs |
40 self.__hgClient = vcs.getClient() |
37 self.__hgClient = vcs.getClient() |
41 |
38 |
42 self.patchesList.header().setSortIndicator( |
39 self.patchesList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder) |
43 0, Qt.SortOrder.AscendingOrder) |
40 |
44 |
|
45 self.__statusDict = { |
41 self.__statusDict = { |
46 "A": self.tr("applied"), |
42 "A": self.tr("applied"), |
47 "U": self.tr("not applied"), |
43 "U": self.tr("not applied"), |
48 "G": self.tr("guarded"), |
44 "G": self.tr("guarded"), |
49 "D": self.tr("missing"), |
45 "D": self.tr("missing"), |
50 } |
46 } |
51 |
47 |
52 self.show() |
48 self.show() |
53 QCoreApplication.processEvents() |
49 QCoreApplication.processEvents() |
54 |
50 |
55 def closeEvent(self, e): |
51 def closeEvent(self, e): |
56 """ |
52 """ |
57 Protected slot implementing a close event handler. |
53 Protected slot implementing a close event handler. |
58 |
54 |
59 @param e close event (QCloseEvent) |
55 @param e close event (QCloseEvent) |
60 """ |
56 """ |
61 if self.__hgClient.isExecuting(): |
57 if self.__hgClient.isExecuting(): |
62 self.__hgClient.cancel() |
58 self.__hgClient.cancel() |
63 |
59 |
64 e.accept() |
60 e.accept() |
65 |
61 |
66 def start(self): |
62 def start(self): |
67 """ |
63 """ |
68 Public slot to start the list command. |
64 Public slot to start the list command. |
69 """ |
65 """ |
70 self.errorGroup.hide() |
66 self.errorGroup.hide() |
71 self.activateWindow() |
67 self.activateWindow() |
72 |
68 |
73 self.__getSeries() |
69 self.__getSeries() |
74 |
70 |
75 def __getSeries(self, missing=False): |
71 def __getSeries(self, missing=False): |
76 """ |
72 """ |
77 Private slot to get the list of applied, unapplied and guarded patches |
73 Private slot to get the list of applied, unapplied and guarded patches |
78 and patches missing in the series file. |
74 and patches missing in the series file. |
79 |
75 |
80 @param missing flag indicating to get the patches missing in the |
76 @param missing flag indicating to get the patches missing in the |
81 series file (boolean) |
77 series file (boolean) |
82 """ |
78 """ |
83 if missing: |
79 if missing: |
84 self.__mode = "missing" |
80 self.__mode = "missing" |
85 else: |
81 else: |
86 self.__mode = "qseries" |
82 self.__mode = "qseries" |
87 |
83 |
88 args = self.vcs.initCommand("qseries") |
84 args = self.vcs.initCommand("qseries") |
89 args.append('--summary') |
85 args.append("--summary") |
90 args.append('--verbose') |
86 args.append("--verbose") |
91 if missing: |
87 if missing: |
92 args.append('--missing') |
88 args.append("--missing") |
93 |
89 |
94 out, err = self.__hgClient.runcommand(args) |
90 out, err = self.__hgClient.runcommand(args) |
95 if err: |
91 if err: |
96 self.__showError(err) |
92 self.__showError(err) |
97 if out: |
93 if out: |
98 for line in out.splitlines(): |
94 for line in out.splitlines(): |
104 self.__getSeries(True) |
100 self.__getSeries(True) |
105 elif self.__mode == "missing": |
101 elif self.__mode == "missing": |
106 self.__getTop() |
102 self.__getTop() |
107 else: |
103 else: |
108 self.__finish() |
104 self.__finish() |
109 |
105 |
110 def __getTop(self): |
106 def __getTop(self): |
111 """ |
107 """ |
112 Private slot to get patch at the top of the stack. |
108 Private slot to get patch at the top of the stack. |
113 """ |
109 """ |
114 self.__mode = "qtop" |
110 self.__mode = "qtop" |
115 |
111 |
116 args = self.vcs.initCommand("qtop") |
112 args = self.vcs.initCommand("qtop") |
117 |
113 |
118 out, err = self.__hgClient.runcommand(args) |
114 out, err = self.__hgClient.runcommand(args) |
119 if err: |
115 if err: |
120 self.__showError(err) |
116 self.__showError(err) |
121 if out: |
117 if out: |
122 for line in out.splitlines(): |
118 for line in out.splitlines(): |
123 self.__processOutputLine(line) |
119 self.__processOutputLine(line) |
124 if self.__hgClient.wasCanceled(): |
120 if self.__hgClient.wasCanceled(): |
125 break |
121 break |
126 self.__finish() |
122 self.__finish() |
127 |
123 |
128 def __finish(self): |
124 def __finish(self): |
129 """ |
125 """ |
130 Private slot called when the process finished or the user pressed |
126 Private slot called when the process finished or the user pressed |
131 the button. |
127 the button. |
132 """ |
128 """ |
133 self.buttonBox.button( |
129 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True) |
134 QDialogButtonBox.StandardButton.Close).setEnabled(True) |
130 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
135 self.buttonBox.button( |
131 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True) |
136 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
132 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setFocus( |
137 self.buttonBox.button( |
133 Qt.FocusReason.OtherFocusReason |
138 QDialogButtonBox.StandardButton.Close).setDefault(True) |
134 ) |
139 self.buttonBox.button( |
135 |
140 QDialogButtonBox.StandardButton.Close).setFocus( |
|
141 Qt.FocusReason.OtherFocusReason) |
|
142 |
|
143 if self.patchesList.topLevelItemCount() == 0: |
136 if self.patchesList.topLevelItemCount() == 0: |
144 # no patches present |
137 # no patches present |
145 self.__generateItem( |
138 self.__generateItem(0, "", self.tr("no patches found"), "", True) |
146 0, "", self.tr("no patches found"), "", True) |
|
147 self.__resizeColumns() |
139 self.__resizeColumns() |
148 self.__resort() |
140 self.__resort() |
149 |
141 |
150 def on_buttonBox_clicked(self, button): |
142 def on_buttonBox_clicked(self, button): |
151 """ |
143 """ |
152 Private slot called by a button of the button box clicked. |
144 Private slot called by a button of the button box clicked. |
153 |
145 |
154 @param button button that was clicked (QAbstractButton) |
146 @param button button that was clicked (QAbstractButton) |
155 """ |
147 """ |
156 if button == self.buttonBox.button( |
148 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close): |
157 QDialogButtonBox.StandardButton.Close |
|
158 ): |
|
159 self.close() |
149 self.close() |
160 elif button == self.buttonBox.button( |
150 elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel): |
161 QDialogButtonBox.StandardButton.Cancel |
|
162 ): |
|
163 self.__mode = "" |
151 self.__mode = "" |
164 self.__hgClient.cancel() |
152 self.__hgClient.cancel() |
165 |
153 |
166 def __resort(self): |
154 def __resort(self): |
167 """ |
155 """ |
168 Private method to resort the tree. |
156 Private method to resort the tree. |
169 """ |
157 """ |
170 self.patchesList.sortItems( |
158 self.patchesList.sortItems( |
171 self.patchesList.sortColumn(), |
159 self.patchesList.sortColumn(), |
172 self.patchesList.header().sortIndicatorOrder()) |
160 self.patchesList.header().sortIndicatorOrder(), |
173 |
161 ) |
|
162 |
174 def __resizeColumns(self): |
163 def __resizeColumns(self): |
175 """ |
164 """ |
176 Private method to resize the list columns. |
165 Private method to resize the list columns. |
177 """ |
166 """ |
178 self.patchesList.header().resizeSections( |
167 self.patchesList.header().resizeSections( |
179 QHeaderView.ResizeMode.ResizeToContents) |
168 QHeaderView.ResizeMode.ResizeToContents |
|
169 ) |
180 self.patchesList.header().setStretchLastSection(True) |
170 self.patchesList.header().setStretchLastSection(True) |
181 |
171 |
182 def __generateItem(self, index, status, name, summary, error=False): |
172 def __generateItem(self, index, status, name, summary, error=False): |
183 """ |
173 """ |
184 Private method to generate a patch item in the list of patches. |
174 Private method to generate a patch item in the list of patches. |
185 |
175 |
186 @param index index of the patch (integer, -1 for missing) |
176 @param index index of the patch (integer, -1 for missing) |
187 @param status status of the patch (string) |
177 @param status status of the patch (string) |
188 @param name name of the patch (string) |
178 @param name name of the patch (string) |
189 @param summary first line of the patch header (string) |
179 @param summary first line of the patch header (string) |
190 @param error flag indicating an error entry (boolean) |
180 @param error flag indicating an error entry (boolean) |
191 """ |
181 """ |
192 if error: |
182 if error: |
193 itm = QTreeWidgetItem(self.patchesList, [ |
183 itm = QTreeWidgetItem(self.patchesList, ["", name, "", summary]) |
194 "", |
|
195 name, |
|
196 "", |
|
197 summary |
|
198 ]) |
|
199 else: |
184 else: |
200 if index == -1: |
185 if index == -1: |
201 index = "" |
186 index = "" |
202 try: |
187 try: |
203 statusStr = self.__statusDict[status] |
188 statusStr = self.__statusDict[status] |
214 itm.setForeground(column, Qt.GlobalColor.blue) |
199 itm.setForeground(column, Qt.GlobalColor.blue) |
215 elif status == "D": |
200 elif status == "D": |
216 # missing |
201 # missing |
217 for column in range(itm.columnCount()): |
202 for column in range(itm.columnCount()): |
218 itm.setForeground(column, Qt.GlobalColor.red) |
203 itm.setForeground(column, Qt.GlobalColor.red) |
219 |
204 |
220 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignRight) |
205 itm.setTextAlignment(0, Qt.AlignmentFlag.AlignRight) |
221 itm.setTextAlignment(2, Qt.AlignmentFlag.AlignHCenter) |
206 itm.setTextAlignment(2, Qt.AlignmentFlag.AlignHCenter) |
222 |
207 |
223 def __markTopItem(self, name): |
208 def __markTopItem(self, name): |
224 """ |
209 """ |
225 Private slot to mark the top patch entry. |
210 Private slot to mark the top patch entry. |
226 |
211 |
227 @param name name of the patch (string) |
212 @param name name of the patch (string) |
228 """ |
213 """ |
229 items = self.patchesList.findItems( |
214 items = self.patchesList.findItems(name, Qt.MatchFlag.MatchCaseSensitive, 1) |
230 name, Qt.MatchFlag.MatchCaseSensitive, 1) |
|
231 if items: |
215 if items: |
232 itm = items[0] |
216 itm = items[0] |
233 for column in range(itm.columnCount()): |
217 for column in range(itm.columnCount()): |
234 font = itm.font(column) |
218 font = itm.font(column) |
235 font.setBold(True) |
219 font.setBold(True) |
236 itm.setFont(column, font) |
220 itm.setFont(column, font) |
237 |
221 |
238 def __processOutputLine(self, line): |
222 def __processOutputLine(self, line): |
239 """ |
223 """ |
240 Private method to process the lines of output. |
224 Private method to process the lines of output. |
241 |
225 |
242 @param line output line to be processed (string) |
226 @param line output line to be processed (string) |
243 """ |
227 """ |
244 if self.__mode == "qtop": |
228 if self.__mode == "qtop": |
245 self.__markTopItem(line) |
229 self.__markTopItem(line) |
246 else: |
230 else: |