eric6/Project/Project.py

branch
maintenance
changeset 8273
698ae46f40a4
parent 8176
31965986ecd1
parent 8265
0090cfa83159
child 8400
b3eefd7e58d1
equal deleted inserted replaced
8190:fb0ef164f536 8273:698ae46f40a4
12 import shutil 12 import shutil
13 import glob 13 import glob
14 import fnmatch 14 import fnmatch
15 import copy 15 import copy
16 import zipfile 16 import zipfile
17 import contextlib
17 18
18 from PyQt5.QtCore import ( 19 from PyQt5.QtCore import (
19 pyqtSlot, QFile, QFileInfo, pyqtSignal, QCryptographicHash, QIODevice, 20 pyqtSlot, QFile, QFileInfo, pyqtSignal, QCryptographicHash, QIODevice,
20 QByteArray, QObject, QProcess 21 QByteArray, QObject, QProcess
21 ) 22 )
166 Constructor 167 Constructor
167 168
168 @param parent parent widget (usually the ui object) (QWidget) 169 @param parent parent widget (usually the ui object) (QWidget)
169 @param filename optional filename of a project file to open (string) 170 @param filename optional filename of a project file to open (string)
170 """ 171 """
171 super(Project, self).__init__(parent) 172 super().__init__(parent)
172 173
173 self.ui = parent 174 self.ui = parent
174 175
175 self.__progLanguages = [ 176 self.__progLanguages = [
176 "Python3", 177 "Python3",
235 # *.py should always be associated with source files 236 # *.py should always be associated with source files
236 for ext in [".py"]: 237 for ext in [".py"]:
237 if ext not in extensions: 238 if ext not in extensions:
238 extensions.append(ext) 239 extensions.append(ext)
239 return extensions 240 return extensions
240 elif language == "Ruby":
241 return ['.rb']
242 elif language == "JavaScript":
243 return ['.js']
244 elif language == "Mixed":
245 return (Preferences.getPython("Python3Extensions") +
246 ['.rb', '.js'])
247 else: 241 else:
248 return [""] 242 return {
243 "Ruby": [".rb"],
244 "JavaScript": [".js"],
245 "Mixed": (
246 Preferences.getPython("Python3Extensions") +
247 ['.rb', '.js']),
248 }.get(language, "")
249 249
250 def getProgrammingLanguages(self): 250 def getProgrammingLanguages(self):
251 """ 251 """
252 Public method to get the programming languages supported by project. 252 Public method to get the programming languages supported by project.
253 253
605 "makefile": "OTHERS", 605 "makefile": "OTHERS",
606 "Makefile": "OTHERS", 606 "Makefile": "OTHERS",
607 } 607 }
608 608
609 # Sources 609 # Sources
610 if self.pdata["MIXEDLANGUAGE"]: 610 sourceKey = (
611 sourceKey = "Mixed" 611 "Mixed"
612 else: 612 if self.pdata["MIXEDLANGUAGE"] else
613 sourceKey = self.pdata["PROGLANGUAGE"] 613 self.pdata["PROGLANGUAGE"]
614 )
614 for ext in self.__sourceExtensions(sourceKey): 615 for ext in self.__sourceExtensions(sourceKey):
615 self.pdata["FILETYPES"]["*{0}".format(ext)] = "SOURCES" 616 self.pdata["FILETYPES"]["*{0}".format(ext)] = "SOURCES"
616 617
617 # IDL interfaces 618 # IDL interfaces
618 self.pdata["FILETYPES"]["*.idl"] = "INTERFACES" 619 self.pdata["FILETYPES"]["*.idl"] = "INTERFACES"
643 "PySide6", "PySide6C"]: 644 "PySide6", "PySide6C"]:
644 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" 645 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS"
645 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" 646 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS"
646 647
647 # Project type specific ones 648 # Project type specific ones
648 try: 649 with contextlib.suppress(KeyError):
649 if self.__fileTypeCallbacks[ 650 if self.__fileTypeCallbacks[
650 self.pdata["PROJECTTYPE"]] is not None: 651 self.pdata["PROJECTTYPE"]] is not None:
651 ftypes = self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"]]() 652 ftypes = self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"]]()
652 self.pdata["FILETYPES"].update(ftypes) 653 self.pdata["FILETYPES"].update(ftypes)
653 except KeyError:
654 pass
655 654
656 self.setDirty(True) 655 self.setDirty(True)
657 656
658 def updateFileTypes(self): 657 def updateFileTypes(self):
659 """ 658 """
667 "PySide6", "PySide6C"]: 666 "PySide6", "PySide6C"]:
668 if "*.ts" not in self.pdata["FILETYPES"]: 667 if "*.ts" not in self.pdata["FILETYPES"]:
669 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS" 668 self.pdata["FILETYPES"]["*.ts"] = "TRANSLATIONS"
670 if "*.qm" not in self.pdata["FILETYPES"]: 669 if "*.qm" not in self.pdata["FILETYPES"]:
671 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS" 670 self.pdata["FILETYPES"]["*.qm"] = "TRANSLATIONS"
672 try: 671 with contextlib.suppress(KeyError):
673 if self.__fileTypeCallbacks[ 672 if self.__fileTypeCallbacks[
674 self.pdata["PROJECTTYPE"]] is not None: 673 self.pdata["PROJECTTYPE"]] is not None:
675 ftypes = self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"]]() 674 ftypes = self.__fileTypeCallbacks[self.pdata["PROJECTTYPE"]]()
676 for pattern, ftype in list(ftypes.items()): 675 for pattern, ftype in list(ftypes.items()):
677 if pattern not in self.pdata["FILETYPES"]: 676 if pattern not in self.pdata["FILETYPES"]:
678 self.pdata["FILETYPES"][pattern] = ftype 677 self.pdata["FILETYPES"][pattern] = ftype
679 self.setDirty(True) 678 self.setDirty(True)
680 except KeyError:
681 pass
682 679
683 def __loadRecent(self): 680 def __loadRecent(self):
684 """ 681 """
685 Private method to load the recently opened project filenames. 682 Private method to load the recently opened project filenames.
686 """ 683 """
1490 langFile = self.getRelativePath(langFile) 1487 langFile = self.getRelativePath(langFile)
1491 qmFile = self.__binaryTranslationFile(langFile) 1488 qmFile = self.__binaryTranslationFile(langFile)
1492 self.pdata["TRANSLATIONS"].remove(langFile) 1489 self.pdata["TRANSLATIONS"].remove(langFile)
1493 self.__model.removeItem(langFile) 1490 self.__model.removeItem(langFile)
1494 if qmFile: 1491 if qmFile:
1495 try: 1492 with contextlib.suppress(ValueError):
1496 if self.pdata["TRANSLATIONSBINPATH"]: 1493 if self.pdata["TRANSLATIONSBINPATH"]:
1497 qmFile = self.getRelativePath( 1494 qmFile = self.getRelativePath(
1498 os.path.join(self.pdata["TRANSLATIONSBINPATH"], 1495 os.path.join(self.pdata["TRANSLATIONSBINPATH"],
1499 os.path.basename(qmFile))) 1496 os.path.basename(qmFile)))
1500 self.pdata["TRANSLATIONS"].remove(qmFile) 1497 self.pdata["TRANSLATIONS"].remove(qmFile)
1501 self.__model.removeItem(qmFile) 1498 self.__model.removeItem(qmFile)
1502 except ValueError:
1503 pass
1504 self.setDirty(True) 1499 self.setDirty(True)
1505 1500
1506 def deleteLanguageFile(self, langFile): 1501 def deleteLanguageFile(self, langFile):
1507 """ 1502 """
1508 Public slot to delete a translation from the project directory. 1503 Public slot to delete a translation from the project directory.
1509 1504
1510 @param langFile the translation file to be removed (string) 1505 @param langFile the translation file to be removed (string)
1511 """ 1506 """
1512 try: 1507 try:
1513 from ThirdParty.Send2Trash.send2trash import send2trash as s2t 1508 from send2trash import send2trash as s2t
1514 except ImportError: 1509 except ImportError:
1515 s2t = os.remove 1510 s2t = os.remove
1516 1511
1517 langFile = self.getRelativePath(langFile) 1512 langFile = self.getRelativePath(langFile)
1518 qmFile = self.__binaryTranslationFile(langFile) 1513 qmFile = self.__binaryTranslationFile(langFile)
1563 @param updateModel flag indicating an update of the model is 1558 @param updateModel flag indicating an update of the model is
1564 requested (boolean) 1559 requested (boolean)
1565 """ 1560 """
1566 dirty = False 1561 dirty = False
1567 1562
1568 if os.path.isabs(fn): 1563 # make it relative to the project root, if it starts with that path
1569 # make it relative to the project root, if it starts with that path 1564 # assume relative paths are relative to the project root
1570 newfn = self.getRelativePath(fn) 1565 newfn = self.getRelativePath(fn) if os.path.isabs(fn) else fn
1571 else:
1572 # assume relative paths are relative to the project root
1573 newfn = fn
1574 newdir = os.path.dirname(newfn) 1566 newdir = os.path.dirname(newfn)
1575 1567
1576 if isSourceFile: 1568 if isSourceFile:
1577 filetype = "SOURCES" 1569 filetype = "SOURCES"
1578 else: 1570 else:
2216 dn = self.getRelativePath(dn) 2208 dn = self.getRelativePath(dn)
2217 for entry in self.pdata["OTHERS"][:]: 2209 for entry in self.pdata["OTHERS"][:]:
2218 if entry.startswith(dn): 2210 if entry.startswith(dn):
2219 self.pdata["OTHERS"].remove(entry) 2211 self.pdata["OTHERS"].remove(entry)
2220 dirty = True 2212 dirty = True
2221 if not dn.endswith(os.sep): 2213 dn2 = dn if dn.endswith(os.sep) else dn + os.sep
2222 dn2 = dn + os.sep
2223 else:
2224 dn2 = dn
2225 for key in ["SOURCES", "FORMS", "INTERFACES", "PROTOCOLS", "RESOURCES", 2214 for key in ["SOURCES", "FORMS", "INTERFACES", "PROTOCOLS", "RESOURCES",
2226 "TRANSLATIONS", ]: 2215 "TRANSLATIONS", ]:
2227 for entry in self.pdata[key][:]: 2216 for entry in self.pdata[key][:]:
2228 if entry.startswith(dn2): 2217 if entry.startswith(dn2):
2229 self.pdata[key].remove(entry) 2218 self.pdata[key].remove(entry)
2239 2228
2240 @param fn filename to be deleted from the project 2229 @param fn filename to be deleted from the project
2241 @return flag indicating success (boolean) 2230 @return flag indicating success (boolean)
2242 """ 2231 """
2243 try: 2232 try:
2244 from ThirdParty.Send2Trash.send2trash import send2trash as s2t 2233 from send2trash import send2trash as s2t
2245 except ImportError: 2234 except ImportError:
2246 s2t = os.remove 2235 s2t = os.remove
2247 2236
2248 try: 2237 try:
2249 s2t(os.path.join(self.ppath, fn)) 2238 s2t(os.path.join(self.ppath, fn))
2286 """ 2275 """
2287 if not os.path.isabs(dn): 2276 if not os.path.isabs(dn):
2288 dn = os.path.join(self.ppath, dn) 2277 dn = os.path.join(self.ppath, dn)
2289 try: 2278 try:
2290 try: 2279 try:
2291 from ThirdParty.Send2Trash.send2trash import send2trash 2280 from send2trash import send2trash
2292 send2trash(dn) 2281 send2trash(dn)
2293 except ImportError: 2282 except ImportError:
2294 shutil.rmtree(dn, True) 2283 shutil.rmtree(dn, True)
2295 except OSError as err: 2284 except OSError as err:
2296 E5MessageBox.critical( 2285 E5MessageBox.critical(
2310 2299
2311 @param fn filename to be checked (string) 2300 @param fn filename to be checked (string)
2312 @return flag indicating, if the project contains the file (boolean) 2301 @return flag indicating, if the project contains the file (boolean)
2313 """ 2302 """
2314 fn = self.getRelativePath(fn) 2303 fn = self.getRelativePath(fn)
2315 if ( 2304 return (
2316 fn in self.pdata["SOURCES"] or 2305 fn in self.pdata["SOURCES"] or
2317 fn in self.pdata["FORMS"] or 2306 fn in self.pdata["FORMS"] or
2318 fn in self.pdata["INTERFACES"] or 2307 fn in self.pdata["INTERFACES"] or
2319 fn in self.pdata["PROTOCOLS"] or 2308 fn in self.pdata["PROTOCOLS"] or
2320 fn in self.pdata["RESOURCES"] or 2309 fn in self.pdata["RESOURCES"] or
2321 fn in self.pdata["OTHERS"] 2310 fn in self.pdata["OTHERS"]
2322 ): 2311 )
2323 return True
2324 else:
2325 return False
2326 2312
2327 def createNewProject(self): 2313 def createNewProject(self):
2328 """ 2314 """
2329 Public slot to built a new project. 2315 Public slot to built a new project.
2330 2316
2928 if fnmatch.fnmatch(filename, pattern): 2914 if fnmatch.fnmatch(filename, pattern):
2929 return language 2915 return language
2930 2916
2931 # try project type specific defaults next 2917 # try project type specific defaults next
2932 projectType = self.pdata["PROJECTTYPE"] 2918 projectType = self.pdata["PROJECTTYPE"]
2933 try: 2919 with contextlib.suppress(KeyError):
2934 if self.__lexerAssociationCallbacks[projectType] is not None: 2920 if self.__lexerAssociationCallbacks[projectType] is not None:
2935 return self.__lexerAssociationCallbacks[projectType](filename) 2921 return self.__lexerAssociationCallbacks[projectType](filename)
2936 except KeyError:
2937 pass
2938 2922
2939 # return empty string to signal to use the global setting 2923 # return empty string to signal to use the global setting
2940 return "" 2924 return ""
2941 2925
2942 @pyqtSlot() 2926 @pyqtSlot()
2961 Utilities.getHomeDir(), 2945 Utilities.getHomeDir(),
2962 self.tr("Project Files (*.epj);;XML Project Files (*.e4p)")) 2946 self.tr("Project Files (*.epj);;XML Project Files (*.e4p)"))
2963 2947
2964 QApplication.processEvents() 2948 QApplication.processEvents()
2965 2949
2966 if fn: 2950 if fn and self.closeProject():
2967 if self.closeProject(): 2951 with E5OverrideCursor():
2952 ok = self.__readProject(fn)
2953 if ok:
2954 self.opened = True
2955 if not self.pdata["FILETYPES"]:
2956 self.initFileTypes()
2957 else:
2958 self.updateFileTypes()
2959
2960 try:
2961 # create management directory if not present
2962 self.createProjectManagementDir()
2963 except OSError:
2964 E5MessageBox.critical(
2965 self.ui,
2966 self.tr("Create project management directory"),
2967 self.tr(
2968 "<p>The project directory <b>{0}</b> is not"
2969 " writable.</p>")
2970 .format(self.ppath))
2971 return
2972
2973 # read a user specific project file
2974 self.__readUserProperties()
2975
2968 with E5OverrideCursor(): 2976 with E5OverrideCursor():
2969 ok = self.__readProject(fn) 2977 oldState = self.isDirty()
2970 if ok: 2978 self.vcs = self.initVCS()
2971 self.opened = True 2979 if self.vcs is None and self.isDirty() == oldState:
2972 if not self.pdata["FILETYPES"]: 2980 # check, if project is version controlled
2973 self.initFileTypes() 2981 pluginManager = e5App().getObject("PluginManager")
2974 else: 2982 for indicator, vcsData in (
2975 self.updateFileTypes() 2983 pluginManager.getVcsSystemIndicators().items()
2976 2984 ):
2977 try: 2985 if os.path.exists(
2978 # create management directory if not present 2986 os.path.join(self.ppath, indicator)):
2979 self.createProjectManagementDir() 2987 if len(vcsData) > 1:
2980 except OSError: 2988 vcsList = []
2981 E5MessageBox.critical( 2989 for (
2982 self.ui, 2990 _vcsSystemStr, vcsSystemDisplay
2983 self.tr("Create project management directory"), 2991 ) in vcsData:
2984 self.tr( 2992 vcsList.append(vcsSystemDisplay)
2985 "<p>The project directory <b>{0}</b> is not" 2993 with E5OverridenCursor():
2986 " writable.</p>") 2994 res, vcs_ok = QInputDialog.getItem(
2987 .format(self.ppath)) 2995 None,
2988 return 2996 self.tr("New Project"),
2989 2997 self.tr(
2990 # read a user specific project file 2998 "Select Version Control"
2991 self.__readUserProperties() 2999 " System"),
2992 3000 vcsList,
2993 with E5OverrideCursor(): 3001 0, False)
2994 oldState = self.isDirty() 3002 if vcs_ok:
2995 self.vcs = self.initVCS()
2996 if self.vcs is None and self.isDirty() == oldState:
2997 # check, if project is version controlled
2998 pluginManager = e5App().getObject("PluginManager")
2999 for indicator, vcsData in (
3000 pluginManager.getVcsSystemIndicators().items()
3001 ):
3002 if os.path.exists(
3003 os.path.join(self.ppath, indicator)):
3004 if len(vcsData) > 1:
3005 vcsList = []
3006 for ( 3003 for (
3007 _vcsSystemStr, vcsSystemDisplay 3004 vcsSystemStr, vcsSystemDisplay
3008 ) in vcsData: 3005 ) in vcsData:
3009 vcsList.append(vcsSystemDisplay) 3006 if res == vcsSystemDisplay:
3010 with E5OverridenCursor(): 3007 vcsSystem = vcsSystemStr
3011 res, vcs_ok = QInputDialog.getItem( 3008 break
3012 None,
3013 self.tr("New Project"),
3014 self.tr(
3015 "Select Version Control"
3016 " System"),
3017 vcsList,
3018 0, False)
3019 if vcs_ok:
3020 for (
3021 vcsSystemStr, vcsSystemDisplay
3022 ) in vcsData:
3023 if res == vcsSystemDisplay:
3024 vcsSystem = vcsSystemStr
3025 break
3026 else:
3027 vcsSystem = "None"
3028 else: 3009 else:
3029 vcsSystem = "None" 3010 vcsSystem = "None"
3030 else: 3011 else:
3031 vcsSystem = vcsData[0][0] 3012 vcsSystem = "None"
3032 self.pdata["VCS"] = vcsSystem 3013 else:
3033 self.vcs = self.initVCS() 3014 vcsSystem = vcsData[0][0]
3034 self.setDirty(True) 3015 self.pdata["VCS"] = vcsSystem
3035 if ( 3016 self.vcs = self.initVCS()
3036 self.vcs is not None and 3017 self.setDirty(True)
3037 (self.vcs.vcsRegisteredState(self.ppath) != 3018 if (
3038 self.vcs.canBeCommitted) 3019 self.vcs is not None and
3039 ): 3020 (self.vcs.vcsRegisteredState(self.ppath) !=
3040 self.pdata["VCS"] = 'None' 3021 self.vcs.canBeCommitted)
3041 self.vcs = self.initVCS() 3022 ):
3042 self.closeAct.setEnabled(True) 3023 self.pdata["VCS"] = 'None'
3043 self.saveasAct.setEnabled(True) 3024 self.vcs = self.initVCS()
3044 self.actGrp2.setEnabled(True) 3025 self.closeAct.setEnabled(True)
3045 self.propsAct.setEnabled(True) 3026 self.saveasAct.setEnabled(True)
3046 self.userPropsAct.setEnabled(True) 3027 self.actGrp2.setEnabled(True)
3047 self.filetypesAct.setEnabled(True) 3028 self.propsAct.setEnabled(True)
3048 self.lexersAct.setEnabled(True) 3029 self.userPropsAct.setEnabled(True)
3049 self.sessActGrp.setEnabled(True) 3030 self.filetypesAct.setEnabled(True)
3050 self.dbgActGrp.setEnabled(True) 3031 self.lexersAct.setEnabled(True)
3051 self.menuDebuggerAct.setEnabled(True) 3032 self.sessActGrp.setEnabled(True)
3052 self.menuSessionAct.setEnabled(True) 3033 self.dbgActGrp.setEnabled(True)
3053 self.menuCheckAct.setEnabled(True) 3034 self.menuDebuggerAct.setEnabled(True)
3054 self.menuShowAct.setEnabled(True) 3035 self.menuSessionAct.setEnabled(True)
3055 self.menuDiagramAct.setEnabled(True) 3036 self.menuCheckAct.setEnabled(True)
3056 self.menuApidocAct.setEnabled(True) 3037 self.menuShowAct.setEnabled(True)
3057 self.menuPackagersAct.setEnabled(True) 3038 self.menuDiagramAct.setEnabled(True)
3058 self.pluginGrp.setEnabled( 3039 self.menuApidocAct.setEnabled(True)
3059 self.pdata["PROJECTTYPE"] in ["E6Plugin"]) 3040 self.menuPackagersAct.setEnabled(True)
3060 self.addLanguageAct.setEnabled( 3041 self.pluginGrp.setEnabled(
3061 bool(self.pdata["TRANSLATIONPATTERN"])) 3042 self.pdata["PROJECTTYPE"] in ["E6Plugin"])
3062 self.makeGrp.setEnabled( 3043 self.addLanguageAct.setEnabled(
3063 self.pdata["MAKEPARAMS"]["MakeEnabled"]) 3044 bool(self.pdata["TRANSLATIONPATTERN"]))
3064 self.menuMakeAct.setEnabled( 3045 self.makeGrp.setEnabled(
3065 self.pdata["MAKEPARAMS"]["MakeEnabled"]) 3046 self.pdata["MAKEPARAMS"]["MakeEnabled"])
3066 3047 self.menuMakeAct.setEnabled(
3067 # open a project debugger properties file being quiet 3048 self.pdata["MAKEPARAMS"]["MakeEnabled"])
3068 # about errors
3069 if Preferences.getProject("AutoLoadDbgProperties"):
3070 self.__readDebugProperties(True)
3071
3072 self.__model.projectOpened()
3073 self.projectOpenedHooks.emit()
3074 self.projectOpened.emit()
3075 3049
3076 if Preferences.getProject("SearchNewFiles"): 3050 # open a project debugger properties file being quiet
3077 self.__doSearchNewFiles() 3051 # about errors
3052 if Preferences.getProject("AutoLoadDbgProperties"):
3053 self.__readDebugProperties(True)
3078 3054
3079 # read a project tasks file 3055 self.__model.projectOpened()
3080 self.__readTasks() 3056 self.projectOpenedHooks.emit()
3081 self.ui.taskViewer.setProjectOpen(True) 3057 self.projectOpened.emit()
3082 # rescan project tasks 3058
3083 if Preferences.getProject("TasksProjectRescanOnOpen"): 3059 if Preferences.getProject("SearchNewFiles"):
3084 e5App().getObject("TaskViewer" 3060 self.__doSearchNewFiles()
3085 ).regenerateProjectTasks(quiet=True) 3061
3062 # read a project tasks file
3063 self.__readTasks()
3064 self.ui.taskViewer.setProjectOpen(True)
3065 # rescan project tasks
3066 if Preferences.getProject("TasksProjectRescanOnOpen"):
3067 e5App().getObject("TaskViewer"
3068 ).regenerateProjectTasks(quiet=True)
3069
3070 if restoreSession:
3071 # open the main script
3072 if self.pdata["MAINSCRIPT"]:
3073 if not os.path.isabs(self.pdata["MAINSCRIPT"]):
3074 ms = os.path.join(
3075 self.ppath, self.pdata["MAINSCRIPT"])
3076 else:
3077 ms = self.pdata["MAINSCRIPT"]
3078 self.sourceFile.emit(ms)
3086 3079
3087 if restoreSession: 3080 # open a project session file being quiet about errors
3088 # open the main script 3081 if reopen:
3089 if self.pdata["MAINSCRIPT"]: 3082 self.__readSession(quiet=True, indicator="_tmp")
3090 if not os.path.isabs(self.pdata["MAINSCRIPT"]): 3083 elif Preferences.getProject("AutoLoadSession"):
3091 ms = os.path.join( 3084 self.__readSession(quiet=True)
3092 self.ppath, self.pdata["MAINSCRIPT"]) 3085
3093 else: 3086 # start the VCS monitor thread
3094 ms = self.pdata["MAINSCRIPT"] 3087 if self.vcs is not None:
3095 self.sourceFile.emit(ms) 3088 self.vcs.startStatusMonitor(self)
3096 3089 self.vcs.vcsStatusMonitorData.connect(
3097 # open a project session file being quiet about errors 3090 self.__model.changeVCSStates)
3098 if reopen: 3091 self.vcs.vcsStatusMonitorStatus.connect(
3099 self.__readSession(quiet=True, indicator="_tmp") 3092 self.__statusMonitorStatus)
3100 elif Preferences.getProject("AutoLoadSession"): 3093 self.vcs.vcsStatusMonitorInfo.connect(
3101 self.__readSession(quiet=True) 3094 self.vcsStatusMonitorInfo)
3102 3095 self.vcs.vcsStatusChanged.connect(
3103 # start the VCS monitor thread 3096 self.__vcsStatusChanged)
3104 if self.vcs is not None:
3105 self.vcs.startStatusMonitor(self)
3106 self.vcs.vcsStatusMonitorData.connect(
3107 self.__model.changeVCSStates)
3108 self.vcs.vcsStatusMonitorStatus.connect(
3109 self.__statusMonitorStatus)
3110 self.vcs.vcsStatusMonitorInfo.connect(
3111 self.vcsStatusMonitorInfo)
3112 self.vcs.vcsStatusChanged.connect(
3113 self.__vcsStatusChanged)
3114 3097
3115 def reopenProject(self): 3098 def reopenProject(self):
3116 """ 3099 """
3117 Public slot to reopen the current project. 3100 Public slot to reopen the current project.
3118 """ 3101 """
3146 Public slot to save the current project to a different file. 3129 Public slot to save the current project to a different file.
3147 3130
3148 @return flag indicating success (boolean) 3131 @return flag indicating success (boolean)
3149 """ 3132 """
3150 defaultFilter = self.tr("Project Files (*.epj)") 3133 defaultFilter = self.tr("Project Files (*.epj)")
3151 if self.ppath: 3134 defaultPath = (
3152 defaultPath = self.ppath 3135 self.ppath
3153 else: 3136 if self.ppath else
3154 defaultPath = ( 3137 (Preferences.getMultiProject("Workspace") or
3155 Preferences.getMultiProject("Workspace") or 3138 Utilities.getHomeDir())
3156 Utilities.getHomeDir() 3139 )
3157 )
3158 fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( 3140 fn, selectedFilter = E5FileDialog.getSaveFileNameAndFilter(
3159 self.parent(), 3141 self.parent(),
3160 self.tr("Save project as"), 3142 self.tr("Save project as"),
3161 defaultPath, 3143 defaultPath,
3162 self.tr("Project Files (*.epj);;" 3144 self.tr("Project Files (*.epj);;"
3542 programming language. 3524 programming language.
3543 3525
3544 @return default extension (including the dot) (string) 3526 @return default extension (including the dot) (string)
3545 """ 3527 """
3546 lang = self.pdata["PROGLANGUAGE"] 3528 lang = self.pdata["PROGLANGUAGE"]
3547 if lang == "": 3529 if lang in ("", "Python"):
3548 lang = "Python3"
3549 elif lang == "Python":
3550 lang = "Python3" 3530 lang = "Python3"
3551 return self.__sourceExtensions(lang)[0] 3531 return self.__sourceExtensions(lang)[0]
3552 3532
3553 def getProjectPath(self): 3533 def getProjectPath(self):
3554 """ 3534 """
3560 3540
3561 def startswithProjectPath(self, path): 3541 def startswithProjectPath(self, path):
3562 """ 3542 """
3563 Public method to check, if a path starts with the project path. 3543 Public method to check, if a path starts with the project path.
3564 3544
3565 @param path path to be checked (string) 3545 @param path path to be checked
3546 @type str
3566 @return flag indicating that the path starts with the project path 3547 @return flag indicating that the path starts with the project path
3567 (boolean) 3548 @rtype bool
3568 """ 3549 """
3569 if self.ppath: 3550 return (
3570 if path == self.ppath: 3551 bool(self.ppath) and
3571 return True 3552 (path == self.ppath or
3572 elif ( 3553 Utilities.normcasepath(Utilities.toNativeSeparators(path))
3573 Utilities.normcasepath(Utilities.toNativeSeparators(path)) 3554 .startswith(Utilities.normcasepath(
3574 .startswith(Utilities.normcasepath( 3555 Utilities.toNativeSeparators(self.ppath + "/")))
3575 Utilities.toNativeSeparators(self.ppath + "/"))) 3556 )
3576 ): 3557 )
3577 return True 3558
3578 else:
3579 return False
3580 else:
3581 return False
3582
3583 def getProjectFile(self): 3559 def getProjectFile(self):
3584 """ 3560 """
3585 Public method to get the path of the project file. 3561 Public method to get the path of the project file.
3586 3562
3587 @return path of the project file (string) 3563 @return path of the project file (string)
3767 @return flag indicating membership 3743 @return flag indicating membership
3768 @rtype bool 3744 @rtype bool
3769 """ 3745 """
3770 newfn = os.path.abspath(fn) 3746 newfn = os.path.abspath(fn)
3771 newfn = self.getRelativePath(newfn) 3747 newfn = self.getRelativePath(newfn)
3772 for group in ["SOURCES", "FORMS", "INTERFACES", "PROTOCOLS", 3748 return any(
3773 "RESOURCES", "TRANSLATIONS", "OTHERS"]: 3749 newfn in self.pdata[group]
3774 if newfn in self.pdata[group]: 3750 for group in [
3775 return True 3751 "SOURCES", "FORMS", "INTERFACES", "PROTOCOLS", "RESOURCES",
3776 return False 3752 "TRANSLATIONS", "OTHERS"
3753 ]
3754 )
3777 3755
3778 def isProjectFile(self, fn): 3756 def isProjectFile(self, fn):
3779 """ 3757 """
3780 Public method used to check, if the passed in filename belongs to the 3758 Public method used to check, if the passed in filename belongs to the
3781 project. 3759 project.
3782 3760
3783 @param fn filename to be checked (string) 3761 @param fn filename to be checked (string)
3784 @return flag indicating membership (boolean) 3762 @return flag indicating membership (boolean)
3785 """ 3763 """
3786 for group in ["SOURCES", "FORMS", "INTERFACES", "PROTOCOLS", 3764 return any(
3787 "RESOURCES", "TRANSLATIONS", "OTHERS"]: 3765 self.__checkProjectFileGroup(fn, group)
3788 if self.__checkProjectFileGroup(fn, group): 3766 for group in [
3789 return True 3767 "SOURCES", "FORMS", "INTERFACES", "PROTOCOLS", "RESOURCES",
3790 3768 "TRANSLATIONS", "OTHERS"
3791 return False 3769 ]
3770 )
3792 3771
3793 def __checkProjectFileGroup(self, fn, group): 3772 def __checkProjectFileGroup(self, fn, group):
3794 """ 3773 """
3795 Private method to check, if a file is in a specific file group of the 3774 Private method to check, if a file is in a specific file group of the
3796 project. 3775 project.
3799 @param group group to check (string) 3778 @param group group to check (string)
3800 @return flag indicating membership (boolean) 3779 @return flag indicating membership (boolean)
3801 """ 3780 """
3802 newfn = os.path.abspath(fn) 3781 newfn = os.path.abspath(fn)
3803 newfn = self.getRelativePath(newfn) 3782 newfn = self.getRelativePath(newfn)
3804 if newfn in self.pdata[group]: 3783 if (
3784 newfn in self.pdata[group] or
3785 (group == "OTHERS" and
3786 any(newfn.startswith(entry) for entry in self.pdata[group]))
3787 ):
3805 return True 3788 return True
3806 elif group == "OTHERS":
3807 for entry in self.pdata[group]:
3808 if newfn.startswith(entry):
3809 return True
3810 3789
3811 if Utilities.isWindowsPlatform(): 3790 if Utilities.isWindowsPlatform():
3812 # try the above case-insensitive 3791 # try the above case-insensitive
3813 newfn = newfn.lower() 3792 newfn = newfn.lower()
3814 for entry in self.pdata[group]: 3793 if any(entry.lower() == newfn for entry in self.pdata[group]):
3815 if entry.lower() == newfn: 3794 return True
3816 return True 3795 elif (
3817 elif group == "OTHERS": 3796 group == "OTHERS" and
3818 for entry in self.pdata[group]: 3797 any(newfn.startswith(entry.lower())
3819 if newfn.startswith(entry.lower()): 3798 for entry in self.pdata[group])
3820 return True 3799 ):
3800 return True
3821 3801
3822 return False 3802 return False
3823 3803
3824 def isProjectSource(self, fn): 3804 def isProjectSource(self, fn):
3825 """ 3805 """
4564 """ 4544 """
4565 self.__loadRecent() 4545 self.__loadRecent()
4566 4546
4567 self.recentMenu.clear() 4547 self.recentMenu.clear()
4568 4548
4569 idx = 1 4549 for idx, rp in enumerate(self.recent, start=1):
4570 for rp in self.recent: 4550 formatStr = '&{0:d}. {1}' if idx < 10 else '{0:d}. {1}'
4571 if idx < 10:
4572 formatStr = '&{0:d}. {1}'
4573 else:
4574 formatStr = '{0:d}. {1}'
4575 act = self.recentMenu.addAction( 4551 act = self.recentMenu.addAction(
4576 formatStr.format( 4552 formatStr.format(
4577 idx, 4553 idx,
4578 Utilities.compactPath(rp, self.ui.maxMenuFilePathLen))) 4554 Utilities.compactPath(rp, self.ui.maxMenuFilePathLen)))
4579 act.setData(rp) 4555 act.setData(rp)
4580 act.setEnabled(QFileInfo(rp).exists()) 4556 act.setEnabled(QFileInfo(rp).exists())
4581 idx += 1
4582 4557
4583 self.recentMenu.addSeparator() 4558 self.recentMenu.addSeparator()
4584 self.recentMenu.addAction(self.tr('&Clear'), self.clearRecent) 4559 self.recentMenu.addAction(self.tr('&Clear'), self.clearRecent)
4585 4560
4586 def __openRecent(self, act): 4561 def __openRecent(self, act):
4669 curpath = os.path.join(self.ppath, directory) 4644 curpath = os.path.join(self.ppath, directory)
4670 try: 4645 try:
4671 newSources = os.listdir(curpath) 4646 newSources = os.listdir(curpath)
4672 except OSError: 4647 except OSError:
4673 newSources = [] 4648 newSources = []
4674 if self.pdata["TRANSLATIONPATTERN"]: 4649 pattern = (
4675 pattern = ( 4650 self.pdata["TRANSLATIONPATTERN"].replace("%language%", "*")
4676 self.pdata["TRANSLATIONPATTERN"] 4651 if self.pdata["TRANSLATIONPATTERN"] else
4677 .replace("%language%", "*") 4652 "*.ts"
4678 ) 4653 )
4679 else:
4680 pattern = "*.ts"
4681 binpattern = self.__binaryTranslationFile(pattern) 4654 binpattern = self.__binaryTranslationFile(pattern)
4682 for ns in newSources: 4655 for ns in newSources:
4683 # ignore hidden files and directories 4656 # ignore hidden files and directories
4684 if ns.startswith('.'): 4657 if ns.startswith('.'):
4685 continue 4658 continue
4692 continue 4665 continue
4693 4666
4694 # set fn to project relative name 4667 # set fn to project relative name
4695 # then reset ns to fully qualified name for insertion, 4668 # then reset ns to fully qualified name for insertion,
4696 # possibly. 4669 # possibly.
4697 if directory == "": 4670 fn = os.path.join(directory, ns) if directory else ns
4698 fn = ns
4699 else:
4700 fn = os.path.join(directory, ns)
4701 ns = os.path.abspath(os.path.join(curpath, ns)) 4671 ns = os.path.abspath(os.path.join(curpath, ns))
4702 4672
4703 # do not bother with dirs here... 4673 # do not bother with dirs here...
4704 if os.path.isdir(ns): 4674 if os.path.isdir(ns):
4705 if recursiveSearch: 4675 if recursiveSearch:
4726 (filetype == "PROTOCOLS" and 4696 (filetype == "PROTOCOLS" and
4727 fn not in self.pdata["PROTOCOLS"]) or 4697 fn not in self.pdata["PROTOCOLS"]) or
4728 (filetype == "RESOURCES" and 4698 (filetype == "RESOURCES" and
4729 fn not in self.pdata["RESOURCES"]) or 4699 fn not in self.pdata["RESOURCES"]) or
4730 (filetype == "OTHERS" and 4700 (filetype == "OTHERS" and
4731 fn not in self.pdata["OTHERS"]) 4701 fn not in self.pdata["OTHERS"]) or
4702 (filetype == "TRANSLATIONS" and
4703 fn not in self.pdata["TRANSLATIONS"] and
4704 (fnmatch.fnmatch(ns, pattern) or
4705 fnmatch.fnmatch(ns, binpattern)))
4732 ): 4706 ):
4733 if autoInclude and AI: 4707 if autoInclude and AI:
4734 self.appendFile(ns) 4708 self.appendFile(ns)
4735 else: 4709 else:
4736 newFiles.append(ns) 4710 newFiles.append(ns)
4737 elif (
4738 filetype == "TRANSLATIONS" and
4739 fn not in self.pdata["TRANSLATIONS"]
4740 ):
4741 if (
4742 fnmatch.fnmatch(ns, pattern) or
4743 fnmatch.fnmatch(ns, binpattern)
4744 ):
4745 if autoInclude and AI:
4746 self.appendFile(ns)
4747 else:
4748 newFiles.append(ns)
4749 4711
4750 # if autoInclude is set there is no more work left 4712 # if autoInclude is set there is no more work left
4751 if (autoInclude and AI): 4713 if (autoInclude and AI):
4752 return 4714 return
4753 4715
4809 Public method to remove actions from the list of actions. 4771 Public method to remove actions from the list of actions.
4810 4772
4811 @param actions list of actions (list of E5Action) 4773 @param actions list of actions (list of E5Action)
4812 """ 4774 """
4813 for act in actions: 4775 for act in actions:
4814 try: 4776 with contextlib.suppress(ValueError):
4815 self.actions.remove(act) 4777 self.actions.remove(act)
4816 except ValueError:
4817 pass
4818 4778
4819 def getMenu(self, menuName): 4779 def getMenu(self, menuName):
4820 """ 4780 """
4821 Public method to get a reference to the main menu or a submenu. 4781 Public method to get a reference to the main menu or a submenu.
4822 4782
4864 if self.pdata["VCS"] and self.pdata["VCS"] != 'None': 4824 if self.pdata["VCS"] and self.pdata["VCS"] != 'None':
4865 vcsSystem = self.pdata["VCS"] 4825 vcsSystem = self.pdata["VCS"]
4866 else: 4826 else:
4867 forProject = False 4827 forProject = False
4868 4828
4869 if forProject and self.pdata["VCS"] and self.pdata["VCS"] != 'None': 4829 if (
4870 if ( 4830 forProject and
4871 self.pudata["VCSOVERRIDE"] and 4831 self.pdata["VCS"] and
4872 not nooverride 4832 self.pdata["VCS"] != 'None' and
4873 ): 4833 self.pudata["VCSOVERRIDE"] and
4874 vcsSystem = self.pudata["VCSOVERRIDE"] 4834 not nooverride
4875 override = True 4835 ):
4836 vcsSystem = self.pudata["VCSOVERRIDE"]
4837 override = True
4876 4838
4877 if vcsSystem is not None: 4839 if vcsSystem is not None:
4878 import VCS 4840 import VCS
4879 try: 4841 try:
4880 vcs = VCS.factory(vcsSystem) 4842 vcs = VCS.factory(vcsSystem)
4917 vcs.vcsInitConfig(self) 4879 vcs.vcsInitConfig(self)
4918 4880
4919 if vcs and forProject: 4881 if vcs and forProject:
4920 # set the vcs options 4882 # set the vcs options
4921 if vcs.vcsSupportCommandOptions(): 4883 if vcs.vcsSupportCommandOptions():
4922 try: 4884 with contextlib.suppress(LookupError):
4923 vcsopt = copy.deepcopy(self.pdata["VCSOPTIONS"]) 4885 vcsopt = copy.deepcopy(self.pdata["VCSOPTIONS"])
4924 vcs.vcsSetOptions(vcsopt) 4886 vcs.vcsSetOptions(vcsopt)
4925 except LookupError:
4926 pass
4927 # set vcs specific data 4887 # set vcs specific data
4928 try: 4888 with contextlib.suppress(LookupError):
4929 vcsother = copy.deepcopy(self.pdata["VCSOTHERDATA"]) 4889 vcsother = copy.deepcopy(self.pdata["VCSOTHERDATA"])
4930 vcs.vcsSetOtherData(vcsother) 4890 vcs.vcsSetOtherData(vcsother)
4931 except LookupError:
4932 pass
4933 4891
4934 if forProject: 4892 if forProject:
4935 if vcs is None: 4893 if vcs is None:
4936 import VCS 4894 import VCS
4937 self.vcsProjectHelper = VCS.getBasicHelper(self) 4895 self.vcsProjectHelper = VCS.getBasicHelper(self)
5339 " ", 5297 " ",
5340 ] 5298 ]
5341 5299
5342 # write the file 5300 # write the file
5343 try: 5301 try:
5344 if self.pdata["EOL"] == 0: 5302 newline = None if self.pdata["EOL"] == 0 else self.getEolString()
5345 newline = None
5346 else:
5347 newline = self.getEolString()
5348 with open(pkglist, "w", encoding="utf-8", 5303 with open(pkglist, "w", encoding="utf-8",
5349 newline=newline) as pkglistFile: 5304 newline=newline) as pkglistFile:
5350 pkglistFile.write("\n".join(header) + "\n") 5305 pkglistFile.write("\n".join(header) + "\n")
5351 pkglistFile.write( 5306 pkglistFile.write(
5352 "\n".join([Utilities.fromNativeSeparators(f) 5307 "\n".join([Utilities.fromNativeSeparators(f)
5408 progress = E5ProgressDialog( 5363 progress = E5ProgressDialog(
5409 self.tr("Creating plugin archives..."), self.tr("Abort"), 5364 self.tr("Creating plugin archives..."), self.tr("Abort"),
5410 0, len(selectedLists), self.tr("%v/%m Archives")) 5365 0, len(selectedLists), self.tr("%v/%m Archives"))
5411 progress.setMinimumDuration(0) 5366 progress.setMinimumDuration(0)
5412 progress.setWindowTitle(self.tr("Create Plugin Archives")) 5367 progress.setWindowTitle(self.tr("Create Plugin Archives"))
5413 count = 0
5414 errors = 0 5368 errors = 0
5415 for pkglist in selectedLists: 5369 for count, pkglist in enumerate(selectedLists):
5416 progress.setValue(count) 5370 progress.setValue(count)
5417 if progress.wasCanceled(): 5371 if progress.wasCanceled():
5418 break 5372 break
5419 5373
5420 try: 5374 try:
5427 self.tr( 5381 self.tr(
5428 """<p>The file <b>{0}</b> could not be read.</p>""" 5382 """<p>The file <b>{0}</b> could not be read.</p>"""
5429 """<p>Reason: {1}</p>""").format( 5383 """<p>Reason: {1}</p>""").format(
5430 os.path.basename(pkglist), str(why))) 5384 os.path.basename(pkglist), str(why)))
5431 errors += 1 5385 errors += 1
5432 count += 1
5433 continue 5386 continue
5434 5387
5435 lines = names.splitlines() 5388 lines = names.splitlines()
5436 archiveName = "" 5389 archiveName = ""
5437 archiveVersion = "" 5390 archiveVersion = ""
5456 """<p>The file <b>{0}</b> is not ready yet.""" 5409 """<p>The file <b>{0}</b> is not ready yet."""
5457 """</p><p>Please rework it and delete the""" 5410 """</p><p>Please rework it and delete the"""
5458 """'; initial_list' line of the header.""" 5411 """'; initial_list' line of the header."""
5459 """</p>""").format(os.path.basename(pkglist))) 5412 """</p>""").format(os.path.basename(pkglist)))
5460 errors += 1 5413 errors += 1
5461 count += 1
5462 listOK = False 5414 listOK = False
5463 break 5415 break
5464 elif line.strip(): 5416 elif line.strip():
5465 names.append(line.strip()) 5417 names.append(line.strip())
5466 5418
5467 if not listOK: 5419 if not listOK:
5468 continue 5420 continue
5469 5421
5470 names = sorted(names) 5422 names = sorted(names)
5471 if archiveName: 5423 archive = (
5472 archive = os.path.join(self.ppath, archiveName) 5424 os.path.join(self.ppath, archiveName)
5473 else: 5425 if archiveName else
5474 archive = os.path.join( 5426 os.path.join(self.ppath,
5475 self.ppath, 5427 self.pdata["MAINSCRIPT"].replace(".py", ".zip"))
5476 self.pdata["MAINSCRIPT"].replace(".py", ".zip")) 5428 )
5477 try: 5429 try:
5478 archiveFile = zipfile.ZipFile(archive, "w") 5430 archiveFile = zipfile.ZipFile(archive, "w")
5479 except OSError as why: 5431 except OSError as why:
5480 E5MessageBox.critical( 5432 E5MessageBox.critical(
5481 self.ui, 5433 self.ui,
5483 self.tr( 5435 self.tr(
5484 """<p>The eric plugin archive file <b>{0}</b>""" 5436 """<p>The eric plugin archive file <b>{0}</b>"""
5485 """ could not be created.</p>""" 5437 """ could not be created.</p>"""
5486 """<p>Reason: {1}</p>""").format(archive, str(why))) 5438 """<p>Reason: {1}</p>""").format(archive, str(why)))
5487 errors += 1 5439 errors += 1
5488 count += 1
5489 continue 5440 continue
5490 5441
5491 for name in names: 5442 for name in names:
5492 if name: 5443 if name:
5493 try: 5444 try:
5524 archiveFile.writestr("VERSION", version.encode("utf-8")) 5475 archiveFile.writestr("VERSION", version.encode("utf-8"))
5525 archiveFile.close() 5476 archiveFile.close()
5526 5477
5527 if archive not in self.pdata["OTHERS"]: 5478 if archive not in self.pdata["OTHERS"]:
5528 self.appendFile(archive) 5479 self.appendFile(archive)
5529
5530 count += 1
5531 5480
5532 progress.setValue(len(selectedLists)) 5481 progress.setValue(len(selectedLists))
5533 5482
5534 if errors: 5483 if errors:
5535 self.ui.showNotification( 5484 self.ui.showNotification(
5536 UI.PixmapCache.getPixmap("pluginArchive48"), 5485 UI.PixmapCache.getPixmap("pluginArchive48"),
5537 self.tr("Create Plugin Archive"), 5486 self.tr("Create Plugin Archive"),
5538 self.tr("<p>The eric plugin archive files were " 5487 self.tr("<p>The eric plugin archive files were "
5539 "created with some errors.</p>"), 5488 "created with some errors.</p>"),
5540 kind=NotificationTypes.Critical, 5489 kind=NotificationTypes.CRITICAL,
5541 timeout=0) 5490 timeout=0)
5542 else: 5491 else:
5543 self.ui.showNotification( 5492 self.ui.showNotification(
5544 UI.PixmapCache.getPixmap("pluginArchive48"), 5493 UI.PixmapCache.getPixmap("pluginArchive48"),
5545 self.tr("Create Plugin Archive"), 5494 self.tr("Create Plugin Archive"),
5557 Private method to create dir entries in the zip file. 5506 Private method to create dir entries in the zip file.
5558 5507
5559 @param path name of the directory entry to create (string) 5508 @param path name of the directory entry to create (string)
5560 @param zipFile open ZipFile object (zipfile.ZipFile) 5509 @param zipFile open ZipFile object (zipfile.ZipFile)
5561 """ 5510 """
5562 if path == "" or path == "/" or path == "\\": 5511 if path in ("", "/", "\\"):
5563 return 5512 return
5564 5513
5565 if not path.endswith("/") and not path.endswith("\\"): 5514 if not path.endswith("/") and not path.endswith("\\"):
5566 path = "{0}/".format(path) 5515 path = "{0}/".format(path)
5567 5516
5705 not self.pdata["MAKEPARAMS"]["MakeEnabled"] or 5654 not self.pdata["MAKEPARAMS"]["MakeEnabled"] or
5706 self.__makeProcess is not None 5655 self.__makeProcess is not None
5707 ): 5656 ):
5708 return 5657 return
5709 5658
5710 if self.pdata["MAKEPARAMS"]["MakeExecutable"]: 5659 prog = (
5711 prog = self.pdata["MAKEPARAMS"]["MakeExecutable"] 5660 self.pdata["MAKEPARAMS"]["MakeExecutable"]
5712 else: 5661 if self.pdata["MAKEPARAMS"]["MakeExecutable"] else
5713 prog = Project.DefaultMake 5662 Project.DefaultMake
5663 )
5714 5664
5715 args = [] 5665 args = []
5716 if self.pdata["MAKEPARAMS"]["MakeParameters"]: 5666 if self.pdata["MAKEPARAMS"]["MakeParameters"]:
5717 args.extend(Utilities.parseOptionString( 5667 args.extend(Utilities.parseOptionString(
5718 self.pdata["MAKEPARAMS"]["MakeParameters"])) 5668 self.pdata["MAKEPARAMS"]["MakeParameters"]))
5805 5755
5806 self.ui.showNotification( 5756 self.ui.showNotification(
5807 UI.PixmapCache.getPixmap("makefile48"), 5757 UI.PixmapCache.getPixmap("makefile48"),
5808 title, 5758 title,
5809 message, 5759 message,
5810 kind=NotificationTypes.Warning, 5760 kind=NotificationTypes.WARNING,
5811 timeout=0) 5761 timeout=0)
5812 elif exitCode > 1: 5762 elif exitCode > 1:
5813 E5MessageBox.critical( 5763 E5MessageBox.critical(
5814 self.ui, 5764 self.ui,
5815 self.tr("Execute Make"), 5765 self.tr("Execute Make"),

eric ide

mercurial