src/eric7/Project/Project.py

branch
eric7
changeset 9517
d73c3a1e432b
parent 9516
0f023e61a9b5
child 9520
e12589f1d408
equal deleted inserted replaced
9516:0f023e61a9b5 9517:d73c3a1e432b
65 class Project(QObject): 65 class Project(QObject):
66 """ 66 """
67 Class implementing the project management functionality. 67 Class implementing the project management functionality.
68 68
69 @signal dirty(bool) emitted when the dirty state changes 69 @signal dirty(bool) emitted when the dirty state changes
70 @signal projectLanguageAdded(str) emitted after a new language was added 70 @signal projectFileAdded(str, str) emitted after a new file was added
71 @signal projectFileRemoved(str, str) emitted after a file of the project was removed
72 @signal projectFileCompiled(str, str) emitted after a form was compiled
71 @signal projectLanguageAddedByCode(str) emitted after a new language was 73 @signal projectLanguageAddedByCode(str) emitted after a new language was
72 added. The language code is sent by this signal. 74 added. The language code is sent by this signal.
73 @signal projectLanguageRemoved(str) emitted after a language was removed
74 @signal projectFormAdded(str) emitted after a new form was added
75 @signal projectFormRemoved(str) emitted after a form was removed
76 @signal projectFormCompiled(str) emitted after a form was compiled
77 @signal projectSourceAdded(str) emitted after a new source file was added
78 @signal projectSourceRemoved(str) emitted after a source was removed
79 @signal projectInterfaceAdded(str) emitted after a new IDL file was added
80 @signal projectInterfaceRemoved(str) emitted after a IDL file was removed
81 @signal projectProtocolAdded(str) emitted after a new proto file was added
82 @signal projectProtocolRemoved(str) emitted after a proto file was removed
83 @signal projectResourceAdded(str) emitted after a new resource file was
84 added
85 @signal projectResourceRemoved(str) emitted after a resource was removed
86 @signal projectOthersAdded(str) emitted after a file or directory was added
87 to the OTHERS project data area
88 @signal projectOthersRemoved(str) emitted after a file was removed from the
89 OTHERS project data area
90 @signal projectAboutToBeCreated() emitted just before the project will be 75 @signal projectAboutToBeCreated() emitted just before the project will be
91 created 76 created
92 @signal newProjectHooks() emitted after a new project was generated but 77 @signal newProjectHooks() emitted after a new project was generated but
93 before the newProject() signal is sent 78 before the newProject() signal is sent
94 @signal newProject() emitted after a new project was generated 79 @signal newProject() emitted after a new project was generated
129 @signal projectChanged() emitted to signal a change of the project 114 @signal projectChanged() emitted to signal a change of the project
130 @signal appendStdout(str) emitted after something was received from 115 @signal appendStdout(str) emitted after something was received from
131 a QProcess on stdout 116 a QProcess on stdout
132 @signal appendStderr(str) emitted after something was received from 117 @signal appendStderr(str) emitted after something was received from
133 a QProcess on stderr 118 a QProcess on stderr
119 @signal processChangedProjectFiles() emitted to indicate, that changed project files
120 should be processed
134 """ 121 """
135 122
136 dirty = pyqtSignal(bool) 123 dirty = pyqtSignal(bool)
137 projectLanguageAdded = pyqtSignal(str) 124 projectFileAdded = pyqtSignal(str, str)
125 projectFileRemoved = pyqtSignal(str, str)
126 projectFileCompiled = pyqtSignal(str, str)
138 projectLanguageAddedByCode = pyqtSignal(str) 127 projectLanguageAddedByCode = pyqtSignal(str)
139 projectLanguageRemoved = pyqtSignal(str)
140 projectFormAdded = pyqtSignal(str)
141 projectFormRemoved = pyqtSignal(str)
142 projectFormCompiled = pyqtSignal(str)
143 projectSourceAdded = pyqtSignal(str)
144 projectSourceRemoved = pyqtSignal(str)
145 projectInterfaceAdded = pyqtSignal(str)
146 projectInterfaceRemoved = pyqtSignal(str)
147 projectProtocolAdded = pyqtSignal(str)
148 projectProtocolRemoved = pyqtSignal(str)
149 projectResourceAdded = pyqtSignal(str)
150 projectResourceRemoved = pyqtSignal(str)
151 projectOthersAdded = pyqtSignal(str)
152 projectOthersRemoved = pyqtSignal(str)
153 projectAboutToBeCreated = pyqtSignal() 128 projectAboutToBeCreated = pyqtSignal()
154 newProjectHooks = pyqtSignal() 129 newProjectHooks = pyqtSignal()
155 newProject = pyqtSignal() 130 newProject = pyqtSignal()
156 sourceFile = pyqtSignal(str) 131 sourceFile = pyqtSignal(str)
157 designerFile = pyqtSignal(str) 132 designerFile = pyqtSignal(str)
174 showMenu = pyqtSignal(str, QMenu) 149 showMenu = pyqtSignal(str, QMenu)
175 lexerAssociationsChanged = pyqtSignal() 150 lexerAssociationsChanged = pyqtSignal()
176 projectChanged = pyqtSignal() 151 projectChanged = pyqtSignal()
177 appendStdout = pyqtSignal(str) 152 appendStdout = pyqtSignal(str)
178 appendStderr = pyqtSignal(str) 153 appendStderr = pyqtSignal(str)
154 processChangedProjectFiles = pyqtSignal()
179 155
180 eols = [os.linesep, "\n", "\r", "\r\n"] 156 eols = [os.linesep, "\n", "\r", "\r\n"]
181 157
182 DefaultMake = "make" 158 DefaultMake = "make"
183 DefaultMakefile = "makefile" 159 DefaultMakefile = "makefile"
233 self.codecoverage = None 209 self.codecoverage = None
234 self.profiledata = None 210 self.profiledata = None
235 self.applicationDiagram = None 211 self.applicationDiagram = None
236 self.loadedDiagram = None 212 self.loadedDiagram = None
237 self.__findProjectFileDialog = None 213 self.__findProjectFileDialog = None
214
215 self.processChangedProjectFiles.connect(self.__autoExecuteMake)
238 216
239 def __sourceExtensions(self, language): 217 def __sourceExtensions(self, language):
240 """ 218 """
241 Private method to get the source extensions of a programming language. 219 Private method to get the source extensions of a programming language.
242 220
546 "DOCSTRING": "", 524 "DOCSTRING": "",
547 "TESTING_FRAMEWORK": "", 525 "TESTING_FRAMEWORK": "",
548 "LICENSE": "", 526 "LICENSE": "",
549 "EMBEDDED_VENV": False, 527 "EMBEDDED_VENV": False,
550 } 528 }
551 # TODO: Move these to a file categories repository 529 # TODO: Move these to a file categories repository populated through the
530 # project browsers
552 self.__knownFileCategories = [ 531 self.__knownFileCategories = [
553 "FORMS", 532 "FORMS",
554 "OTHERS", 533 "OTHERS",
555 "RESOURCES", 534 "RESOURCES",
556 "SOURCES", 535 "SOURCES",
583 "SOURCES": self.tr("Sources"), 562 "SOURCES": self.tr("Sources"),
584 "TRANSLATIONS": self.tr("Translations"), 563 "TRANSLATIONS": self.tr("Translations"),
585 "INTERFACES": self.tr("Interfaces"), 564 "INTERFACES": self.tr("Interfaces"),
586 "PROTOCOLS": self.tr("Protocols"), 565 "PROTOCOLS": self.tr("Protocols"),
587 } 566 }
567 self.__fileCategoryExtensions = {
568 "FORMS": ["*.ui"],
569 "OTHERS": [],
570 "RESOURCES": ["*.qrc"],
571 "SOURCES": ["*.py", "*.pyw"], # Python files as default
572 "TRANSLATIONS": ["*.ts", "*.qm"],
573 "INTERFACES": ["*.idl"],
574 "PROTOCOLS": ["*.proto"],
575 }
576 # until here
588 577
589 self.__initDebugProperties() 578 self.__initDebugProperties()
590 579
591 self.pudata = { 580 self.pudata = {
592 "VCSOVERRIDE": "", 581 "VCSOVERRIDE": "",
621 return default 610 return default
622 611
623 def setProjectData(self, data, dataKey=None, setDirty=True): 612 def setProjectData(self, data, dataKey=None, setDirty=True):
624 """ 613 """
625 Public method to set data associated with the given data key in the project 614 Public method to set data associated with the given data key in the project
626 dictionary 615 dictionary.
627 616
628 Note: If no data key is given or is None, the data must be a dictionary used 617 Note: If no data key is given or is None, the data must be a dictionary used
629 to update the project data. 618 to update the project data.
630 619
631 @param data data to be set or a dictionary to update the project data 620 @param data data to be set or a dictionary to update the project data
778 @type str 767 @type str
779 @return user type string for the category 768 @return user type string for the category
780 @rtype str 769 @rtype str
781 """ 770 """
782 return self.__fileCategoryTyeStrings[category] 771 return self.__fileCategoryTyeStrings[category]
772
773 def getFileCategoryExtension(self, category, reverse=False):
774 """
775 Public method to get a list of default file extensions for the given category.
776
777 @param category file type category
778 @type str
779 @param reverse flag indicating to get all other extensions except the one of
780 the given category
781 @type bool
782 @return list of default file extensions for the category
783 @rtype list of str
784 """
785 if reverse:
786 extensions = []
787 for cat, ext in self.__fileCategoryExtensions.items():
788 if cat != category:
789 extensions += ext
790 return extensions
791 else:
792 return self.__fileCategoryExtensions[category][:]
783 793
784 def initFileTypes(self): 794 def initFileTypes(self):
785 """ 795 """
786 Public method to initialize the filetype associations with default 796 Public method to initialize the filetype associations with default
787 values. 797 values.
1075 1085
1076 # check, if the files of the project still exist in the 1086 # check, if the files of the project still exist in the
1077 # project directory 1087 # project directory
1078 for fileCategory in self.__knownFileCategories: 1088 for fileCategory in self.__knownFileCategories:
1079 self.__checkFilesExist(fileCategory) 1089 self.__checkFilesExist(fileCategory)
1080 ##self.__checkFilesExist("SOURCES")
1081 ##self.__checkFilesExist("FORMS")
1082 ##self.__checkFilesExist("INTERFACES")
1083 ##self.__checkFilesExist("PROTOCOLS")
1084 ##self.__checkFilesExist("TRANSLATIONS")
1085 ##self.__checkFilesExist("RESOURCES")
1086 ##self.__checkFilesExist("OTHERS")
1087 1090
1088 # get the names of subdirectories the files are stored in 1091 # get the names of subdirectories the files are stored in
1089 for fileCategory in [ 1092 for fileCategory in [
1090 c for c in self.__knownFileCategories if c != "OTHERS" 1093 c for c in self.__knownFileCategories if c != "OTHERS"
1091 ]: 1094 ]:
1092 for fn in self.__pdata[fileCategory]: 1095 for fn in self.__pdata[fileCategory]:
1093 ##self.__pdata["SOURCES"]
1094 ##+ self.__pdata["FORMS"]
1095 ##+ self.__pdata["INTERFACES"]
1096 ##+ self.__pdata["PROTOCOLS"]
1097 ##+ self.__pdata["RESOURCES"]
1098 ##+ self.__pdata["TRANSLATIONS"]
1099 ##):
1100 dn = os.path.dirname(fn) 1096 dn = os.path.dirname(fn)
1101 if dn not in self.subdirs: 1097 if dn not in self.subdirs:
1102 self.subdirs.append(dn) 1098 self.subdirs.append(dn)
1103 1099
1104 # get the names of other subdirectories 1100 # get the names of other subdirectories
1817 break 1813 break
1818 1814
1819 if filetype == "__IGNORE__": 1815 if filetype == "__IGNORE__":
1820 return 1816 return
1821 1817
1822 # TODO: change this logic to be more generic (use fileCategory) 1818 if filetype in (
1823 if filetype in ["SOURCES", "FORMS", "INTERFACES", "PROTOCOLS", "RESOURCES"]: 1819 category
1824 if filetype == "SOURCES": 1820 for category in self.getFileCategories()
1825 if newfn not in self.__pdata["SOURCES"]: 1821 if category not in ("TRANSLATIONS", "OTHERS")
1826 self.__pdata["SOURCES"].append(newfn) 1822 ):
1827 self.projectSourceAdded.emit(newfn) 1823 if newfn not in self.__pdata[filetype]:
1828 updateModel and self.__model.addNewItem("SOURCES", newfn) 1824 self.__pdata[filetype].append(newfn)
1829 dirty = True 1825 self.projectFileAdded.emit(newfn, filetype)
1830 else: 1826 updateModel and self.__model.addNewItem(filetype, newfn)
1831 updateModel and self.repopulateItem(newfn) 1827 dirty = True
1832 elif filetype == "FORMS": 1828 else:
1833 if newfn not in self.__pdata["FORMS"]: 1829 updateModel and self.repopulateItem(newfn)
1834 self.__pdata["FORMS"].append(newfn)
1835 self.projectFormAdded.emit(newfn)
1836 updateModel and self.__model.addNewItem("FORMS", newfn)
1837 dirty = True
1838 else:
1839 updateModel and self.repopulateItem(newfn)
1840 elif filetype == "INTERFACES":
1841 if newfn not in self.__pdata["INTERFACES"]:
1842 self.__pdata["INTERFACES"].append(newfn)
1843 self.projectInterfaceAdded.emit(newfn)
1844 (updateModel and self.__model.addNewItem("INTERFACES", newfn))
1845 dirty = True
1846 else:
1847 updateModel and self.repopulateItem(newfn)
1848 elif filetype == "PROTOCOLS":
1849 if newfn not in self.__pdata["PROTOCOLS"]:
1850 self.__pdata["PROTOCOLS"].append(newfn)
1851 self.projectProtocolAdded.emit(newfn)
1852 (updateModel and self.__model.addNewItem("PROTOCOLS", newfn))
1853 dirty = True
1854 else:
1855 updateModel and self.repopulateItem(newfn)
1856 elif filetype == "RESOURCES":
1857 if newfn not in self.__pdata["RESOURCES"]:
1858 self.__pdata["RESOURCES"].append(newfn)
1859 self.projectResourceAdded.emit(newfn)
1860 updateModel and self.__model.addNewItem("RESOURCES", newfn)
1861 dirty = True
1862 else:
1863 updateModel and self.repopulateItem(newfn)
1864 if newdir not in self.subdirs: 1830 if newdir not in self.subdirs:
1865 self.subdirs.append(newdir) 1831 self.subdirs.append(newdir)
1866 elif filetype == "TRANSLATIONS": 1832 elif filetype == "TRANSLATIONS":
1867 if newfn not in self.__pdata["TRANSLATIONS"]: 1833 if newfn not in self.__pdata["TRANSLATIONS"]:
1868 self.__pdata["TRANSLATIONS"].append(newfn) 1834 self.__pdata["TRANSLATIONS"].append(newfn)
1869 updateModel and self.__model.addNewItem("TRANSLATIONS", newfn) 1835 updateModel and self.__model.addNewItem("TRANSLATIONS", newfn)
1870 self.projectLanguageAdded.emit(newfn) 1836 self.projectFileAdded.emit(newfn, "TRANSLATIONS")
1871 dirty = True 1837 dirty = True
1872 else: 1838 else:
1873 updateModel and self.repopulateItem(newfn) 1839 updateModel and self.repopulateItem(newfn)
1874 else: # filetype == "OTHERS" 1840 elif filetype == "OTHERS":
1875 if newfn not in self.__pdata["OTHERS"]: 1841 if newfn not in self.__pdata["OTHERS"]:
1876 self.__pdata["OTHERS"].append(newfn) 1842 self.__pdata["OTHERS"].append(newfn)
1877 self.othersAdded(newfn, updateModel) 1843 self.othersAdded(newfn, updateModel)
1878 dirty = True 1844 dirty = True
1879 else: 1845 else:
2119 self.setDirty(True) 2085 self.setDirty(True)
2120 2086
2121 if os.path.isdir(fn) and fn not in self.otherssubdirs: 2087 if os.path.isdir(fn) and fn not in self.otherssubdirs:
2122 self.otherssubdirs.append(fn) 2088 self.otherssubdirs.append(fn)
2123 2089
2124 ##def addSourceFiles(self):
2125 ##"""
2126 ##Public slot to add source files to the current project.
2127 ##"""
2128 ##self.addFiles("source")
2129 ##
2130 ##def addUiFiles(self):
2131 ##"""
2132 ##Public slot to add forms to the current project.
2133 ##"""
2134 ##self.addFiles("form")
2135 ##
2136 ##def addIdlFiles(self):
2137 ##"""
2138 ##Public slot to add IDL interfaces to the current project.
2139 ##"""
2140 ##self.addFiles("interface")
2141 ##
2142 ##def addProtoFiles(self):
2143 ##"""
2144 ##Public slot to add protocol files to the current project.
2145 ##"""
2146 ##self.addFiles("protocol")
2147 ##
2148 ##def addResourceFiles(self):
2149 ##"""
2150 ##Public slot to add Qt resources to the current project.
2151 ##"""
2152 ##self.addFiles("resource")
2153 ##
2154 ##def addOthersFiles(self):
2155 ##"""
2156 ##Public slot to add files to the OTHERS project data.
2157 ##"""
2158 ##self.addFiles("others")
2159 ##
2160 ##def addSourceDir(self):
2161 ##"""
2162 ##Public slot to add all source files of a directory to the current
2163 ##project.
2164 ##"""
2165 ##self.addDirectory("source")
2166 ##
2167 ##def addUiDir(self):
2168 ##"""
2169 ##Public slot to add all forms of a directory to the current project.
2170 ##"""
2171 ##self.addDirectory("form")
2172 ##
2173 ##def addIdlDir(self):
2174 ##"""
2175 ##Public slot to add all IDL interfaces of a directory to the current
2176 ##project.
2177 ##"""
2178 ##self.addDirectory("interface")
2179 ##
2180 ##def addProtoDir(self):
2181 ##"""
2182 ##Public slot to add all protocol files of a directory to the current
2183 ##project.
2184 ##"""
2185 ##self.addDirectory("protocol")
2186 ##
2187 ##def addResourceDir(self):
2188 ##"""
2189 ##Public slot to add all Qt resource files of a directory to the current
2190 ##project.
2191 ##"""
2192 ##self.addDirectory("resource")
2193 ##
2194 ##def addOthersDir(self):
2195 ##"""
2196 ##Public slot to add a directory to the OTHERS project data.
2197 ##"""
2198 ##self.addDirectory("others")
2199 ##
2200 def renameMainScript(self, oldfn, newfn): 2090 def renameMainScript(self, oldfn, newfn):
2201 """ 2091 """
2202 Public method to rename the main script. 2092 Public method to rename the main script.
2203 2093
2204 @param oldfn old filename (string) 2094 @param oldfn old filename (string)
2260 """Reason: {1}</p>""" 2150 """Reason: {1}</p>"""
2261 ).format(oldfn, str(msg)), 2151 ).format(oldfn, str(msg)),
2262 ) 2152 )
2263 return False 2153 return False
2264 2154
2265 ##if (
2266 ##fn in self.__pdata["SOURCES"]
2267 ##or fn in self.__pdata["FORMS"]
2268 ##or fn in self.__pdata["TRANSLATIONS"]
2269 ##or fn in self.__pdata["INTERFACES"]
2270 ##or fn in self.__pdata["PROTOCOLS"]
2271 ##or fn in self.__pdata["RESOURCES"]
2272 ##or fn in self.__pdata["OTHERS"]
2273 ##):
2274 if any(fn in self.__pdata[category] for category in self.__knownFileCategories): 2155 if any(fn in self.__pdata[category] for category in self.__knownFileCategories):
2275 self.renameFileInPdata(oldfn, newfn, isSourceFile) 2156 self.renameFileInPdata(oldfn, newfn, isSourceFile)
2276 2157
2277 return True 2158 return True
2278 2159
2305 @param start prefix (string) 2186 @param start prefix (string)
2306 @return list of files starting with a common prefix (list of strings) 2187 @return list of files starting with a common prefix (list of strings)
2307 """ 2188 """
2308 filelist = [] 2189 filelist = []
2309 start = self.getRelativePath(start) 2190 start = self.getRelativePath(start)
2310 ##for key in [
2311 ##"SOURCES",
2312 ##"FORMS",
2313 ##"INTERFACES",
2314 ##"PROTOCOLS",
2315 ##"RESOURCES",
2316 ##"OTHERS",
2317 ##]:
2318 for fileCategory in [ 2191 for fileCategory in [
2319 c for c in self.__knownFileCategories if c != "TRANSLATIONS" 2192 c for c in self.__knownFileCategories if c != "TRANSLATIONS"
2320 ]: 2193 ]:
2321 for entry in self.__pdata[fileCategory][:]: 2194 for entry in self.__pdata[fileCategory][:]:
2322 if entry.startswith(start): 2195 if entry.startswith(start):
2329 """ 2202 """
2330 reorganized = False 2203 reorganized = False
2331 2204
2332 # init data store for the reorganization 2205 # init data store for the reorganization
2333 newPdata = {} 2206 newPdata = {}
2334 ##for key in [
2335 ##"SOURCES",
2336 ##"FORMS",
2337 ##"INTERFACES",
2338 ##"PROTOCOLS",
2339 ##"RESOURCES",
2340 ##"OTHERS",
2341 ##"TRANSLATIONS",
2342 ##]:
2343 for fileCategory in self.__knownFileCategories: 2207 for fileCategory in self.__knownFileCategories:
2344 newPdata[fileCategory] = [] 2208 newPdata[fileCategory] = []
2345 2209
2346 # iterate over all files checking for a reassignment 2210 # iterate over all files checking for a reassignment
2347 ##for key in [
2348 ##"SOURCES",
2349 ##"FORMS",
2350 ##"INTERFACES",
2351 ##"PROTOCOLS",
2352 ##"RESOURCES",
2353 ##"OTHERS",
2354 ##"TRANSLATIONS",
2355 ##]:
2356 for fileCategory in self.__knownFileCategories: 2211 for fileCategory in self.__knownFileCategories:
2357 for fn in self.__pdata[fileCategory][:]: 2212 for fn in self.__pdata[fileCategory][:]:
2358 filetype = fileCategory 2213 filetype = fileCategory
2359 bfn = os.path.basename(fn) 2214 bfn = os.path.basename(fn)
2360 for pattern in sorted(self.__pdata["FILETYPES"].keys(), reverse=True): 2215 for pattern in sorted(self.__pdata["FILETYPES"].keys(), reverse=True):
2467 @param fn filename to be removed from the project 2322 @param fn filename to be removed from the project
2468 @param updateModel flag indicating an update of the model is 2323 @param updateModel flag indicating an update of the model is
2469 requested (boolean) 2324 requested (boolean)
2470 """ 2325 """
2471 fn = self.getRelativePath(fn) 2326 fn = self.getRelativePath(fn)
2472 dirty = True 2327 for fileCategory in self.getFileCategories():
2473 # TODO: change this logic to be more generic (use fileCategory) 2328 if fn in self.__pdata[fileCategory]:
2474 if fn in self.__pdata["SOURCES"]: 2329 self.__pdata[fileCategory].remove(fn)
2475 self.__pdata["SOURCES"].remove(fn) 2330 self.projectFileRemoved(fn, fileCategory)
2476 self.projectSourceRemoved.emit(fn) 2331 self.setDirty(True)
2477 elif fn in self.__pdata["FORMS"]: 2332 if updateModel:
2478 self.__pdata["FORMS"].remove(fn) 2333 self.__model.removeItem(fn)
2479 self.projectFormRemoved.emit(fn) 2334 break
2480 elif fn in self.__pdata["INTERFACES"]:
2481 self.__pdata["INTERFACES"].remove(fn)
2482 self.projectInterfaceRemoved.emit(fn)
2483 elif fn in self.__pdata["PROTOCOLS"]:
2484 self.__pdata["PROTOCOLS"].remove(fn)
2485 self.projectProtocolRemoved.emit(fn)
2486 elif fn in self.__pdata["RESOURCES"]:
2487 self.__pdata["RESOURCES"].remove(fn)
2488 self.projectResourceRemoved.emit(fn)
2489 elif fn in self.__pdata["OTHERS"]:
2490 self.__pdata["OTHERS"].remove(fn)
2491 self.projectOthersRemoved.emit(fn)
2492 elif fn in self.__pdata["TRANSLATIONS"]:
2493 self.__pdata["TRANSLATIONS"].remove(fn)
2494 self.projectLanguageRemoved.emit(fn)
2495 else:
2496 dirty = False
2497 updateModel and self.__model.removeItem(fn)
2498 if dirty:
2499 self.setDirty(True)
2500 2335
2501 def removeDirectory(self, dn): 2336 def removeDirectory(self, dn):
2502 """ 2337 """
2503 Public method to remove a directory from the project. 2338 Public method to remove a directory from the project.
2504 2339
2511 for entry in self.__pdata["OTHERS"][:]: 2346 for entry in self.__pdata["OTHERS"][:]:
2512 if entry.startswith(dn): 2347 if entry.startswith(dn):
2513 self.__pdata["OTHERS"].remove(entry) 2348 self.__pdata["OTHERS"].remove(entry)
2514 dirty = True 2349 dirty = True
2515 dn2 = dn if dn.endswith(os.sep) else dn + os.sep 2350 dn2 = dn if dn.endswith(os.sep) else dn + os.sep
2516 ##for key in [
2517 ##"SOURCES",
2518 ##"FORMS",
2519 ##"INTERFACES",
2520 ##"PROTOCOLS",
2521 ##"RESOURCES",
2522 ##"TRANSLATIONS",
2523 ##]:
2524 for fileCategory in [c for c in self.__knownFileCategories if c != "OTHERS"]: 2351 for fileCategory in [c for c in self.__knownFileCategories if c != "OTHERS"]:
2525 for entry in self.__pdata[fileCategory][:]: 2352 for entry in self.__pdata[fileCategory][:]:
2526 if entry.startswith(dn2): 2353 if entry.startswith(dn2):
2527 self.__pdata[fileCategory].remove(entry) 2354 self.__pdata[fileCategory].remove(entry)
2528 dirty = True 2355 dirty = True
2617 return any( 2444 return any(
2618 fn in self.__pdata[category] 2445 fn in self.__pdata[category]
2619 for category in self.__knownFileCategories 2446 for category in self.__knownFileCategories
2620 if category != "TRANSLATIONS" 2447 if category != "TRANSLATIONS"
2621 ) 2448 )
2622 ##fn in self.__pdata["SOURCES"]
2623 ##or fn in self.__pdata["FORMS"]
2624 ##or fn in self.__pdata["INTERFACES"]
2625 ##or fn in self.__pdata["PROTOCOLS"]
2626 ##or fn in self.__pdata["RESOURCES"]
2627 ##or fn in self.__pdata["OTHERS"]
2628 ##)
2629 2449
2630 def createNewProject(self): 2450 def createNewProject(self):
2631 """ 2451 """
2632 Public slot to built a new project. 2452 Public slot to built a new project.
2633 2453
3047 "%language%", "*" 2867 "%language%", "*"
3048 ) 2868 )
3049 for ts in tslist: 2869 for ts in tslist:
3050 if fnmatch.fnmatch(ts, pattern): 2870 if fnmatch.fnmatch(ts, pattern):
3051 self.__pdata["TRANSLATIONS"].append(ts) 2871 self.__pdata["TRANSLATIONS"].append(ts)
3052 self.projectLanguageAdded.emit(ts) 2872 self.projectFileAdded.emit(ts, "TRANSLATIONS")
3053 if self.__pdata["TRANSLATIONSBINPATH"]: 2873 if self.__pdata["TRANSLATIONSBINPATH"]:
3054 tpd = os.path.join( 2874 tpd = os.path.join(
3055 self.ppath, self.__pdata["TRANSLATIONSBINPATH"] 2875 self.ppath, self.__pdata["TRANSLATIONSBINPATH"]
3056 ) 2876 )
3057 pattern = os.path.basename( 2877 pattern = os.path.basename(
3059 ).replace("%language%", "*") 2879 ).replace("%language%", "*")
3060 pattern = self.__binaryTranslationFile(pattern) 2880 pattern = self.__binaryTranslationFile(pattern)
3061 qmlist = Utilities.direntries(tpd, True, pattern) 2881 qmlist = Utilities.direntries(tpd, True, pattern)
3062 for qm in qmlist: 2882 for qm in qmlist:
3063 self.__pdata["TRANSLATIONS"].append(qm) 2883 self.__pdata["TRANSLATIONS"].append(qm)
3064 self.projectLanguageAdded.emit(qm) 2884 self.projectFileAdded.emit(qm, "TRANSLATIONS")
3065 if not self.__pdata["MAINSCRIPT"] and bool(mainscriptname): 2885 if not self.__pdata["MAINSCRIPT"] and bool(mainscriptname):
3066 if self.__pdata["PROGLANGUAGE"] in ["Python3", "MicroPython"]: 2886 if self.__pdata["PROGLANGUAGE"] in ["Python3", "MicroPython"]:
3067 self.__pdata["MAINSCRIPT"] = "{0}.py".format(mainscriptname) 2887 self.__pdata["MAINSCRIPT"] = "{0}.py".format(mainscriptname)
3068 elif self.__pdata["PROGLANGUAGE"] == "Ruby": 2888 elif self.__pdata["PROGLANGUAGE"] == "Ruby":
3069 self.__pdata["MAINSCRIPT"] = "{0}.rb".format(mainscriptname) 2889 self.__pdata["MAINSCRIPT"] = "{0}.rb".format(mainscriptname)
3771 @return list of file names 3591 @return list of file names
3772 @rtype list of str 3592 @rtype list of str
3773 @exception ValueError raised when an unsupported file type is given 3593 @exception ValueError raised when an unsupported file type is given
3774 """ 3594 """
3775 if fileType not in self.__knownFileCategories: 3595 if fileType not in self.__knownFileCategories:
3776 ##[
3777 ##"SOURCES",
3778 ##"FORMS",
3779 ##"RESOURCES",
3780 ##"INTERFACES",
3781 ##"PROTOCOLS",
3782 ##"OTHERS",
3783 ##"TRANSLATIONS",
3784 ##]:
3785 raise ValueError("Given file type has incorrect value.") 3596 raise ValueError("Given file type has incorrect value.")
3786 3597
3787 if normalized: 3598 if normalized:
3788 return [os.path.join(self.ppath, fn) for fn in self.__pdata[fileType]] 3599 return [os.path.join(self.ppath, fn) for fn in self.__pdata[fileType]]
3789 else: 3600 else:
4195 newfn = os.path.abspath(fn) 4006 newfn = os.path.abspath(fn)
4196 newfn = self.getRelativePath(newfn) 4007 newfn = self.getRelativePath(newfn)
4197 return any( 4008 return any(
4198 newfn in self.__pdata[category] 4009 newfn in self.__pdata[category]
4199 for category in self.__knownFileCategories 4010 for category in self.__knownFileCategories
4200 ##[
4201 ##"SOURCES",
4202 ##"FORMS",
4203 ##"INTERFACES",
4204 ##"PROTOCOLS",
4205 ##"RESOURCES",
4206 ##"TRANSLATIONS",
4207 ##"OTHERS",
4208 ##]
4209 ) 4011 )
4210 4012
4211 def isProjectFile(self, fn): 4013 def isProjectFile(self, fn):
4212 """ 4014 """
4213 Public method used to check, if the passed in filename belongs to the 4015 Public method used to check, if the passed in filename belongs to the
4217 @return flag indicating membership (boolean) 4019 @return flag indicating membership (boolean)
4218 """ 4020 """
4219 return any( 4021 return any(
4220 self.__checkProjectFileGroup(fn, category) 4022 self.__checkProjectFileGroup(fn, category)
4221 for category in self.__knownFileCategories 4023 for category in self.__knownFileCategories
4222 ##[
4223 ##"SOURCES",
4224 ##"FORMS",
4225 ##"INTERFACES",
4226 ##"PROTOCOLS",
4227 ##"RESOURCES",
4228 ##"TRANSLATIONS",
4229 ##"OTHERS",
4230 ##]
4231 ) 4024 )
4232 4025
4233 def __checkProjectFileGroup(self, fn, group): 4026 def __checkProjectFileGroup(self, fn, group):
4234 """ 4027 """
4235 Private method to check, if a file is in a specific file group of the 4028 Private method to check, if a file is in a specific file group of the
4258 ): 4051 ):
4259 return True 4052 return True
4260 4053
4261 return False 4054 return False
4262 4055
4263 # TODO: change the following methods to a more generic logic using fileCategories 4056 def isProjectCategory(self, fn, category):
4264 def isProjectSource(self, fn): 4057 """
4265 """ 4058 Public method to check, if the passed in filename belongs to the given
4266 Public method used to check, if the passed in filename belongs to the 4059 category.
4267 project sources.
4268
4269 @param fn filename to be checked (string)
4270 @return flag indicating membership (boolean)
4271 """
4272 return self.__checkProjectFileGroup(fn, "SOURCES")
4273
4274 def isProjectForm(self, fn):
4275 """
4276 Public method used to check, if the passed in filename belongs to the
4277 project forms.
4278
4279 @param fn filename to be checked (string)
4280 @return flag indicating membership (boolean)
4281 """
4282 return self.__checkProjectFileGroup(fn, "FORMS")
4283
4284 def isProjectInterface(self, fn):
4285 """
4286 Public method used to check, if the passed in filename belongs to the
4287 project interfaces.
4288
4289 @param fn filename to be checked (string)
4290 @return flag indicating membership (boolean)
4291 """
4292 return self.__checkProjectFileGroup(fn, "INTERFACES")
4293
4294 def isProjectProtocol(self, fn):
4295 """
4296 Public method used to check, if the passed in filename belongs to the
4297 project protocols.
4298 4060
4299 @param fn filename to be checked 4061 @param fn filename to be checked
4062 @type str
4063 @param category file category to check against
4300 @type str 4064 @type str
4301 @return flag indicating membership 4065 @return flag indicating membership
4302 @rtype bool 4066 @rtype bool
4303 """ 4067 """
4304 return self.__checkProjectFileGroup(fn, "PROTOCOLS") 4068 if category in self.getFileCategories():
4305 4069 return self.__checkProjectFileGroup(fn, category)
4306 def isProjectResource(self, fn): 4070 else:
4307 """ 4071 return False # unknown category always returns False
4308 Public method used to check, if the passed in filename belongs to the
4309 project resources.
4310
4311 @param fn filename to be checked (string)
4312 @return flag indicating membership (boolean)
4313 """
4314 return self.__checkProjectFileGroup(fn, "RESOURCES")
4315 4072
4316 def initActions(self): 4073 def initActions(self):
4317 """ 4074 """
4318 Public slot to initialize the project related actions. 4075 Public slot to initialize the project related actions.
4319 """ 4076 """
5765 or fnmatch.fnmatch(ns, binpattern) 5522 or fnmatch.fnmatch(ns, binpattern)
5766 ) 5523 )
5767 ) 5524 )
5768 ) 5525 )
5769 ): 5526 ):
5770 ##(filetype == "SOURCES" and fn not in self.__pdata["SOURCES"])
5771 ##or (filetype == "FORMS" and fn not in self.__pdata["FORMS"])
5772 ##or (filetype == "INTERFACES" and fn not in self.__pdata["INTERFACES"])
5773 ##or (filetype == "PROTOCOLS" and fn not in self.__pdata["PROTOCOLS"])
5774 ##or (filetype == "RESOURCES" and fn not in self.__pdata["RESOURCES"])
5775 ##or (filetype == "OTHERS" and fn not in self.__pdata["OTHERS"])
5776 ##or (
5777 ##filetype == "TRANSLATIONS"
5778 ##and fn not in self.__pdata["TRANSLATIONS"]
5779 ##and (
5780 ##fnmatch.fnmatch(ns, pattern)
5781 ##or fnmatch.fnmatch(ns, binpattern)
5782 ##)
5783 ##)
5784 ##):
5785 if autoInclude and AI: 5527 if autoInclude and AI:
5786 self.appendFile(ns) 5528 self.appendFile(ns)
5787 else: 5529 else:
5788 newFiles.append(ns) 5530 newFiles.append(ns)
5789 5531
5823 5565
5824 @param fn filename or directory name added (string) 5566 @param fn filename or directory name added (string)
5825 @param updateModel flag indicating an update of the model is requested 5567 @param updateModel flag indicating an update of the model is requested
5826 (boolean) 5568 (boolean)
5827 """ 5569 """
5828 self.projectOthersAdded.emit(fn) 5570 self.projectFileAdded.emit(fn, "OTHERS")
5829 updateModel and self.__model.addNewItem("OTHERS", fn) 5571 updateModel and self.__model.addNewItem("OTHERS", fn)
5830 5572
5831 def getActions(self): 5573 def getActions(self):
5832 """ 5574 """
5833 Public method to get a list of all actions. 5575 Public method to get a list of all actions.
6350 return # don't overwrite 6092 return # don't overwrite
6351 6093
6352 # build the list of entries 6094 # build the list of entries
6353 lst_ = [] 6095 lst_ = []
6354 for key in self.__knownFileCategories: 6096 for key in self.__knownFileCategories:
6355 ##[
6356 ##"SOURCES",
6357 ##"FORMS",
6358 ##"RESOURCES",
6359 ##"TRANSLATIONS",
6360 ##"INTERFACES",
6361 ##"PROTOCOLS",
6362 ##"OTHERS",
6363 ##]:
6364 lst_.extend(self.__pdata[key]) 6097 lst_.extend(self.__pdata[key])
6365 lst = [] 6098 lst = []
6366 for entry in lst_: 6099 for entry in lst_:
6367 if os.path.isdir(self.getAbsolutePath(entry)): 6100 if os.path.isdir(self.getAbsolutePath(entry)):
6368 lst.extend( 6101 lst.extend(
6744 @rtype bool 6477 @rtype bool
6745 """ 6478 """
6746 return self.__pdata["MAKEPARAMS"]["MakeEnabled"] 6479 return self.__pdata["MAKEPARAMS"]["MakeEnabled"]
6747 6480
6748 @pyqtSlot() 6481 @pyqtSlot()
6749 def executeMake(self): 6482 def __autoExecuteMake(self):
6750 """ 6483 """
6751 Public slot to execute a project specific make run (auto-run) 6484 Private slot to execute a project specific make run (auto-run)
6752 (execute or question). 6485 (execute or question).
6753 """ 6486 """
6754 self.__executeMake( 6487 if Preferences.getProject("AutoExecuteMake"):
6755 questionOnly=self.__pdata["MAKEPARAMS"]["MakeTestOnly"], interactive=False 6488 self.__executeMake(
6756 ) 6489 questionOnly=self.__pdata["MAKEPARAMS"]["MakeTestOnly"],
6490 interactive=False,
6491 )
6757 6492
6758 @pyqtSlot() 6493 @pyqtSlot()
6759 def __executeMake(self, questionOnly=False, interactive=True): 6494 def __executeMake(self, questionOnly=False, interactive=True):
6760 """ 6495 """
6761 Private method to execute a project specific make run. 6496 Private method to execute a project specific make run.

eric ide

mercurial