5 |
5 |
6 """ |
6 """ |
7 Module implementing the Call Trace viewer widget. |
7 Module implementing the Call Trace viewer widget. |
8 """ |
8 """ |
9 |
9 |
10 |
10 import re |
11 from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QRegExp, QFileInfo |
11 |
|
12 from PyQt5.QtCore import pyqtSlot, pyqtSignal, Qt, QFileInfo |
12 from PyQt5.QtWidgets import QWidget, QTreeWidgetItem |
13 from PyQt5.QtWidgets import QWidget, QTreeWidgetItem |
13 |
14 |
14 from E5Gui.E5Application import e5App |
15 from E5Gui.E5Application import e5App |
15 from E5Gui import E5FileDialog, E5MessageBox |
16 from E5Gui import E5FileDialog, E5MessageBox |
16 |
17 |
61 self.callTrace.setHeaderItem(self.__headerItem) |
62 self.callTrace.setHeaderItem(self.__headerItem) |
62 |
63 |
63 self.__callStack = [] |
64 self.__callStack = [] |
64 |
65 |
65 self.__entryFormat = "{0}:{1} ({2})" |
66 self.__entryFormat = "{0}:{1} ({2})" |
66 self.__entryRe = QRegExp(r"""(.+):(\d+)\s\((.*)\)""") |
67 self.__entryRe = re.compile(r"""(.+):(\d+)\s\((.*)\)""") |
67 |
68 |
68 self.__projectMode = False |
69 self.__projectMode = False |
69 self.__project = None |
70 self.__project = None |
70 self.__tracedDebuggerId = "" |
71 self.__tracedDebuggerId = "" |
71 |
72 |
174 if not res: |
175 if not res: |
175 return |
176 return |
176 fname = Utilities.toNativeSeparators(fname) |
177 fname = Utilities.toNativeSeparators(fname) |
177 |
178 |
178 try: |
179 try: |
179 f = open(fname, "w", encoding="utf-8") |
180 with open(fname, "w", encoding="utf-8") as f: |
180 itm = self.callTrace.topLevelItem(0) |
181 itm = self.callTrace.topLevelItem(0) |
181 while itm is not None: |
182 while itm is not None: |
182 isCall = itm.data(0, Qt.UserRole) |
183 isCall = itm.data(0, Qt.UserRole) |
183 if isCall: |
184 if isCall: |
184 call = "->" |
185 call = "->" |
185 else: |
186 else: |
186 call = "<-" |
187 call = "<-" |
187 f.write("{0} {1} || {2}\n".format( |
188 f.write("{0} {1} || {2}\n".format( |
188 call, |
189 call, |
189 itm.text(1), itm.text(2))) |
190 itm.text(1), itm.text(2))) |
190 itm = self.callTrace.itemBelow(itm) |
191 itm = self.callTrace.itemBelow(itm) |
191 f.close() |
|
192 except IOError as err: |
192 except IOError as err: |
193 E5MessageBox.critical( |
193 E5MessageBox.critical( |
194 self, |
194 self, |
195 self.tr("Error saving Call Trace Info"), |
195 self.tr("Error saving Call Trace Info"), |
196 self.tr("""<p>The call trace info could not""" |
196 self.tr("""<p>The call trace info could not""" |
208 @param column column that was double clicked |
208 @param column column that was double clicked |
209 @type int |
209 @type int |
210 """ |
210 """ |
211 if item is not None and column > 0: |
211 if item is not None and column > 0: |
212 columnStr = item.text(column) |
212 columnStr = item.text(column) |
213 if self.__entryRe.exactMatch(columnStr.strip()): |
213 match = self.__entryRe.fullmatch(columnStr.strip()) |
214 filename, lineno, func = self.__entryRe.capturedTexts()[1:] |
214 if match: |
|
215 filename, lineno, func = match.groups() |
215 try: |
216 try: |
216 lineno = int(lineno) |
217 lineno = int(lineno) |
217 except ValueError: |
218 except ValueError: |
218 # do nothing, if the line info is not an integer |
219 # do nothing, if the line info is not an integer |
219 return |
220 return |