26 |
30 |
27 class SyntaxCheckerDialog(QDialog, Ui_SyntaxCheckerDialog): |
31 class SyntaxCheckerDialog(QDialog, Ui_SyntaxCheckerDialog): |
28 """ |
32 """ |
29 Class implementing a dialog to display the results of a syntax check run. |
33 Class implementing a dialog to display the results of a syntax check run. |
30 """ |
34 """ |
|
35 |
31 filenameRole = Qt.ItemDataRole.UserRole + 1 |
36 filenameRole = Qt.ItemDataRole.UserRole + 1 |
32 lineRole = Qt.ItemDataRole.UserRole + 2 |
37 lineRole = Qt.ItemDataRole.UserRole + 2 |
33 indexRole = Qt.ItemDataRole.UserRole + 3 |
38 indexRole = Qt.ItemDataRole.UserRole + 3 |
34 errorRole = Qt.ItemDataRole.UserRole + 4 |
39 errorRole = Qt.ItemDataRole.UserRole + 4 |
35 warningRole = Qt.ItemDataRole.UserRole + 5 |
40 warningRole = Qt.ItemDataRole.UserRole + 5 |
36 |
41 |
37 def __init__(self, parent=None): |
42 def __init__(self, parent=None): |
38 """ |
43 """ |
39 Constructor |
44 Constructor |
40 |
45 |
41 @param parent The parent widget. (QWidget) |
46 @param parent The parent widget. (QWidget) |
42 """ |
47 """ |
43 super().__init__(parent) |
48 super().__init__(parent) |
44 self.setupUi(self) |
49 self.setupUi(self) |
45 self.setWindowFlags(Qt.WindowType.Window) |
50 self.setWindowFlags(Qt.WindowType.Window) |
46 |
51 |
47 self.showButton = self.buttonBox.addButton( |
52 self.showButton = self.buttonBox.addButton( |
48 self.tr("Show"), QDialogButtonBox.ButtonRole.ActionRole) |
53 self.tr("Show"), QDialogButtonBox.ButtonRole.ActionRole |
|
54 ) |
49 self.showButton.setToolTip( |
55 self.showButton.setToolTip( |
50 self.tr("Press to show all files containing an issue")) |
56 self.tr("Press to show all files containing an issue") |
51 self.buttonBox.button( |
57 ) |
52 QDialogButtonBox.StandardButton.Close).setEnabled(False) |
58 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False) |
53 self.buttonBox.button( |
59 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
54 QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
60 |
55 |
|
56 self.resultList.headerItem().setText(self.resultList.columnCount(), "") |
61 self.resultList.headerItem().setText(self.resultList.columnCount(), "") |
57 self.resultList.header().setSortIndicator( |
62 self.resultList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder) |
58 0, Qt.SortOrder.AscendingOrder) |
63 |
59 |
|
60 self.noResults = True |
64 self.noResults = True |
61 self.cancelled = False |
65 self.cancelled = False |
62 self.__lastFileItem = None |
66 self.__lastFileItem = None |
63 self.__batch = False |
67 self.__batch = False |
64 self.__finished = True |
68 self.__finished = True |
65 self.__errorItem = None |
69 self.__errorItem = None |
66 self.__timenow = time.monotonic() |
70 self.__timenow = time.monotonic() |
67 |
71 |
68 self.__fileList = [] |
72 self.__fileList = [] |
69 self.__project = None |
73 self.__project = None |
70 self.filterFrame.setVisible(False) |
74 self.filterFrame.setVisible(False) |
71 |
75 |
72 self.checkProgress.setVisible(False) |
76 self.checkProgress.setVisible(False) |
73 self.checkProgressLabel.setVisible(False) |
77 self.checkProgressLabel.setVisible(False) |
74 self.checkProgressLabel.setMaximumWidth(600) |
78 self.checkProgressLabel.setMaximumWidth(600) |
75 |
79 |
76 try: |
80 try: |
77 self.syntaxCheckService = ericApp().getObject('SyntaxCheckService') |
81 self.syntaxCheckService = ericApp().getObject("SyntaxCheckService") |
78 self.syntaxCheckService.syntaxChecked.connect(self.__processResult) |
82 self.syntaxCheckService.syntaxChecked.connect(self.__processResult) |
79 self.syntaxCheckService.batchFinished.connect(self.__batchFinished) |
83 self.syntaxCheckService.batchFinished.connect(self.__batchFinished) |
80 self.syntaxCheckService.error.connect(self.__processError) |
84 self.syntaxCheckService.error.connect(self.__processError) |
81 except KeyError: |
85 except KeyError: |
82 self.syntaxCheckService = None |
86 self.syntaxCheckService = None |
83 self.filename = None |
87 self.filename = None |
84 |
88 |
85 def __resort(self): |
89 def __resort(self): |
86 """ |
90 """ |
87 Private method to resort the tree. |
91 Private method to resort the tree. |
88 """ |
92 """ |
89 self.resultList.sortItems(self.resultList.sortColumn(), |
93 self.resultList.sortItems( |
90 self.resultList.header().sortIndicatorOrder() |
94 self.resultList.sortColumn(), self.resultList.header().sortIndicatorOrder() |
91 ) |
95 ) |
92 |
96 |
93 def __createErrorItem(self, filename, message): |
97 def __createErrorItem(self, filename, message): |
94 """ |
98 """ |
95 Private slot to create a new error item in the result list. |
99 Private slot to create a new error item in the result list. |
96 |
100 |
97 @param filename name of the file |
101 @param filename name of the file |
98 @type str |
102 @type str |
99 @param message error message |
103 @param message error message |
100 @type str |
104 @type str |
101 """ |
105 """ |
102 if self.__errorItem is None: |
106 if self.__errorItem is None: |
103 self.__errorItem = QTreeWidgetItem(self.resultList, [ |
107 self.__errorItem = QTreeWidgetItem(self.resultList, [self.tr("Errors")]) |
104 self.tr("Errors")]) |
|
105 self.__errorItem.setExpanded(True) |
108 self.__errorItem.setExpanded(True) |
106 self.__errorItem.setForeground(0, Qt.GlobalColor.red) |
109 self.__errorItem.setForeground(0, Qt.GlobalColor.red) |
107 |
110 |
108 msg = "{0} ({1})".format(self.__project.getRelativePath(filename), |
111 msg = "{0} ({1})".format(self.__project.getRelativePath(filename), message) |
109 message) |
|
110 if not self.resultList.findItems(msg, Qt.MatchFlag.MatchExactly): |
112 if not self.resultList.findItems(msg, Qt.MatchFlag.MatchExactly): |
111 itm = QTreeWidgetItem(self.__errorItem, [msg]) |
113 itm = QTreeWidgetItem(self.__errorItem, [msg]) |
112 itm.setForeground(0, Qt.GlobalColor.red) |
114 itm.setForeground(0, Qt.GlobalColor.red) |
113 itm.setFirstColumnSpanned(True) |
115 itm.setFirstColumnSpanned(True) |
114 |
116 |
115 def __createResultItem(self, filename, line, index, error, sourcecode, |
117 def __createResultItem( |
116 isWarning=False): |
118 self, filename, line, index, error, sourcecode, isWarning=False |
|
119 ): |
117 """ |
120 """ |
118 Private method to create an entry in the result list. |
121 Private method to create an entry in the result list. |
119 |
122 |
120 @param filename file name of file (string) |
123 @param filename file name of file (string) |
121 @param line line number of faulty source (integer or string) |
124 @param line line number of faulty source (integer or string) |
122 @param index index number of fault (integer) |
125 @param index index number of fault (integer) |
123 @param error error text (string) |
126 @param error error text (string) |
124 @param sourcecode faulty line of code (string) |
127 @param sourcecode faulty line of code (string) |
125 @param isWarning flag indicating a warning message (boolean) |
128 @param isWarning flag indicating a warning message (boolean) |
126 """ |
129 """ |
127 if ( |
130 if ( |
128 self.__lastFileItem is None or |
131 self.__lastFileItem is None |
129 self.__lastFileItem.data(0, self.filenameRole) != filename |
132 or self.__lastFileItem.data(0, self.filenameRole) != filename |
130 ): |
133 ): |
131 # It's a new file |
134 # It's a new file |
132 self.__lastFileItem = QTreeWidgetItem(self.resultList, [ |
135 self.__lastFileItem = QTreeWidgetItem( |
133 self.__project.getRelativePath(filename)]) |
136 self.resultList, [self.__project.getRelativePath(filename)] |
|
137 ) |
134 self.__lastFileItem.setFirstColumnSpanned(True) |
138 self.__lastFileItem.setFirstColumnSpanned(True) |
135 self.__lastFileItem.setExpanded(True) |
139 self.__lastFileItem.setExpanded(True) |
136 self.__lastFileItem.setData(0, self.filenameRole, filename) |
140 self.__lastFileItem.setData(0, self.filenameRole, filename) |
137 |
141 |
138 itm = QTreeWidgetItem(self.__lastFileItem) |
142 itm = QTreeWidgetItem(self.__lastFileItem) |
139 if isWarning: |
143 if isWarning: |
140 itm.setIcon(0, UI.PixmapCache.getIcon("warning")) |
144 itm.setIcon(0, UI.PixmapCache.getIcon("warning")) |
141 else: |
145 else: |
142 itm.setIcon(0, UI.PixmapCache.getIcon("syntaxError")) |
146 itm.setIcon(0, UI.PixmapCache.getIcon("syntaxError")) |
146 itm.setData(0, self.filenameRole, filename) |
150 itm.setData(0, self.filenameRole, filename) |
147 itm.setData(0, self.lineRole, int(line)) |
151 itm.setData(0, self.lineRole, int(line)) |
148 itm.setData(0, self.indexRole, index) |
152 itm.setData(0, self.indexRole, index) |
149 itm.setData(0, self.errorRole, error) |
153 itm.setData(0, self.errorRole, error) |
150 itm.setData(0, self.warningRole, isWarning) |
154 itm.setData(0, self.warningRole, isWarning) |
151 |
155 |
152 def prepare(self, fileList, project): |
156 def prepare(self, fileList, project): |
153 """ |
157 """ |
154 Public method to prepare the dialog with a list of filenames. |
158 Public method to prepare the dialog with a list of filenames. |
155 |
159 |
156 @param fileList list of filenames (list of strings) |
160 @param fileList list of filenames (list of strings) |
157 @param project reference to the project object (Project) |
161 @param project reference to the project object (Project) |
158 """ |
162 """ |
159 self.__fileList = fileList[:] |
163 self.__fileList = fileList[:] |
160 self.__project = project |
164 self.__project = project |
161 |
165 |
162 self.buttonBox.button( |
166 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True) |
163 QDialogButtonBox.StandardButton.Close).setEnabled(True) |
167 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
164 self.buttonBox.button( |
168 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True) |
165 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
169 |
166 self.buttonBox.button( |
|
167 QDialogButtonBox.StandardButton.Close).setDefault(True) |
|
168 |
|
169 self.filterFrame.setVisible(True) |
170 self.filterFrame.setVisible(True) |
170 |
171 |
171 self.__data = self.__project.getData("CHECKERSPARMS", "SyntaxChecker") |
172 self.__data = self.__project.getData("CHECKERSPARMS", "SyntaxChecker") |
172 if self.__data is None or "ExcludeFiles" not in self.__data: |
173 if self.__data is None or "ExcludeFiles" not in self.__data: |
173 self.__data = {"ExcludeFiles": ""} |
174 self.__data = {"ExcludeFiles": ""} |
174 self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) |
175 self.excludeFilesEdit.setText(self.__data["ExcludeFiles"]) |
175 |
176 |
176 def start(self, fn, codestring=""): |
177 def start(self, fn, codestring=""): |
177 """ |
178 """ |
178 Public slot to start the syntax check. |
179 Public slot to start the syntax check. |
179 |
180 |
180 @param fn file or list of files or directory to be checked |
181 @param fn file or list of files or directory to be checked |
181 (string or list of strings) |
182 (string or list of strings) |
182 @param codestring string containing the code to be checked (string). |
183 @param codestring string containing the code to be checked (string). |
183 If this is given, fn must be a single file name. |
184 If this is given, fn must be a single file name. |
184 """ |
185 """ |
185 self.__batch = False |
186 self.__batch = False |
186 |
187 |
187 if self.syntaxCheckService is not None: |
188 if self.syntaxCheckService is not None: |
188 if self.__project is None: |
189 if self.__project is None: |
189 self.__project = ericApp().getObject("Project") |
190 self.__project = ericApp().getObject("Project") |
190 |
191 |
191 self.cancelled = False |
192 self.cancelled = False |
192 self.buttonBox.button( |
193 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled( |
193 QDialogButtonBox.StandardButton.Close).setEnabled(False) |
194 False |
194 self.buttonBox.button( |
195 ) |
195 QDialogButtonBox.StandardButton.Cancel).setEnabled(True) |
196 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled( |
196 self.buttonBox.button( |
197 True |
197 QDialogButtonBox.StandardButton.Cancel).setDefault(True) |
198 ) |
|
199 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault( |
|
200 True |
|
201 ) |
198 self.showButton.setEnabled(False) |
202 self.showButton.setEnabled(False) |
199 self.checkProgress.setVisible(True) |
203 self.checkProgress.setVisible(True) |
200 QApplication.processEvents() |
204 QApplication.processEvents() |
201 |
205 |
202 if isinstance(fn, list): |
206 if isinstance(fn, list): |
203 self.files = fn |
207 self.files = fn |
204 elif os.path.isdir(fn): |
208 elif os.path.isdir(fn): |
205 self.files = [] |
209 self.files = [] |
206 for ext in self.syntaxCheckService.getExtensions(): |
210 for ext in self.syntaxCheckService.getExtensions(): |
207 self.files.extend( |
211 self.files.extend( |
208 Utilities.direntries(fn, True, '*{0}'.format(ext), 0)) |
212 Utilities.direntries(fn, True, "*{0}".format(ext), 0) |
|
213 ) |
209 else: |
214 else: |
210 self.files = [fn] |
215 self.files = [fn] |
211 |
216 |
212 self.__errorItem = None |
217 self.__errorItem = None |
213 self.__clearErrors(self.files) |
218 self.__clearErrors(self.files) |
214 |
219 |
215 if codestring or len(self.files) > 0: |
220 if codestring or len(self.files) > 0: |
216 self.checkProgress.setMaximum(max(1, len(self.files))) |
221 self.checkProgress.setMaximum(max(1, len(self.files))) |
217 self.checkProgress.setVisible(len(self.files) > 1) |
222 self.checkProgress.setVisible(len(self.files) > 1) |
218 self.checkProgressLabel.setVisible(len(self.files) > 1) |
223 self.checkProgressLabel.setVisible(len(self.files) > 1) |
219 QApplication.processEvents() |
224 QApplication.processEvents() |
226 self.__batch = False |
231 self.__batch = False |
227 self.check(codestring) |
232 self.check(codestring) |
228 else: |
233 else: |
229 self.__batch = True |
234 self.__batch = True |
230 self.checkBatch() |
235 self.checkBatch() |
231 |
236 |
232 def check(self, codestring=''): |
237 def check(self, codestring=""): |
233 """ |
238 """ |
234 Public method to start a check for one file. |
239 Public method to start a check for one file. |
235 |
240 |
236 The results are reported to the __processResult slot. |
241 The results are reported to the __processResult slot. |
237 |
242 |
238 @param codestring optional sourcestring (str) |
243 @param codestring optional sourcestring (str) |
239 """ |
244 """ |
240 if self.syntaxCheckService is None or not self.files: |
245 if self.syntaxCheckService is None or not self.files: |
241 self.checkProgressLabel.setPath("") |
246 self.checkProgressLabel.setPath("") |
242 self.checkProgress.setMaximum(1) |
247 self.checkProgress.setMaximum(1) |
243 self.checkProgress.setValue(1) |
248 self.checkProgress.setValue(1) |
244 self.__finish() |
249 self.__finish() |
245 return |
250 return |
246 |
251 |
247 self.filename = self.files.pop(0) |
252 self.filename = self.files.pop(0) |
248 self.checkProgress.setValue(self.progress) |
253 self.checkProgress.setValue(self.progress) |
249 self.checkProgressLabel.setPath(self.filename) |
254 self.checkProgressLabel.setPath(self.filename) |
250 QApplication.processEvents() |
255 QApplication.processEvents() |
251 self.__resort() |
256 self.__resort() |
252 |
257 |
253 if self.cancelled: |
258 if self.cancelled: |
254 return |
259 return |
255 |
260 |
256 self.__lastFileItem = None |
261 self.__lastFileItem = None |
257 |
262 |
258 if codestring: |
263 if codestring: |
259 self.source = codestring |
264 self.source = codestring |
260 else: |
265 else: |
261 try: |
266 try: |
262 self.source = Utilities.readEncodedFile(self.filename)[0] |
267 self.source = Utilities.readEncodedFile(self.filename)[0] |
263 self.source = Utilities.normalizeCode(self.source) |
268 self.source = Utilities.normalizeCode(self.source) |
264 except (UnicodeError, OSError) as msg: |
269 except (UnicodeError, OSError) as msg: |
265 self.noResults = False |
270 self.noResults = False |
266 self.__createResultItem( |
271 self.__createResultItem( |
267 self.filename, 1, 0, |
272 self.filename, |
268 self.tr("Error: {0}").format(str(msg)) |
273 1, |
269 .rstrip(), "") |
274 0, |
|
275 self.tr("Error: {0}").format(str(msg)).rstrip(), |
|
276 "", |
|
277 ) |
270 self.progress += 1 |
278 self.progress += 1 |
271 # Continue with next file |
279 # Continue with next file |
272 self.check() |
280 self.check() |
273 return |
281 return |
274 |
282 |
275 self.__finished = False |
283 self.__finished = False |
276 self.syntaxCheckService.syntaxCheck(None, self.filename, self.source) |
284 self.syntaxCheckService.syntaxCheck(None, self.filename, self.source) |
277 |
285 |
278 def checkBatch(self): |
286 def checkBatch(self): |
279 """ |
287 """ |
280 Public method to start a style check batch job. |
288 Public method to start a style check batch job. |
281 |
289 |
282 The results are reported to the __processResult slot. |
290 The results are reported to the __processResult slot. |
283 """ |
291 """ |
284 self.__lastFileItem = None |
292 self.__lastFileItem = None |
285 |
293 |
286 self.checkProgressLabel.setPath(self.tr("Preparing files...")) |
294 self.checkProgressLabel.setPath(self.tr("Preparing files...")) |
287 |
295 |
288 argumentsList = [] |
296 argumentsList = [] |
289 for progress, filename in enumerate(self.files, start=1): |
297 for progress, filename in enumerate(self.files, start=1): |
290 self.checkProgress.setValue(progress) |
298 self.checkProgress.setValue(progress) |
291 if time.monotonic() - self.__timenow > 0.01: |
299 if time.monotonic() - self.__timenow > 0.01: |
292 QApplication.processEvents() |
300 QApplication.processEvents() |
293 self.__timenow = time.monotonic() |
301 self.__timenow = time.monotonic() |
294 |
302 |
295 try: |
303 try: |
296 source = Utilities.readEncodedFile(filename)[0] |
304 source = Utilities.readEncodedFile(filename)[0] |
297 source = Utilities.normalizeCode(source) |
305 source = Utilities.normalizeCode(source) |
298 except (UnicodeError, OSError) as msg: |
306 except (UnicodeError, OSError) as msg: |
299 self.noResults = False |
307 self.noResults = False |
300 self.__createResultItem( |
308 self.__createResultItem( |
301 self.filename, 1, 0, |
309 self.filename, |
302 self.tr("Error: {0}").format(str(msg)) |
310 1, |
303 .rstrip(), "") |
311 0, |
|
312 self.tr("Error: {0}").format(str(msg)).rstrip(), |
|
313 "", |
|
314 ) |
304 continue |
315 continue |
305 |
316 |
306 argumentsList.append((filename, source)) |
317 argumentsList.append((filename, source)) |
307 |
318 |
308 # reset the progress bar to the checked files |
319 # reset the progress bar to the checked files |
309 self.checkProgress.setValue(self.progress) |
320 self.checkProgress.setValue(self.progress) |
310 self.checkProgressLabel.setPath(self.tr("Transferring data...")) |
321 self.checkProgressLabel.setPath(self.tr("Transferring data...")) |
311 QApplication.processEvents() |
322 QApplication.processEvents() |
312 |
323 |
313 self.__finished = False |
324 self.__finished = False |
314 self.syntaxCheckService.syntaxBatchCheck(argumentsList) |
325 self.syntaxCheckService.syntaxBatchCheck(argumentsList) |
315 |
326 |
316 def __batchFinished(self): |
327 def __batchFinished(self): |
317 """ |
328 """ |
318 Private slot handling the completion of a batch job. |
329 Private slot handling the completion of a batch job. |
319 """ |
330 """ |
320 self.checkProgressLabel.setPath("") |
331 self.checkProgressLabel.setPath("") |
321 self.checkProgress.setMaximum(1) |
332 self.checkProgress.setMaximum(1) |
322 self.checkProgress.setValue(1) |
333 self.checkProgress.setValue(1) |
323 self.__finish() |
334 self.__finish() |
324 |
335 |
325 def __processError(self, fn, msg): |
336 def __processError(self, fn, msg): |
326 """ |
337 """ |
327 Private slot to process an error indication from the service. |
338 Private slot to process an error indication from the service. |
328 |
339 |
329 @param fn filename of the file |
340 @param fn filename of the file |
330 @type str |
341 @type str |
331 @param msg error message |
342 @param msg error message |
332 @type str |
343 @type str |
333 """ |
344 """ |
334 self.__createErrorItem(fn, msg) |
345 self.__createErrorItem(fn, msg) |
335 |
346 |
336 if not self.__batch: |
347 if not self.__batch: |
337 self.check() |
348 self.check() |
338 |
349 |
339 def __processResult(self, fn, problems): |
350 def __processResult(self, fn, problems): |
340 """ |
351 """ |
341 Private slot to display the reported messages. |
352 Private slot to display the reported messages. |
342 |
353 |
343 @param fn filename of the checked file (str) |
354 @param fn filename of the checked file (str) |
344 @param problems dictionary with the keys 'error' and 'warnings' which |
355 @param problems dictionary with the keys 'error' and 'warnings' which |
345 hold a list containing details about the error/ warnings |
356 hold a list containing details about the error/ warnings |
346 (file name, line number, column, codestring (only at syntax |
357 (file name, line number, column, codestring (only at syntax |
347 errors), the message) (dict) |
358 errors), the message) (dict) |
348 """ |
359 """ |
349 if self.__finished: |
360 if self.__finished: |
350 return |
361 return |
351 |
362 |
352 # Check if it's the requested file, otherwise ignore signal if not |
363 # Check if it's the requested file, otherwise ignore signal if not |
353 # in batch mode |
364 # in batch mode |
354 if not self.__batch and fn != self.filename: |
365 if not self.__batch and fn != self.filename: |
355 return |
366 return |
356 |
367 |
357 error = problems.get('error') |
368 error = problems.get("error") |
358 if error: |
369 if error: |
359 self.noResults = False |
370 self.noResults = False |
360 _fn, lineno, col, code, msg = error |
371 _fn, lineno, col, code, msg = error |
361 self.__createResultItem(_fn, lineno, col, msg, code, False) |
372 self.__createResultItem(_fn, lineno, col, msg, code, False) |
362 |
373 |
363 warnings = problems.get('warnings', []) |
374 warnings = problems.get("warnings", []) |
364 if warnings: |
375 if warnings: |
365 if self.__batch: |
376 if self.__batch: |
366 try: |
377 try: |
367 source = Utilities.readEncodedFile(fn)[0] |
378 source = Utilities.readEncodedFile(fn)[0] |
368 source = Utilities.normalizeCode(source) |
379 source = Utilities.normalizeCode(source) |
391 self.__timenow = time.monotonic() |
401 self.__timenow = time.monotonic() |
392 self.__resort() |
402 self.__resort() |
393 |
403 |
394 if not self.__batch: |
404 if not self.__batch: |
395 self.check() |
405 self.check() |
396 |
406 |
397 def __finish(self): |
407 def __finish(self): |
398 """ |
408 """ |
399 Private slot called when the syntax check finished or the user |
409 Private slot called when the syntax check finished or the user |
400 pressed the button. |
410 pressed the button. |
401 """ |
411 """ |
402 if not self.__finished: |
412 if not self.__finished: |
403 self.__finished = True |
413 self.__finished = True |
404 |
414 |
405 self.cancelled = True |
415 self.cancelled = True |
406 self.buttonBox.button( |
416 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled( |
407 QDialogButtonBox.StandardButton.Close).setEnabled(True) |
417 True |
408 self.buttonBox.button( |
418 ) |
409 QDialogButtonBox.StandardButton.Cancel).setEnabled(False) |
419 self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled( |
410 self.buttonBox.button( |
420 False |
411 QDialogButtonBox.StandardButton.Close).setDefault(True) |
421 ) |
412 |
422 self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault( |
|
423 True |
|
424 ) |
|
425 |
413 if self.noResults: |
426 if self.noResults: |
414 QTreeWidgetItem(self.resultList, [self.tr('No issues found.')]) |
427 QTreeWidgetItem(self.resultList, [self.tr("No issues found.")]) |
415 QApplication.processEvents() |
428 QApplication.processEvents() |
416 self.showButton.setEnabled(False) |
429 self.showButton.setEnabled(False) |
417 else: |
430 else: |
418 self.showButton.setEnabled(True) |
431 self.showButton.setEnabled(True) |
419 self.resultList.header().resizeSections( |
432 self.resultList.header().resizeSections( |
420 QHeaderView.ResizeMode.ResizeToContents) |
433 QHeaderView.ResizeMode.ResizeToContents |
|
434 ) |
421 self.resultList.header().setStretchLastSection(True) |
435 self.resultList.header().setStretchLastSection(True) |
422 |
436 |
423 self.checkProgress.setVisible(False) |
437 self.checkProgress.setVisible(False) |
424 self.checkProgressLabel.setVisible(False) |
438 self.checkProgressLabel.setVisible(False) |
425 |
439 |
426 def on_buttonBox_clicked(self, button): |
440 def on_buttonBox_clicked(self, button): |
427 """ |
441 """ |
428 Private slot called by a button of the button box clicked. |
442 Private slot called by a button of the button box clicked. |
429 |
443 |
430 @param button button that was clicked (QAbstractButton) |
444 @param button button that was clicked (QAbstractButton) |
431 """ |
445 """ |
432 if button == self.buttonBox.button( |
446 if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close): |
433 QDialogButtonBox.StandardButton.Close |
|
434 ): |
|
435 self.close() |
447 self.close() |
436 elif button == self.buttonBox.button( |
448 elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel): |
437 QDialogButtonBox.StandardButton.Cancel |
|
438 ): |
|
439 if self.__batch: |
449 if self.__batch: |
440 self.syntaxCheckService.cancelSyntaxBatchCheck() |
450 self.syntaxCheckService.cancelSyntaxBatchCheck() |
441 QTimer.singleShot(1000, self.__finish) |
451 QTimer.singleShot(1000, self.__finish) |
442 else: |
452 else: |
443 self.__finish() |
453 self.__finish() |
444 elif button == self.showButton: |
454 elif button == self.showButton: |
445 self.on_showButton_clicked() |
455 self.on_showButton_clicked() |
446 |
456 |
447 @pyqtSlot() |
457 @pyqtSlot() |
448 def on_startButton_clicked(self): |
458 def on_startButton_clicked(self): |
449 """ |
459 """ |
450 Private slot to start a syntax check run. |
460 Private slot to start a syntax check run. |
451 """ |
461 """ |
452 fileList = self.__fileList[:] |
462 fileList = self.__fileList[:] |
453 |
463 |
454 filterString = self.excludeFilesEdit.text() |
464 filterString = self.excludeFilesEdit.text() |
455 if ( |
465 if ( |
456 "ExcludeFiles" not in self.__data or |
466 "ExcludeFiles" not in self.__data |
457 filterString != self.__data["ExcludeFiles"] |
467 or filterString != self.__data["ExcludeFiles"] |
458 ): |
468 ): |
459 self.__data["ExcludeFiles"] = filterString |
469 self.__data["ExcludeFiles"] = filterString |
460 self.__project.setData("CHECKERSPARMS", "SyntaxChecker", |
470 self.__project.setData("CHECKERSPARMS", "SyntaxChecker", self.__data) |
461 self.__data) |
471 filterList = [f.strip() for f in filterString.split(",") if f.strip()] |
462 filterList = [f.strip() for f in filterString.split(",") |
|
463 if f.strip()] |
|
464 if filterList: |
472 if filterList: |
465 for fileFilter in filterList: |
473 for fileFilter in filterList: |
466 fileList = [ |
474 fileList = [f for f in fileList if not fnmatch.fnmatch(f, fileFilter)] |
467 f for f in fileList if not fnmatch.fnmatch(f, fileFilter) |
475 |
468 ] |
|
469 |
|
470 self.resultList.clear() |
476 self.resultList.clear() |
471 self.noResults = True |
477 self.noResults = True |
472 self.cancelled = False |
478 self.cancelled = False |
473 self.start(fileList) |
479 self.start(fileList) |
474 |
480 |
475 def on_resultList_itemActivated(self, itm, col): |
481 def on_resultList_itemActivated(self, itm, col): |
476 """ |
482 """ |
477 Private slot to handle the activation of an item. |
483 Private slot to handle the activation of an item. |
478 |
484 |
479 @param itm reference to the activated item (QTreeWidgetItem) |
485 @param itm reference to the activated item (QTreeWidgetItem) |
480 @param col column the item was activated in (integer) |
486 @param col column the item was activated in (integer) |
481 """ |
487 """ |
482 if self.noResults: |
488 if self.noResults: |
483 return |
489 return |
484 |
490 |
485 vm = ericApp().getObject("ViewManager") |
491 vm = ericApp().getObject("ViewManager") |
486 |
492 |
487 if itm.parent(): |
493 if itm.parent(): |
488 fn = os.path.abspath(itm.data(0, self.filenameRole)) |
494 fn = os.path.abspath(itm.data(0, self.filenameRole)) |
489 lineno = itm.data(0, self.lineRole) |
495 lineno = itm.data(0, self.lineRole) |
490 index = itm.data(0, self.indexRole) |
496 index = itm.data(0, self.indexRole) |
491 error = itm.data(0, self.errorRole) |
497 error = itm.data(0, self.errorRole) |
492 |
498 |
493 vm.openSourceFile(fn, lineno) |
499 vm.openSourceFile(fn, lineno) |
494 editor = vm.getOpenEditor(fn) |
500 editor = vm.getOpenEditor(fn) |
495 |
501 |
496 if itm.data(0, self.warningRole): |
502 if itm.data(0, self.warningRole): |
497 editor.toggleWarning(lineno, 0, True, error) |
503 editor.toggleWarning(lineno, 0, True, error) |
498 else: |
504 else: |
499 editor.toggleSyntaxError(lineno, index, True, error, show=True) |
505 editor.toggleSyntaxError(lineno, index, True, error, show=True) |
500 else: |
506 else: |
507 index = citm.data(0, self.indexRole) |
513 index = citm.data(0, self.indexRole) |
508 error = citm.data(0, self.errorRole) |
514 error = citm.data(0, self.errorRole) |
509 if citm.data(0, self.warningRole): |
515 if citm.data(0, self.warningRole): |
510 editor.toggleWarning(lineno, 0, True, error) |
516 editor.toggleWarning(lineno, 0, True, error) |
511 else: |
517 else: |
512 editor.toggleSyntaxError( |
518 editor.toggleSyntaxError(lineno, index, True, error, show=True) |
513 lineno, index, True, error, show=True) |
519 |
514 |
|
515 editor = vm.activeWindow() |
520 editor = vm.activeWindow() |
516 editor.updateVerticalScrollBar() |
521 editor.updateVerticalScrollBar() |
517 |
522 |
518 @pyqtSlot() |
523 @pyqtSlot() |
519 def on_showButton_clicked(self): |
524 def on_showButton_clicked(self): |
520 """ |
525 """ |
521 Private slot to handle the "Show" button press. |
526 Private slot to handle the "Show" button press. |
522 """ |
527 """ |
523 vm = ericApp().getObject("ViewManager") |
528 vm = ericApp().getObject("ViewManager") |
524 |
529 |
525 selectedIndexes = [] |
530 selectedIndexes = [] |
526 for index in range(self.resultList.topLevelItemCount()): |
531 for index in range(self.resultList.topLevelItemCount()): |
527 if self.resultList.topLevelItem(index).isSelected(): |
532 if self.resultList.topLevelItem(index).isSelected(): |
528 selectedIndexes.append(index) |
533 selectedIndexes.append(index) |
529 if len(selectedIndexes) == 0: |
534 if len(selectedIndexes) == 0: |
541 index = citm.data(0, self.indexRole) |
546 index = citm.data(0, self.indexRole) |
542 error = citm.data(0, self.errorRole) |
547 error = citm.data(0, self.errorRole) |
543 if citm.data(0, self.warningRole): |
548 if citm.data(0, self.warningRole): |
544 editor.toggleWarning(lineno, 0, True, error) |
549 editor.toggleWarning(lineno, 0, True, error) |
545 else: |
550 else: |
546 editor.toggleSyntaxError( |
551 editor.toggleSyntaxError(lineno, index, True, error, show=True) |
547 lineno, index, True, error, show=True) |
552 |
548 |
|
549 # go through the list again to clear syntax error and |
553 # go through the list again to clear syntax error and |
550 # flakes warning markers for files, that are ok |
554 # flakes warning markers for files, that are ok |
551 openFiles = vm.getOpenFilenames() |
555 openFiles = vm.getOpenFilenames() |
552 errorFiles = [] |
556 errorFiles = [] |
553 for index in range(self.resultList.topLevelItemCount()): |
557 for index in range(self.resultList.topLevelItemCount()): |
554 itm = self.resultList.topLevelItem(index) |
558 itm = self.resultList.topLevelItem(index) |
555 errorFiles.append( |
559 errorFiles.append(os.path.abspath(itm.data(0, self.filenameRole))) |
556 os.path.abspath(itm.data(0, self.filenameRole))) |
|
557 for file in openFiles: |
560 for file in openFiles: |
558 if file not in errorFiles: |
561 if file not in errorFiles: |
559 editor = vm.getOpenEditor(file) |
562 editor = vm.getOpenEditor(file) |
560 editor.clearSyntaxError() |
563 editor.clearSyntaxError() |
561 editor.clearFlakesWarnings() |
564 editor.clearFlakesWarnings() |
562 |
565 |
563 editor = vm.activeWindow() |
566 editor = vm.activeWindow() |
564 editor.updateVerticalScrollBar() |
567 editor.updateVerticalScrollBar() |
565 |
568 |
566 def __clearErrors(self, files): |
569 def __clearErrors(self, files): |
567 """ |
570 """ |
568 Private method to clear all error and warning markers of |
571 Private method to clear all error and warning markers of |
569 open editors to be checked. |
572 open editors to be checked. |
570 |
573 |
571 @param files list of files to be checked (list of string) |
574 @param files list of files to be checked (list of string) |
572 """ |
575 """ |
573 vm = ericApp().getObject("ViewManager") |
576 vm = ericApp().getObject("ViewManager") |
574 openFiles = vm.getOpenFilenames() |
577 openFiles = vm.getOpenFilenames() |
575 for file in [f for f in openFiles if f in files]: |
578 for file in [f for f in openFiles if f in files]: |