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