src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9335
ec381c083dbd
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
11 import os 11 import os
12 import time 12 import time
13 13
14 from PyQt6.QtCore import pyqtSlot, Qt, QTimer 14 from PyQt6.QtCore import pyqtSlot, Qt, QTimer
15 from PyQt6.QtWidgets import ( 15 from PyQt6.QtWidgets import (
16 QDialog, QDialogButtonBox, QTreeWidgetItem, QApplication, QHeaderView 16 QDialog,
17 QDialogButtonBox,
18 QTreeWidgetItem,
19 QApplication,
20 QHeaderView,
17 ) 21 )
18 22
19 from EricWidgets.EricApplication import ericApp 23 from EricWidgets.EricApplication import ericApp
20 24
21 from .Ui_SyntaxCheckerDialog import Ui_SyntaxCheckerDialog 25 from .Ui_SyntaxCheckerDialog import Ui_SyntaxCheckerDialog
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)
378 scr_line = source[lineno - 1].strip() 389 scr_line = source[lineno - 1].strip()
379 except IndexError: 390 except IndexError:
380 scr_line = "" 391 scr_line = ""
381 else: 392 else:
382 scr_line = "" 393 scr_line = ""
383 self.__createResultItem(filename, lineno, col, msg, scr_line, 394 self.__createResultItem(filename, lineno, col, msg, scr_line, True)
384 True)
385 395
386 self.progress += 1 396 self.progress += 1
387 self.checkProgress.setValue(self.progress) 397 self.checkProgress.setValue(self.progress)
388 self.checkProgressLabel.setPath(fn) 398 self.checkProgressLabel.setPath(fn)
389 if time.monotonic() - self.__timenow > 0.01: 399 if time.monotonic() - self.__timenow > 0.01:
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]:

eric ide

mercurial