Continued refactoring of the project browser related code in order to extract some as plugins later on. eric7

Thu, 17 Nov 2022 18:11:42 +0100

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Thu, 17 Nov 2022 18:11:42 +0100
branch
eric7
changeset 9517
d73c3a1e432b
parent 9516
0f023e61a9b5
child 9518
cbccd588d48e

Continued refactoring of the project browser related code in order to extract some as plugins later on.

src/eric7/Debugger/DebugUI.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/ImportsDiagramBuilder.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/PackageDiagramBuilder.py file | annotate | diff | comparison | revisions
src/eric7/Graphics/UMLClassDiagramBuilder.py file | annotate | diff | comparison | revisions
src/eric7/JediInterface/JediServer.py file | annotate | diff | comparison | revisions
src/eric7/Preferences/ConfigurationPages/ProjectPage.ui file | annotate | diff | comparison | revisions
src/eric7/Project/Project.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectBrowser.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectFormsBrowser.py file | annotate | diff | comparison | revisions
src/eric7/Project/ProjectResourcesBrowser.py file | annotate | diff | comparison | revisions
src/eric7/QScintilla/Editor.py file | annotate | diff | comparison | revisions
src/eric7/Tasks/TaskViewer.py file | annotate | diff | comparison | revisions
src/eric7/UI/FindFileWidget.py file | annotate | diff | comparison | revisions
src/eric7/UI/FindFileWidget.ui file | annotate | diff | comparison | revisions
src/eric7/UI/UserInterface.py file | annotate | diff | comparison | revisions
--- a/src/eric7/Debugger/DebugUI.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Debugger/DebugUI.py	Thu Nov 17 18:11:42 2022 +0100
@@ -38,11 +38,6 @@
 
     @signal clientStack(stack, debuggerId) emitted at breaking after a reported
         exception
-    @signal compileForms() emitted if changed project forms should be compiled
-    @signal compileResources() emitted if changed project resources should be
-        compiled
-    @signal executeMake() emitted if a project specific make run should be
-        performed
     @signal debuggingStarted(filename) emitted when a debugging session was
         started
     @signal resetUI(full) emitted to reset the UI partially or fully
@@ -50,16 +45,16 @@
         by an exception and acknowledged by the user
     @signal appendStdout(msg) emitted when the client program has terminated
         and the display of the termination dialog is suppressed
+    @signal processChangedProjectFiles() emitted to indicate, that changed project files
+        should be processed
     """
 
     clientStack = pyqtSignal(list, str)
     resetUI = pyqtSignal(bool)
     exceptionInterrupt = pyqtSignal()
-    compileForms = pyqtSignal()
-    compileResources = pyqtSignal()
-    executeMake = pyqtSignal()
     debuggingStarted = pyqtSignal(str)
     appendStdout = pyqtSignal(str)
+    processChangedProjectFiles = pyqtSignal()
 
     def __init__(self, ui, vm, debugServer, debugViewer, project):
         """
@@ -1907,19 +1902,6 @@
         line = qvList[1]
         self.viewmanager.openSourceFile(filename, line)
 
-    def __compileChangedProjectFiles(self):
-        """
-        Private method to signal compilation of changed forms and resources
-        is wanted.
-        """
-        if Preferences.getProject("AutoCompileForms"):
-            self.compileForms.emit()
-        if Preferences.getProject("AutoCompileResources"):
-            self.compileResources.emit()
-        if Preferences.getProject("AutoExecuteMake"):
-            self.executeMake.emit()
-        QApplication.processEvents()
-
     def __coverageScript(self):
         """
         Private slot to handle the coverage of script action.
@@ -1930,7 +1912,7 @@
         """
         Private slot to handle the coverage of project action.
         """
-        self.__compileChangedProjectFiles()
+        self.processChangedProjectFiles.emit()
         self.doCoverage(True)
 
     def doCoverage(self, runProject, script=""):
@@ -2134,7 +2116,7 @@
         """
         Private slot to handle the profile project action.
         """
-        self.__compileChangedProjectFiles()
+        self.processChangedProjectFiles.emit()
         self.doProfile(True)
 
     def doProfile(self, runProject, script=""):
@@ -2338,7 +2320,7 @@
         """
         Private slot to handle the run project action.
         """
-        self.__compileChangedProjectFiles()
+        self.processChangedProjectFiles.emit()
         self.doRun(True)
 
     def doRun(self, runProject, script=""):
@@ -2533,7 +2515,7 @@
         """
         Private slot to handle the debug project action.
         """
-        self.__compileChangedProjectFiles()
+        self.processChangedProjectFiles.emit()
         self.doDebug(True)
 
     def doDebug(self, debugProject, script=""):
@@ -2788,7 +2770,7 @@
                 reportSyntaxErrors=True
             ):
                 doNotStart = True
-            self.__compileChangedProjectFiles()
+            self.processChangedProjectFiles.emit()
             forProject = True
         else:
             return  # should not happen
--- a/src/eric7/Graphics/ImportsDiagramBuilder.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Graphics/ImportsDiagramBuilder.py	Thu Nov 17 18:11:42 2022 +0100
@@ -52,7 +52,7 @@
 
         self.__relPackagePath = (
             self.project.getRelativePath(self.packagePath)
-            if self.project.isProjectSource(self.packagePath)
+            if self.project.isProjectCategory(self.packagePath, "SOURCES")
             else ""
         )
 
--- a/src/eric7/Graphics/PackageDiagramBuilder.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Graphics/PackageDiagramBuilder.py	Thu Nov 17 18:11:42 2022 +0100
@@ -49,7 +49,7 @@
 
         self.__relPackage = (
             self.project.getRelativePath(self.package)
-            if self.project.isProjectSource(self.package)
+            if self.project.isProjectCategory(self.package, "SOURCES")
             else ""
         )
 
--- a/src/eric7/Graphics/UMLClassDiagramBuilder.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Graphics/UMLClassDiagramBuilder.py	Thu Nov 17 18:11:42 2022 +0100
@@ -46,7 +46,7 @@
 
         self.__relFile = (
             self.project.getRelativePath(self.file)
-            if self.project.isProjectSource(self.file)
+            if self.project.isProjectCategory(self.file, "SOURCES")
             else ""
         )
 
@@ -59,7 +59,7 @@
             self.tr("Class Diagram {0}: {1}").format(
                 pname, self.project.getRelativePath(self.file)
             )
-            if pname and self.project.isProjectSource(self.file)
+            if pname and self.project.isProjectCategory(self.file, "SOURCES")
             else self.tr("Class Diagram: {0}").format(self.file)
         )
         self.umlView.setDiagramName(name)
--- a/src/eric7/JediInterface/JediServer.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/JediInterface/JediServer.py	Thu Nov 17 18:11:42 2022 +0100
@@ -141,7 +141,7 @@
             and self.__ericProject.getProjectLanguage() == language
         ):
             filename = editor.getFileName()
-            if self.__ericProject.isProjectSource(filename):
+            if self.__ericProject.isProjectCategory(filename, "SOURCES"):
                 idString = JediServer.IdProject
 
         if not idString and language in self.__editorLanguageMapping:
--- a/src/eric7/Preferences/ConfigurationPages/ProjectPage.ui	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Preferences/ConfigurationPages/ProjectPage.ui	Thu Nov 17 18:11:42 2022 +0100
@@ -179,7 +179,7 @@
    <item>
     <widget class="QGroupBox" name="groupBox_5">
      <property name="title">
-      <string>Automatisations</string>
+      <string>Automations</string>
      </property>
      <layout class="QGridLayout" name="gridLayout">
       <item row="0" column="0">
--- a/src/eric7/Project/Project.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Project/Project.py	Thu Nov 17 18:11:42 2022 +0100
@@ -67,26 +67,11 @@
     Class implementing the project management functionality.
 
     @signal dirty(bool) emitted when the dirty state changes
-    @signal projectLanguageAdded(str) emitted after a new language was added
+    @signal projectFileAdded(str, str) emitted after a new file was added
+    @signal projectFileRemoved(str, str) emitted after a file of the project was removed
+    @signal projectFileCompiled(str, str) emitted after a form was compiled
     @signal projectLanguageAddedByCode(str) emitted after a new language was
         added. The language code is sent by this signal.
-    @signal projectLanguageRemoved(str) emitted after a language was removed
-    @signal projectFormAdded(str) emitted after a new form was added
-    @signal projectFormRemoved(str) emitted after a form was removed
-    @signal projectFormCompiled(str) emitted after a form was compiled
-    @signal projectSourceAdded(str) emitted after a new source file was added
-    @signal projectSourceRemoved(str) emitted after a source was removed
-    @signal projectInterfaceAdded(str) emitted after a new IDL file was added
-    @signal projectInterfaceRemoved(str) emitted after a IDL file was removed
-    @signal projectProtocolAdded(str) emitted after a new proto file was added
-    @signal projectProtocolRemoved(str) emitted after a proto file was removed
-    @signal projectResourceAdded(str) emitted after a new resource file was
-        added
-    @signal projectResourceRemoved(str) emitted after a resource was removed
-    @signal projectOthersAdded(str) emitted after a file or directory was added
-        to the OTHERS project data area
-    @signal projectOthersRemoved(str) emitted after a file was removed from the
-        OTHERS project data area
     @signal projectAboutToBeCreated() emitted just before the project will be
         created
     @signal newProjectHooks() emitted after a new project was generated but
@@ -131,25 +116,15 @@
         a QProcess on stdout
     @signal appendStderr(str) emitted after something was received from
         a QProcess on stderr
+    @signal processChangedProjectFiles() emitted to indicate, that changed project files
+        should be processed
     """
 
     dirty = pyqtSignal(bool)
-    projectLanguageAdded = pyqtSignal(str)
+    projectFileAdded = pyqtSignal(str, str)
+    projectFileRemoved = pyqtSignal(str, str)
+    projectFileCompiled = pyqtSignal(str, str)
     projectLanguageAddedByCode = pyqtSignal(str)
-    projectLanguageRemoved = pyqtSignal(str)
-    projectFormAdded = pyqtSignal(str)
-    projectFormRemoved = pyqtSignal(str)
-    projectFormCompiled = pyqtSignal(str)
-    projectSourceAdded = pyqtSignal(str)
-    projectSourceRemoved = pyqtSignal(str)
-    projectInterfaceAdded = pyqtSignal(str)
-    projectInterfaceRemoved = pyqtSignal(str)
-    projectProtocolAdded = pyqtSignal(str)
-    projectProtocolRemoved = pyqtSignal(str)
-    projectResourceAdded = pyqtSignal(str)
-    projectResourceRemoved = pyqtSignal(str)
-    projectOthersAdded = pyqtSignal(str)
-    projectOthersRemoved = pyqtSignal(str)
     projectAboutToBeCreated = pyqtSignal()
     newProjectHooks = pyqtSignal()
     newProject = pyqtSignal()
@@ -176,6 +151,7 @@
     projectChanged = pyqtSignal()
     appendStdout = pyqtSignal(str)
     appendStderr = pyqtSignal(str)
+    processChangedProjectFiles = pyqtSignal()
 
     eols = [os.linesep, "\n", "\r", "\r\n"]
 
@@ -236,6 +212,8 @@
         self.loadedDiagram = None
         self.__findProjectFileDialog = None
 
+        self.processChangedProjectFiles.connect(self.__autoExecuteMake)
+
     def __sourceExtensions(self, language):
         """
         Private method to get the source extensions of a programming language.
@@ -548,7 +526,8 @@
             "LICENSE": "",
             "EMBEDDED_VENV": False,
         }
-        # TODO: Move these to a file categories repository
+        # TODO: Move these to a file categories repository populated through the
+        #       project browsers
         self.__knownFileCategories = [
             "FORMS",
             "OTHERS",
@@ -585,6 +564,16 @@
             "INTERFACES": self.tr("Interfaces"),
             "PROTOCOLS": self.tr("Protocols"),
         }
+        self.__fileCategoryExtensions = {
+            "FORMS": ["*.ui"],
+            "OTHERS": [],
+            "RESOURCES": ["*.qrc"],
+            "SOURCES": ["*.py", "*.pyw"],  # Python files as default
+            "TRANSLATIONS": ["*.ts", "*.qm"],
+            "INTERFACES": ["*.idl"],
+            "PROTOCOLS": ["*.proto"],
+        }
+        # until here
 
         self.__initDebugProperties()
 
@@ -623,7 +612,7 @@
     def setProjectData(self, data, dataKey=None, setDirty=True):
         """
         Public method to set data associated with the given data key in the project
-        dictionary
+        dictionary.
 
         Note: If no data key is given or is None, the data must be a dictionary used
         to update the project data.
@@ -781,6 +770,27 @@
         """
         return self.__fileCategoryTyeStrings[category]
 
+    def getFileCategoryExtension(self, category, reverse=False):
+        """
+        Public method to get a list of default file extensions for the given category.
+
+        @param category file type category
+        @type str
+        @param reverse flag indicating to get all other extensions except the one of
+            the given category
+        @type bool
+        @return list of default file extensions for the category
+        @rtype list of str
+        """
+        if reverse:
+            extensions = []
+            for cat, ext in self.__fileCategoryExtensions.items():
+                if cat != category:
+                    extensions += ext
+            return extensions
+        else:
+            return self.__fileCategoryExtensions[category][:]
+
     def initFileTypes(self):
         """
         Public method to initialize the filetype associations with default
@@ -1077,26 +1087,12 @@
             # project directory
             for fileCategory in self.__knownFileCategories:
                 self.__checkFilesExist(fileCategory)
-            ##self.__checkFilesExist("SOURCES")
-            ##self.__checkFilesExist("FORMS")
-            ##self.__checkFilesExist("INTERFACES")
-            ##self.__checkFilesExist("PROTOCOLS")
-            ##self.__checkFilesExist("TRANSLATIONS")
-            ##self.__checkFilesExist("RESOURCES")
-            ##self.__checkFilesExist("OTHERS")
 
             # get the names of subdirectories the files are stored in
             for fileCategory in [
                 c for c in self.__knownFileCategories if c != "OTHERS"
             ]:
                 for fn in self.__pdata[fileCategory]:
-                    ##self.__pdata["SOURCES"]
-                    ##+ self.__pdata["FORMS"]
-                    ##+ self.__pdata["INTERFACES"]
-                    ##+ self.__pdata["PROTOCOLS"]
-                    ##+ self.__pdata["RESOURCES"]
-                    ##+ self.__pdata["TRANSLATIONS"]
-                    ##):
                     dn = os.path.dirname(fn)
                     if dn not in self.subdirs:
                         self.subdirs.append(dn)
@@ -1819,59 +1815,29 @@
         if filetype == "__IGNORE__":
             return
 
-        # TODO: change this logic to be more generic (use fileCategory)
-        if filetype in ["SOURCES", "FORMS", "INTERFACES", "PROTOCOLS", "RESOURCES"]:
-            if filetype == "SOURCES":
-                if newfn not in self.__pdata["SOURCES"]:
-                    self.__pdata["SOURCES"].append(newfn)
-                    self.projectSourceAdded.emit(newfn)
-                    updateModel and self.__model.addNewItem("SOURCES", newfn)
-                    dirty = True
-                else:
-                    updateModel and self.repopulateItem(newfn)
-            elif filetype == "FORMS":
-                if newfn not in self.__pdata["FORMS"]:
-                    self.__pdata["FORMS"].append(newfn)
-                    self.projectFormAdded.emit(newfn)
-                    updateModel and self.__model.addNewItem("FORMS", newfn)
-                    dirty = True
-                else:
-                    updateModel and self.repopulateItem(newfn)
-            elif filetype == "INTERFACES":
-                if newfn not in self.__pdata["INTERFACES"]:
-                    self.__pdata["INTERFACES"].append(newfn)
-                    self.projectInterfaceAdded.emit(newfn)
-                    (updateModel and self.__model.addNewItem("INTERFACES", newfn))
-                    dirty = True
-                else:
-                    updateModel and self.repopulateItem(newfn)
-            elif filetype == "PROTOCOLS":
-                if newfn not in self.__pdata["PROTOCOLS"]:
-                    self.__pdata["PROTOCOLS"].append(newfn)
-                    self.projectProtocolAdded.emit(newfn)
-                    (updateModel and self.__model.addNewItem("PROTOCOLS", newfn))
-                    dirty = True
-                else:
-                    updateModel and self.repopulateItem(newfn)
-            elif filetype == "RESOURCES":
-                if newfn not in self.__pdata["RESOURCES"]:
-                    self.__pdata["RESOURCES"].append(newfn)
-                    self.projectResourceAdded.emit(newfn)
-                    updateModel and self.__model.addNewItem("RESOURCES", newfn)
-                    dirty = True
-                else:
-                    updateModel and self.repopulateItem(newfn)
+        if filetype in (
+            category
+            for category in self.getFileCategories()
+            if category not in ("TRANSLATIONS", "OTHERS")
+        ):
+            if newfn not in self.__pdata[filetype]:
+                self.__pdata[filetype].append(newfn)
+                self.projectFileAdded.emit(newfn, filetype)
+                updateModel and self.__model.addNewItem(filetype, newfn)
+                dirty = True
+            else:
+                updateModel and self.repopulateItem(newfn)
             if newdir not in self.subdirs:
                 self.subdirs.append(newdir)
         elif filetype == "TRANSLATIONS":
             if newfn not in self.__pdata["TRANSLATIONS"]:
                 self.__pdata["TRANSLATIONS"].append(newfn)
                 updateModel and self.__model.addNewItem("TRANSLATIONS", newfn)
-                self.projectLanguageAdded.emit(newfn)
+                self.projectFileAdded.emit(newfn, "TRANSLATIONS")
                 dirty = True
             else:
                 updateModel and self.repopulateItem(newfn)
-        else:  # filetype == "OTHERS"
+        elif filetype == "OTHERS":
             if newfn not in self.__pdata["OTHERS"]:
                 self.__pdata["OTHERS"].append(newfn)
                 self.othersAdded(newfn, updateModel)
@@ -2121,82 +2087,6 @@
             if os.path.isdir(fn) and fn not in self.otherssubdirs:
                 self.otherssubdirs.append(fn)
 
-    ##def addSourceFiles(self):
-        ##"""
-        ##Public slot to add source files to the current project.
-        ##"""
-        ##self.addFiles("source")
-##
-    ##def addUiFiles(self):
-        ##"""
-        ##Public slot to add forms to the current project.
-        ##"""
-        ##self.addFiles("form")
-##
-    ##def addIdlFiles(self):
-        ##"""
-        ##Public slot to add IDL interfaces to the current project.
-        ##"""
-        ##self.addFiles("interface")
-##
-    ##def addProtoFiles(self):
-        ##"""
-        ##Public slot to add protocol files to the current project.
-        ##"""
-        ##self.addFiles("protocol")
-##
-    ##def addResourceFiles(self):
-        ##"""
-        ##Public slot to add Qt resources to the current project.
-        ##"""
-        ##self.addFiles("resource")
-##
-    ##def addOthersFiles(self):
-        ##"""
-        ##Public slot to add files to the OTHERS project data.
-        ##"""
-        ##self.addFiles("others")
-##
-    ##def addSourceDir(self):
-        ##"""
-        ##Public slot to add all source files of a directory to the current
-        ##project.
-        ##"""
-        ##self.addDirectory("source")
-##
-    ##def addUiDir(self):
-        ##"""
-        ##Public slot to add all forms of a directory to the current project.
-        ##"""
-        ##self.addDirectory("form")
-##
-    ##def addIdlDir(self):
-        ##"""
-        ##Public slot to add all IDL interfaces of a directory to the current
-        ##project.
-        ##"""
-        ##self.addDirectory("interface")
-##
-    ##def addProtoDir(self):
-        ##"""
-        ##Public slot to add all protocol files of a directory to the current
-        ##project.
-        ##"""
-        ##self.addDirectory("protocol")
-##
-    ##def addResourceDir(self):
-        ##"""
-        ##Public slot to add all Qt resource files of a directory to the current
-        ##project.
-        ##"""
-        ##self.addDirectory("resource")
-##
-    ##def addOthersDir(self):
-        ##"""
-        ##Public slot to add a directory to the OTHERS project data.
-        ##"""
-        ##self.addDirectory("others")
-##
     def renameMainScript(self, oldfn, newfn):
         """
         Public method to rename the main script.
@@ -2262,15 +2152,6 @@
             )
             return False
 
-        ##if (
-        ##fn in self.__pdata["SOURCES"]
-        ##or fn in self.__pdata["FORMS"]
-        ##or fn in self.__pdata["TRANSLATIONS"]
-        ##or fn in self.__pdata["INTERFACES"]
-        ##or fn in self.__pdata["PROTOCOLS"]
-        ##or fn in self.__pdata["RESOURCES"]
-        ##or fn in self.__pdata["OTHERS"]
-        ##):
         if any(fn in self.__pdata[category] for category in self.__knownFileCategories):
             self.renameFileInPdata(oldfn, newfn, isSourceFile)
 
@@ -2307,14 +2188,6 @@
         """
         filelist = []
         start = self.getRelativePath(start)
-        ##for key in [
-        ##"SOURCES",
-        ##"FORMS",
-        ##"INTERFACES",
-        ##"PROTOCOLS",
-        ##"RESOURCES",
-        ##"OTHERS",
-        ##]:
         for fileCategory in [
             c for c in self.__knownFileCategories if c != "TRANSLATIONS"
         ]:
@@ -2331,28 +2204,10 @@
 
         # init data store for the reorganization
         newPdata = {}
-        ##for key in [
-        ##"SOURCES",
-        ##"FORMS",
-        ##"INTERFACES",
-        ##"PROTOCOLS",
-        ##"RESOURCES",
-        ##"OTHERS",
-        ##"TRANSLATIONS",
-        ##]:
         for fileCategory in self.__knownFileCategories:
             newPdata[fileCategory] = []
 
         # iterate over all files checking for a reassignment
-        ##for key in [
-        ##"SOURCES",
-        ##"FORMS",
-        ##"INTERFACES",
-        ##"PROTOCOLS",
-        ##"RESOURCES",
-        ##"OTHERS",
-        ##"TRANSLATIONS",
-        ##]:
         for fileCategory in self.__knownFileCategories:
             for fn in self.__pdata[fileCategory][:]:
                 filetype = fileCategory
@@ -2469,34 +2324,14 @@
             requested (boolean)
         """
         fn = self.getRelativePath(fn)
-        dirty = True
-        # TODO: change this logic to be more generic (use fileCategory)
-        if fn in self.__pdata["SOURCES"]:
-            self.__pdata["SOURCES"].remove(fn)
-            self.projectSourceRemoved.emit(fn)
-        elif fn in self.__pdata["FORMS"]:
-            self.__pdata["FORMS"].remove(fn)
-            self.projectFormRemoved.emit(fn)
-        elif fn in self.__pdata["INTERFACES"]:
-            self.__pdata["INTERFACES"].remove(fn)
-            self.projectInterfaceRemoved.emit(fn)
-        elif fn in self.__pdata["PROTOCOLS"]:
-            self.__pdata["PROTOCOLS"].remove(fn)
-            self.projectProtocolRemoved.emit(fn)
-        elif fn in self.__pdata["RESOURCES"]:
-            self.__pdata["RESOURCES"].remove(fn)
-            self.projectResourceRemoved.emit(fn)
-        elif fn in self.__pdata["OTHERS"]:
-            self.__pdata["OTHERS"].remove(fn)
-            self.projectOthersRemoved.emit(fn)
-        elif fn in self.__pdata["TRANSLATIONS"]:
-            self.__pdata["TRANSLATIONS"].remove(fn)
-            self.projectLanguageRemoved.emit(fn)
-        else:
-            dirty = False
-        updateModel and self.__model.removeItem(fn)
-        if dirty:
-            self.setDirty(True)
+        for fileCategory in self.getFileCategories():
+            if fn in self.__pdata[fileCategory]:
+                self.__pdata[fileCategory].remove(fn)
+                self.projectFileRemoved(fn, fileCategory)
+                self.setDirty(True)
+                if updateModel:
+                    self.__model.removeItem(fn)
+                break
 
     def removeDirectory(self, dn):
         """
@@ -2513,14 +2348,6 @@
                 self.__pdata["OTHERS"].remove(entry)
                 dirty = True
         dn2 = dn if dn.endswith(os.sep) else dn + os.sep
-        ##for key in [
-        ##"SOURCES",
-        ##"FORMS",
-        ##"INTERFACES",
-        ##"PROTOCOLS",
-        ##"RESOURCES",
-        ##"TRANSLATIONS",
-        ##]:
         for fileCategory in [c for c in self.__knownFileCategories if c != "OTHERS"]:
             for entry in self.__pdata[fileCategory][:]:
                 if entry.startswith(dn2):
@@ -2619,13 +2446,6 @@
             for category in self.__knownFileCategories
             if category != "TRANSLATIONS"
         )
-        ##fn in self.__pdata["SOURCES"]
-        ##or fn in self.__pdata["FORMS"]
-        ##or fn in self.__pdata["INTERFACES"]
-        ##or fn in self.__pdata["PROTOCOLS"]
-        ##or fn in self.__pdata["RESOURCES"]
-        ##or fn in self.__pdata["OTHERS"]
-        ##)
 
     def createNewProject(self):
         """
@@ -3049,7 +2869,7 @@
                     for ts in tslist:
                         if fnmatch.fnmatch(ts, pattern):
                             self.__pdata["TRANSLATIONS"].append(ts)
-                            self.projectLanguageAdded.emit(ts)
+                            self.projectFileAdded.emit(ts, "TRANSLATIONS")
                     if self.__pdata["TRANSLATIONSBINPATH"]:
                         tpd = os.path.join(
                             self.ppath, self.__pdata["TRANSLATIONSBINPATH"]
@@ -3061,7 +2881,7 @@
                         qmlist = Utilities.direntries(tpd, True, pattern)
                         for qm in qmlist:
                             self.__pdata["TRANSLATIONS"].append(qm)
-                            self.projectLanguageAdded.emit(qm)
+                            self.projectFileAdded.emit(qm, "TRANSLATIONS")
                 if not self.__pdata["MAINSCRIPT"] and bool(mainscriptname):
                     if self.__pdata["PROGLANGUAGE"] in ["Python3", "MicroPython"]:
                         self.__pdata["MAINSCRIPT"] = "{0}.py".format(mainscriptname)
@@ -3773,15 +3593,6 @@
         @exception ValueError raised when an unsupported file type is given
         """
         if fileType not in self.__knownFileCategories:
-            ##[
-            ##"SOURCES",
-            ##"FORMS",
-            ##"RESOURCES",
-            ##"INTERFACES",
-            ##"PROTOCOLS",
-            ##"OTHERS",
-            ##"TRANSLATIONS",
-            ##]:
             raise ValueError("Given file type has incorrect value.")
 
         if normalized:
@@ -4197,15 +4008,6 @@
         return any(
             newfn in self.__pdata[category]
             for category in self.__knownFileCategories
-            ##[
-            ##"SOURCES",
-            ##"FORMS",
-            ##"INTERFACES",
-            ##"PROTOCOLS",
-            ##"RESOURCES",
-            ##"TRANSLATIONS",
-            ##"OTHERS",
-            ##]
         )
 
     def isProjectFile(self, fn):
@@ -4219,15 +4021,6 @@
         return any(
             self.__checkProjectFileGroup(fn, category)
             for category in self.__knownFileCategories
-            ##[
-            ##"SOURCES",
-            ##"FORMS",
-            ##"INTERFACES",
-            ##"PROTOCOLS",
-            ##"RESOURCES",
-            ##"TRANSLATIONS",
-            ##"OTHERS",
-            ##]
         )
 
     def __checkProjectFileGroup(self, fn, group):
@@ -4260,58 +4053,22 @@
 
         return False
 
-    # TODO: change the following methods to a more generic logic using fileCategories
-    def isProjectSource(self, fn):
-        """
-        Public method used to check, if the passed in filename belongs to the
-        project sources.
-
-        @param fn filename to be checked (string)
-        @return flag indicating membership (boolean)
-        """
-        return self.__checkProjectFileGroup(fn, "SOURCES")
-
-    def isProjectForm(self, fn):
-        """
-        Public method used to check, if the passed in filename belongs to the
-        project forms.
-
-        @param fn filename to be checked (string)
-        @return flag indicating membership (boolean)
-        """
-        return self.__checkProjectFileGroup(fn, "FORMS")
-
-    def isProjectInterface(self, fn):
-        """
-        Public method used to check, if the passed in filename belongs to the
-        project interfaces.
-
-        @param fn filename to be checked (string)
-        @return flag indicating membership (boolean)
-        """
-        return self.__checkProjectFileGroup(fn, "INTERFACES")
-
-    def isProjectProtocol(self, fn):
-        """
-        Public method used to check, if the passed in filename belongs to the
-        project protocols.
+    def isProjectCategory(self, fn, category):
+        """
+        Public method to check, if the passed in filename belongs to the given
+        category.
 
         @param fn filename to be checked
         @type str
+        @param category file category to check against
+        @type str
         @return flag indicating membership
         @rtype bool
         """
-        return self.__checkProjectFileGroup(fn, "PROTOCOLS")
-
-    def isProjectResource(self, fn):
-        """
-        Public method used to check, if the passed in filename belongs to the
-        project resources.
-
-        @param fn filename to be checked (string)
-        @return flag indicating membership (boolean)
-        """
-        return self.__checkProjectFileGroup(fn, "RESOURCES")
+        if category in self.getFileCategories():
+            return self.__checkProjectFileGroup(fn, category)
+        else:
+            return False  # unknown category always returns False
 
     def initActions(self):
         """
@@ -5767,21 +5524,6 @@
                         )
                     )
                 ):
-                    ##(filetype == "SOURCES" and fn not in self.__pdata["SOURCES"])
-                    ##or (filetype == "FORMS" and fn not in self.__pdata["FORMS"])
-                    ##or (filetype == "INTERFACES" and fn not in self.__pdata["INTERFACES"])
-                    ##or (filetype == "PROTOCOLS" and fn not in self.__pdata["PROTOCOLS"])
-                    ##or (filetype == "RESOURCES" and fn not in self.__pdata["RESOURCES"])
-                    ##or (filetype == "OTHERS" and fn not in self.__pdata["OTHERS"])
-                    ##or (
-                    ##filetype == "TRANSLATIONS"
-                    ##and fn not in self.__pdata["TRANSLATIONS"]
-                    ##and (
-                    ##fnmatch.fnmatch(ns, pattern)
-                    ##or fnmatch.fnmatch(ns, binpattern)
-                    ##)
-                    ##)
-                    ##):
                     if autoInclude and AI:
                         self.appendFile(ns)
                     else:
@@ -5825,7 +5567,7 @@
         @param updateModel flag indicating an update of the model is requested
             (boolean)
         """
-        self.projectOthersAdded.emit(fn)
+        self.projectFileAdded.emit(fn, "OTHERS")
         updateModel and self.__model.addNewItem("OTHERS", fn)
 
     def getActions(self):
@@ -6352,15 +6094,6 @@
         # build the list of entries
         lst_ = []
         for key in self.__knownFileCategories:
-            ##[
-            ##"SOURCES",
-            ##"FORMS",
-            ##"RESOURCES",
-            ##"TRANSLATIONS",
-            ##"INTERFACES",
-            ##"PROTOCOLS",
-            ##"OTHERS",
-            ##]:
             lst_.extend(self.__pdata[key])
         lst = []
         for entry in lst_:
@@ -6746,14 +6479,16 @@
         return self.__pdata["MAKEPARAMS"]["MakeEnabled"]
 
     @pyqtSlot()
-    def executeMake(self):
-        """
-        Public slot to execute a project specific make run (auto-run)
+    def __autoExecuteMake(self):
+        """
+        Private slot to execute a project specific make run (auto-run)
         (execute or question).
         """
-        self.__executeMake(
-            questionOnly=self.__pdata["MAKEPARAMS"]["MakeTestOnly"], interactive=False
-        )
+        if Preferences.getProject("AutoExecuteMake"):
+            self.__executeMake(
+                questionOnly=self.__pdata["MAKEPARAMS"]["MakeTestOnly"],
+                interactive=False,
+            )
 
     @pyqtSlot()
     def __executeMake(self, questionOnly=False, interactive=True):
--- a/src/eric7/Project/ProjectBrowser.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Project/ProjectBrowser.py	Thu Nov 17 18:11:42 2022 +0100
@@ -78,6 +78,8 @@
         (list of str, bool)
     @signal uipreview(str) emitted to preview a forms file
     @signal umlFile(filename) emitted to open an eric UML file (str)
+    @signal processChangedProjectFiles() emitted to indicate, that changed project files
+        should be processed
     """
 
     appendStderr = pyqtSignal(str)
@@ -95,6 +97,7 @@
     trpreview = pyqtSignal((list,), (list, bool))
     uipreview = pyqtSignal(str)
     umlFile = pyqtSignal(str)
+    processChangedProjectFiles = pyqtSignal()
 
     def __init__(self, project, parent=None):
         """
@@ -309,19 +312,18 @@
         """
         Public slot to handle the editorChanged signal.
 
-        @param fn filename of the changed file (string)
+        @param fn filename of the changed file
+        @type str
         """
         if Preferences.getProject("FollowEditor"):
-            if self.project.isProjectSource(fn):
-                self.__browsers["sources"].selectFile(fn)
-            elif self.project.isProjectForm(fn):
-                self.__browsers["forms"].selectFile(fn)
-            elif self.project.isProjectResource(fn):
-                self.__browsers["resources"].selectFile(fn)
-            elif self.project.isProjectInterface(fn):
-                self.__browsers["interfaces"].selectFile(fn)
-            elif self.project.isProjectProtocol(fn):
-                self.__browsers["protocols"].selectFile(fn)
+            for fileCategory in (
+                cat
+                for cat in self.project.getFileCategories()
+                if cat not in ("TRANSLATIONS", "OTHERS")
+            ):
+                if self.project.isProjectCategory(fn, fileCategory):
+                    self.__browsers[fileCategory.lower()].selectFile(fn)
+                    break
 
     def handleEditorLineChanged(self, fn, lineno):
         """
@@ -333,7 +335,7 @@
         if (
             Preferences.getProject("FollowEditor")
             and Preferences.getProject("FollowCursorLine")
-            and self.project.isProjectSource(fn)
+            and self.project.isProjectCategory(fn, "SOURCES")
         ):
             self.__browsers["sources"].selectFileLine(fn, lineno)
 
--- a/src/eric7/Project/ProjectFormsBrowser.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Project/ProjectFormsBrowser.py	Thu Nov 17 18:11:42 2022 +0100
@@ -141,6 +141,7 @@
         project.projectPropertiesChanged.connect(self._initMenusAndVcs)
 
         projectBrowser.preferencesChanged.connect(self.handlePreferencesChanged)
+        projectBrowser.processChangedProjectFiles.connect(self.__compileChangedForms)
 
         self.appendStderr.connect(projectBrowser.appendStderr)
         self.closeSourceWindow.connect(projectBrowser.closeSourceWindow)
@@ -801,7 +802,7 @@
                     self.tr("Form Compilation"),
                     self.tr("The compilation of the form file" " was successful."),
                 )
-                self.project.projectFormCompiled.emit(self.compiledFile)
+                self.project.projectFileCompiled.emit(self.compiledFile, "FORMS")
             except OSError as msg:
                 ui.showNotification(
                     EricPixmapCache.getPixmap("designer48"),
@@ -1026,81 +1027,82 @@
                     break
             progress.setValue(numForms)
 
-    def compileChangedForms(self):
+    def __compileChangedForms(self):
         """
-        Public method to compile all changed forms to source files.
+        Private method to compile all changed forms to source files.
         """
-        if self.hooks["compileChangedForms"] is not None:
-            self.hooks["compileChangedForms"](
-                self.project.getProjectData(dataKey="FORMS")
-            )
-        else:
-            if self.project.getProjectType() not in [
-                "PyQt5",
-                "PyQt6",
-                "E7Plugin",
-                "PySide2",
-                "PySide6",
-            ]:
-                # ignore the request for non Qt GUI projects
-                return
+        if Preferences.getProject("AutoCompileForms"):
+            if self.hooks["compileChangedForms"] is not None:
+                self.hooks["compileChangedForms"](
+                    self.project.getProjectData(dataKey="FORMS")
+                )
+            else:
+                if self.project.getProjectType() not in [
+                    "PyQt5",
+                    "PyQt6",
+                    "E7Plugin",
+                    "PySide2",
+                    "PySide6",
+                ]:
+                    # ignore the request for non Qt GUI projects
+                    return
+
+                if len(self.project.getProjectData(dataKey="FORMS")) == 0:
+                    # The project does not contain form files.
+                    return
 
-            if len(self.project.getProjectData(dataKey="FORMS")) == 0:
-                # The project does not contain form files.
-                return
+                progress = EricProgressDialog(
+                    self.tr("Determining changed forms..."),
+                    self.tr("Abort"),
+                    0,
+                    100,
+                    self.tr("%v/%m Forms"),
+                    self,
+                )
+                progress.setMinimumDuration(0)
+                progress.setWindowTitle(self.tr("Forms"))
 
-            progress = EricProgressDialog(
-                self.tr("Determining changed forms..."),
-                self.tr("Abort"),
-                0,
-                100,
-                self.tr("%v/%m Forms"),
-                self,
-            )
-            progress.setMinimumDuration(0)
-            progress.setWindowTitle(self.tr("Forms"))
+                # get list of changed forms
+                changedForms = []
+                progress.setMaximum(len(self.project.getProjectData(dataKey="FORMS")))
+                for prog, fn in enumerate(self.project.getProjectData(dataKey="FORMS")):
+                    progress.setValue(prog)
+                    QApplication.processEvents()
 
-            # get list of changed forms
-            changedForms = []
-            progress.setMaximum(len(self.project.getProjectData(dataKey="FORMS")))
-            for prog, fn in enumerate(self.project.getProjectData(dataKey="FORMS")):
-                progress.setValue(prog)
+                    ifn = os.path.join(self.project.ppath, fn)
+                    if self.project.getProjectLanguage() == "Python3":
+                        dirname, filename = os.path.split(os.path.splitext(ifn)[0])
+                        ofn = os.path.join(dirname, "Ui_" + filename + ".py")
+                    elif self.project.getProjectLanguage() == "Ruby":
+                        ofn = os.path.splitext(ifn)[0] + ".rb"
+                    if (
+                        not os.path.exists(ofn)
+                        or os.stat(ifn).st_mtime > os.stat(ofn).st_mtime
+                    ):
+                        changedForms.append(fn)
+                progress.setValue(len(self.project.getProjectData(dataKey="FORMS")))
                 QApplication.processEvents()
 
-                ifn = os.path.join(self.project.ppath, fn)
-                if self.project.getProjectLanguage() == "Python3":
-                    dirname, filename = os.path.split(os.path.splitext(ifn)[0])
-                    ofn = os.path.join(dirname, "Ui_" + filename + ".py")
-                elif self.project.getProjectLanguage() == "Ruby":
-                    ofn = os.path.splitext(ifn)[0] + ".rb"
-                if (
-                    not os.path.exists(ofn)
-                    or os.stat(ifn).st_mtime > os.stat(ofn).st_mtime
-                ):
-                    changedForms.append(fn)
-            progress.setValue(len(self.project.getProjectData(dataKey="FORMS")))
-            QApplication.processEvents()
+                if changedForms:
+                    progress.setLabelText(self.tr("Compiling changed forms..."))
+                    progress.setMaximum(len(changedForms))
+                    progress.setValue(prog)
+                    QApplication.processEvents()
+                    for prog, fn in enumerate(changedForms):
+                        progress.setValue(prog)
+                        if progress.wasCanceled():
+                            break
 
-            if changedForms:
-                progress.setLabelText(self.tr("Compiling changed forms..."))
-                progress.setMaximum(len(changedForms))
-                progress.setValue(prog)
-                QApplication.processEvents()
-                for prog, fn in enumerate(changedForms):
-                    progress.setValue(prog)
-                    if progress.wasCanceled():
-                        break
-
-                    proc = self.__compileUI(fn, True, progress)
-                    if proc is not None:
-                        while proc.state() == QProcess.ProcessState.Running:
-                            QApplication.processEvents()
-                            QThread.msleep(300)
-                            QApplication.processEvents()
-                    else:
-                        break
-                progress.setValue(len(changedForms))
-                QApplication.processEvents()
+                        proc = self.__compileUI(fn, True, progress)
+                        if proc is not None:
+                            while proc.state() == QProcess.ProcessState.Running:
+                                QApplication.processEvents()
+                                QThread.msleep(300)
+                                QApplication.processEvents()
+                        else:
+                            break
+                    progress.setValue(len(changedForms))
+                    QApplication.processEvents()
 
     def handlePreferencesChanged(self):
         """
--- a/src/eric7/Project/ProjectResourcesBrowser.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Project/ProjectResourcesBrowser.py	Thu Nov 17 18:11:42 2022 +0100
@@ -85,6 +85,9 @@
         project.projectPropertiesChanged.connect(self._initMenusAndVcs)
 
         projectBrowser.preferencesChanged.connect(self.handlePreferencesChanged)
+        projectBrowser.processChangedProjectFiles.connect(
+            self.__compileChangedResources
+        )
 
         self.appendStderr.connect(projectBrowser.appendStderr)
         self.closeSourceWindow.connect(projectBrowser.closeSourceWindow)
@@ -879,76 +882,81 @@
 
         return False
 
-    def compileChangedResources(self):
+    def __compileChangedResources(self):
         """
-        Public method to compile all changed resources to source files.
+        Private method to compile all changed resources to source files.
         """
-        if self.hooks["compileChangedResources"] is not None:
-            self.hooks["compileChangedResources"](
-                self.project.getProjectData(dataKey="RESOURCES")
-            )
-        else:
-            if len(self.project.getProjectData(dataKey="RESOURCES")) == 0:
-                # The project does not contain resource files
-                return
+        if Preferences.getProject("AutoCompileResources"):
+            if self.hooks["compileChangedResources"] is not None:
+                self.hooks["compileChangedResources"](
+                    self.project.getProjectData(dataKey="RESOURCES")
+                )
+            else:
+                if len(self.project.getProjectData(dataKey="RESOURCES")) == 0:
+                    # The project does not contain resource files
+                    return
+
+                progress = EricProgressDialog(
+                    self.tr("Determining changed resources..."),
+                    self.tr("Abort"),
+                    0,
+                    100,
+                    self.tr("%v/%m Resources"),
+                    self,
+                )
+                progress.setMinimumDuration(0)
+                progress.setWindowTitle(self.tr("Resources"))
 
-            progress = EricProgressDialog(
-                self.tr("Determining changed resources..."),
-                self.tr("Abort"),
-                0,
-                100,
-                self.tr("%v/%m Resources"),
-                self,
-            )
-            progress.setMinimumDuration(0)
-            progress.setWindowTitle(self.tr("Resources"))
-
-            # get list of changed resources
-            changedResources = []
-            progress.setMaximum(len(self.project.getProjectData(dataKey="RESOURCES")))
-            for prog, fn in enumerate(self.project.getProjectData(dataKey="RESOURCES")):
-                progress.setValue(prog)
+                # get list of changed resources
+                changedResources = []
+                progress.setMaximum(
+                    len(self.project.getProjectData(dataKey="RESOURCES"))
+                )
+                for prog, fn in enumerate(
+                    self.project.getProjectData(dataKey="RESOURCES")
+                ):
+                    progress.setValue(prog)
+                    QApplication.processEvents()
+                    ifn = os.path.join(self.project.ppath, fn)
+                    if self.project.getProjectLanguage() == "Python3":
+                        dirname, filename = os.path.split(os.path.splitext(ifn)[0])
+                        ofn = os.path.join(
+                            dirname, self.RCFilenameFormatPython.format(filename)
+                        )
+                    elif self.project.getProjectLanguage() == "Ruby":
+                        dirname, filename = os.path.split(os.path.splitext(ifn)[0])
+                        ofn = os.path.join(
+                            dirname, self.RCFilenameFormatRuby.format(filename)
+                        )
+                    else:
+                        return
+                    if (
+                        not os.path.exists(ofn)
+                        or os.stat(ifn).st_mtime > os.stat(ofn).st_mtime
+                        or self.__checkResourcesNewer(ifn, os.stat(ofn).st_mtime)
+                    ):
+                        changedResources.append(fn)
+                progress.setValue(len(self.project.getProjectData(dataKey="RESOURCES")))
                 QApplication.processEvents()
-                ifn = os.path.join(self.project.ppath, fn)
-                if self.project.getProjectLanguage() == "Python3":
-                    dirname, filename = os.path.split(os.path.splitext(ifn)[0])
-                    ofn = os.path.join(
-                        dirname, self.RCFilenameFormatPython.format(filename)
-                    )
-                elif self.project.getProjectLanguage() == "Ruby":
-                    dirname, filename = os.path.split(os.path.splitext(ifn)[0])
-                    ofn = os.path.join(
-                        dirname, self.RCFilenameFormatRuby.format(filename)
-                    )
-                else:
-                    return
-                if (
-                    not os.path.exists(ofn)
-                    or os.stat(ifn).st_mtime > os.stat(ofn).st_mtime
-                    or self.__checkResourcesNewer(ifn, os.stat(ofn).st_mtime)
-                ):
-                    changedResources.append(fn)
-            progress.setValue(len(self.project.getProjectData(dataKey="RESOURCES")))
-            QApplication.processEvents()
 
-            if changedResources:
-                progress.setLabelText(self.tr("Compiling changed resources..."))
-                progress.setMaximum(len(changedResources))
-                progress.setValue(0)
-                QApplication.processEvents()
-                for prog, fn in enumerate(changedResources):
-                    progress.setValue(prog)
-                    if progress.wasCanceled():
-                        break
-                    proc = self.__compileQRC(fn, True, progress)
-                    if proc is not None:
-                        while proc.state() == QProcess.ProcessState.Running:
-                            QThread.msleep(100)
-                            QApplication.processEvents()
-                    else:
-                        break
-                progress.setValue(len(changedResources))
-                QApplication.processEvents()
+                if changedResources:
+                    progress.setLabelText(self.tr("Compiling changed resources..."))
+                    progress.setMaximum(len(changedResources))
+                    progress.setValue(0)
+                    QApplication.processEvents()
+                    for prog, fn in enumerate(changedResources):
+                        progress.setValue(prog)
+                        if progress.wasCanceled():
+                            break
+                        proc = self.__compileQRC(fn, True, progress)
+                        if proc is not None:
+                            while proc.state() == QProcess.ProcessState.Running:
+                                QThread.msleep(100)
+                                QApplication.processEvents()
+                        else:
+                            break
+                    progress.setValue(len(changedResources))
+                    QApplication.processEvents()
 
     def handlePreferencesChanged(self):
         """
--- a/src/eric7/QScintilla/Editor.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/QScintilla/Editor.py	Thu Nov 17 18:11:42 2022 +0100
@@ -605,7 +605,7 @@
         if (
             self.fileName
             and self.project.isOpen()
-            and self.project.isProjectSource(self.fileName)
+            and self.project.isProjectCategory(self.fileName, "SOURCES")
         ):
             self.project.projectPropertiesChanged.connect(
                 self.__projectPropertiesChanged
@@ -5716,7 +5716,9 @@
         coEnable = False
 
         # first check if the file belongs to a project
-        if self.project.isOpen() and self.project.isProjectSource(self.fileName):
+        if self.project.isOpen() and self.project.isProjectCategory(
+            self.fileName, "SOURCES"
+        ):
             fn = self.project.getMainScript(True)
             if fn is not None:
                 prEnable = self.project.isPy3Project() and bool(
@@ -5756,7 +5758,9 @@
         Private slot handling the aboutToShow signal of the diagrams context
         menu.
         """
-        if self.project.isOpen() and self.project.isProjectSource(self.fileName):
+        if self.project.isOpen() and self.project.isProjectCategory(
+            self.fileName, "SOURCES"
+        ):
             self.applicationDiagramMenuAct.setEnabled(True)
         else:
             self.applicationDiagramMenuAct.setEnabled(False)
@@ -6140,7 +6144,9 @@
 
         # first check if the file belongs to a project and there is
         # a project coverage file
-        if self.project.isOpen() and self.project.isProjectSource(self.fileName):
+        if self.project.isOpen() and self.project.isProjectCategory(
+            self.fileName, "SOURCES"
+        ):
             pfn = self.project.getMainScript(True)
             if pfn is not None:
                 files |= set(Utilities.getCoverageFileNames(pfn))
@@ -6317,7 +6323,9 @@
 
         # first check if the file belongs to a project and there is
         # a project profile file
-        if self.project.isOpen() and self.project.isProjectSource(self.fileName):
+        if self.project.isOpen() and self.project.isProjectCategory(
+            self.fileName, "SOURCES"
+        ):
             fn = self.project.getMainScript(True)
             if fn is not None:
                 files |= set(Utilities.getProfileFileNames(fn))
@@ -7907,7 +7915,7 @@
         """
         Public slot to handle the opening of a project.
         """
-        if self.fileName and self.project.isProjectSource(self.fileName):
+        if self.fileName and self.project.isProjectCategory(self.fileName, "SOURCES"):
             self.project.projectPropertiesChanged.connect(
                 self.__projectPropertiesChanged
             )
@@ -7980,7 +7988,7 @@
         if (
             self.fileName
             and self.project.isOpen()
-            and self.project.isProjectSource(self.fileName)
+            and self.project.isProjectCategory(self.fileName, "SOURCES")
         ):
             pwl, pel = self.project.getProjectDictionaries()
             self.__setSpellingLanguage(
@@ -9103,7 +9111,7 @@
             withProject = (
                 self.fileName
                 and self.project.isOpen()
-                and self.project.isProjectSource(self.fileName)
+                and self.project.isProjectCategory(self.fileName, "SOURCES")
             )
             dlg = BlackConfigurationDialog(withProject=withProject)
             if dlg.exec() == QDialog.DialogCode.Accepted:
@@ -9139,7 +9147,7 @@
             withProject = (
                 self.fileName
                 and self.project.isOpen()
-                and self.project.isProjectSource(self.fileName)
+                and self.project.isProjectCategory(self.fileName, "SOURCES")
             )
             dlg = IsortConfigurationDialog(withProject=withProject)
             if dlg.exec() == QDialog.DialogCode.Accepted:
--- a/src/eric7/Tasks/TaskViewer.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/Tasks/TaskViewer.py	Thu Nov 17 18:11:42 2022 +0100
@@ -447,7 +447,9 @@
             summary,
             filename=filename,
             lineno=lineno,
-            isProjectTask=(self.project and self.project.isProjectSource(filename)),
+            isProjectTask=(
+                self.project and self.project.isProjectCategory(filename, "SOURCES")
+            ),
             taskType=TaskType(taskType),
             description=description,
         )
@@ -509,7 +511,7 @@
             checking some conditions (boolean)
         """
         if conditionally:
-            if self.project and self.project.isProjectSource(filename):
+            if self.project and self.project.isProjectCategory(filename, "SOURCES"):
                 # project related tasks will not be cleared
                 return
             if not Preferences.getTasks("ClearOnFileClose"):
--- a/src/eric7/UI/FindFileWidget.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/UI/FindFileWidget.py	Thu Nov 17 18:11:42 2022 +0100
@@ -18,6 +18,7 @@
     QComboBox,
     QDialog,
     QDialogButtonBox,
+    QListWidgetItem,
     QMenu,
     QTreeWidgetItem,
     QVBoxLayout,
@@ -145,12 +146,30 @@
             )
         )
 
+        self.__project = project
+
+        # populate the file type list
+        for fileCategory in [
+            c
+            for c in self.__project.getFileCategories()
+            if c not in ("TRANSLATIONS", "OTHERS")
+        ]:
+            itm = QListWidgetItem(
+                self.__project.getFileCategoryType(fileCategory), self.fileTypeList
+            )
+            itm.setData(Qt.ItemDataRole.UserRole, fileCategory)
+            itm.setFlags(itm.flags() | Qt.ItemFlag.ItemIsUserCheckable)
+            itm.setCheckState(
+                Qt.CheckState.Checked
+                if fileCategory == "SOURCES"
+                else Qt.CheckState.Unchecked
+            )
+
         # ensure the file type tab is the current one
         self.fileOptionsWidget.setCurrentWidget(self.fileTypeTab)
 
-        self.project = project
-        self.project.projectOpened.connect(self.__projectOpened)
-        self.project.projectClosed.connect(self.__projectClosed)
+        self.__project.projectOpened.connect(self.__projectOpened)
+        self.__project.projectClosed.connect(self.__projectClosed)
 
         self.__standardListFont = self.findList.font()
         self.findList.headerItem().setText(self.findList.columnCount(), "")
@@ -158,23 +177,6 @@
         self.__section0Size = self.findList.header().sectionSize(0)
         self.findList.setExpandsOnDoubleClick(False)
 
-        # TODO: move these to a project browser file category repository
-        # Qt Designer form files
-        self.filterForms = r".*\.ui$"
-        self.formsExt = ["*.ui"]
-
-        # Corba interface files
-        self.filterInterfaces = r".*\.idl$"
-        self.interfacesExt = ["*.idl"]
-
-        # Protobuf protocol files
-        self.filterProtocols = r".*\.proto$"
-        self.protocolsExt = ["*.proto"]
-
-        # Qt resources files
-        self.filterResources = r".*\.qrc$"
-        self.resourcesExt = ["*.qrc"]
-
         self.__cancelSearch = False
         self.__lastFileItem = None
         self.__populating = False
@@ -245,7 +247,7 @@
             (defaults to False)
         @type bool (optional)
         """
-        if self.project.isOpen():
+        if self.__project.isOpen():
             self.projectButton.setEnabled(True)
             self.projectButton.setChecked(True)
         else:
@@ -442,113 +444,72 @@
         if self.projectButton.isChecked():
             if self.filterCheckBox.isChecked():
                 files = [
-                    self.project.getRelativePath(file)
+                    self.__project.getRelativePath(file)
                     for file in self.__getFileList(
-                        self.project.getProjectPath(),
+                        self.__project.getProjectPath(),
                         filterRe,
                         excludeHiddenDirs=self.excludeHiddenCheckBox.isChecked(),
                     )
                 ]
             else:
                 files = []
-                # TODO: make this more generic (using fileCategory)
-                if self.sourcesCheckBox.isChecked():
-                    files += self.project.getProjectData(dataKey="SOURCES")
-                if self.formsCheckBox.isChecked():
-                    files += self.project.getProjectData("FORMS")
-                if self.interfacesCheckBox.isChecked():
-                    files += self.project.getProjectData("INTERFACES")
-                if self.protocolsCheckBox.isChecked():
-                    files += self.project.getProjectData("PROTOCOLS")
-                if self.resourcesCheckBox.isChecked():
-                    files += self.project.getProjectData("RESOURCES")
+                for row in range(self.fileTypeList.count()):
+                    itm = self.fileTypeList.item(row)
+                    if itm.checkState() == Qt.CheckState.Checked:
+                        files += self.__project.getProjectData(
+                            dataKey=itm.data(Qt.ItemDataRole.UserRole)
+                        )
         elif self.dirButton.isChecked():
             if not self.filterCheckBox.isChecked():
                 filters = []
-                if self.project.isOpen() and os.path.abspath(
+                if self.__project.isOpen() and os.path.abspath(
                     self.dirPicker.currentText()
-                ).startswith(self.project.getProjectPath()):
-                    if self.sourcesCheckBox.isChecked():
-                        filters.extend(
-                            [
-                                "^{0}$".format(
-                                    assoc.replace(".", r"\.").replace("*", ".*")
-                                )
-                                for assoc in self.project.getFiletypeAssociations(
-                                    "SOURCES"
-                                )
-                            ]
-                        )
-                    if self.formsCheckBox.isChecked():
-                        filters.extend(
-                            [
-                                "^{0}$".format(
-                                    assoc.replace(".", r"\.").replace("*", ".*")
-                                )
-                                for assoc in self.project.getFiletypeAssociations(
-                                    "FORMS"
-                                )
-                            ]
-                        )
-                    if self.interfacesCheckBox.isChecked():
-                        filters.extend(
-                            [
-                                "^{0}$".format(
-                                    assoc.replace(".", r"\.").replace("*", ".*")
-                                )
-                                for assoc in self.project.getFiletypeAssociations(
-                                    "INTERFACES"
-                                )
-                            ]
-                        )
-                    if self.protocolsCheckBox.isChecked():
-                        filters.extend(
-                            [
-                                "^{0}$".format(
-                                    assoc.replace(".", r"\.").replace("*", ".*")
+                ).startswith(self.__project.getProjectPath()):
+                    for row in range(self.fileTypeList.count()):
+                        itm = self.fileTypeList.item(row)
+                        if itm.checkState() == Qt.CheckState.Checked:
+                            filters.extend(
+                                [
+                                    "^{0}$".format(
+                                        assoc.replace(".", r"\.").replace("*", ".*")
+                                    )
+                                    for assoc in self.__project.getFiletypeAssociations(
+                                        itm.data(Qt.ItemDataRole.UserRole)
+                                    )
+                                ]
+                            )
+                else:
+                    for row in range(self.fileTypeList.count()):
+                        itm = self.fileTypeList.item(row)
+                        if itm.checkState() == Qt.CheckState.Checked:
+                            fileType = itm.data(Qt.ItemDataRole.UserRole)
+                            if fileType == "SOURCES":
+                                filters.extend(
+                                    [
+                                        "^{0}$".format(
+                                            assoc.replace(".", r"\.").replace("*", ".*")
+                                        )
+                                        for assoc in list(
+                                            Preferences.getEditorLexerAssocs().keys()
+                                        )
+                                        if assoc
+                                        not in self.__project.getFileCategoryExtension(
+                                            fileType, reverse=True
+                                        )
+                                    ]
                                 )
-                                for assoc in self.project.getFiletypeAssociations(
-                                    "PROTOCOLS"
-                                )
-                            ]
-                        )
-                    if self.resourcesCheckBox.isChecked():
-                        filters.extend(
-                            [
-                                "^{0}$".format(
-                                    assoc.replace(".", r"\.").replace("*", ".*")
-                                )
-                                for assoc in self.project.getFiletypeAssociations(
-                                    "RESOURCES"
+                            else:
+                                filters.extend(
+                                    [
+                                        "^{0}$".format(
+                                            ext.replace(".", r"\.").replace("*", ".*")
+                                        )
+                                        for ext in self.__project.getFileCategoryExtension(
+                                            # __IGNORE_WARNING__
+                                            fileType
+                                        )
+                                    ]
                                 )
-                            ]
-                        )
-                else:
-                    # TODO: make this more generic (use project browser type repository
-                    if self.sourcesCheckBox.isChecked():
-                        filters.extend(
-                            [
-                                "^{0}$".format(
-                                    assoc.replace(".", r"\.").replace("*", ".*")
-                                )
-                                for assoc in list(
-                                    Preferences.getEditorLexerAssocs().keys()
-                                )
-                                if assoc
-                                not in self.formsExt
-                                + self.interfacesExt
-                                + self.protocolsExt
-                                + self.resourcesExt
-                            ]
-                        )
-                    if self.formsCheckBox.isChecked():
-                        filters.append(self.filterForms)
-                    if self.interfacesCheckBox.isChecked():
-                        filters.append(self.filterInterfaces)
-                    if self.protocolsCheckBox.isChecked():
-                        filters.append(self.filterProtocols)
-                    if self.resourcesCheckBox.isChecked():
-                        filters.append(self.filterResources)
                 filterString = "|".join(filters)
                 filterRe = re.compile(filterString)
             files = self.__getFileList(
@@ -644,7 +605,7 @@
                 break
 
             fn = (
-                os.path.join(self.project.getProjectPath(), file)
+                os.path.join(self.__project.getProjectPath(), file)
                 if self.projectButton.isChecked()
                 else file
             )
@@ -750,8 +711,8 @@
             end = 0
 
         fileName = (
-            os.path.join(self.project.getProjectPath(), file)
-            if self.project.isOpen()
+            os.path.join(self.__project.getProjectPath(), file)
+            if self.__project.isOpen()
             else file
         )
         fileExt = os.path.splitext(fileName)[1]
@@ -846,7 +807,7 @@
                 origHash = itm.data(0, self.md5Role)
 
                 if self.projectButton.isChecked():
-                    fn = os.path.join(self.project.getProjectPath(), file)
+                    fn = os.path.join(self.__project.getProjectPath(), file)
                 else:
                     fn = file
 
--- a/src/eric7/UI/FindFileWidget.ui	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/UI/FindFileWidget.ui	Thu Nov 17 18:11:42 2022 +0100
@@ -151,6 +151,12 @@
    </item>
    <item>
     <widget class="QTabWidget" name="fileOptionsWidget">
+     <property name="sizePolicy">
+      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+       <horstretch>0</horstretch>
+       <verstretch>1</verstretch>
+      </sizepolicy>
+     </property>
      <property name="currentIndex">
       <number>0</number>
      </property>
@@ -158,68 +164,37 @@
       <attribute name="title">
        <string>File Type</string>
       </attribute>
-      <layout class="QGridLayout" name="gridLayout_4">
-       <item row="0" column="0">
-        <widget class="QCheckBox" name="sourcesCheckBox">
+      <layout class="QVBoxLayout" name="verticalLayout_3">
+       <item>
+        <widget class="QListWidget" name="fileTypeList">
+         <property name="minimumSize">
+          <size>
+           <width>0</width>
+           <height>125</height>
+          </size>
+         </property>
          <property name="toolTip">
-          <string>Search in source files</string>
+          <string>Select the file types to search in</string>
+         </property>
+         <property name="alternatingRowColors">
+          <bool>true</bool>
          </property>
-         <property name="text">
-          <string>&amp;Sources</string>
+         <property name="selectionMode">
+          <enum>QAbstractItemView::NoSelection</enum>
          </property>
-         <property name="checked">
+         <property name="sortingEnabled">
           <bool>true</bool>
          </property>
         </widget>
        </item>
-       <item row="0" column="1">
-        <widget class="QCheckBox" name="interfacesCheckBox">
-         <property name="toolTip">
-          <string>Search in interfaces</string>
-         </property>
-         <property name="text">
-          <string>&amp;Interfaces</string>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="0">
-        <widget class="QCheckBox" name="formsCheckBox">
-         <property name="toolTip">
-          <string>Search in forms</string>
-         </property>
-         <property name="text">
-          <string>&amp;Forms</string>
-         </property>
-        </widget>
-       </item>
-       <item row="1" column="1">
-        <widget class="QCheckBox" name="protocolsCheckBox">
-         <property name="toolTip">
-          <string>Search in protocols</string>
-         </property>
-         <property name="text">
-          <string>&amp;Protocols</string>
-         </property>
-        </widget>
-       </item>
-       <item row="2" column="0">
-        <widget class="QCheckBox" name="resourcesCheckBox">
-         <property name="toolTip">
-          <string>Search in resources</string>
-         </property>
-         <property name="text">
-          <string>&amp;Resources</string>
-         </property>
-        </widget>
-       </item>
-       <item row="3" column="0" colspan="2">
+       <item>
         <widget class="Line" name="line">
          <property name="orientation">
           <enum>Qt::Horizontal</enum>
          </property>
         </widget>
        </item>
-       <item row="4" column="0" colspan="2">
+       <item>
         <layout class="QHBoxLayout" name="horizontalLayout">
          <item>
           <widget class="QCheckBox" name="filterCheckBox">
@@ -503,11 +478,7 @@
   <tabstop>wordToolButton</tabstop>
   <tabstop>regexpToolButton</tabstop>
   <tabstop>fileOptionsWidget</tabstop>
-  <tabstop>sourcesCheckBox</tabstop>
-  <tabstop>formsCheckBox</tabstop>
-  <tabstop>resourcesCheckBox</tabstop>
-  <tabstop>interfacesCheckBox</tabstop>
-  <tabstop>protocolsCheckBox</tabstop>
+  <tabstop>fileTypeList</tabstop>
   <tabstop>filterCheckBox</tabstop>
   <tabstop>filterEdit</tabstop>
   <tabstop>projectButton</tabstop>
--- a/src/eric7/UI/UserInterface.py	Wed Nov 16 18:11:52 2022 +0100
+++ b/src/eric7/UI/UserInterface.py	Thu Nov 17 18:11:42 2022 +0100
@@ -458,15 +458,13 @@
         self.debuggerUI.resetUI.connect(self.__debuggingDone)
         self.debuggerUI.debuggingStarted.connect(self.__programChange)
         self.debuggerUI.debuggingStarted.connect(self.__debuggingStarted)
-        # TODO: check how this can be changed
-        self.debuggerUI.compileForms.connect(
-            self.projectBrowser.getProjectBrowser("forms").compileChangedForms
-        )
-        # TODO: check how this can be changed
-        self.debuggerUI.compileResources.connect(
-            self.projectBrowser.getProjectBrowser("resources").compileChangedResources
-        )
-        self.debuggerUI.executeMake.connect(self.project.executeMake)
+        self.debuggerUI.processChangedProjectFiles.connect(
+            self.projectBrowser.processChangedProjectFiles
+        )
+        self.debuggerUI.processChangedProjectFiles.connect(
+            self.project.processChangedProjectFiles
+        )
+        ##self.debuggerUI.executeMake.connect(self.project.executeMake)
         self.debuggerUI.appendStdout.connect(self.appendToStdout)
 
         self.__debugServer.clientDisassembly.connect(

eric ide

mercurial