31 |
33 |
32 def __init__(self, debugServer, parent=None): |
34 def __init__(self, debugServer, parent=None): |
33 """ |
35 """ |
34 Constructor |
36 Constructor |
35 |
37 |
36 @param debugServer reference to the debug server object (DebugServer) |
38 @param debugServer reference to the debug server object |
37 @param parent reference to the parent widget (QWidget) |
39 @type DebugServer |
|
40 @param parent reference to the parent widget |
|
41 @type QWidget |
38 """ |
42 """ |
39 super(CallStackViewer, self).__init__(parent) |
43 super(CallStackViewer, self).__init__(parent) |
40 |
44 |
41 self.setHeaderHidden(True) |
45 self.__layout = QVBoxLayout(self) |
42 self.setAlternatingRowColors(True) |
46 self.setLayout(self.__layout) |
43 self.setItemsExpandable(False) |
47 self.__debuggerLabel = QLabel(self) |
44 self.setRootIsDecorated(False) |
48 self.__layout.addWidget(self.__debuggerLabel) |
|
49 self.__callStackList = QTreeWidget(self) |
|
50 self.__layout.addWidget(self.__callStackList) |
|
51 |
|
52 self.__callStackList.setHeaderHidden(True) |
|
53 self.__callStackList.setAlternatingRowColors(True) |
|
54 self.__callStackList.setItemsExpandable(False) |
|
55 self.__callStackList.setRootIsDecorated(False) |
45 self.setWindowTitle(self.tr("Call Stack")) |
56 self.setWindowTitle(self.tr("Call Stack")) |
46 |
57 |
47 self.__menu = QMenu(self) |
58 self.__menu = QMenu(self.__callStackList) |
48 self.__sourceAct = self.__menu.addAction( |
59 self.__sourceAct = self.__menu.addAction( |
49 self.tr("Show source"), self.__openSource) |
60 self.tr("Show source"), self.__openSource) |
50 self.__menu.addAction(self.tr("Clear"), self.clear) |
61 self.__menu.addAction(self.tr("Clear"), self.__callStackList.clear) |
51 self.__menu.addSeparator() |
62 self.__menu.addSeparator() |
52 self.__menu.addAction(self.tr("Save"), self.__saveStackTrace) |
63 self.__menu.addAction(self.tr("Save"), self.__saveStackTrace) |
53 self.setContextMenuPolicy(Qt.CustomContextMenu) |
64 self.__callStackList.setContextMenuPolicy(Qt.CustomContextMenu) |
54 self.customContextMenuRequested.connect(self.__showContextMenu) |
65 self.__callStackList.customContextMenuRequested.connect( |
|
66 self.__showContextMenu) |
55 |
67 |
56 self.__dbs = debugServer |
68 self.__dbs = debugServer |
57 |
69 |
58 # file name, line number, function name, arguments |
70 # file name, line number, function name, arguments |
59 self.__entryFormat = self.tr("File: {0}\nLine: {1}\n{2}{3}") |
71 self.__entryFormat = self.tr("File: {0}\nLine: {1}\n{2}{3}") |
62 |
74 |
63 self.__projectMode = False |
75 self.__projectMode = False |
64 self.__project = None |
76 self.__project = None |
65 |
77 |
66 self.__dbs.clientStack.connect(self.__showCallStack) |
78 self.__dbs.clientStack.connect(self.__showCallStack) |
67 self.itemDoubleClicked.connect(self.__itemDoubleClicked) |
79 self.__callStackList.itemDoubleClicked.connect( |
|
80 self.__itemDoubleClicked) |
68 |
81 |
69 def setDebugger(self, debugUI): |
82 def setDebugger(self, debugUI): |
70 """ |
83 """ |
71 Public method to set a reference to the Debug UI. |
84 Public method to set a reference to the Debug UI. |
72 |
85 |
73 @param debugUI reference to the DebugUI object (DebugUI) |
86 @param debugUI reference to the DebugUI object |
|
87 @type DebugUI |
74 """ |
88 """ |
75 debugUI.clientStack.connect(self.__showCallStack) |
89 debugUI.clientStack.connect(self.__showCallStack) |
76 |
90 |
77 def setProjectMode(self, enabled): |
91 def setProjectMode(self, enabled): |
78 """ |
92 """ |
79 Public slot to set the call trace viewer to project mode. |
93 Public slot to set the call trace viewer to project mode. |
80 |
94 |
81 In project mode the call trace info is shown with project relative |
95 In project mode the call trace info is shown with project relative |
82 path names. |
96 path names. |
83 |
97 |
84 @param enabled flag indicating to enable the project mode (boolean) |
98 @param enabled flag indicating to enable the project mode |
|
99 @type bool |
85 """ |
100 """ |
86 self.__projectMode = enabled |
101 self.__projectMode = enabled |
87 if enabled and self.__project is None: |
102 if enabled and self.__project is None: |
88 self.__project = e5App().getObject("Project") |
103 self.__project = e5App().getObject("Project") |
89 |
104 |
90 def __showContextMenu(self, coord): |
105 def __showContextMenu(self, coord): |
91 """ |
106 """ |
92 Private slot to show the context menu. |
107 Private slot to show the context menu. |
93 |
108 |
94 @param coord the position of the mouse pointer (QPoint) |
109 @param coord the position of the mouse pointer |
95 """ |
110 @type QPoint |
96 if self.topLevelItemCount() > 0: |
111 """ |
97 itm = self.currentItem() |
112 if self.__callStackList.topLevelItemCount() > 0: |
|
113 itm = self.__callStackList.currentItem() |
98 self.__sourceAct.setEnabled(itm is not None) |
114 self.__sourceAct.setEnabled(itm is not None) |
99 self.__menu.popup(self.mapToGlobal(coord)) |
115 self.__menu.popup(self.__callStackList.mapToGlobal(coord)) |
100 |
116 |
101 def __showCallStack(self, stack): |
117 def clear(self): |
|
118 """ |
|
119 Public method to clear the stack viewer data. |
|
120 """ |
|
121 self.__debuggerLabel.clear() |
|
122 self.__callStackList.clear() |
|
123 |
|
124 def __showCallStack(self, stack, debuggerId): |
102 """ |
125 """ |
103 Private slot to show the call stack of the program being debugged. |
126 Private slot to show the call stack of the program being debugged. |
104 |
127 |
105 @param stack list of tuples with call stack data (file name, |
128 @param stack list of tuples with call stack data (file name, |
106 line number, function name, formatted argument/values list) |
129 line number, function name, formatted argument/values list) |
107 @type list of tuples of (str, str, str, str) |
130 @type list of tuples of (str, str, str, str) |
108 """ |
131 @param debuggerId ID of the debugger backend |
109 self.clear() |
132 @type str |
|
133 """ |
|
134 self.__debuggerLabel.setText(debuggerId) |
|
135 |
|
136 self.__callStackList.clear() |
110 for fname, fline, ffunc, fargs in stack: |
137 for fname, fline, ffunc, fargs in stack: |
111 if self.__projectMode: |
138 if self.__projectMode: |
112 dfname = self.__project.getRelativePath(fname) |
139 dfname = self.__project.getRelativePath(fname) |
113 else: |
140 else: |
114 dfname = fname |
141 dfname = fname |
115 if ffunc and not ffunc.startswith("<"): |
142 if ffunc and not ffunc.startswith("<"): |
116 # use normal format |
143 # use normal format |
117 itm = QTreeWidgetItem( |
144 itm = QTreeWidgetItem( |
118 self, |
145 self.__callStackList, |
119 [self.__entryFormat.format(dfname, fline, ffunc, fargs)]) |
146 [self.__entryFormat.format(dfname, fline, ffunc, fargs)] |
|
147 ) |
120 else: |
148 else: |
121 # use short format |
149 # use short format |
122 itm = QTreeWidgetItem( |
150 itm = QTreeWidgetItem( |
123 self, [self.__entryFormatShort.format(dfname, fline)]) |
151 self.__callStackList, |
|
152 [self.__entryFormatShort.format(dfname, fline)] |
|
153 ) |
124 itm.setData(0, self.FilenameRole, fname) |
154 itm.setData(0, self.FilenameRole, fname) |
125 itm.setData(0, self.LinenoRole, fline) |
155 itm.setData(0, self.LinenoRole, fline) |
126 |
156 |
127 self.resizeColumnToContents(0) |
157 self.__callStackList.resizeColumnToContents(0) |
128 |
158 |
129 def __itemDoubleClicked(self, itm): |
159 def __itemDoubleClicked(self, itm): |
130 """ |
160 """ |
131 Private slot to handle a double click of a stack entry. |
161 Private slot to handle a double click of a stack entry. |
132 |
162 |
133 @param itm reference to the double clicked item (QTreeWidgetItem) |
163 @param itm reference to the double clicked item |
|
164 @type QTreeWidgetItem |
134 """ |
165 """ |
135 fname = itm.data(0, self.FilenameRole) |
166 fname = itm.data(0, self.FilenameRole) |
136 fline = itm.data(0, self.LinenoRole) |
167 fline = itm.data(0, self.LinenoRole) |
137 if self.__projectMode: |
168 if self.__projectMode: |
138 fname = self.__project.getAbsolutePath(fname) |
169 fname = self.__project.getAbsolutePath(fname) |
139 self.sourceFile.emit(fname, fline) |
170 self.sourceFile.emit(fname, fline) |
140 |
171 |
141 index = self.indexOfTopLevelItem(itm) |
172 index = self.__callStackList.indexOfTopLevelItem(itm) |
142 self.frameSelected.emit(index) |
173 self.frameSelected.emit(index) |
143 |
174 |
144 def __openSource(self): |
175 def __openSource(self): |
145 """ |
176 """ |
146 Private slot to show the source for the selected stack entry. |
177 Private slot to show the source for the selected stack entry. |
147 """ |
178 """ |
148 itm = self.currentItem() |
179 itm = self.__callStackList.currentItem() |
149 if itm: |
180 if itm: |
150 self.__itemDoubleClicked(itm) |
181 self.__itemDoubleClicked(itm) |
151 |
182 |
152 def __saveStackTrace(self): |
183 def __saveStackTrace(self): |
153 """ |
184 """ |
154 Private slot to save the stack trace info to a file. |
185 Private slot to save the stack trace info to a file. |
155 """ |
186 """ |
156 if self.topLevelItemCount() > 0: |
187 if self.__callStackList.topLevelItemCount() > 0: |
157 fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( |
188 fname, selectedFilter = E5FileDialog.getSaveFileNameAndFilter( |
158 self, |
189 self, |
159 self.tr("Save Call Stack Info"), |
190 self.tr("Save Call Stack Info"), |
160 "", |
191 "", |
161 self.tr("Text Files (*.txt);;All Files (*)"), |
192 self.tr("Text Files (*.txt);;All Files (*)"), |