|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2004 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the writer class for writing an XML session file. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 import time |
|
13 |
|
14 from E5Gui.E5Application import e5App |
|
15 |
|
16 from .XMLStreamWriterBase import XMLStreamWriterBase |
|
17 from .Config import sessionFileFormatVersion |
|
18 |
|
19 import Preferences |
|
20 |
|
21 |
|
22 class SessionWriter(XMLStreamWriterBase): |
|
23 """ |
|
24 Class implementing the writer class for writing an XML session file. |
|
25 """ |
|
26 def __init__(self, device, projectName): |
|
27 """ |
|
28 Constructor |
|
29 |
|
30 @param device reference to the I/O device to write to |
|
31 @type QIODevice |
|
32 @param projectName name of the project or None for the |
|
33 global session |
|
34 @type str or None |
|
35 """ |
|
36 XMLStreamWriterBase.__init__(self, device) |
|
37 |
|
38 self.name = projectName |
|
39 self.project = e5App().getObject("Project") |
|
40 self.projectBrowser = e5App().getObject("ProjectBrowser") |
|
41 self.multiProject = e5App().getObject("MultiProject") |
|
42 self.vm = e5App().getObject("ViewManager") |
|
43 self.dbg = e5App().getObject("DebugUI") |
|
44 self.dbs = e5App().getObject("DebugServer") |
|
45 |
|
46 def writeXML(self): |
|
47 """ |
|
48 Public method to write the XML to the file. |
|
49 """ |
|
50 isGlobal = self.name is None |
|
51 |
|
52 XMLStreamWriterBase.writeXML(self) |
|
53 |
|
54 self.writeDTD('<!DOCTYPE Session SYSTEM "Session-{0}.dtd">'.format( |
|
55 sessionFileFormatVersion)) |
|
56 |
|
57 # add some generation comments |
|
58 if not isGlobal: |
|
59 self.writeComment( |
|
60 " eric6 session file for project {0} ".format(self.name)) |
|
61 self.writeComment( |
|
62 " This file was generated automatically, do not edit. ") |
|
63 if Preferences.getProject("XMLTimestamp") or isGlobal: |
|
64 self.writeComment( |
|
65 " Saved: {0} ".format(time.strftime('%Y-%m-%d, %H:%M:%S'))) |
|
66 |
|
67 # add the main tag |
|
68 self.writeStartElement("Session") |
|
69 self.writeAttribute("version", sessionFileFormatVersion) |
|
70 |
|
71 # step 0: save open multi project and project for the global session |
|
72 if isGlobal: |
|
73 if self.multiProject.isOpen(): |
|
74 self.writeTextElement( |
|
75 "MultiProject", self.multiProject.getMultiProjectFile()) |
|
76 if self.project.isOpen(): |
|
77 self.writeTextElement("Project", self.project.getProjectFile()) |
|
78 |
|
79 # step 1: save all open (project) filenames and the active window |
|
80 if self.vm.canSplit(): |
|
81 self.writeEmptyElement("ViewManagerSplits") |
|
82 self.writeAttribute("count", str(self.vm.splitCount())) |
|
83 self.writeAttribute("orientation", |
|
84 str(self.vm.getSplitOrientation())) |
|
85 |
|
86 allOpenEditorLists = self.vm.getOpenEditorsForSession() |
|
87 editorDict = {} # remember editors by file name to detect clones |
|
88 self.writeStartElement("Filenames") |
|
89 for splitIndex, openEditorList in enumerate(allOpenEditorLists): |
|
90 for editorIndex, editor in enumerate(openEditorList): |
|
91 fileName = editor.getFileName() |
|
92 if isGlobal or self.project.isProjectFile(fileName): |
|
93 line, index = editor.getCursorPosition() |
|
94 folds = ','.join( |
|
95 [str(i + 1) for i in editor.contractedFolds()]) |
|
96 zoom = editor.getZoom() |
|
97 if fileName in editorDict: |
|
98 isClone = int(editorDict[fileName].isClone(editor)) |
|
99 else: |
|
100 isClone = 0 |
|
101 editorDict[fileName] = editor |
|
102 self.writeStartElement("Filename") |
|
103 self.writeAttribute("cline", str(line)) |
|
104 self.writeAttribute("cindex", str(index)) |
|
105 self.writeAttribute("folds", folds) |
|
106 self.writeAttribute("zoom", str(zoom)) |
|
107 self.writeAttribute("cloned", str(isClone)) |
|
108 self.writeAttribute("splitindex", str(splitIndex)) |
|
109 self.writeAttribute("editorindex", str(editorIndex)) |
|
110 self.writeCharacters(fileName) |
|
111 self.writeEndElement() |
|
112 self.writeEndElement() |
|
113 |
|
114 aw = self.vm.getActiveName() |
|
115 if aw and self.project.isProjectFile(aw): |
|
116 ed = self.vm.getOpenEditor(aw) |
|
117 line, index = ed.getCursorPosition() |
|
118 self.writeStartElement("ActiveWindow") |
|
119 self.writeAttribute("cline", str(line)) |
|
120 self.writeAttribute("cindex", str(index)) |
|
121 self.writeCharacters(aw) |
|
122 self.writeEndElement() |
|
123 |
|
124 # step 2a: save all breakpoints |
|
125 allBreaks = Preferences.getProject("SessionAllBreakpoints") |
|
126 projectFiles = self.project.getSources(True) |
|
127 bpModel = self.dbs.getBreakPointModel() |
|
128 self.writeStartElement("Breakpoints") |
|
129 for row in range(bpModel.rowCount()): |
|
130 index = bpModel.index(row, 0) |
|
131 fname, lineno, cond, temp, enabled, count = \ |
|
132 bpModel.getBreakPointByIndex(index)[:6] |
|
133 if isGlobal or allBreaks or fname in projectFiles: |
|
134 self.writeStartElement("Breakpoint") |
|
135 self.writeTextElement("BpFilename", fname) |
|
136 self.writeEmptyElement("Linenumber") |
|
137 self.writeAttribute("value", str(lineno)) |
|
138 self.writeTextElement("Condition", str(cond)) |
|
139 self.writeEmptyElement("Temporary") |
|
140 self.writeAttribute("value", str(temp)) |
|
141 self.writeEmptyElement("Enabled") |
|
142 self.writeAttribute("value", str(enabled)) |
|
143 self.writeEmptyElement("Count") |
|
144 self.writeAttribute("value", str(count)) |
|
145 self.writeEndElement() |
|
146 self.writeEndElement() |
|
147 |
|
148 # step 2b: save all watch expressions |
|
149 self.writeStartElement("Watchexpressions") |
|
150 wpModel = self.dbs.getWatchPointModel() |
|
151 for row in range(wpModel.rowCount()): |
|
152 index = wpModel.index(row, 0) |
|
153 cond, special, temp, enabled, count = \ |
|
154 wpModel.getWatchPointByIndex(index)[:5] |
|
155 self.writeStartElement("Watchexpression") |
|
156 self.writeTextElement("Condition", str(cond)) |
|
157 self.writeEmptyElement("Temporary") |
|
158 self.writeAttribute("value", str(temp)) |
|
159 self.writeEmptyElement("Enabled") |
|
160 self.writeAttribute("value", str(enabled)) |
|
161 self.writeEmptyElement("Count") |
|
162 self.writeAttribute("value", str(count)) |
|
163 self.writeTextElement("Special", special) |
|
164 self.writeEndElement() |
|
165 self.writeEndElement() |
|
166 |
|
167 # step 3: save the debug info |
|
168 self.writeStartElement("DebugInfo") |
|
169 if isGlobal: |
|
170 if len(self.dbg.argvHistory): |
|
171 dbgCmdline = str(self.dbg.argvHistory[0]) |
|
172 else: |
|
173 dbgCmdline = "" |
|
174 if len(self.dbg.wdHistory): |
|
175 dbgWd = self.dbg.wdHistory[0] |
|
176 else: |
|
177 dbgWd = "" |
|
178 if len(self.dbg.envHistory): |
|
179 dbgEnv = self.dbg.envHistory[0] |
|
180 else: |
|
181 dbgEnv = "" |
|
182 self.writeTextElement("VirtualEnv", self.dbg.lastUsedVenvName) |
|
183 self.writeTextElement("CommandLine", dbgCmdline) |
|
184 self.writeTextElement("WorkingDirectory", dbgWd) |
|
185 self.writeTextElement("Environment", dbgEnv) |
|
186 self.writeEmptyElement("ReportExceptions") |
|
187 self.writeAttribute("value", str(self.dbg.exceptions)) |
|
188 self.writeStartElement("Exceptions") |
|
189 for exc in self.dbg.excList: |
|
190 self.writeTextElement("Exception", exc) |
|
191 self.writeEndElement() |
|
192 self.writeStartElement("IgnoredExceptions") |
|
193 for iexc in self.dbg.excIgnoreList: |
|
194 self.writeTextElement("IgnoredException", iexc) |
|
195 self.writeEndElement() |
|
196 self.writeEmptyElement("AutoClearShell") |
|
197 self.writeAttribute("value", str(self.dbg.autoClearShell)) |
|
198 self.writeEmptyElement("TracePython") |
|
199 self.writeAttribute("value", str(self.dbg.tracePython)) |
|
200 self.writeEmptyElement("AutoContinue") |
|
201 self.writeAttribute("value", str(self.dbg.autoContinue)) |
|
202 self.writeEmptyElement("CovexcPattern") # kept for compatibility |
|
203 else: |
|
204 self.writeTextElement("VirtualEnv", self.project.dbgVirtualEnv) |
|
205 self.writeTextElement("CommandLine", self.project.dbgCmdline) |
|
206 self.writeTextElement("WorkingDirectory", self.project.dbgWd) |
|
207 self.writeTextElement("Environment", self.project.dbgEnv) |
|
208 self.writeEmptyElement("ReportExceptions") |
|
209 self.writeAttribute("value", str(self.project.dbgReportExceptions)) |
|
210 self.writeStartElement("Exceptions") |
|
211 for exc in self.project.dbgExcList: |
|
212 self.writeTextElement("Exception", exc) |
|
213 self.writeEndElement() |
|
214 self.writeStartElement("IgnoredExceptions") |
|
215 for iexc in self.project.dbgExcIgnoreList: |
|
216 self.writeTextElement("IgnoredException", iexc) |
|
217 self.writeEndElement() |
|
218 self.writeEmptyElement("AutoClearShell") |
|
219 self.writeAttribute("value", str(self.project.dbgAutoClearShell)) |
|
220 self.writeEmptyElement("TracePython") |
|
221 self.writeAttribute("value", str(self.project.dbgTracePython)) |
|
222 self.writeEmptyElement("AutoContinue") |
|
223 self.writeAttribute("value", str(self.project.dbgAutoContinue)) |
|
224 self.writeEmptyElement("CovexcPattern") # kept for compatibility |
|
225 self.writeEndElement() |
|
226 |
|
227 # step 4: save bookmarks of all open (project) files |
|
228 self.writeStartElement("Bookmarks") |
|
229 for fileName in editorDict: |
|
230 if isGlobal or self.project.isProjectFile(fileName): |
|
231 editor = editorDict[fileName] |
|
232 for bookmark in editor.getBookmarks(): |
|
233 self.writeStartElement("Bookmark") |
|
234 self.writeTextElement("BmFilename", fileName) |
|
235 self.writeEmptyElement("Linenumber") |
|
236 self.writeAttribute("value", str(bookmark)) |
|
237 self.writeEndElement() |
|
238 self.writeEndElement() |
|
239 |
|
240 # step 5: save state of the various project browsers |
|
241 if not isGlobal: |
|
242 self.writeStartElement("ProjectBrowserStates") |
|
243 for browserName in self.projectBrowser.getProjectBrowserNames(): |
|
244 self.writeStartElement("ProjectBrowserState") |
|
245 self.writeAttribute("name", browserName) |
|
246 # get the names of expanded files and directories |
|
247 names = self.projectBrowser\ |
|
248 .getProjectBrowser(browserName).getExpandedItemNames() |
|
249 for name in names: |
|
250 self.writeTextElement("ExpandedItemName", name) |
|
251 self.writeEndElement() |
|
252 self.writeEndElement() |
|
253 |
|
254 # add the main end tag |
|
255 self.writeEndElement() |
|
256 self.writeEndDocument() |