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 |
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 """ |
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 |
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: |