|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2010 - 2019 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing a class for reading an XML session file. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 from E5Gui.E5Application import e5App |
|
13 |
|
14 from .Config import sessionFileFormatVersion |
|
15 from .XMLStreamReaderBase import XMLStreamReaderBase |
|
16 |
|
17 |
|
18 class SessionReader(XMLStreamReaderBase): |
|
19 """ |
|
20 Class for reading an XML session file. |
|
21 """ |
|
22 supportedVersions = ["4.3", "4.4", "5.0", "6.0", "6.1", "6.2"] |
|
23 |
|
24 def __init__(self, device, isGlobal): |
|
25 """ |
|
26 Constructor |
|
27 |
|
28 @param device reference to the I/O device to read from |
|
29 @type QIODevice |
|
30 @param isGlobal flag indicating to read the global session |
|
31 @type bool |
|
32 """ |
|
33 XMLStreamReaderBase.__init__(self, device) |
|
34 |
|
35 self.version = "" |
|
36 self.isGlobal = isGlobal |
|
37 |
|
38 self.project = e5App().getObject("Project") |
|
39 self.projectBrowser = e5App().getObject("ProjectBrowser") |
|
40 self.multiProject = e5App().getObject("MultiProject") |
|
41 self.vm = e5App().getObject("ViewManager") |
|
42 self.dbg = e5App().getObject("DebugUI") |
|
43 self.dbs = e5App().getObject("DebugServer") |
|
44 |
|
45 if not self.isGlobal: |
|
46 # clear all breakpoints and bookmarks first |
|
47 # (in case we are rereading a session file) |
|
48 files = self.project.getSources(True) |
|
49 for file in files: |
|
50 editor = self.vm.getOpenEditor(file) |
|
51 if editor is not None: |
|
52 editor.clearBookmarks() |
|
53 self.dbs.getBreakPointModel().deleteAll() |
|
54 self.dbs.getWatchPointModel().deleteAll() |
|
55 |
|
56 def readXML(self, quiet=False): |
|
57 """ |
|
58 Public method to read and parse the XML document. |
|
59 |
|
60 @param quiet flag indicating quiet operations. |
|
61 If this flag is true, no errors are reported. |
|
62 @type bool |
|
63 """ |
|
64 while not self.atEnd(): |
|
65 self.readNext() |
|
66 if self.isStartElement(): |
|
67 if self.name() == "Session": |
|
68 self.version = self.attribute( |
|
69 "version", sessionFileFormatVersion) |
|
70 if self.version not in self.supportedVersions: |
|
71 self.raiseUnsupportedFormatVersion(self.version) |
|
72 elif self.name() == "MultiProject": |
|
73 self.multiProject.openMultiProject( |
|
74 self.readElementText(), False) |
|
75 elif self.name() == "Project": |
|
76 self.project.openProject(self.readElementText(), False) |
|
77 elif self.name() == "Filenames": |
|
78 self.__readFilenames() |
|
79 elif self.name() == "ActiveWindow": |
|
80 cline = int(self.attribute("cline", "0")) |
|
81 cindex = int(self.attribute("cindex", "0")) |
|
82 filename = self.readElementText() |
|
83 self.vm.openFiles(filename) |
|
84 ed = self.vm.getOpenEditor(filename) |
|
85 if ed is not None: |
|
86 ed.setCursorPosition(cline, cindex) |
|
87 ed.ensureCursorVisible() |
|
88 elif self.name() == "Breakpoints": |
|
89 self.__readBreakpoints() |
|
90 elif self.name() == "Watchexpressions": |
|
91 self.__readWatchexpressions() |
|
92 elif self.name() == "DebugInfo": |
|
93 self.__readDebugInfo() |
|
94 elif self.name() == "Bookmarks": |
|
95 self.__readBookmarks() |
|
96 elif self.name() == "ProjectBrowserStates": |
|
97 self.__readProjectBrowserStates() |
|
98 elif self.name() == "ViewManagerSplits": |
|
99 splitCount = int(self.attribute("count", "0")) |
|
100 orientation = int(self.attribute("orientation", "1")) |
|
101 self.vm.setSplitOrientation(orientation) |
|
102 self.vm.setSplitCount(splitCount) |
|
103 else: |
|
104 self.raiseUnexpectedStartTag(self.name()) |
|
105 |
|
106 if not quiet: |
|
107 self.showErrorMessage() |
|
108 |
|
109 def __readFilenames(self): |
|
110 """ |
|
111 Private method to read the file name infos. |
|
112 """ |
|
113 editorDict = {} |
|
114 while not self.atEnd(): |
|
115 self.readNext() |
|
116 if self.isEndElement() and self.name() == "Filenames": |
|
117 break |
|
118 |
|
119 if self.isStartElement(): |
|
120 if self.name() == "Filename": |
|
121 cline = int(self.attribute("cline", "0")) |
|
122 cindex = int(self.attribute("cindex", "0")) |
|
123 folds = self.attribute("folds") |
|
124 if folds: |
|
125 folds = [int(f) - 1 for f in folds.split(',')] |
|
126 else: |
|
127 folds = [] |
|
128 zoom = int(self.attribute("zoom", "-9999")) |
|
129 cloned = bool(int(self.attribute("cloned", "0"))) |
|
130 splitIndex = int(self.attribute("splitindex", "0")) |
|
131 editorIndex = int(self.attribute("editorindex", "-1")) |
|
132 filename = self.readElementText() |
|
133 |
|
134 if cloned and filename in editorDict: |
|
135 editor = editorDict[filename] |
|
136 ed = self.vm.newEditorView( |
|
137 filename, editor, editor.getFileType(), |
|
138 indexes=(splitIndex, editorIndex)) |
|
139 else: |
|
140 ed = self.vm.openSourceFile( |
|
141 filename, indexes=(splitIndex, editorIndex)) |
|
142 editorDict[filename] = ed |
|
143 if ed is not None: |
|
144 if zoom > -9999: |
|
145 ed.zoomTo(zoom) |
|
146 if folds: |
|
147 ed.recolor() |
|
148 ed.setContractedFolds(folds) |
|
149 ed.setCursorPosition(cline, cindex) |
|
150 ed.ensureCursorVisible() |
|
151 else: |
|
152 self.raiseUnexpectedStartTag(self.name()) |
|
153 |
|
154 def __readBreakpoints(self): |
|
155 """ |
|
156 Private method to read the break point infos. |
|
157 """ |
|
158 while not self.atEnd(): |
|
159 self.readNext() |
|
160 if self.isEndElement() and self.name() == "Breakpoints": |
|
161 break |
|
162 |
|
163 if self.isStartElement(): |
|
164 if self.name() == "Breakpoint": |
|
165 self.__readBreakpoint() |
|
166 else: |
|
167 self.raiseUnexpectedStartTag(self.name()) |
|
168 |
|
169 def __readBreakpoint(self): |
|
170 """ |
|
171 Private method to read the break point info. |
|
172 """ |
|
173 filename = "" |
|
174 lineno = 0 |
|
175 bpCond = "" |
|
176 bpTemp = False |
|
177 bpEnabled = True |
|
178 bpCount = 0 |
|
179 |
|
180 while not self.atEnd(): |
|
181 self.readNext() |
|
182 if self.isEndElement() and self.name() == "Breakpoint": |
|
183 self.dbs.getBreakPointModel().addBreakPoint( |
|
184 filename, lineno, (bpCond, bpTemp, bpEnabled, bpCount)) |
|
185 break |
|
186 |
|
187 if self.isStartElement(): |
|
188 if self.name() == "BpFilename": |
|
189 filename = self.readElementText() |
|
190 elif self.name() == "Linenumber": |
|
191 lineno = int(self.attribute("value", "0")) |
|
192 elif self.name() == "Condition": |
|
193 bpCond = self.readElementText() |
|
194 if bpCond == 'None': |
|
195 bpCond = '' |
|
196 elif self.name() == "Temporary": |
|
197 bpTemp = self.toBool(self.attribute("value", "False")) |
|
198 elif self.name() == "Enabled": |
|
199 bpEnabled = self.toBool(self.attribute("value", "True")) |
|
200 elif self.name() == "Count": |
|
201 bpCount = int(self.attribute("value", "0")) |
|
202 else: |
|
203 self.raiseUnexpectedStartTag(self.name()) |
|
204 |
|
205 def __readWatchexpressions(self): |
|
206 """ |
|
207 Private method to read watch expression infos. |
|
208 """ |
|
209 while not self.atEnd(): |
|
210 self.readNext() |
|
211 if self.isEndElement() and self.name() == "Watchexpressions": |
|
212 break |
|
213 |
|
214 if self.isStartElement(): |
|
215 if self.name() == "Watchexpression": |
|
216 self.__readWatchexpression() |
|
217 else: |
|
218 self.raiseUnexpectedStartTag(self.name()) |
|
219 |
|
220 def __readWatchexpression(self): |
|
221 """ |
|
222 Private method to read the watch expression info. |
|
223 """ |
|
224 weCond = "" |
|
225 weTemp = False |
|
226 weEnabled = True |
|
227 weCount = 0 |
|
228 weSpecialCond = "" |
|
229 |
|
230 while not self.atEnd(): |
|
231 self.readNext() |
|
232 if self.isEndElement() and self.name() == "Watchexpression": |
|
233 self.dbs.getWatchPointModel().addWatchPoint( |
|
234 weCond, weSpecialCond, (weTemp, weEnabled, weCount)) |
|
235 break |
|
236 |
|
237 if self.isStartElement(): |
|
238 if self.name() == "Condition": |
|
239 weCond = self.readElementText() |
|
240 if weCond == 'None': |
|
241 weCond = '' |
|
242 elif self.name() == "Temporary": |
|
243 weTemp = self.toBool(self.attribute("value", "False")) |
|
244 elif self.name() == "Enabled": |
|
245 weEnabled = self.toBool(self.attribute("value", "True")) |
|
246 elif self.name() == "Count": |
|
247 weCount = int(self.attribute("value", "0")) |
|
248 elif self.name() == "Special": |
|
249 weSpecialCond = self.readElementText() |
|
250 else: |
|
251 self.raiseUnexpectedStartTag(self.name()) |
|
252 |
|
253 def __readDebugInfo(self): |
|
254 """ |
|
255 Private method to read the debug infos. |
|
256 """ |
|
257 dbgExcList = [] |
|
258 dbgExcIgnoreList = [] |
|
259 |
|
260 while not self.atEnd(): |
|
261 self.readNext() |
|
262 if self.isEndElement(): |
|
263 if self.name() == "DebugInfo": |
|
264 break |
|
265 elif self.name() == "Exceptions": |
|
266 self.dbg.setExcList(dbgExcList) |
|
267 if not self.isGlobal: |
|
268 self.project.dbgExcList = dbgExcList[:] |
|
269 elif self.name() == "IgnoredExceptions": |
|
270 self.dbg.setExcIgnoreList(dbgExcIgnoreList) |
|
271 if not self.isGlobal: |
|
272 self.project.dbgExcIgnoreList = dbgExcIgnoreList[:] |
|
273 |
|
274 if self.isStartElement(): |
|
275 if self.name() == "VirtualEnv": |
|
276 txt = self.readElementText() |
|
277 self.dbg.lastUsedVenvName = txt |
|
278 if not self.isGlobal: |
|
279 self.project.dbgVirtualEnv = txt |
|
280 elif self.name() == "Interpreter": |
|
281 # just read this obsolete entry and ignore it |
|
282 self.readElementText() |
|
283 elif self.name() == "CommandLine": |
|
284 txt = self.readElementText() |
|
285 self.dbg.setArgvHistory(txt) |
|
286 if not self.isGlobal: |
|
287 self.project.dbgCmdline = txt |
|
288 elif self.name() == "WorkingDirectory": |
|
289 txt = self.readElementText() |
|
290 self.dbg.setWdHistory(txt) |
|
291 if not self.isGlobal: |
|
292 self.project.dbgWd = txt |
|
293 elif self.name() == "Environment": |
|
294 txt = self.readElementText() |
|
295 self.dbg.setEnvHistory(txt) |
|
296 if not self.isGlobal: |
|
297 self.project.dbgEnv = txt |
|
298 elif self.name() == "ReportExceptions": |
|
299 exc = self.toBool(self.attribute("value", "True")) |
|
300 self.dbg.setExceptionReporting(exc) |
|
301 if not self.isGlobal: |
|
302 self.project.dbgReportExceptions = exc |
|
303 elif self.name() == "Exceptions": |
|
304 pass # ignore this start tag |
|
305 elif self.name() == "Exception": |
|
306 dbgExcList.append(self.readElementText()) |
|
307 elif self.name() == "IgnoredExceptions": |
|
308 pass # ignore this start tag |
|
309 elif self.name() == "IgnoredException": |
|
310 dbgExcIgnoreList.append(self.readElementText()) |
|
311 elif self.name() == "AutoClearShell": |
|
312 val = self.toBool(self.attribute("value")) |
|
313 self.dbg.setAutoClearShell(val) |
|
314 if not self.isGlobal: |
|
315 self.project.dbgAutoClearShell = val |
|
316 elif self.name() == "TracePython": |
|
317 val = self.toBool(self.attribute("value")) |
|
318 self.dbg.setTracePython(val) |
|
319 if not self.isGlobal: |
|
320 self.project.dbgTracePython = val |
|
321 elif self.name() == "AutoContinue": |
|
322 val = self.toBool(self.attribute("value")) |
|
323 self.dbg.setAutoContinue(val) |
|
324 if not self.isGlobal: |
|
325 self.project.dbgAutoContinue = val |
|
326 elif self.name() == "CovexcPattern": |
|
327 pass # ignore this start tag |
|
328 else: |
|
329 self.raiseUnexpectedStartTag(self.name()) |
|
330 |
|
331 def __readBookmarks(self): |
|
332 """ |
|
333 Private method to read the bookmark infos. |
|
334 """ |
|
335 while not self.atEnd(): |
|
336 self.readNext() |
|
337 if self.isEndElement() and self.name() == "Bookmarks": |
|
338 break |
|
339 |
|
340 if self.isStartElement(): |
|
341 if self.name() == "Bookmark": |
|
342 self.__readBookmark() |
|
343 else: |
|
344 self.raiseUnexpectedStartTag(self.name()) |
|
345 |
|
346 def __readBookmark(self): |
|
347 """ |
|
348 Private method to read the bookmark info. |
|
349 """ |
|
350 filename = "" |
|
351 lineno = 0 |
|
352 |
|
353 while not self.atEnd(): |
|
354 self.readNext() |
|
355 if self.isEndElement() and self.name() == "Bookmark": |
|
356 editor = self.vm.getOpenEditor(filename) |
|
357 if editor is not None: |
|
358 editor.toggleBookmark(lineno) |
|
359 break |
|
360 |
|
361 if self.isStartElement(): |
|
362 if self.name() == "BmFilename": |
|
363 filename = self.readElementText() |
|
364 elif self.name() == "Linenumber": |
|
365 lineno = int(self.attribute("value", "0")) |
|
366 else: |
|
367 self.raiseUnexpectedStartTag(self.name()) |
|
368 |
|
369 def __readProjectBrowserStates(self): |
|
370 """ |
|
371 Private method to read the project browser state infos. |
|
372 """ |
|
373 while not self.atEnd(): |
|
374 self.readNext() |
|
375 if self.isEndElement() and self.name() == "ProjectBrowserStates": |
|
376 break |
|
377 |
|
378 if self.isStartElement(): |
|
379 if self.name() == "ProjectBrowserState": |
|
380 browserName = self.attribute("name", "") |
|
381 if not browserName: |
|
382 self.raiseBadValue("ProjectBrowserState.name") |
|
383 self.__readProjectBrowserState(browserName) |
|
384 else: |
|
385 self.raiseUnexpectedStartTag(self.name()) |
|
386 |
|
387 def __readProjectBrowserState(self, browserName): |
|
388 """ |
|
389 Private method to read the project browser state info. |
|
390 |
|
391 @param browserName name of the project browser |
|
392 @type str |
|
393 """ |
|
394 expandedNames = [] |
|
395 |
|
396 while not self.atEnd(): |
|
397 self.readNext() |
|
398 if self.isEndElement() and self.name() == "ProjectBrowserState": |
|
399 projectBrowser = \ |
|
400 self.projectBrowser.getProjectBrowser(browserName) |
|
401 if projectBrowser is not None: |
|
402 projectBrowser.expandItemsByName(expandedNames) |
|
403 break |
|
404 |
|
405 if self.isStartElement(): |
|
406 if self.name() == "ExpandedItemName": |
|
407 itemName = self.readElementText() |
|
408 if itemName: |
|
409 expandedNames.append(itemName) |
|
410 else: |
|
411 self.raiseUnexpectedStartTag(self.name()) |