src/eric7/Project/Project.py

branch
eric7
changeset 9624
b47dfa7a137d
parent 9612
93b496cc3c88
child 9626
5bb5c85d71c3
equal deleted inserted replaced
9623:9c1f429cb56b 9624:b47dfa7a137d
31 pyqtSlot, 31 pyqtSlot,
32 ) 32 )
33 from PyQt6.QtGui import QAction, QKeySequence 33 from PyQt6.QtGui import QAction, QKeySequence
34 from PyQt6.QtWidgets import QDialog, QInputDialog, QLineEdit, QMenu, QToolBar 34 from PyQt6.QtWidgets import QDialog, QInputDialog, QLineEdit, QMenu, QToolBar
35 35
36 from eric7 import Globals, Preferences, Utilities 36 from eric7 import Preferences, Utilities
37 from eric7.CodeFormatting.BlackFormattingAction import BlackFormattingAction 37 from eric7.CodeFormatting.BlackFormattingAction import BlackFormattingAction
38 from eric7.CodeFormatting.BlackUtilities import aboutBlack 38 from eric7.CodeFormatting.BlackUtilities import aboutBlack
39 from eric7.CodeFormatting.IsortFormattingAction import IsortFormattingAction 39 from eric7.CodeFormatting.IsortFormattingAction import IsortFormattingAction
40 from eric7.CodeFormatting.IsortUtilities import aboutIsort 40 from eric7.CodeFormatting.IsortUtilities import aboutIsort
41 from eric7.EricGui import EricPixmapCache 41 from eric7.EricGui import EricPixmapCache
50 from eric7.EricXML.SessionReader import SessionReader 50 from eric7.EricXML.SessionReader import SessionReader
51 from eric7.EricXML.TasksReader import TasksReader 51 from eric7.EricXML.TasksReader import TasksReader
52 from eric7.EricXML.UserProjectReader import UserProjectReader 52 from eric7.EricXML.UserProjectReader import UserProjectReader
53 from eric7.Globals import recentNameProject 53 from eric7.Globals import recentNameProject
54 from eric7.Sessions.SessionFile import SessionFile 54 from eric7.Sessions.SessionFile import SessionFile
55 from eric7.SystemUtilities import (
56 FileSystemUtilities,
57 OSUtilities,
58 PythonUtilities,
59 QtUtilities,
60 )
55 from eric7.Tasks.TasksFile import TasksFile 61 from eric7.Tasks.TasksFile import TasksFile
56 from eric7.UI import Config 62 from eric7.UI import Config
57 from eric7.UI.NotificationWidget import NotificationTypes 63 from eric7.UI.NotificationWidget import NotificationTypes
58 64
59 from .DebuggerPropertiesFile import DebuggerPropertiesFile 65 from .DebuggerPropertiesFile import DebuggerPropertiesFile
345 "MicroPython": ["Console", "Other"], 351 "MicroPython": ["Console", "Other"],
346 "Ruby": ["Console", "Other"], 352 "Ruby": ["Console", "Other"],
347 "JavaScript": ["Other"], 353 "JavaScript": ["Other"],
348 } 354 }
349 355
350 if Utilities.checkPyside(variant=2): 356 if QtUtilities.checkPyside(variant=2):
351 self.__projectTypes["PySide2"] = self.tr("PySide2 GUI") 357 self.__projectTypes["PySide2"] = self.tr("PySide2 GUI")
352 self.__projectTypes["PySide2C"] = self.tr("PySide2 Console") 358 self.__projectTypes["PySide2C"] = self.tr("PySide2 Console")
353 self.__projectProgLanguages["Python3"].extend(["PySide2", "PySide2C"]) 359 self.__projectProgLanguages["Python3"].extend(["PySide2", "PySide2C"])
354 360
355 if Utilities.checkPyside(variant=6): 361 if QtUtilities.checkPyside(variant=6):
356 self.__projectTypes["PySide6"] = self.tr("PySide6 GUI") 362 self.__projectTypes["PySide6"] = self.tr("PySide6 GUI")
357 self.__projectTypes["PySide6C"] = self.tr("PySide6 Console") 363 self.__projectTypes["PySide6C"] = self.tr("PySide6 Console")
358 self.__projectProgLanguages["Python3"].extend(["PySide6", "PySide6C"]) 364 self.__projectProgLanguages["Python3"].extend(["PySide6", "PySide6C"])
359 365
360 def getProjectTypes(self, progLanguage=""): 366 def getProjectTypes(self, progLanguage=""):
1894 if dlg.exec() == QDialog.DialogCode.Accepted: 1900 if dlg.exec() == QDialog.DialogCode.Accepted:
1895 fnames, target, isSource = dlg.getData() 1901 fnames, target, isSource = dlg.getData()
1896 if target != "": 1902 if target != "":
1897 for fn in fnames: 1903 for fn in fnames:
1898 targetfile = os.path.join(target, os.path.basename(fn)) 1904 targetfile = os.path.join(target, os.path.basename(fn))
1899 if not Utilities.samepath(os.path.dirname(fn), target): 1905 if not FileSystemUtilities.samepath(os.path.dirname(fn), target):
1900 try: 1906 try:
1901 if not os.path.isdir(target): 1907 if not os.path.isdir(target):
1902 os.makedirs(target) 1908 os.makedirs(target)
1903 1909
1904 if os.path.exists(targetfile): 1910 if os.path.exists(targetfile):
1969 " any files belonging to the selected category.</p>" 1975 " any files belonging to the selected category.</p>"
1970 ), 1976 ),
1971 ) 1977 )
1972 return 1978 return
1973 1979
1974 if not Utilities.samepath(target, source) and not os.path.isdir(target): 1980 if not FileSystemUtilities.samepath(target, source) and not os.path.isdir(
1981 target
1982 ):
1975 try: 1983 try:
1976 os.makedirs(target) 1984 os.makedirs(target)
1977 except OSError as why: 1985 except OSError as why:
1978 EricMessageBox.critical( 1986 EricMessageBox.critical(
1979 self.ui, 1987 self.ui,
1989 for pattern in ignorePatterns: 1997 for pattern in ignorePatterns:
1990 if fnmatch.fnmatch(file, pattern): 1998 if fnmatch.fnmatch(file, pattern):
1991 continue 1999 continue
1992 2000
1993 targetfile = os.path.join(target, os.path.basename(file)) 2001 targetfile = os.path.join(target, os.path.basename(file))
1994 if not Utilities.samepath(target, source): 2002 if not FileSystemUtilities.samepath(target, source):
1995 try: 2003 try:
1996 if os.path.exists(targetfile): 2004 if os.path.exists(targetfile):
1997 res = EricMessageBox.yesNo( 2005 res = EricMessageBox.yesNo(
1998 self.ui, 2006 self.ui,
1999 self.tr("Add directory"), 2007 self.tr("Add directory"),
2147 "", 2155 "",
2148 EricFileDialog.DontConfirmOverwrite, 2156 EricFileDialog.DontConfirmOverwrite,
2149 ) 2157 )
2150 if not newfn: 2158 if not newfn:
2151 return False 2159 return False
2152 newfn = Utilities.toNativeSeparators(newfn) 2160 newfn = FileSystemUtilities.toNativeSeparators(newfn)
2153 2161
2154 if os.path.exists(newfn): 2162 if os.path.exists(newfn):
2155 res = EricMessageBox.yesNo( 2163 res = EricMessageBox.yesNo(
2156 self.ui, 2164 self.ui,
2157 self.tr("Rename File"), 2165 self.tr("Rename File"),
2828 2836
2829 with EricOverrideCursor(): 2837 with EricOverrideCursor():
2830 # search the project directory for files with known extensions 2838 # search the project directory for files with known extensions
2831 filespecs = list(self.__pdata["FILETYPES"].keys()) 2839 filespecs = list(self.__pdata["FILETYPES"].keys())
2832 for filespec in filespecs: 2840 for filespec in filespecs:
2833 files = Utilities.direntries(self.ppath, True, filespec) 2841 files = FileSystemUtilities.direntries(self.ppath, True, filespec)
2834 for file in files: 2842 for file in files:
2835 self.appendFile(file) 2843 self.appendFile(file)
2836 2844
2837 # special handling for translation files 2845 # special handling for translation files
2838 if self.translationsRoot: 2846 if self.translationsRoot:
2848 pattern = pattern.replace("%language%", "*") 2856 pattern = pattern.replace("%language%", "*")
2849 else: 2857 else:
2850 tpd = self.__pdata["TRANSLATIONPATTERN"].split("%language%")[0] 2858 tpd = self.__pdata["TRANSLATIONPATTERN"].split("%language%")[0]
2851 else: 2859 else:
2852 pattern = "*.ts" 2860 pattern = "*.ts"
2853 tslist.extend(Utilities.direntries(tpd, True, pattern)) 2861 tslist.extend(FileSystemUtilities.direntries(tpd, True, pattern))
2854 pattern = self.__binaryTranslationFile(pattern) 2862 pattern = self.__binaryTranslationFile(pattern)
2855 if pattern: 2863 if pattern:
2856 tslist.extend(Utilities.direntries(tpd, True, pattern)) 2864 tslist.extend(FileSystemUtilities.direntries(tpd, True, pattern))
2857 if tslist: 2865 if tslist:
2858 if "_" in os.path.basename(tslist[0]): 2866 if "_" in os.path.basename(tslist[0]):
2859 # the first entry determines the mainscript name 2867 # the first entry determines the mainscript name
2860 mainscriptname = ( 2868 mainscriptname = (
2861 os.path.splitext(mainscript)[0] 2869 os.path.splitext(mainscript)[0]
2900 ) 2908 )
2901 pattern = os.path.basename( 2909 pattern = os.path.basename(
2902 self.__pdata["TRANSLATIONPATTERN"] 2910 self.__pdata["TRANSLATIONPATTERN"]
2903 ).replace("%language%", "*") 2911 ).replace("%language%", "*")
2904 pattern = self.__binaryTranslationFile(pattern) 2912 pattern = self.__binaryTranslationFile(pattern)
2905 qmlist = Utilities.direntries(tpd, True, pattern) 2913 qmlist = FileSystemUtilities.direntries(tpd, True, pattern)
2906 for qm in qmlist: 2914 for qm in qmlist:
2907 self.__pdata["TRANSLATIONS"].append(qm) 2915 self.__pdata["TRANSLATIONS"].append(qm)
2908 self.projectFileAdded.emit(qm, "TRANSLATIONS") 2916 self.projectFileAdded.emit(qm, "TRANSLATIONS")
2909 if not self.__pdata["MAINSCRIPT"] and bool(mainscriptname): 2917 if not self.__pdata["MAINSCRIPT"] and bool(mainscriptname):
2910 if self.__pdata["PROGLANGUAGE"] in ["Python3", "MicroPython"]: 2918 if self.__pdata["PROGLANGUAGE"] in ["Python3", "MicroPython"]:
3114 3122
3115 if fn is None: 3123 if fn is None:
3116 fn = EricFileDialog.getOpenFileName( 3124 fn = EricFileDialog.getOpenFileName(
3117 self.parent(), 3125 self.parent(),
3118 self.tr("Open project"), 3126 self.tr("Open project"),
3119 Preferences.getMultiProject("Workspace") or Utilities.getHomeDir(), 3127 Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir(),
3120 self.tr("Project Files (*.epj);;XML Project Files (*.e4p)"), 3128 self.tr("Project Files (*.epj);;XML Project Files (*.e4p)"),
3121 ) 3129 )
3122 3130
3123 if fn and self.closeProject(): 3131 if fn and self.closeProject():
3124 with EricOverrideCursor(): 3132 with EricOverrideCursor():
3310 """ 3318 """
3311 defaultFilter = self.tr("Project Files (*.epj)") 3319 defaultFilter = self.tr("Project Files (*.epj)")
3312 defaultPath = ( 3320 defaultPath = (
3313 self.ppath 3321 self.ppath
3314 if self.ppath 3322 if self.ppath
3315 else (Preferences.getMultiProject("Workspace") or Utilities.getHomeDir()) 3323 else (Preferences.getMultiProject("Workspace") or OSUtilities.getHomeDir())
3316 ) 3324 )
3317 fn, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( 3325 fn, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
3318 self.parent(), 3326 self.parent(),
3319 self.tr("Save Project"), 3327 self.tr("Save Project"),
3320 defaultPath, 3328 defaultPath,
3748 @return flag indicating that the path starts with the project path 3756 @return flag indicating that the path starts with the project path
3749 @rtype bool 3757 @rtype bool
3750 """ 3758 """
3751 return bool(self.ppath) and ( 3759 return bool(self.ppath) and (
3752 path == self.ppath 3760 path == self.ppath
3753 or Utilities.normcasepath(Utilities.toNativeSeparators(path)).startswith( 3761 or FileSystemUtilities.normcasepath(
3754 Utilities.normcasepath(Utilities.toNativeSeparators(self.ppath + "/")) 3762 FileSystemUtilities.toNativeSeparators(path)
3763 ).startswith(
3764 FileSystemUtilities.normcasepath(
3765 FileSystemUtilities.toNativeSeparators(self.ppath + "/")
3766 )
3755 ) 3767 )
3756 ) 3768 )
3757 3769
3758 def getProjectFile(self): 3770 def getProjectFile(self):
3759 """ 3771 """
3825 3837
3826 @param path file or directory name to convert (string) 3838 @param path file or directory name to convert (string)
3827 @return project relative path or unchanged path, if path doesn't 3839 @return project relative path or unchanged path, if path doesn't
3828 belong to the project (string) 3840 belong to the project (string)
3829 """ 3841 """
3830 return Utilities.fromNativeSeparators(self.getRelativePath(path)) 3842 return FileSystemUtilities.fromNativeSeparators(self.getRelativePath(path))
3831 3843
3832 def getAbsolutePath(self, fn): 3844 def getAbsolutePath(self, fn):
3833 """ 3845 """
3834 Public method to convert a project relative file path to an absolute 3846 Public method to convert a project relative file path to an absolute
3835 file path. 3847 file path.
3848 3860
3849 @param fn file or directory name to convert (string) 3861 @param fn file or directory name to convert (string)
3850 @return absolute path (string) 3862 @return absolute path (string)
3851 """ 3863 """
3852 if not os.path.isabs(fn): 3864 if not os.path.isabs(fn):
3853 fn = os.path.join(self.ppath, Utilities.toNativeSeparators(fn)) 3865 fn = os.path.join(self.ppath, FileSystemUtilities.toNativeSeparators(fn))
3854 return fn 3866 return fn
3855 3867
3856 def getEolString(self): 3868 def getEolString(self):
3857 """ 3869 """
3858 Public method to get the EOL-string to be used by the project. 3870 Public method to get the EOL-string to be used by the project.
3965 ericApp() 3977 ericApp()
3966 .getObject("VirtualEnvManager") 3978 .getObject("VirtualEnvManager")
3967 .getVirtualenvInterpreter(venvName) 3979 .getVirtualenvInterpreter(venvName)
3968 ) 3980 )
3969 if not interpreter and resolveGlobal: 3981 if not interpreter and resolveGlobal:
3970 interpreter = Globals.getPythonExecutable() 3982 interpreter = PythonUtilities.getPythonExecutable()
3971 3983
3972 return interpreter 3984 return interpreter
3973 3985
3974 def getProjectExecPath(self): 3986 def getProjectExecPath(self):
3975 """ 3987 """
4060 group == "OTHERS" 4072 group == "OTHERS"
4061 and any(newfn.startswith(entry) for entry in self.__pdata[group]) 4073 and any(newfn.startswith(entry) for entry in self.__pdata[group])
4062 ): 4074 ):
4063 return True 4075 return True
4064 4076
4065 if Utilities.isWindowsPlatform(): 4077 if OSUtilities.isWindowsPlatform():
4066 # try the above case-insensitive 4078 # try the above case-insensitive
4067 newfn = newfn.lower() 4079 newfn = newfn.lower()
4068 if any(entry.lower() == newfn for entry in self.__pdata[group]): 4080 if any(entry.lower() == newfn for entry in self.__pdata[group]):
4069 return True 4081 return True
4070 4082
5388 """ 5400 """
5389 Private method to synchronize the list of recently opened projects 5401 Private method to synchronize the list of recently opened projects
5390 with the central store. 5402 with the central store.
5391 """ 5403 """
5392 for recent in self.recent[:]: 5404 for recent in self.recent[:]:
5393 if Utilities.samepath(self.pfile, recent): 5405 if FileSystemUtilities.samepath(self.pfile, recent):
5394 self.recent.remove(recent) 5406 self.recent.remove(recent)
5395 self.recent.insert(0, self.pfile) 5407 self.recent.insert(0, self.pfile)
5396 maxRecent = Preferences.getProject("RecentNumber") 5408 maxRecent = Preferences.getProject("RecentNumber")
5397 if len(self.recent) > maxRecent: 5409 if len(self.recent) > maxRecent:
5398 self.recent = self.recent[:maxRecent] 5410 self.recent = self.recent[:maxRecent]
5408 5420
5409 for idx, rp in enumerate(self.recent, start=1): 5421 for idx, rp in enumerate(self.recent, start=1):
5410 formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}" 5422 formatStr = "&{0:d}. {1}" if idx < 10 else "{0:d}. {1}"
5411 act = self.recentMenu.addAction( 5423 act = self.recentMenu.addAction(
5412 formatStr.format( 5424 formatStr.format(
5413 idx, Utilities.compactPath(rp, self.ui.maxMenuFilePathLen) 5425 idx, FileSystemUtilities.compactPath(rp, self.ui.maxMenuFilePathLen)
5414 ) 5426 )
5415 ) 5427 )
5416 act.setData(rp) 5428 act.setData(rp)
5417 act.setEnabled(pathlib.Path(rp).exists()) 5429 act.setEnabled(pathlib.Path(rp).exists())
5418 5430
5518 for ns in newSources: 5530 for ns in newSources:
5519 # ignore hidden files and directories 5531 # ignore hidden files and directories
5520 if ns.startswith("."): 5532 if ns.startswith("."):
5521 continue 5533 continue
5522 if ( 5534 if (
5523 Utilities.isWindowsPlatform() 5535 OSUtilities.isWindowsPlatform()
5524 and os.path.isdir(os.path.join(curpath, ns)) 5536 and os.path.isdir(os.path.join(curpath, ns))
5525 and ns.startswith("_") 5537 and ns.startswith("_")
5526 ): 5538 ):
5527 # dot net hack 5539 # dot net hack
5528 continue 5540 continue
6137 for entry in lst_: 6149 for entry in lst_:
6138 if os.path.isdir(self.getAbsolutePath(entry)): 6150 if os.path.isdir(self.getAbsolutePath(entry)):
6139 lst.extend( 6151 lst.extend(
6140 [ 6152 [
6141 self.getRelativePath(p) 6153 self.getRelativePath(p)
6142 for p in Utilities.direntries(self.getAbsolutePath(entry), True) 6154 for p in FileSystemUtilities.direntries(
6155 self.getAbsolutePath(entry), True
6156 )
6143 ] 6157 ]
6144 ) 6158 )
6145 continue 6159 continue
6146 else: 6160 else:
6147 lst.append(entry) 6161 lst.append(entry)
6161 try: 6175 try:
6162 newline = None if self.__pdata["EOL"] == 0 else self.getEolString() 6176 newline = None if self.__pdata["EOL"] == 0 else self.getEolString()
6163 with open(pkglist, "w", encoding="utf-8", newline=newline) as pkglistFile: 6177 with open(pkglist, "w", encoding="utf-8", newline=newline) as pkglistFile:
6164 pkglistFile.write("\n".join(header) + "\n") 6178 pkglistFile.write("\n".join(header) + "\n")
6165 pkglistFile.write( 6179 pkglistFile.write(
6166 "\n".join([Utilities.fromNativeSeparators(f) for f in lst]) 6180 "\n".join(
6181 [FileSystemUtilities.fromNativeSeparators(f) for f in lst]
6182 )
6167 ) 6183 )
6168 pkglistFile.write("\n") 6184 pkglistFile.write("\n")
6169 # ensure the file ends with an empty line 6185 # ensure the file ends with an empty line
6170 except OSError as why: 6186 except OSError as why:
6171 EricMessageBox.critical( 6187 EricMessageBox.critical(

eric ide

mercurial