--- a/eric6/UI/UserInterface.py Mon Feb 01 10:38:43 2021 +0100 +++ b/eric6/UI/UserInterface.py Tue Mar 02 17:12:08 2021 +0100 @@ -51,6 +51,10 @@ import UI.PixmapCache +from Sessions.SessionFile import SessionFile + +from Tasks.TasksFile import TasksFile + from E5Network.E5NetworkProxyFactory import ( E5NetworkProxyFactory, proxyAuthenticationRequired ) @@ -250,14 +254,6 @@ # register it early because it is needed very soon e5App().registerObject("VirtualEnvManager", self.virtualenvManager) - # Generate the debug server object - from Debugger.DebugServer import DebugServer - debugServer = DebugServer(self.__originalPathString) - - # Create the background service object - from Utilities.BackgroundService import BackgroundService - self.backgroundService = BackgroundService() - # Generate an empty project object and multi project object from Project.Project import Project self.project = Project(self) @@ -266,6 +262,15 @@ from MultiProject.MultiProject import MultiProject self.multiProject = MultiProject(self.project, self) + # Generate the debug server object + from Debugger.DebugServer import DebugServer + debugServer = DebugServer(self.__originalPathString, + project=self.project) + + # Create the background service object + from Utilities.BackgroundService import BackgroundService + self.backgroundService = BackgroundService() + splash.showMessage(self.tr("Initializing Plugin Manager...")) # Initialize the Plugin Manager (Plugins are initialized later @@ -610,6 +615,10 @@ self.__inVersionCheck = False self.__versionCheckProgress = None + # create the various JSON file interfaces + self.__sessionFile = SessionFile(True) + self.__tasksFile = TasksFile(True) + # Initialize the actions, menus, toolbars and statusbar splash.showMessage(self.tr("Initializing Actions...")) self.__initActions() @@ -1368,8 +1377,8 @@ '--' option are considered debug arguments to the program for the debugger. All files named before the '--' option are opened in a text editor, unless the argument ends in - .e4p, then it is opened as a project file. If it ends in - .e4m or .e5m, it is opened as a multiproject. + .epj or .e4p, then it is opened as a project file. If it + ends in .emj, .e4m or .e5m, it is opened as a multi project. """ # check and optionally read a crash session and ignore any arguments if self.__readCrashSession(): @@ -1429,10 +1438,10 @@ except IndexError: ext = "" - if ext in ['.e4p']: + if ext in ('.epj', '.e4p'): self.project.openProject(arg) opens += 1 - elif ext in ['.e4m', '.e5m']: + elif ext in ('.emj', '.e4m', '.e5m'): self.multiProject.openMultiProject(arg) opens += 1 else: @@ -3319,8 +3328,7 @@ """ filetb = self.viewmanager.initFileToolbar(self.toolbarManager) edittb = self.viewmanager.initEditToolbar(self.toolbarManager) - searchtb, quicksearchtb = self.viewmanager.initSearchToolbars( - self.toolbarManager) + searchtb = self.viewmanager.initSearchToolbar(self.toolbarManager) viewtb = self.viewmanager.initViewToolbar(self.toolbarManager) starttb, debugtb = self.debuggerUI.initToolbars(self.toolbarManager) multiprojecttb = self.multiProject.initToolbar(self.toolbarManager) @@ -3441,7 +3449,6 @@ self.addToolBar(filetb) self.addToolBar(edittb) self.addToolBar(searchtb) - self.addToolBar(quicksearchtb) self.addToolBar(viewtb) self.addToolBar(starttb) self.addToolBar(debugtb) @@ -3459,7 +3466,6 @@ # hide toolbars not wanted in the initial layout searchtb.hide() - quicksearchtb.hide() viewtb.hide() debugtb.hide() multiprojecttb.hide() @@ -3488,8 +3494,6 @@ self.__toolbars["view_profiles"] = [profilestb.windowTitle(), profilestb, ""] self.__toolbars["plugins"] = [pluginstb.windowTitle(), pluginstb, ""] - self.__toolbars["quicksearch"] = [quicksearchtb.windowTitle(), - quicksearchtb, ""] self.__toolbars["multiproject"] = [multiprojecttb.windowTitle(), multiprojecttb, ""] self.__toolbars["spelling"] = [spellingtb.windowTitle(), spellingtb, @@ -5985,6 +5989,9 @@ elif res == 0: # successful break + elif res == -1: + # web browser did not start + continue else: return False @@ -5994,7 +6001,7 @@ else: clientArgs.append("--newtab={0}".format(home)) - if clientArgs: + if clientArgs and self.__webBrowserClient: self.__webBrowserClient.processArgs(clientArgs, disconnect=False) return True @@ -6287,7 +6294,8 @@ None, self.tr("Export Keyboard Shortcuts"), "", - self.tr("Keyboard shortcut file (*.e4k)"), + self.tr("Keyboard Shortcuts File (*.ekj);;" + "XML Keyboard Shortcuts File (*.e4k)"), "", E5FileDialog.Options(E5FileDialog.DontConfirmOverwrite)) @@ -6300,8 +6308,18 @@ if ex: fn += ex - from Preferences import Shortcuts - Shortcuts.exportShortcuts(fn) + if os.path.exists(fn): + ok = E5MessageBox.yesNo( + self, + self.tr("Export Keyboard Shortcuts"), + self.tr("""<p>The keyboard shortcuts file <b>{0}</b> exists""" + """ already. Overwrite it?</p>""").format(fn)) + else: + ok = True + + if ok: + from Preferences import Shortcuts + Shortcuts.exportShortcuts(fn) def __importShortcuts(self): """ @@ -6311,7 +6329,8 @@ None, self.tr("Import Keyboard Shortcuts"), "", - self.tr("Keyboard shortcut file (*.e4k)")) + self.tr("Keyboard Shortcuts File (*.ekj);;" + "XML Keyboard shortcut file (*.e4k)")) if fn: from Preferences import Shortcuts @@ -6471,51 +6490,41 @@ def __writeTasks(self): """ - Private slot to write the tasks data to an XML file (.e6t). - """ - fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.e6t") - f = QFile(fn) - ok = f.open(QIODevice.WriteOnly) - if not ok: - E5MessageBox.critical( - self, - self.tr("Save tasks"), - self.tr( - "<p>The tasks file <b>{0}</b> could not be written.</p>") - .format(fn)) - return - - from E5XML.TasksWriter import TasksWriter - TasksWriter(f, False).writeXML() - f.close() - + Private slot to write the tasks data to a JSON file (.etj). + """ + fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.etj") + self.__tasksFile.writeFile(fn) + def __readTasks(self): """ - Private slot to read in the tasks file (.e6t). - """ - fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.e6t") - if not os.path.exists(fn): - # try again with the old extension - fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.e4t") - if not os.path.exists(fn): - return - f = QFile(fn) - if f.open(QIODevice.ReadOnly): - from E5XML.TasksReader import TasksReader - reader = TasksReader(f, viewer=self.taskViewer) - reader.readXML() - f.close() + Private slot to read in the tasks file (.etj or .e6t). + """ + fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.etj") + if os.path.exists(fn): + # try new style JSON file first + self.__tasksFile.readFile(fn) else: - E5MessageBox.critical( - self, - self.tr("Read tasks"), - self.tr( - "<p>The tasks file <b>{0}</b> could not be read.</p>") - .format(fn)) + # try old style XML file second + fn = os.path.join(Utilities.getConfigDir(), "eric6tasks.e6t") + if os.path.exists(fn): + f = QFile(fn) + if f.open(QIODevice.ReadOnly): + from E5XML.TasksReader import TasksReader + reader = TasksReader(f, viewer=self.taskViewer) + reader.readXML() + f.close() + else: + E5MessageBox.critical( + self, + self.tr("Read Tasks"), + self.tr( + "<p>The tasks file <b>{0}</b> could not be" + " read.</p>") + .format(fn)) def __writeSession(self, filename="", crashSession=False): """ - Private slot to write the session data to an XML file (.e5s). + Private slot to write the session data to a JSON file (.esj). @param filename name of a session file to write @type str @@ -6524,33 +6533,38 @@ @return flag indicating success @rtype bool """ - res = False if filename: fn = filename elif crashSession: fn = os.path.join(Utilities.getConfigDir(), - "eric6_crash_session.e5s") + "eric6_crash_session.esj") else: fn = os.path.join(Utilities.getConfigDir(), - "eric6session.e5s") - f = QFile(fn) - if f.open(QIODevice.WriteOnly): - from E5XML.SessionWriter import SessionWriter - SessionWriter(f, None).writeXML() - f.close() - res = True + "eric6session.esj") + + if fn.endswith(".esj"): + res = self.__sessionFile.writeFile(fn) else: - E5MessageBox.critical( - self, - self.tr("Save session"), - self.tr("<p>The session file <b>{0}</b> could not be" - " written.</p>") - .format(fn)) + f = QFile(fn) + if f.open(QIODevice.WriteOnly): + from E5XML.SessionWriter import SessionWriter + SessionWriter(f, None).writeXML() + f.close() + res = True + else: + E5MessageBox.critical( + self, + self.tr("Save Session"), + self.tr("<p>The session file <b>{0}</b> could not be" + " written.</p>") + .format(fn)) + res = False + return res - + def __readSession(self, filename=""): """ - Private slot to read in the session file (.e5s or .e4s). + Private slot to read in the session file (.esj or .e5s). @param filename name of a session file to read @type str @@ -6561,14 +6575,14 @@ fn = filename else: fn = os.path.join(Utilities.getConfigDir(), - "eric6session.e5s") + "eric6session.esj") if not os.path.exists(fn): fn = os.path.join(Utilities.getConfigDir(), - "eric6session.e4s") + "eric6session.e5s") if not os.path.exists(fn): E5MessageBox.critical( self, - self.tr("Read session"), + self.tr("Read Session"), self.tr("<p>The session file <b>{0}</b> could not" " be read.</p>") .format(fn)) @@ -6576,22 +6590,29 @@ res = False if fn: - f = QFile(fn) - if f.open(QIODevice.ReadOnly): - from E5XML.SessionReader import SessionReader + if fn.endswith(".esj"): + # new JSON based format self.__readingSession = True - reader = SessionReader(f, True) - reader.readXML() + res = self.__sessionFile.readFile(fn) self.__readingSession = False - f.close() - res = True else: - E5MessageBox.critical( - self, - self.tr("Read session"), - self.tr("<p>The session file <b>{0}</b> could not be" - " read.</p>") - .format(fn)) + # old XML based format + f = QFile(fn) + if f.open(QIODevice.ReadOnly): + from E5XML.SessionReader import SessionReader + self.__readingSession = True + reader = SessionReader(f, True) + reader.readXML() + self.__readingSession = False + f.close() + res = True + else: + E5MessageBox.critical( + self, + self.tr("Read session"), + self.tr("<p>The session file <b>{0}</b> could not be" + " read.</p>") + .format(fn)) # Write a crash session after a session was read. self.__writeCrashSession() @@ -6604,9 +6625,10 @@ """ sessionFile, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( self, - self.tr("Save session"), + self.tr("Save Session"), Utilities.getHomeDir(), - self.tr("eric Session Files (*.e5s)"), + self.tr("eric Session Files (*.esj);;" + "eric XML Session Files (*.e5s)"), "") if not sessionFile: @@ -6628,7 +6650,8 @@ self, self.tr("Load session"), Utilities.getHomeDir(), - self.tr("eric Session Files (*.e5s)")) + self.tr("eric Session Files (*.esj);;" + "eric XML Session Files (*.e5s)")) if not sessionFile: return @@ -6639,14 +6662,15 @@ """ Private slot to delete the crash session file. """ - fn = os.path.join(Utilities.getConfigDir(), - "eric6_crash_session.e5s") - if os.path.exists(fn): - try: - os.remove(fn) - except OSError: - # ignore it silently - pass + for ext in (".esj", ".e5s"): + fn = os.path.join(Utilities.getConfigDir(), + f"eric6_crash_session{ext}") + if os.path.exists(fn): + try: + os.remove(fn) + except OSError: + # ignore it silently + pass def __writeCrashSession(self): """ @@ -6673,7 +6697,7 @@ Preferences.getUI("OpenCrashSessionOnStartup") ): fn = os.path.join(Utilities.getConfigDir(), - "eric6_crash_session.e5s") + "eric6_crash_session.esj") if os.path.exists(fn): yes = E5MessageBox.yesNo( self,