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

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9335
ec381c083dbd
diff -r e9e7eca7efee -r bf71ee032bb4 src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py
--- a/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py	Wed Jul 13 11:16:20 2022 +0200
+++ b/src/eric7/Plugins/CheckerPlugins/SyntaxChecker/SyntaxCheckerDialog.py	Wed Jul 13 14:55:47 2022 +0200
@@ -13,7 +13,11 @@
 
 from PyQt6.QtCore import pyqtSlot, Qt, QTimer
 from PyQt6.QtWidgets import (
-    QDialog, QDialogButtonBox, QTreeWidgetItem, QApplication, QHeaderView
+    QDialog,
+    QDialogButtonBox,
+    QTreeWidgetItem,
+    QApplication,
+    QHeaderView,
 )
 
 from EricWidgets.EricApplication import ericApp
@@ -28,35 +32,35 @@
     """
     Class implementing a dialog to display the results of a syntax check run.
     """
+
     filenameRole = Qt.ItemDataRole.UserRole + 1
     lineRole = Qt.ItemDataRole.UserRole + 2
     indexRole = Qt.ItemDataRole.UserRole + 3
     errorRole = Qt.ItemDataRole.UserRole + 4
     warningRole = Qt.ItemDataRole.UserRole + 5
-    
+
     def __init__(self, parent=None):
         """
         Constructor
-        
+
         @param parent The parent widget. (QWidget)
         """
         super().__init__(parent)
         self.setupUi(self)
         self.setWindowFlags(Qt.WindowType.Window)
-        
+
         self.showButton = self.buttonBox.addButton(
-            self.tr("Show"), QDialogButtonBox.ButtonRole.ActionRole)
+            self.tr("Show"), QDialogButtonBox.ButtonRole.ActionRole
+        )
         self.showButton.setToolTip(
-            self.tr("Press to show all files containing an issue"))
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close).setEnabled(False)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel).setDefault(True)
-        
+            self.tr("Press to show all files containing an issue")
+        )
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(False)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(True)
+
         self.resultList.headerItem().setText(self.resultList.columnCount(), "")
-        self.resultList.header().setSortIndicator(
-            0, Qt.SortOrder.AscendingOrder)
-        
+        self.resultList.header().setSortIndicator(0, Qt.SortOrder.AscendingOrder)
+
         self.noResults = True
         self.cancelled = False
         self.__lastFileItem = None
@@ -64,59 +68,58 @@
         self.__finished = True
         self.__errorItem = None
         self.__timenow = time.monotonic()
-        
+
         self.__fileList = []
         self.__project = None
         self.filterFrame.setVisible(False)
-        
+
         self.checkProgress.setVisible(False)
         self.checkProgressLabel.setVisible(False)
         self.checkProgressLabel.setMaximumWidth(600)
-        
+
         try:
-            self.syntaxCheckService = ericApp().getObject('SyntaxCheckService')
+            self.syntaxCheckService = ericApp().getObject("SyntaxCheckService")
             self.syntaxCheckService.syntaxChecked.connect(self.__processResult)
             self.syntaxCheckService.batchFinished.connect(self.__batchFinished)
             self.syntaxCheckService.error.connect(self.__processError)
         except KeyError:
             self.syntaxCheckService = None
         self.filename = None
-        
+
     def __resort(self):
         """
         Private method to resort the tree.
         """
-        self.resultList.sortItems(self.resultList.sortColumn(),
-                                  self.resultList.header().sortIndicatorOrder()
-                                  )
-    
+        self.resultList.sortItems(
+            self.resultList.sortColumn(), self.resultList.header().sortIndicatorOrder()
+        )
+
     def __createErrorItem(self, filename, message):
         """
         Private slot to create a new error item in the result list.
-        
+
         @param filename name of the file
         @type str
         @param message error message
         @type str
         """
         if self.__errorItem is None:
-            self.__errorItem = QTreeWidgetItem(self.resultList, [
-                self.tr("Errors")])
+            self.__errorItem = QTreeWidgetItem(self.resultList, [self.tr("Errors")])
             self.__errorItem.setExpanded(True)
             self.__errorItem.setForeground(0, Qt.GlobalColor.red)
-        
-        msg = "{0} ({1})".format(self.__project.getRelativePath(filename),
-                                 message)
+
+        msg = "{0} ({1})".format(self.__project.getRelativePath(filename), message)
         if not self.resultList.findItems(msg, Qt.MatchFlag.MatchExactly):
             itm = QTreeWidgetItem(self.__errorItem, [msg])
             itm.setForeground(0, Qt.GlobalColor.red)
             itm.setFirstColumnSpanned(True)
-        
-    def __createResultItem(self, filename, line, index, error, sourcecode,
-                           isWarning=False):
+
+    def __createResultItem(
+        self, filename, line, index, error, sourcecode, isWarning=False
+    ):
         """
         Private method to create an entry in the result list.
-        
+
         @param filename file name of file (string)
         @param line line number of faulty source (integer or string)
         @param index index number of fault (integer)
@@ -125,16 +128,17 @@
         @param isWarning flag indicating a warning message (boolean)
         """
         if (
-            self.__lastFileItem is None or
-            self.__lastFileItem.data(0, self.filenameRole) != filename
+            self.__lastFileItem is None
+            or self.__lastFileItem.data(0, self.filenameRole) != filename
         ):
             # It's a new file
-            self.__lastFileItem = QTreeWidgetItem(self.resultList, [
-                self.__project.getRelativePath(filename)])
+            self.__lastFileItem = QTreeWidgetItem(
+                self.resultList, [self.__project.getRelativePath(filename)]
+            )
             self.__lastFileItem.setFirstColumnSpanned(True)
             self.__lastFileItem.setExpanded(True)
             self.__lastFileItem.setData(0, self.filenameRole, filename)
-        
+
         itm = QTreeWidgetItem(self.__lastFileItem)
         if isWarning:
             itm.setIcon(0, UI.PixmapCache.getIcon("warning"))
@@ -148,70 +152,71 @@
         itm.setData(0, self.indexRole, index)
         itm.setData(0, self.errorRole, error)
         itm.setData(0, self.warningRole, isWarning)
-        
+
     def prepare(self, fileList, project):
         """
         Public method to prepare the dialog with a list of filenames.
-        
+
         @param fileList list of filenames (list of strings)
         @param project reference to the project object (Project)
         """
         self.__fileList = fileList[:]
         self.__project = project
-        
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close).setEnabled(True)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
-        self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close).setDefault(True)
-        
+
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(True)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
+        self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(True)
+
         self.filterFrame.setVisible(True)
-        
+
         self.__data = self.__project.getData("CHECKERSPARMS", "SyntaxChecker")
         if self.__data is None or "ExcludeFiles" not in self.__data:
             self.__data = {"ExcludeFiles": ""}
         self.excludeFilesEdit.setText(self.__data["ExcludeFiles"])
-        
+
     def start(self, fn, codestring=""):
         """
         Public slot to start the syntax check.
-        
+
         @param fn file or list of files or directory to be checked
                 (string or list of strings)
         @param codestring string containing the code to be checked (string).
             If this is given, fn must be a single file name.
         """
         self.__batch = False
-        
+
         if self.syntaxCheckService is not None:
             if self.__project is None:
                 self.__project = ericApp().getObject("Project")
-            
+
             self.cancelled = False
-            self.buttonBox.button(
-                QDialogButtonBox.StandardButton.Close).setEnabled(False)
-            self.buttonBox.button(
-                QDialogButtonBox.StandardButton.Cancel).setEnabled(True)
-            self.buttonBox.button(
-                QDialogButtonBox.StandardButton.Cancel).setDefault(True)
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(
+                False
+            )
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(
+                True
+            )
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setDefault(
+                True
+            )
             self.showButton.setEnabled(False)
             self.checkProgress.setVisible(True)
             QApplication.processEvents()
-            
+
             if isinstance(fn, list):
                 self.files = fn
             elif os.path.isdir(fn):
                 self.files = []
                 for ext in self.syntaxCheckService.getExtensions():
                     self.files.extend(
-                        Utilities.direntries(fn, True, '*{0}'.format(ext), 0))
+                        Utilities.direntries(fn, True, "*{0}".format(ext), 0)
+                    )
             else:
                 self.files = [fn]
-            
+
             self.__errorItem = None
             self.__clearErrors(self.files)
-            
+
             if codestring or len(self.files) > 0:
                 self.checkProgress.setMaximum(max(1, len(self.files)))
                 self.checkProgress.setVisible(len(self.files) > 1)
@@ -228,13 +233,13 @@
                 else:
                     self.__batch = True
                     self.checkBatch()
-    
-    def check(self, codestring=''):
+
+    def check(self, codestring=""):
         """
         Public method to start a check for one file.
-        
+
         The results are reported to the __processResult slot.
-        
+
         @param codestring optional sourcestring (str)
         """
         if self.syntaxCheckService is None or not self.files:
@@ -243,18 +248,18 @@
             self.checkProgress.setValue(1)
             self.__finish()
             return
-        
+
         self.filename = self.files.pop(0)
         self.checkProgress.setValue(self.progress)
         self.checkProgressLabel.setPath(self.filename)
         QApplication.processEvents()
         self.__resort()
-        
+
         if self.cancelled:
             return
-        
+
         self.__lastFileItem = None
-        
+
         if codestring:
             self.source = codestring
         else:
@@ -264,55 +269,61 @@
             except (UnicodeError, OSError) as msg:
                 self.noResults = False
                 self.__createResultItem(
-                    self.filename, 1, 0,
-                    self.tr("Error: {0}").format(str(msg))
-                    .rstrip(), "")
+                    self.filename,
+                    1,
+                    0,
+                    self.tr("Error: {0}").format(str(msg)).rstrip(),
+                    "",
+                )
                 self.progress += 1
                 # Continue with next file
                 self.check()
                 return
-        
+
         self.__finished = False
         self.syntaxCheckService.syntaxCheck(None, self.filename, self.source)
 
     def checkBatch(self):
         """
         Public method to start a style check batch job.
-        
+
         The results are reported to the __processResult slot.
         """
         self.__lastFileItem = None
-        
+
         self.checkProgressLabel.setPath(self.tr("Preparing files..."))
-        
+
         argumentsList = []
         for progress, filename in enumerate(self.files, start=1):
             self.checkProgress.setValue(progress)
             if time.monotonic() - self.__timenow > 0.01:
                 QApplication.processEvents()
                 self.__timenow = time.monotonic()
-            
+
             try:
                 source = Utilities.readEncodedFile(filename)[0]
                 source = Utilities.normalizeCode(source)
             except (UnicodeError, OSError) as msg:
                 self.noResults = False
                 self.__createResultItem(
-                    self.filename, 1, 0,
-                    self.tr("Error: {0}").format(str(msg))
-                    .rstrip(), "")
+                    self.filename,
+                    1,
+                    0,
+                    self.tr("Error: {0}").format(str(msg)).rstrip(),
+                    "",
+                )
                 continue
-            
+
             argumentsList.append((filename, source))
-        
+
         # reset the progress bar to the checked files
         self.checkProgress.setValue(self.progress)
         self.checkProgressLabel.setPath(self.tr("Transferring data..."))
         QApplication.processEvents()
-        
+
         self.__finished = False
         self.syntaxCheckService.syntaxBatchCheck(argumentsList)
-    
+
     def __batchFinished(self):
         """
         Private slot handling the completion of a batch job.
@@ -321,25 +332,25 @@
         self.checkProgress.setMaximum(1)
         self.checkProgress.setValue(1)
         self.__finish()
-    
+
     def __processError(self, fn, msg):
         """
         Private slot to process an error indication from the service.
-        
+
         @param fn filename of the file
         @type str
         @param msg error message
         @type str
         """
         self.__createErrorItem(fn, msg)
-        
+
         if not self.__batch:
             self.check()
-    
+
     def __processResult(self, fn, problems):
         """
         Private slot to display the reported messages.
-        
+
         @param fn filename of the checked file (str)
         @param problems dictionary with the keys 'error' and 'warnings' which
             hold a list containing details about the error/ warnings
@@ -348,19 +359,19 @@
         """
         if self.__finished:
             return
-        
+
         # Check if it's the requested file, otherwise ignore signal if not
         # in batch mode
         if not self.__batch and fn != self.filename:
             return
 
-        error = problems.get('error')
+        error = problems.get("error")
         if error:
             self.noResults = False
             _fn, lineno, col, code, msg = error
             self.__createResultItem(_fn, lineno, col, msg, code, False)
-        
-        warnings = problems.get('warnings', [])
+
+        warnings = problems.get("warnings", [])
         if warnings:
             if self.__batch:
                 try:
@@ -380,8 +391,7 @@
                         scr_line = ""
                 else:
                     scr_line = ""
-                self.__createResultItem(filename, lineno, col, msg, scr_line,
-                                        True)
+                self.__createResultItem(filename, lineno, col, msg, scr_line, True)
 
         self.progress += 1
         self.checkProgress.setValue(self.progress)
@@ -393,7 +403,7 @@
 
         if not self.__batch:
             self.check()
-        
+
     def __finish(self):
         """
         Private slot called when the syntax check finished or the user
@@ -401,41 +411,41 @@
         """
         if not self.__finished:
             self.__finished = True
-            
+
             self.cancelled = True
-            self.buttonBox.button(
-                QDialogButtonBox.StandardButton.Close).setEnabled(True)
-            self.buttonBox.button(
-                QDialogButtonBox.StandardButton.Cancel).setEnabled(False)
-            self.buttonBox.button(
-                QDialogButtonBox.StandardButton.Close).setDefault(True)
-            
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setEnabled(
+                True
+            )
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel).setEnabled(
+                False
+            )
+            self.buttonBox.button(QDialogButtonBox.StandardButton.Close).setDefault(
+                True
+            )
+
             if self.noResults:
-                QTreeWidgetItem(self.resultList, [self.tr('No issues found.')])
+                QTreeWidgetItem(self.resultList, [self.tr("No issues found.")])
                 QApplication.processEvents()
                 self.showButton.setEnabled(False)
             else:
                 self.showButton.setEnabled(True)
             self.resultList.header().resizeSections(
-                QHeaderView.ResizeMode.ResizeToContents)
+                QHeaderView.ResizeMode.ResizeToContents
+            )
             self.resultList.header().setStretchLastSection(True)
-            
+
             self.checkProgress.setVisible(False)
             self.checkProgressLabel.setVisible(False)
-        
+
     def on_buttonBox_clicked(self, button):
         """
         Private slot called by a button of the button box clicked.
-        
+
         @param button button that was clicked (QAbstractButton)
         """
-        if button == self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Close
-        ):
+        if button == self.buttonBox.button(QDialogButtonBox.StandardButton.Close):
             self.close()
-        elif button == self.buttonBox.button(
-            QDialogButtonBox.StandardButton.Cancel
-        ):
+        elif button == self.buttonBox.button(QDialogButtonBox.StandardButton.Cancel):
             if self.__batch:
                 self.syntaxCheckService.cancelSyntaxBatchCheck()
                 QTimer.singleShot(1000, self.__finish)
@@ -443,56 +453,52 @@
                 self.__finish()
         elif button == self.showButton:
             self.on_showButton_clicked()
-        
+
     @pyqtSlot()
     def on_startButton_clicked(self):
         """
         Private slot to start a syntax check run.
         """
         fileList = self.__fileList[:]
-        
+
         filterString = self.excludeFilesEdit.text()
         if (
-            "ExcludeFiles" not in self.__data or
-            filterString != self.__data["ExcludeFiles"]
+            "ExcludeFiles" not in self.__data
+            or filterString != self.__data["ExcludeFiles"]
         ):
             self.__data["ExcludeFiles"] = filterString
-            self.__project.setData("CHECKERSPARMS", "SyntaxChecker",
-                                   self.__data)
-        filterList = [f.strip() for f in filterString.split(",")
-                      if f.strip()]
+            self.__project.setData("CHECKERSPARMS", "SyntaxChecker", self.__data)
+        filterList = [f.strip() for f in filterString.split(",") if f.strip()]
         if filterList:
             for fileFilter in filterList:
-                fileList = [
-                    f for f in fileList if not fnmatch.fnmatch(f, fileFilter)
-                ]
-        
+                fileList = [f for f in fileList if not fnmatch.fnmatch(f, fileFilter)]
+
         self.resultList.clear()
         self.noResults = True
         self.cancelled = False
         self.start(fileList)
-        
+
     def on_resultList_itemActivated(self, itm, col):
         """
         Private slot to handle the activation of an item.
-        
+
         @param itm reference to the activated item (QTreeWidgetItem)
         @param col column the item was activated in (integer)
         """
         if self.noResults:
             return
-        
+
         vm = ericApp().getObject("ViewManager")
-        
+
         if itm.parent():
             fn = os.path.abspath(itm.data(0, self.filenameRole))
             lineno = itm.data(0, self.lineRole)
             index = itm.data(0, self.indexRole)
             error = itm.data(0, self.errorRole)
-            
+
             vm.openSourceFile(fn, lineno)
             editor = vm.getOpenEditor(fn)
-            
+
             if itm.data(0, self.warningRole):
                 editor.toggleWarning(lineno, 0, True, error)
             else:
@@ -509,19 +515,18 @@
                 if citm.data(0, self.warningRole):
                     editor.toggleWarning(lineno, 0, True, error)
                 else:
-                    editor.toggleSyntaxError(
-                        lineno, index, True, error, show=True)
-        
+                    editor.toggleSyntaxError(lineno, index, True, error, show=True)
+
         editor = vm.activeWindow()
         editor.updateVerticalScrollBar()
-        
+
     @pyqtSlot()
     def on_showButton_clicked(self):
         """
         Private slot to handle the "Show" button press.
         """
         vm = ericApp().getObject("ViewManager")
-        
+
         selectedIndexes = []
         for index in range(self.resultList.topLevelItemCount()):
             if self.resultList.topLevelItem(index).isSelected():
@@ -543,31 +548,29 @@
                 if citm.data(0, self.warningRole):
                     editor.toggleWarning(lineno, 0, True, error)
                 else:
-                    editor.toggleSyntaxError(
-                        lineno, index, True, error, show=True)
-        
+                    editor.toggleSyntaxError(lineno, index, True, error, show=True)
+
         # go through the list again to clear syntax error and
         # flakes warning markers for files, that are ok
         openFiles = vm.getOpenFilenames()
         errorFiles = []
         for index in range(self.resultList.topLevelItemCount()):
             itm = self.resultList.topLevelItem(index)
-            errorFiles.append(
-                os.path.abspath(itm.data(0, self.filenameRole)))
+            errorFiles.append(os.path.abspath(itm.data(0, self.filenameRole)))
         for file in openFiles:
             if file not in errorFiles:
                 editor = vm.getOpenEditor(file)
                 editor.clearSyntaxError()
                 editor.clearFlakesWarnings()
-        
+
         editor = vm.activeWindow()
         editor.updateVerticalScrollBar()
-        
+
     def __clearErrors(self, files):
         """
         Private method to clear all error and warning markers of
         open editors to be checked.
-        
+
         @param files list of files to be checked (list of string)
         """
         vm = ericApp().getObject("ViewManager")

eric ide

mercurial