src/eric7/Project/Project.py

branch
eric7
changeset 9517
d73c3a1e432b
parent 9516
0f023e61a9b5
child 9520
e12589f1d408
--- 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):

eric ide

mercurial