--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/eric7/EricXML/SessionReader.py Sat May 22 11:14:43 2021 +0200 @@ -0,0 +1,425 @@ +# -*- coding: utf-8 -*- + +# Copyright (c) 2010 - 2021 Detlev Offenbach <detlev@die-offenbachs.de> +# + +""" +Module implementing a class for reading an XML session file. +""" + +from E5Gui.E5Application import e5App + +from .Config import sessionFileFormatVersion +from .XMLStreamReaderBase import XMLStreamReaderBase + + +class SessionReader(XMLStreamReaderBase): + """ + Class for reading an XML session file. + """ + supportedVersions = ["4.3", "4.4", "5.0", "6.0", "6.1", "6.2", "6.3", + "6.4"] + + def __init__(self, device, isGlobal): + """ + Constructor + + @param device reference to the I/O device to read from + @type QIODevice + @param isGlobal flag indicating to read the global session + @type bool + """ + XMLStreamReaderBase.__init__(self, device) + + self.version = "" + self.isGlobal = isGlobal + + self.project = e5App().getObject("Project") + self.projectBrowser = e5App().getObject("ProjectBrowser") + self.multiProject = e5App().getObject("MultiProject") + self.vm = e5App().getObject("ViewManager") + self.dbg = e5App().getObject("DebugUI") + self.dbs = e5App().getObject("DebugServer") + + if not self.isGlobal: + # clear all breakpoints and bookmarks first + # (in case we are rereading a session file) + files = self.project.getSources(True) + for file in files: + editor = self.vm.getOpenEditor(file) + if editor is not None: + editor.clearBookmarks() + self.dbs.getBreakPointModel().deleteAll() + self.dbs.getWatchPointModel().deleteAll() + + def readXML(self, quiet=False): + """ + Public method to read and parse the XML document. + + @param quiet flag indicating quiet operations. + If this flag is true, no errors are reported. + @type bool + """ + while not self.atEnd(): + self.readNext() + if self.isStartElement(): + if self.name() == "Session": + self.version = self.attribute( + "version", sessionFileFormatVersion) + if self.version not in self.supportedVersions: + self.raiseUnsupportedFormatVersion(self.version) + elif self.name() == "MultiProject": + self.multiProject.openMultiProject( + self.readElementText(), False) + elif self.name() == "Project": + self.project.openProject(self.readElementText(), False) + elif self.name() == "Filenames": + self.__readFilenames() + elif self.name() == "ActiveWindow": + cline = int(self.attribute("cline", "0")) + cindex = int(self.attribute("cindex", "0")) + filename = self.readElementText() + self.vm.openFiles(filename) + ed = self.vm.getOpenEditor(filename) + if ed is not None: + ed.setCursorPosition(cline, cindex) + ed.ensureCursorVisible() + elif self.name() == "Breakpoints": + self.__readBreakpoints() + elif self.name() == "Watchexpressions": + self.__readWatchexpressions() + elif self.name() == "DebugInfo": + self.__readDebugInfo() + elif self.name() == "Bookmarks": + self.__readBookmarks() + elif self.name() == "ProjectBrowserStates": + self.__readProjectBrowserStates() + elif self.name() == "ViewManagerSplits": + splitCount = int(self.attribute("count", "0")) + orientation = int(self.attribute("orientation", "1")) + self.vm.setSplitOrientation(orientation) + self.vm.setSplitCount(splitCount) + else: + self.raiseUnexpectedStartTag(self.name()) + + if not quiet: + self.showErrorMessage() + + def __readFilenames(self): + """ + Private method to read the file name infos. + """ + editorDict = {} + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "Filenames": + break + + if self.isStartElement(): + if self.name() == "Filename": + cline = int(self.attribute("cline", "0")) + cindex = int(self.attribute("cindex", "0")) + folds = self.attribute("folds") + if folds: + folds = [int(f) - 1 for f in folds.split(',')] + else: + folds = [] + zoom = int(self.attribute("zoom", "-9999")) + cloned = bool(int(self.attribute("cloned", "0"))) + splitIndex = int(self.attribute("splitindex", "0")) + editorIndex = int(self.attribute("editorindex", "-1")) + filename = self.readElementText() + + if cloned and filename in editorDict: + editor = editorDict[filename] + ed = self.vm.newEditorView( + filename, editor, editor.getFileType(), + indexes=(splitIndex, editorIndex)) + else: + ed = self.vm.openSourceFile( + filename, indexes=(splitIndex, editorIndex)) + editorDict[filename] = ed + if ed is not None: + if zoom > -9999: + ed.zoomTo(zoom) + if folds: + ed.recolor() + ed.setContractedFolds(folds) + ed.setCursorPosition(cline, cindex) + ed.ensureCursorVisible() + else: + self.raiseUnexpectedStartTag(self.name()) + + def __readBreakpoints(self): + """ + Private method to read the break point infos. + """ + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "Breakpoints": + break + + if self.isStartElement(): + if self.name() == "Breakpoint": + self.__readBreakpoint() + else: + self.raiseUnexpectedStartTag(self.name()) + + def __readBreakpoint(self): + """ + Private method to read the break point info. + """ + filename = "" + lineno = 0 + bpCond = "" + bpTemp = False + bpEnabled = True + bpCount = 0 + + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "Breakpoint": + self.dbs.getBreakPointModel().addBreakPoint( + filename, lineno, (bpCond, bpTemp, bpEnabled, bpCount)) + break + + if self.isStartElement(): + if self.name() == "BpFilename": + filename = self.readElementText() + elif self.name() == "Linenumber": + lineno = int(self.attribute("value", "0")) + elif self.name() == "Condition": + bpCond = self.readElementText() + if bpCond == 'None': + bpCond = '' + elif self.name() == "Temporary": + bpTemp = self.toBool(self.attribute("value", "False")) + elif self.name() == "Enabled": + bpEnabled = self.toBool(self.attribute("value", "True")) + elif self.name() == "Count": + bpCount = int(self.attribute("value", "0")) + else: + self.raiseUnexpectedStartTag(self.name()) + + def __readWatchexpressions(self): + """ + Private method to read watch expression infos. + """ + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "Watchexpressions": + break + + if self.isStartElement(): + if self.name() == "Watchexpression": + self.__readWatchexpression() + else: + self.raiseUnexpectedStartTag(self.name()) + + def __readWatchexpression(self): + """ + Private method to read the watch expression info. + """ + weCond = "" + weTemp = False + weEnabled = True + weCount = 0 + weSpecialCond = "" + + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "Watchexpression": + self.dbs.getWatchPointModel().addWatchPoint( + weCond, weSpecialCond, (weTemp, weEnabled, weCount)) + break + + if self.isStartElement(): + if self.name() == "Condition": + weCond = self.readElementText() + if weCond == 'None': + weCond = '' + elif self.name() == "Temporary": + weTemp = self.toBool(self.attribute("value", "False")) + elif self.name() == "Enabled": + weEnabled = self.toBool(self.attribute("value", "True")) + elif self.name() == "Count": + weCount = int(self.attribute("value", "0")) + elif self.name() == "Special": + weSpecialCond = self.readElementText() + else: + self.raiseUnexpectedStartTag(self.name()) + + def __readDebugInfo(self): + """ + Private method to read the debug infos. + """ + dbgExcList = [] + dbgExcIgnoreList = [] + + while not self.atEnd(): + self.readNext() + if self.isEndElement(): + if self.name() == "DebugInfo": + break + elif self.name() == "Exceptions": + self.dbg.setExcList(dbgExcList) + if not self.isGlobal: + self.project.dbgExcList = dbgExcList[:] + elif self.name() == "IgnoredExceptions": + self.dbg.setExcIgnoreList(dbgExcIgnoreList) + if not self.isGlobal: + self.project.dbgExcIgnoreList = dbgExcIgnoreList[:] + + if self.isStartElement(): + if self.name() in ("Exceptions", "IgnoredExceptions", + "CovexcPattern"): + pass # ignore these start tags + elif self.name() == "VirtualEnv": + txt = self.readElementText() + self.dbg.lastUsedVenvName = txt + if not self.isGlobal: + self.project.dbgVirtualEnv = txt + elif self.name() == "Interpreter": + # just read this obsolete entry and ignore it + self.readElementText() + elif self.name() == "CommandLine": + txt = self.readElementText() + self.dbg.setArgvHistory(txt) + if not self.isGlobal: + self.project.dbgCmdline = txt + elif self.name() == "WorkingDirectory": + txt = self.readElementText() + self.dbg.setWdHistory(txt) + if not self.isGlobal: + self.project.dbgWd = txt + elif self.name() == "Environment": + txt = self.readElementText() + self.dbg.setEnvHistory(txt) + if not self.isGlobal: + self.project.dbgEnv = txt + elif self.name() == "ReportExceptions": + exc = self.toBool(self.attribute("value", "True")) + self.dbg.setExceptionReporting(exc) + if not self.isGlobal: + self.project.dbgReportExceptions = exc + elif self.name() == "Exception": + dbgExcList.append(self.readElementText()) + elif self.name() == "IgnoredException": + dbgExcIgnoreList.append(self.readElementText()) + elif self.name() == "AutoClearShell": + val = self.toBool(self.attribute("value")) + self.dbg.setAutoClearShell(val) + if not self.isGlobal: + self.project.dbgAutoClearShell = val + elif self.name() == "TracePython": + val = self.toBool(self.attribute("value")) + self.dbg.setTracePython(val) + if not self.isGlobal: + self.project.dbgTracePython = val + elif self.name() == "AutoContinue": + val = self.toBool(self.attribute("value")) + self.dbg.setAutoContinue(val) + if not self.isGlobal: + self.project.dbgAutoContinue = val + elif self.name() == "EnableMultiprocess": + val = self.toBool(self.attribute("value")) + self.dbg.setEnableMultiprocess(val) + if not self.isGlobal: + self.project.dbgEnableMultiprocess = val + elif self.name() == "MultiprocessNoDebug": + txt = self.readElementText() + self.dbg.setMultiprocessNoDebugHistory(txt) + if not self.isGlobal: + self.project.dbgMultiprocessNoDebug = txt + elif self.name() == "GlobalConfigOverride": + configOverride = { + "enable": self.toBool(self.attribute("enable")), + "redirect": self.toBool(self.attribute("redirect")), + } + self.dbg.setEnableGlobalConfigOverride(configOverride) + if not self.isGlobal: + self.project.dbgGlobalConfigOverride = configOverride + else: + self.raiseUnexpectedStartTag(self.name()) + + def __readBookmarks(self): + """ + Private method to read the bookmark infos. + """ + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "Bookmarks": + break + + if self.isStartElement(): + if self.name() == "Bookmark": + self.__readBookmark() + else: + self.raiseUnexpectedStartTag(self.name()) + + def __readBookmark(self): + """ + Private method to read the bookmark info. + """ + filename = "" + lineno = 0 + + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "Bookmark": + editor = self.vm.getOpenEditor(filename) + if editor is not None: + editor.toggleBookmark(lineno) + break + + if self.isStartElement(): + if self.name() == "BmFilename": + filename = self.readElementText() + elif self.name() == "Linenumber": + lineno = int(self.attribute("value", "0")) + else: + self.raiseUnexpectedStartTag(self.name()) + + def __readProjectBrowserStates(self): + """ + Private method to read the project browser state infos. + """ + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "ProjectBrowserStates": + break + + if self.isStartElement(): + if self.name() == "ProjectBrowserState": + browserName = self.attribute("name", "") + if not browserName: + self.raiseBadValue("ProjectBrowserState.name") + self.__readProjectBrowserState(browserName) + else: + self.raiseUnexpectedStartTag(self.name()) + + def __readProjectBrowserState(self, browserName): + """ + Private method to read the project browser state info. + + @param browserName name of the project browser + @type str + """ + expandedNames = [] + + while not self.atEnd(): + self.readNext() + if self.isEndElement() and self.name() == "ProjectBrowserState": + projectBrowser = self.projectBrowser.getProjectBrowser( + browserName) + if projectBrowser is not None: + projectBrowser.expandItemsByName(expandedNames) + break + + if self.isStartElement(): + if self.name() == "ExpandedItemName": + itemName = self.readElementText() + if itemName: + expandedNames.append(itemName) + else: + self.raiseUnexpectedStartTag(self.name())