eric6/Project/Project.py

changeset 7771
787a6b3f8c9f
parent 7759
51aa6c6b66f7
child 7780
41420f82c0ac
equal deleted inserted replaced
7770:49f3377aebf1 7771:787a6b3f8c9f
16 import copy 16 import copy
17 import zipfile 17 import zipfile
18 18
19 from PyQt5.QtCore import ( 19 from PyQt5.QtCore import (
20 pyqtSlot, QFile, QFileInfo, pyqtSignal, QCryptographicHash, QIODevice, 20 pyqtSlot, QFile, QFileInfo, pyqtSignal, QCryptographicHash, QIODevice,
21 QByteArray, QObject, Qt, QProcess 21 QByteArray, QObject, QProcess
22 ) 22 )
23 from PyQt5.QtGui import QCursor, QKeySequence 23 from PyQt5.QtGui import QKeySequence
24 from PyQt5.QtWidgets import ( 24 from PyQt5.QtWidgets import (
25 QLineEdit, QToolBar, QDialog, QInputDialog, QApplication, QMenu, QAction 25 QLineEdit, QToolBar, QDialog, QInputDialog, QApplication, QMenu, QAction
26 ) 26 )
27 from PyQt5.Qsci import QsciScintilla 27 from PyQt5.Qsci import QsciScintilla
28 28
29 from E5Gui.E5Application import e5App 29 from E5Gui.E5Application import e5App
30 from E5Gui import E5FileDialog, E5MessageBox 30 from E5Gui import E5FileDialog, E5MessageBox
31 from E5Gui.E5ListSelectionDialog import E5ListSelectionDialog 31 from E5Gui.E5ListSelectionDialog import E5ListSelectionDialog
32 from E5Gui.E5ProgressDialog import E5ProgressDialog 32 from E5Gui.E5ProgressDialog import E5ProgressDialog
33 from E5Gui.E5OverrideCursor import E5OverrideCursor, E5OverridenCursor
33 34
34 from Globals import recentNameProject 35 from Globals import recentNameProject
35 36
36 import UI.PixmapCache 37 import UI.PixmapCache
37 38
776 reader = ProjectReader(f, self) 777 reader = ProjectReader(f, self)
777 reader.readXML() 778 reader.readXML()
778 res = not reader.hasError() 779 res = not reader.hasError()
779 f.close() 780 f.close()
780 else: 781 else:
781 QApplication.restoreOverrideCursor()
782 E5MessageBox.critical( 782 E5MessageBox.critical(
783 self.ui, 783 self.ui,
784 self.tr("Read project file"), 784 self.tr("Read project file"),
785 self.tr( 785 self.tr(
786 "<p>The project file <b>{0}</b> could not be read.</p>") 786 "<p>The project file <b>{0}</b> could not be read.</p>")
2615 @param mainscript name of the mainscript (string) 2615 @param mainscript name of the mainscript (string)
2616 """ 2616 """
2617 # Show the file type associations for the user to change 2617 # Show the file type associations for the user to change
2618 self.__showFiletypeAssociations() 2618 self.__showFiletypeAssociations()
2619 2619
2620 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 2620 with E5OverrideCursor():
2621 QApplication.processEvents() 2621 # search the project directory for files with known extensions
2622 2622 filespecs = list(self.pdata["FILETYPES"].keys())
2623 # search the project directory for files with known extensions 2623 for filespec in filespecs:
2624 filespecs = list(self.pdata["FILETYPES"].keys()) 2624 files = Utilities.direntries(self.ppath, True, filespec)
2625 for filespec in filespecs: 2625 for file in files:
2626 files = Utilities.direntries(self.ppath, True, filespec) 2626 self.appendFile(file)
2627 for file in files: 2627
2628 self.appendFile(file) 2628 # special handling for translation files
2629 2629 if self.translationsRoot:
2630 # special handling for translation files 2630 tpd = os.path.join(self.ppath, self.translationsRoot)
2631 if self.translationsRoot: 2631 if not self.translationsRoot.endswith(os.sep):
2632 tpd = os.path.join(self.ppath, self.translationsRoot) 2632 tpd = os.path.dirname(tpd)
2633 if not self.translationsRoot.endswith(os.sep):
2634 tpd = os.path.dirname(tpd)
2635 else:
2636 tpd = self.ppath
2637 tslist = []
2638 if self.pdata["TRANSLATIONPATTERN"]:
2639 pattern = os.path.basename(self.pdata["TRANSLATIONPATTERN"])
2640 if "%language%" in pattern:
2641 pattern = pattern.replace("%language%", "*")
2642 else: 2633 else:
2643 tpd = self.pdata["TRANSLATIONPATTERN"].split( 2634 tpd = self.ppath
2644 "%language%")[0] 2635 tslist = []
2645 else: 2636 if self.pdata["TRANSLATIONPATTERN"]:
2646 pattern = "*.ts" 2637 pattern = os.path.basename(self.pdata["TRANSLATIONPATTERN"])
2647 tslist.extend(Utilities.direntries(tpd, True, pattern)) 2638 if "%language%" in pattern:
2648 pattern = self.__binaryTranslationFile(pattern) 2639 pattern = pattern.replace("%language%", "*")
2649 if pattern: 2640 else:
2641 tpd = self.pdata["TRANSLATIONPATTERN"].split(
2642 "%language%")[0]
2643 else:
2644 pattern = "*.ts"
2650 tslist.extend(Utilities.direntries(tpd, True, pattern)) 2645 tslist.extend(Utilities.direntries(tpd, True, pattern))
2651 if tslist: 2646 pattern = self.__binaryTranslationFile(pattern)
2652 if '_' in os.path.basename(tslist[0]): 2647 if pattern:
2653 # the first entry determines the mainscript name 2648 tslist.extend(Utilities.direntries(tpd, True, pattern))
2654 mainscriptname = ( 2649 if tslist:
2655 os.path.splitext(mainscript)[0] or 2650 if '_' in os.path.basename(tslist[0]):
2656 os.path.basename(tslist[0]).split('_')[0] 2651 # the first entry determines the mainscript name
2657 ) 2652 mainscriptname = (
2658 self.pdata["TRANSLATIONPATTERN"] = os.path.join( 2653 os.path.splitext(mainscript)[0] or
2659 os.path.dirname(tslist[0]), 2654 os.path.basename(tslist[0]).split('_')[0]
2660 "{0}_%language%{1}".format( 2655 )
2661 os.path.basename(tslist[0]).split('_')[0], 2656 self.pdata["TRANSLATIONPATTERN"] = os.path.join(
2662 os.path.splitext(tslist[0])[1])) 2657 os.path.dirname(tslist[0]),
2663 else: 2658 "{0}_%language%{1}".format(
2664 mainscriptname = "" 2659 os.path.basename(tslist[0]).split('_')[0],
2665 pattern, ok = QInputDialog.getText( 2660 os.path.splitext(tslist[0])[1]))
2666 None, 2661 else:
2667 self.tr("Translation Pattern"), 2662 mainscriptname = ""
2668 self.tr( 2663 pattern, ok = QInputDialog.getText(
2669 "Enter the path pattern for translation files " 2664 None,
2670 "(use '%language%' in place of the language code):"), 2665 self.tr("Translation Pattern"),
2671 # __IGNORE_WARNING_M601__ 2666 self.tr(
2672 QLineEdit.Normal, 2667 "Enter the path pattern for translation files "
2673 tslist[0]) 2668 "(use '%language%' in place of the language"
2674 if pattern: 2669 " code):"),
2675 self.pdata["TRANSLATIONPATTERN"] = pattern 2670 QLineEdit.Normal,
2676 if self.pdata["TRANSLATIONPATTERN"]: 2671 tslist[0])
2677 self.pdata["TRANSLATIONPATTERN"] = self.getRelativePath( 2672 if pattern:
2678 self.pdata["TRANSLATIONPATTERN"]) 2673 self.pdata["TRANSLATIONPATTERN"] = pattern
2679 pattern = self.pdata["TRANSLATIONPATTERN"].replace( 2674 if self.pdata["TRANSLATIONPATTERN"]:
2680 "%language%", "*") 2675 self.pdata["TRANSLATIONPATTERN"] = self.getRelativePath(
2681 for ts in tslist: 2676 self.pdata["TRANSLATIONPATTERN"])
2682 if fnmatch.fnmatch(ts, pattern): 2677 pattern = self.pdata["TRANSLATIONPATTERN"].replace(
2683 self.pdata["TRANSLATIONS"].append(ts)
2684 self.projectLanguageAdded.emit(ts)
2685 if self.pdata["TRANSLATIONSBINPATH"]:
2686 tpd = os.path.join(self.ppath,
2687 self.pdata["TRANSLATIONSBINPATH"])
2688 pattern = os.path.basename(
2689 self.pdata["TRANSLATIONPATTERN"]).replace(
2690 "%language%", "*") 2678 "%language%", "*")
2691 pattern = self.__binaryTranslationFile(pattern) 2679 for ts in tslist:
2692 qmlist = Utilities.direntries(tpd, True, pattern) 2680 if fnmatch.fnmatch(ts, pattern):
2693 for qm in qmlist: 2681 self.pdata["TRANSLATIONS"].append(ts)
2694 self.pdata["TRANSLATIONS"].append(qm) 2682 self.projectLanguageAdded.emit(ts)
2695 self.projectLanguageAdded.emit(qm) 2683 if self.pdata["TRANSLATIONSBINPATH"]:
2696 if not self.pdata["MAINSCRIPT"] and bool(mainscriptname): 2684 tpd = os.path.join(self.ppath,
2697 if self.pdata["PROGLANGUAGE"] in [ 2685 self.pdata["TRANSLATIONSBINPATH"])
2698 "Python3", "MicroPython" 2686 pattern = os.path.basename(
2699 ]: 2687 self.pdata["TRANSLATIONPATTERN"]).replace(
2700 self.pdata["MAINSCRIPT"] = '{0}.py'.format(mainscriptname) 2688 "%language%", "*")
2701 elif self.pdata["PROGLANGUAGE"] == "Ruby": 2689 pattern = self.__binaryTranslationFile(pattern)
2702 self.pdata["MAINSCRIPT"] = '{0}.rb'.format(mainscriptname) 2690 qmlist = Utilities.direntries(tpd, True, pattern)
2703 self.setDirty(True) 2691 for qm in qmlist:
2704 QApplication.restoreOverrideCursor() 2692 self.pdata["TRANSLATIONS"].append(qm)
2693 self.projectLanguageAdded.emit(qm)
2694 if not self.pdata["MAINSCRIPT"] and bool(mainscriptname):
2695 if self.pdata["PROGLANGUAGE"] in [
2696 "Python3", "MicroPython"
2697 ]:
2698 self.pdata["MAINSCRIPT"] = '{0}.py'.format(
2699 mainscriptname)
2700 elif self.pdata["PROGLANGUAGE"] == "Ruby":
2701 self.pdata["MAINSCRIPT"] = '{0}.rb'.format(
2702 mainscriptname)
2703 self.setDirty(True)
2705 2704
2706 def __showProperties(self): 2705 def __showProperties(self):
2707 """ 2706 """
2708 Private slot to display the properties dialog. 2707 Private slot to display the properties dialog.
2709 """ 2708 """
2893 2892
2894 QApplication.processEvents() 2893 QApplication.processEvents()
2895 2894
2896 if fn: 2895 if fn:
2897 if self.closeProject(): 2896 if self.closeProject():
2898 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 2897 with E5OverrideCursor():
2899 QApplication.processEvents() 2898 ok = self.__readProject(fn)
2900 if self.__readProject(fn): 2899 if ok:
2901 self.opened = True 2900 self.opened = True
2902 if not self.pdata["FILETYPES"]: 2901 if not self.pdata["FILETYPES"]:
2903 self.initFileTypes() 2902 self.initFileTypes()
2904 else: 2903 else:
2905 self.updateFileTypes() 2904 self.updateFileTypes()
2906
2907 QApplication.restoreOverrideCursor()
2908 QApplication.processEvents()
2909 2905
2910 try: 2906 try:
2911 # create management directory if not present 2907 # create management directory if not present
2912 self.createProjectManagementDir() 2908 self.createProjectManagementDir()
2913 except EnvironmentError: 2909 except EnvironmentError:
2921 return 2917 return
2922 2918
2923 # read a user specific project file 2919 # read a user specific project file
2924 self.__readUserProperties() 2920 self.__readUserProperties()
2925 2921
2926 QApplication.setOverrideCursor(QCursor(Qt.WaitCursor)) 2922 with E5OverrideCursor():
2927 QApplication.processEvents() 2923 oldState = self.isDirty()
2928 2924 self.vcs = self.initVCS()
2929 oldState = self.isDirty() 2925 if self.vcs is None and self.isDirty() == oldState:
2930 self.vcs = self.initVCS() 2926 # check, if project is version controlled
2931 if self.vcs is None and self.isDirty() == oldState: 2927 pluginManager = e5App().getObject("PluginManager")
2932 # check, if project is version controlled 2928 for indicator, vcsData in (
2933 pluginManager = e5App().getObject("PluginManager") 2929 pluginManager.getVcsSystemIndicators().items()
2934 for indicator, vcsData in ( 2930 ):
2935 pluginManager.getVcsSystemIndicators().items() 2931 if os.path.exists(
2936 ): 2932 os.path.join(self.ppath, indicator)):
2937 if os.path.exists( 2933 if len(vcsData) > 1:
2938 os.path.join(self.ppath, indicator)): 2934 vcsList = []
2939 if len(vcsData) > 1: 2935 for (
2940 vcsList = [] 2936 _vcsSystemStr, vcsSystemDisplay
2941 for _vcsSystemStr, vcsSystemDisplay in ( 2937 ) in vcsData:
2942 vcsData 2938 vcsList.append(vcsSystemDisplay)
2943 ): 2939 with E5OverridenCursor():
2944 vcsList.append(vcsSystemDisplay) 2940 res, vcs_ok = QInputDialog.getItem(
2945 QApplication.restoreOverrideCursor() 2941 None,
2946 res, vcs_ok = QInputDialog.getItem( 2942 self.tr("New Project"),
2947 None, 2943 self.tr(
2948 self.tr("New Project"), 2944 "Select Version Control"
2949 self.tr( 2945 " System"),
2950 "Select Version Control System"), 2946 vcsList,
2951 vcsList, 2947 0, False)
2952 0, False) 2948 if vcs_ok:
2953 QApplication.setOverrideCursor( 2949 for (
2954 QCursor(Qt.WaitCursor)) 2950 vcsSystemStr, vcsSystemDisplay
2955 QApplication.processEvents() 2951 ) in vcsData:
2956 if vcs_ok: 2952 if res == vcsSystemDisplay:
2957 for vcsSystemStr, vcsSystemDisplay in ( 2953 vcsSystem = vcsSystemStr
2958 vcsData 2954 break
2959 ): 2955 else:
2960 if res == vcsSystemDisplay: 2956 vcsSystem = "None"
2961 vcsSystem = vcsSystemStr
2962 break
2963 else: 2957 else:
2964 vcsSystem = "None" 2958 vcsSystem = "None"
2965 else: 2959 else:
2966 vcsSystem = "None" 2960 vcsSystem = vcsData[0][0]
2967 else: 2961 self.pdata["VCS"] = vcsSystem
2968 vcsSystem = vcsData[0][0] 2962 self.vcs = self.initVCS()
2969 self.pdata["VCS"] = vcsSystem 2963 self.setDirty(True)
2970 self.vcs = self.initVCS() 2964 if (
2971 self.setDirty(True) 2965 self.vcs is not None and
2972 if ( 2966 (self.vcs.vcsRegisteredState(self.ppath) !=
2973 self.vcs is not None and 2967 self.vcs.canBeCommitted)
2974 (self.vcs.vcsRegisteredState(self.ppath) != 2968 ):
2975 self.vcs.canBeCommitted) 2969 self.pdata["VCS"] = 'None'
2976 ): 2970 self.vcs = self.initVCS()
2977 self.pdata["VCS"] = 'None' 2971 self.closeAct.setEnabled(True)
2978 self.vcs = self.initVCS() 2972 self.saveasAct.setEnabled(True)
2979 self.closeAct.setEnabled(True) 2973 self.actGrp2.setEnabled(True)
2980 self.saveasAct.setEnabled(True) 2974 self.propsAct.setEnabled(True)
2981 self.actGrp2.setEnabled(True) 2975 self.userPropsAct.setEnabled(True)
2982 self.propsAct.setEnabled(True) 2976 self.filetypesAct.setEnabled(True)
2983 self.userPropsAct.setEnabled(True) 2977 self.lexersAct.setEnabled(True)
2984 self.filetypesAct.setEnabled(True) 2978 self.sessActGrp.setEnabled(True)
2985 self.lexersAct.setEnabled(True) 2979 self.dbgActGrp.setEnabled(True)
2986 self.sessActGrp.setEnabled(True) 2980 self.menuDebuggerAct.setEnabled(True)
2987 self.dbgActGrp.setEnabled(True) 2981 self.menuSessionAct.setEnabled(True)
2988 self.menuDebuggerAct.setEnabled(True) 2982 self.menuCheckAct.setEnabled(True)
2989 self.menuSessionAct.setEnabled(True) 2983 self.menuShowAct.setEnabled(True)
2990 self.menuCheckAct.setEnabled(True) 2984 self.menuDiagramAct.setEnabled(True)
2991 self.menuShowAct.setEnabled(True) 2985 self.menuApidocAct.setEnabled(True)
2992 self.menuDiagramAct.setEnabled(True) 2986 self.menuPackagersAct.setEnabled(True)
2993 self.menuApidocAct.setEnabled(True) 2987 self.pluginGrp.setEnabled(
2994 self.menuPackagersAct.setEnabled(True) 2988 self.pdata["PROJECTTYPE"] in ["E6Plugin"])
2995 self.pluginGrp.setEnabled( 2989 self.addLanguageAct.setEnabled(
2996 self.pdata["PROJECTTYPE"] in ["E6Plugin"]) 2990 bool(self.pdata["TRANSLATIONPATTERN"]))
2997 self.addLanguageAct.setEnabled( 2991 self.makeGrp.setEnabled(
2998 bool(self.pdata["TRANSLATIONPATTERN"])) 2992 self.pdata["MAKEPARAMS"]["MakeEnabled"])
2999 self.makeGrp.setEnabled( 2993 self.menuMakeAct.setEnabled(
3000 self.pdata["MAKEPARAMS"]["MakeEnabled"]) 2994 self.pdata["MAKEPARAMS"]["MakeEnabled"])
3001 self.menuMakeAct.setEnabled( 2995
3002 self.pdata["MAKEPARAMS"]["MakeEnabled"]) 2996 # open a project debugger properties file being quiet
3003 2997 # about errors
3004 # open a project debugger properties file being quiet 2998 if Preferences.getProject("AutoLoadDbgProperties"):
3005 # about errors 2999 self.__readDebugProperties(True)
3006 if Preferences.getProject("AutoLoadDbgProperties"): 3000
3007 self.__readDebugProperties(True) 3001 self.__model.projectOpened()
3008 3002 self.projectOpenedHooks.emit()
3009 self.__model.projectOpened() 3003 self.projectOpened.emit()
3010 self.projectOpenedHooks.emit()
3011 self.projectOpened.emit()
3012
3013 QApplication.restoreOverrideCursor()
3014 3004
3015 if Preferences.getProject("SearchNewFiles"): 3005 if Preferences.getProject("SearchNewFiles"):
3016 self.__doSearchNewFiles() 3006 self.__doSearchNewFiles()
3017 3007
3018 # read a project tasks file 3008 # read a project tasks file
3048 self.__statusMonitorStatus) 3038 self.__statusMonitorStatus)
3049 self.vcs.vcsStatusMonitorInfo.connect( 3039 self.vcs.vcsStatusMonitorInfo.connect(
3050 self.vcsStatusMonitorInfo) 3040 self.vcsStatusMonitorInfo)
3051 self.vcs.vcsStatusChanged.connect( 3041 self.vcs.vcsStatusChanged.connect(
3052 self.__vcsStatusChanged) 3042 self.__vcsStatusChanged)
3053 else:
3054 QApplication.restoreOverrideCursor()
3055 3043
3056 def reopenProject(self): 3044 def reopenProject(self):
3057 """ 3045 """
3058 Public slot to reopen the current project. 3046 Public slot to reopen the current project.
3059 """ 3047 """
4772 @param fullname full name of the item to repopulate (string) 4760 @param fullname full name of the item to repopulate (string)
4773 """ 4761 """
4774 if not self.isOpen(): 4762 if not self.isOpen():
4775 return 4763 return
4776 4764
4777 name = self.getRelativePath(fullname) 4765 with E5OverrideCursor():
4778 self.prepareRepopulateItem.emit(name) 4766 name = self.getRelativePath(fullname)
4779 self.__model.repopulateItem(name) 4767 self.prepareRepopulateItem.emit(name)
4780 self.completeRepopulateItem.emit(name) 4768 self.__model.repopulateItem(name)
4769 self.completeRepopulateItem.emit(name)
4781 4770
4782 ############################################################## 4771 ##############################################################
4783 ## Below is the VCS interface 4772 ## Below is the VCS interface
4784 ############################################################## 4773 ##############################################################
4785 4774
4823 if vcs: 4812 if vcs:
4824 vcsExists, msg = vcs.vcsExists() 4813 vcsExists, msg = vcs.vcsExists()
4825 if not vcsExists: 4814 if not vcsExists:
4826 if override: 4815 if override:
4827 # override failed, revert to original 4816 # override failed, revert to original
4828 QApplication.restoreOverrideCursor() 4817 with E5OverridenCursor():
4818 E5MessageBox.critical(
4819 self.ui,
4820 self.tr("Version Control System"),
4821 self.tr(
4822 "<p>The selected VCS <b>{0}</b> could not be"
4823 " found. <br/>Reverting override.</p><p>{1}"
4824 "</p>")
4825 .format(vcsSystem, msg))
4826 self.pudata["VCSOVERRIDE"] = ""
4827 return self.initVCS(nooverride=True)
4828
4829 with E5OverridenCursor():
4829 E5MessageBox.critical( 4830 E5MessageBox.critical(
4830 self.ui, 4831 self.ui,
4831 self.tr("Version Control System"), 4832 self.tr("Version Control System"),
4832 self.tr( 4833 self.tr(
4833 "<p>The selected VCS <b>{0}</b> could not be" 4834 "<p>The selected VCS <b>{0}</b> could not be"
4834 " found. <br/>Reverting override.</p><p>{1}</p>") 4835 " found.<br/>Disabling version control.</p>"
4835 .format(vcsSystem, msg)) 4836 "<p>{1}</p>").format(vcsSystem, msg))
4836 self.pudata["VCSOVERRIDE"] = ""
4837 return self.initVCS(nooverride=True)
4838
4839 QApplication.restoreOverrideCursor()
4840 E5MessageBox.critical(
4841 self.ui,
4842 self.tr("Version Control System"),
4843 self.tr(
4844 "<p>The selected VCS <b>{0}</b> could not be"
4845 " found.<br/>Disabling version control.</p>"
4846 "<p>{1}</p>").format(vcsSystem, msg))
4847 vcs = None 4837 vcs = None
4848 if forProject: 4838 if forProject:
4849 self.pdata["VCS"] = 'None' 4839 self.pdata["VCS"] = 'None'
4850 self.setDirty(True) 4840 self.setDirty(True)
4851 else: 4841 else:
5841 "CompressionThreshold": 70, # default value 5831 "CompressionThreshold": 70, # default value
5842 "CompressLevel": 0, # use zlib default 5832 "CompressLevel": 0, # use zlib default
5843 "CompressionDisable": False, 5833 "CompressionDisable": False,
5844 "PathPrefix": "", 5834 "PathPrefix": "",
5845 } 5835 }
5836
5837 #
5838 # eflag: noqa = M601

eric ide

mercurial