73 proxyAuthenticationRequired, |
77 proxyAuthenticationRequired, |
74 ) |
78 ) |
75 from eric7.EricWidgets import EricErrorMessage, EricFileDialog, EricMessageBox |
79 from eric7.EricWidgets import EricErrorMessage, EricFileDialog, EricMessageBox |
76 from eric7.EricWidgets.EricApplication import ericApp |
80 from eric7.EricWidgets.EricApplication import ericApp |
77 from eric7.EricWidgets.EricClickableLabel import EricClickableLabel |
81 from eric7.EricWidgets.EricClickableLabel import EricClickableLabel |
|
82 from eric7.EricWidgets.EricListSelectionDialog import EricListSelectionDialog |
78 from eric7.EricWidgets.EricMainWindow import EricMainWindow |
83 from eric7.EricWidgets.EricMainWindow import EricMainWindow |
79 from eric7.EricWidgets.EricSingleApplication import EricSingleApplicationServer |
84 from eric7.EricWidgets.EricSingleApplication import EricSingleApplicationServer |
80 from eric7.EricWidgets.EricToolBarManager import EricToolBarManager |
85 from eric7.EricWidgets.EricToolBarManager import EricToolBarManager |
81 from eric7.EricWidgets.EricZoomWidget import EricZoomWidget |
86 from eric7.EricWidgets.EricZoomWidget import EricZoomWidget |
82 from eric7.Globals import getConfig |
87 from eric7.Globals import getConfig |
1946 ) |
1951 ) |
1947 ) |
1952 ) |
1948 self.loadSessionAct.triggered.connect(self.__loadSessionFromFile) |
1953 self.loadSessionAct.triggered.connect(self.__loadSessionFromFile) |
1949 self.actions.append(self.loadSessionAct) |
1954 self.actions.append(self.loadSessionAct) |
1950 |
1955 |
|
1956 self.loadCrashSessionAct = EricAction( |
|
1957 self.tr("Load crash session"), |
|
1958 self.tr("Load crash session..."), |
|
1959 0, |
|
1960 0, |
|
1961 self, |
|
1962 "load_crash_session", |
|
1963 ) |
|
1964 self.loadCrashSessionAct.setStatusTip(self.tr("Load crash session")) |
|
1965 self.loadCrashSessionAct.setWhatsThis( |
|
1966 self.tr( |
|
1967 """<b>Load crash session...</b>""" |
|
1968 """<p>This presents a list of available crash session files""" |
|
1969 """ to select from and loads the selected one.</p>""" |
|
1970 ) |
|
1971 ) |
|
1972 self.loadCrashSessionAct.triggered.connect(self.__loadCrashSession) |
|
1973 self.actions.append(self.loadCrashSessionAct) |
|
1974 |
|
1975 self.cleanCrashSessionsAct = EricAction( |
|
1976 self.tr("Clean crash sessions"), |
|
1977 self.tr("Clean crash sessions..."), |
|
1978 0, |
|
1979 0, |
|
1980 self, |
|
1981 "clean_crash_sessions", |
|
1982 ) |
|
1983 self.cleanCrashSessionsAct.setStatusTip(self.tr("Clean crash sessions")) |
|
1984 self.cleanCrashSessionsAct.setWhatsThis( |
|
1985 self.tr( |
|
1986 """<b>Clean crash sessions...</b>""" |
|
1987 """<p>This asks for confirmation and deletes all stale crash session""" |
|
1988 """ files.</p>""" |
|
1989 ) |
|
1990 ) |
|
1991 self.cleanCrashSessionsAct.triggered.connect(self.__cleanCrashSessions) |
|
1992 self.actions.append(self.cleanCrashSessionsAct) |
|
1993 |
1951 self.newWindowAct = EricAction( |
1994 self.newWindowAct = EricAction( |
1952 self.tr("New Window"), |
1995 self.tr("New Window"), |
1953 EricPixmapCache.getIcon("newWindow"), |
1996 EricPixmapCache.getIcon("newWindow"), |
1954 self.tr("New &Window"), |
1997 self.tr("New &Window"), |
1955 QKeySequence(self.tr("Ctrl+Shift+N", "File|New Window")), |
1998 QKeySequence(self.tr("Ctrl+Shift+N", "File|New Window")), |
3817 ############################################################## |
3860 ############################################################## |
3818 |
3861 |
3819 self.__menus["server"] = self.__ericServerInterface.initMenu() |
3862 self.__menus["server"] = self.__ericServerInterface.initMenu() |
3820 |
3863 |
3821 ############################################################## |
3864 ############################################################## |
|
3865 ## Sessions menu |
|
3866 ############################################################## |
|
3867 |
|
3868 self.__menus["sessions"] = QMenu(self.tr("Sessions")) |
|
3869 self.__menus["sessions"].addAction(self.saveSessionAct) |
|
3870 self.__menus["sessions"].addAction(self.loadSessionAct) |
|
3871 self.__menus["sessions"].addSeparator() |
|
3872 self.__menus["sessions"].addAction(self.loadCrashSessionAct) |
|
3873 self.__menus["sessions"].addAction(self.cleanCrashSessionsAct) |
|
3874 |
|
3875 ############################################################## |
3822 ## File menu |
3876 ## File menu |
3823 ############################################################## |
3877 ############################################################## |
3824 |
3878 |
3825 self.__menus["file"] = self.viewmanager.initFileMenu() |
3879 self.__menus["file"] = self.viewmanager.initFileMenu() |
3826 mb.addMenu(self.__menus["file"]) |
3880 mb.addMenu(self.__menus["file"]) |
3827 self.__menus["file"].addSeparator() |
3881 self.__menus["file"].addSeparator() |
3828 self.__menus["file"].addAction(self.saveSessionAct) |
3882 self.__menus["file"].addMenu(self.__menus["sessions"]) |
3829 self.__menus["file"].addAction(self.loadSessionAct) |
|
3830 self.__menus["file"].addSeparator() |
3883 self.__menus["file"].addSeparator() |
3831 self.__menus["file"].addAction(self.restartAct) |
3884 self.__menus["file"].addAction(self.restartAct) |
3832 self.__menus["file"].addAction(self.exitAct) |
3885 self.__menus["file"].addAction(self.exitAct) |
3833 act = self.__menus["file"].actions()[0] |
3886 act = self.__menus["file"].actions()[0] |
3834 sep = self.__menus["file"].insertSeparator(act) |
3887 sep = self.__menus["file"].insertSeparator(act) |
7692 """ |
7745 """ |
7693 fn = os.path.join(Globals.getConfigDir(), "eric7tasks.etj") |
7746 fn = os.path.join(Globals.getConfigDir(), "eric7tasks.etj") |
7694 if os.path.exists(fn): |
7747 if os.path.exists(fn): |
7695 self.__tasksFile.readFile(fn) |
7748 self.__tasksFile.readFile(fn) |
7696 |
7749 |
7697 def __writeSession(self, filename="", crashSession=False): |
7750 def __writeSession(self, filename=""): |
7698 """ |
7751 """ |
7699 Private slot to write the session data to a JSON file (.esj). |
7752 Private slot to write the session data to a JSON file (.esj). |
7700 |
7753 |
7701 @param filename name of a session file to write |
7754 @param filename name of a session file to write |
7702 @type str |
7755 @type str |
7703 @param crashSession flag indicating to write a crash session file |
|
7704 @type bool |
|
7705 @return flag indicating success |
7756 @return flag indicating success |
7706 @rtype bool |
7757 @rtype bool |
7707 """ |
7758 """ |
7708 if filename: |
7759 fn = ( |
7709 fn = filename |
7760 filename |
7710 elif crashSession: |
7761 if filename |
7711 fn = os.path.join(Globals.getConfigDir(), "eric7_crash_session.esj") |
7762 else os.path.join(Globals.getConfigDir(), "eric7session.esj") |
7712 else: |
7763 ) |
7713 fn = os.path.join(Globals.getConfigDir(), "eric7session.esj") |
|
7714 |
7764 |
7715 return self.__sessionFile.writeFile(fn) |
7765 return self.__sessionFile.writeFile(fn) |
7716 |
7766 |
7717 def __readSession(self, filename=""): |
7767 def __readSession(self, filename=""): |
7718 """ |
7768 """ |
7785 if not sessionFile: |
7835 if not sessionFile: |
7786 return |
7836 return |
7787 |
7837 |
7788 self.__readSession(filename=sessionFile) |
7838 self.__readSession(filename=sessionFile) |
7789 |
7839 |
|
7840 def __crashSessionFilePath(self, globPattern=False): |
|
7841 """ |
|
7842 Private method to generate a path name for a unique crash session file. |
|
7843 |
|
7844 @param globPattern flag indicating to get the glob pattern for crash |
|
7845 session files (defaults to False) |
|
7846 @type bool (optional) |
|
7847 @return crash session file path |
|
7848 @rtype str |
|
7849 """ |
|
7850 if globPattern: |
|
7851 return os.path.join(Globals.getConfigDir(), "eric7_crash_session_*.esj") |
|
7852 else: |
|
7853 return os.path.join( |
|
7854 Globals.getConfigDir(), f"eric7_crash_session_{os.getpid()}.esj" |
|
7855 ) |
|
7856 |
|
7857 def __getCrashedSessions(self): |
|
7858 """ |
|
7859 Private method to get a list of crash session file paths of crashed sessions. |
|
7860 |
|
7861 Note: Crashed sessions are those, whose PID does not exist anymore. |
|
7862 |
|
7863 @return list of crashed session file paths |
|
7864 @rtype list of str |
|
7865 """ |
|
7866 crashedSessionsList = [] |
|
7867 |
|
7868 crashSessionPattern = self.__crashSessionFilePath(globPattern=True) |
|
7869 crashSessionPatternParts = crashSessionPattern.split("*", 1) |
|
7870 # crashSessionPatternParts is used to extract the PID from the crash session |
|
7871 # file path |
|
7872 crashSessionsList = glob.glob(crashSessionPattern) |
|
7873 if crashSessionsList: |
|
7874 for crashSession in crashSessionsList: |
|
7875 pid = crashSession.replace(crashSessionPatternParts[0], "").replace( |
|
7876 crashSessionPatternParts[1], "" |
|
7877 ) |
|
7878 if not psutil.pid_exists(int(pid)): |
|
7879 # it is a real crash session |
|
7880 crashedSessionsList.append(crashSession) |
|
7881 |
|
7882 return crashedSessionsList |
|
7883 |
|
7884 def __checkCrashSessionExists(self): |
|
7885 """ |
|
7886 Private method to check for the existence of crash session files and |
|
7887 select the one to open. |
|
7888 |
|
7889 @return file path of the crash session file to open. An empty string indicates |
|
7890 that no crash session file should be opened or exists. |
|
7891 @rtype str |
|
7892 """ |
|
7893 selectedCrashSessionFile = "" |
|
7894 crashedSessionsList = self.__getCrashedSessions() |
|
7895 if crashedSessionsList: |
|
7896 dlg = EricListSelectionDialog( |
|
7897 sorted(crashedSessionsList), |
|
7898 selectionMode=QAbstractItemView.SelectionMode.SingleSelection, |
|
7899 title=self.tr("Found Crash Sessions"), |
|
7900 message=self.tr( |
|
7901 "These crash session files were found. Select the one to" |
|
7902 " open. Select 'Cancel' to not open a crash session." |
|
7903 ), |
|
7904 doubleClickOk=True, |
|
7905 parent=self, |
|
7906 ) |
|
7907 if dlg.exec() == QDialog.DialogCode.Accepted: |
|
7908 selectedCrashSessionFile = dlg.getSelection()[0] |
|
7909 |
|
7910 return selectedCrashSessionFile |
|
7911 |
7790 def __deleteCrashSession(self): |
7912 def __deleteCrashSession(self): |
7791 """ |
7913 """ |
7792 Private slot to delete the crash session file. |
7914 Private slot to delete the crash session file. |
7793 """ |
7915 """ |
7794 fn = os.path.join(Globals.getConfigDir(), "eric7_crash_session.esj") |
7916 fn = self.__crashSessionFilePath() |
7795 if os.path.exists(fn): |
7917 if os.path.exists(fn): |
7796 with contextlib.suppress(OSError): |
7918 with contextlib.suppress(OSError): |
7797 os.remove(fn) |
7919 os.remove(fn) |
7798 |
7920 |
7799 def __writeCrashSession(self): |
7921 def __writeCrashSession(self): |
7818 if ( |
7940 if ( |
7819 not self.__disableCrashSession |
7941 not self.__disableCrashSession |
7820 and not self.__noCrashOpenAtStartup |
7942 and not self.__noCrashOpenAtStartup |
7821 and Preferences.getUI("OpenCrashSessionOnStartup") |
7943 and Preferences.getUI("OpenCrashSessionOnStartup") |
7822 ): |
7944 ): |
7823 fn = os.path.join(Globals.getConfigDir(), "eric7_crash_session.esj") |
7945 fn = self.__checkCrashSessionExists() |
7824 if os.path.exists(fn): |
7946 if fn: |
7825 yes = EricMessageBox.yesNo( |
7947 res = self.__readSession(filename=fn) |
7826 self, |
|
7827 self.tr("Crash Session found!"), |
|
7828 self.tr( |
|
7829 """A session file of a crashed session was""" |
|
7830 """ found. Shall this session be restored?""" |
|
7831 ), |
|
7832 ) |
|
7833 if yes: |
|
7834 res = self.__readSession(filename=fn) |
|
7835 |
7948 |
7836 return res |
7949 return res |
|
7950 |
|
7951 @pyqtSlot() |
|
7952 def __loadCrashSession(self): |
|
7953 """ |
|
7954 Private slot to load a crash session. |
|
7955 """ |
|
7956 fn = self.__checkCrashSessionExists() |
|
7957 if fn: |
|
7958 self.__readSession(filename=fn) |
|
7959 |
|
7960 @pyqtSlot() |
|
7961 def __cleanCrashSessions(self): |
|
7962 """ |
|
7963 Private slot to clean all stale crash sessions. |
|
7964 """ |
|
7965 from .DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog |
|
7966 |
|
7967 crashedSessionsList = self.__getCrashedSessions() |
|
7968 if crashedSessionsList: |
|
7969 dlg = DeleteFilesConfirmationDialog( |
|
7970 parent=self, |
|
7971 caption=self.tr("Clean stale crash sessions"), |
|
7972 message=self.tr( |
|
7973 "Do you really want to delete these stale crash session files?" |
|
7974 ), |
|
7975 files=sorted(crashedSessionsList), |
|
7976 ) |
|
7977 if dlg.exec() == QDialog.DialogCode.Accepted: |
|
7978 for crashSession in crashedSessionsList: |
|
7979 os.remove(crashSession) |
7837 |
7980 |
7838 def showFindFileByNameDialog(self): |
7981 def showFindFileByNameDialog(self): |
7839 """ |
7982 """ |
7840 Public slot to show the Find File by Name dialog. |
7983 Public slot to show the Find File by Name dialog. |
7841 """ |
7984 """ |