2987:c99695c0f13a | 2988:f53c03574697 |
---|---|
21 """ | 21 """ |
22 | 22 |
23 import os | 23 import os |
24 | 24 |
25 from PyQt4.QtCore import pyqtSignal | 25 from PyQt4.QtCore import pyqtSignal |
26 from PyQt4.QtGui import QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QSizePolicy, \ | 26 from PyQt4.QtGui import QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, \ |
27 QPushButton, QComboBox, QLabel, QTreeWidget, QTreeWidgetItem, QHeaderView | 27 QSizePolicy, QPushButton, QComboBox, QLabel, QTreeWidget, \ |
28 QTreeWidgetItem, QHeaderView | |
28 | 29 |
29 import UI.PixmapCache | 30 import UI.PixmapCache |
30 import Preferences | 31 import Preferences |
31 | 32 |
32 from E5Gui.E5TabWidget import E5TabWidget | 33 from E5Gui.E5TabWidget import E5TabWidget |
35 class DebugViewer(QWidget): | 36 class DebugViewer(QWidget): |
36 """ | 37 """ |
37 Class implementing a widget conatining various debug related views. | 38 Class implementing a widget conatining various debug related views. |
38 | 39 |
39 The individual tabs contain the interpreter shell (optional), | 40 The individual tabs contain the interpreter shell (optional), |
40 the filesystem browser (optional), the two variables viewers (global and local), | 41 the filesystem browser (optional), the two variables viewers |
41 a breakpoint viewer, a watch expression viewer and the exception logger. Additionally | 42 (global and local), a breakpoint viewer, a watch expression viewer and |
42 a list of all threads is shown. | 43 the exception logger. Additionally a list of all threads is shown. |
43 | 44 |
44 @signal sourceFile(string, int) emitted to open a source file at a line | 45 @signal sourceFile(string, int) emitted to open a source file at a line |
45 """ | 46 """ |
46 sourceFile = pyqtSignal(str, int) | 47 sourceFile = pyqtSignal(str, int) |
47 | 48 |
52 | 53 |
53 @param debugServer reference to the debug server object | 54 @param debugServer reference to the debug server object |
54 @param docked flag indicating a dock window | 55 @param docked flag indicating a dock window |
55 @param vm reference to the viewmanager object | 56 @param vm reference to the viewmanager object |
56 @param parent parent widget (QWidget) | 57 @param parent parent widget (QWidget) |
57 @param embeddedShell flag indicating whether the shell should be included. | 58 @param embeddedShell flag indicating whether the shell should be |
58 This flag is set to False by those layouts, that have the interpreter | 59 included. This flag is set to False by those layouts, that have |
59 shell in a separate window. | 60 the interpreter shell in a separate window. |
60 @param embeddedBrowser flag indicating whether the file browser should | 61 @param embeddedBrowser flag indicating whether the file browser should |
61 be included. This flag is set to False by those layouts, that | 62 be included. This flag is set to False by those layouts, that |
62 have the file browser in a separate window or embedded | 63 have the file browser in a separate window or embedded |
63 in the project browser instead. | 64 in the project browser instead. |
64 """ | 65 """ |
65 super().__init__(parent) | 66 super().__init__(parent) |
66 | 67 |
67 self.debugServer = debugServer | 68 self.debugServer = debugServer |
68 self.debugUI = None | 69 self.debugUI = None |
108 | 109 |
109 self.glvWidgetHLayout = QHBoxLayout() | 110 self.glvWidgetHLayout = QHBoxLayout() |
110 self.glvWidgetHLayout.setContentsMargins(3, 3, 3, 3) | 111 self.glvWidgetHLayout.setContentsMargins(3, 3, 3, 3) |
111 | 112 |
112 self.globalsFilterEdit = QLineEdit(self.glvWidget) | 113 self.globalsFilterEdit = QLineEdit(self.glvWidget) |
113 self.globalsFilterEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) | 114 self.globalsFilterEdit.setSizePolicy( |
115 QSizePolicy.Expanding, QSizePolicy.Fixed) | |
114 self.glvWidgetHLayout.addWidget(self.globalsFilterEdit) | 116 self.glvWidgetHLayout.addWidget(self.globalsFilterEdit) |
115 self.globalsFilterEdit.setToolTip( | 117 self.globalsFilterEdit.setToolTip( |
116 self.trUtf8("Enter regular expression patterns separated by ';' to define " | 118 self.trUtf8("Enter regular expression patterns separated by ';'" |
117 "variable filters. ")) | 119 " to define variable filters. ")) |
118 self.globalsFilterEdit.setWhatsThis( | 120 self.globalsFilterEdit.setWhatsThis( |
119 self.trUtf8("Enter regular expression patterns separated by ';' to define " | 121 self.trUtf8("Enter regular expression patterns separated by ';'" |
120 "variable filters. All variables and class attributes matched by one of " | 122 " to define variable filters. All variables and" |
121 "the expressions are not shown in the list above.")) | 123 " class attributes matched by one of the expressions" |
122 | 124 " are not shown in the list above.")) |
123 self.setGlobalsFilterButton = QPushButton(self.trUtf8('Set'), self.glvWidget) | 125 |
126 self.setGlobalsFilterButton = QPushButton( | |
127 self.trUtf8('Set'), self.glvWidget) | |
124 self.glvWidgetHLayout.addWidget(self.setGlobalsFilterButton) | 128 self.glvWidgetHLayout.addWidget(self.setGlobalsFilterButton) |
125 self.glvWidgetVLayout.addLayout(self.glvWidgetHLayout) | 129 self.glvWidgetVLayout.addLayout(self.glvWidgetHLayout) |
126 | 130 |
127 index = self.__tabWidget.addTab(self.glvWidget, | 131 index = self.__tabWidget.addTab(self.glvWidget, |
128 UI.PixmapCache.getIcon("globalVariables.png"), '') | 132 UI.PixmapCache.getIcon("globalVariables.png"), '') |
129 self.__tabWidget.setTabToolTip(index, self.globalsViewer.windowTitle()) | 133 self.__tabWidget.setTabToolTip(index, self.globalsViewer.windowTitle()) |
130 | 134 |
131 self.setGlobalsFilterButton.clicked[()].connect(self.__setGlobalsFilter) | 135 self.setGlobalsFilterButton.clicked[()].connect( |
136 self.__setGlobalsFilter) | |
132 self.globalsFilterEdit.returnPressed.connect(self.__setGlobalsFilter) | 137 self.globalsFilterEdit.returnPressed.connect(self.__setGlobalsFilter) |
133 | 138 |
134 # add the local variables viewer | 139 # add the local variables viewer |
135 self.lvWidget = QWidget() | 140 self.lvWidget = QWidget() |
136 self.lvWidgetVLayout = QVBoxLayout(self.lvWidget) | 141 self.lvWidgetVLayout = QVBoxLayout(self.lvWidget) |
140 | 145 |
141 self.lvWidgetHLayout1 = QHBoxLayout() | 146 self.lvWidgetHLayout1 = QHBoxLayout() |
142 self.lvWidgetHLayout1.setContentsMargins(3, 3, 3, 3) | 147 self.lvWidgetHLayout1.setContentsMargins(3, 3, 3, 3) |
143 | 148 |
144 self.stackComboBox = QComboBox(self.lvWidget) | 149 self.stackComboBox = QComboBox(self.lvWidget) |
145 self.stackComboBox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) | 150 self.stackComboBox.setSizePolicy( |
151 QSizePolicy.Expanding, QSizePolicy.Fixed) | |
146 self.lvWidgetHLayout1.addWidget(self.stackComboBox) | 152 self.lvWidgetHLayout1.addWidget(self.stackComboBox) |
147 | 153 |
148 self.sourceButton = QPushButton(self.trUtf8('Source'), self.lvWidget) | 154 self.sourceButton = QPushButton(self.trUtf8('Source'), self.lvWidget) |
149 self.lvWidgetHLayout1.addWidget(self.sourceButton) | 155 self.lvWidgetHLayout1.addWidget(self.sourceButton) |
150 self.sourceButton.setEnabled(False) | 156 self.sourceButton.setEnabled(False) |
155 | 161 |
156 self.lvWidgetHLayout2 = QHBoxLayout() | 162 self.lvWidgetHLayout2 = QHBoxLayout() |
157 self.lvWidgetHLayout2.setContentsMargins(3, 3, 3, 3) | 163 self.lvWidgetHLayout2.setContentsMargins(3, 3, 3, 3) |
158 | 164 |
159 self.localsFilterEdit = QLineEdit(self.lvWidget) | 165 self.localsFilterEdit = QLineEdit(self.lvWidget) |
160 self.localsFilterEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) | 166 self.localsFilterEdit.setSizePolicy( |
167 QSizePolicy.Expanding, QSizePolicy.Fixed) | |
161 self.lvWidgetHLayout2.addWidget(self.localsFilterEdit) | 168 self.lvWidgetHLayout2.addWidget(self.localsFilterEdit) |
162 self.localsFilterEdit.setToolTip( | 169 self.localsFilterEdit.setToolTip( |
163 self.trUtf8("Enter regular expression patterns separated by ';' to define " | 170 self.trUtf8( |
171 "Enter regular expression patterns separated by ';' to define " | |
164 "variable filters. ")) | 172 "variable filters. ")) |
165 self.localsFilterEdit.setWhatsThis( | 173 self.localsFilterEdit.setWhatsThis( |
166 self.trUtf8("Enter regular expression patterns separated by ';' to define " | 174 self.trUtf8( |
167 "variable filters. All variables and class attributes matched by one of " | 175 "Enter regular expression patterns separated by ';' to define " |
168 "the expressions are not shown in the list above.")) | 176 "variable filters. All variables and class attributes matched" |
169 | 177 " by one of the expressions are not shown in the list above.")) |
170 self.setLocalsFilterButton = QPushButton(self.trUtf8('Set'), self.lvWidget) | 178 |
179 self.setLocalsFilterButton = QPushButton( | |
180 self.trUtf8('Set'), self.lvWidget) | |
171 self.lvWidgetHLayout2.addWidget(self.setLocalsFilterButton) | 181 self.lvWidgetHLayout2.addWidget(self.setLocalsFilterButton) |
172 self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout2) | 182 self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout2) |
173 | 183 |
174 index = self.__tabWidget.addTab(self.lvWidget, | 184 index = self.__tabWidget.addTab(self.lvWidget, |
175 UI.PixmapCache.getIcon("localVariables.png"), '') | 185 UI.PixmapCache.getIcon("localVariables.png"), '') |
176 self.__tabWidget.setTabToolTip(index, self.localsViewer.windowTitle()) | 186 self.__tabWidget.setTabToolTip(index, self.localsViewer.windowTitle()) |
177 | 187 |
178 self.sourceButton.clicked[()].connect(self.__showSource) | 188 self.sourceButton.clicked[()].connect(self.__showSource) |
179 self.stackComboBox.currentIndexChanged[int].connect(self.__frameSelected) | 189 self.stackComboBox.currentIndexChanged[int].connect( |
190 self.__frameSelected) | |
180 self.setLocalsFilterButton.clicked[()].connect(self.__setLocalsFilter) | 191 self.setLocalsFilterButton.clicked[()].connect(self.__setLocalsFilter) |
181 self.localsFilterEdit.returnPressed.connect(self.__setLocalsFilter) | 192 self.localsFilterEdit.returnPressed.connect(self.__setLocalsFilter) |
182 | 193 |
183 from .CallStackViewer import CallStackViewer | 194 from .CallStackViewer import CallStackViewer |
184 # add the call stack viewer | 195 # add the call stack viewer |
185 self.callStackViewer = CallStackViewer(self.debugServer) | 196 self.callStackViewer = CallStackViewer(self.debugServer) |
186 index = self.__tabWidget.addTab(self.callStackViewer, | 197 index = self.__tabWidget.addTab(self.callStackViewer, |
187 UI.PixmapCache.getIcon("step.png"), "") | 198 UI.PixmapCache.getIcon("step.png"), "") |
188 self.__tabWidget.setTabToolTip(index, self.callStackViewer.windowTitle()) | 199 self.__tabWidget.setTabToolTip( |
200 index, self.callStackViewer.windowTitle()) | |
189 self.callStackViewer.sourceFile.connect(self.sourceFile) | 201 self.callStackViewer.sourceFile.connect(self.sourceFile) |
190 self.callStackViewer.frameSelected.connect(self.__callStackFrameSelected) | 202 self.callStackViewer.frameSelected.connect( |
203 self.__callStackFrameSelected) | |
191 | 204 |
192 from .CallTraceViewer import CallTraceViewer | 205 from .CallTraceViewer import CallTraceViewer |
193 # add the call trace viewer | 206 # add the call trace viewer |
194 self.callTraceViewer = CallTraceViewer(self.debugServer) | 207 self.callTraceViewer = CallTraceViewer(self.debugServer) |
195 index = self.__tabWidget.addTab(self.callTraceViewer, | 208 index = self.__tabWidget.addTab(self.callTraceViewer, |
196 UI.PixmapCache.getIcon("callTrace.png"), "") | 209 UI.PixmapCache.getIcon("callTrace.png"), "") |
197 self.__tabWidget.setTabToolTip(index, self.callTraceViewer.windowTitle()) | 210 self.__tabWidget.setTabToolTip( |
211 index, self.callTraceViewer.windowTitle()) | |
198 self.callTraceViewer.sourceFile.connect(self.sourceFile) | 212 self.callTraceViewer.sourceFile.connect(self.sourceFile) |
199 | 213 |
200 from .BreakPointViewer import BreakPointViewer | 214 from .BreakPointViewer import BreakPointViewer |
201 # add the breakpoint viewer | 215 # add the breakpoint viewer |
202 self.breakpointViewer = BreakPointViewer() | 216 self.breakpointViewer = BreakPointViewer() |
203 self.breakpointViewer.setModel(self.debugServer.getBreakPointModel()) | 217 self.breakpointViewer.setModel(self.debugServer.getBreakPointModel()) |
204 index = self.__tabWidget.addTab(self.breakpointViewer, | 218 index = self.__tabWidget.addTab(self.breakpointViewer, |
205 UI.PixmapCache.getIcon("breakpoints.png"), '') | 219 UI.PixmapCache.getIcon("breakpoints.png"), '') |
206 self.__tabWidget.setTabToolTip(index, self.breakpointViewer.windowTitle()) | 220 self.__tabWidget.setTabToolTip( |
221 index, self.breakpointViewer.windowTitle()) | |
207 self.breakpointViewer.sourceFile.connect(self.sourceFile) | 222 self.breakpointViewer.sourceFile.connect(self.sourceFile) |
208 | 223 |
209 from .WatchPointViewer import WatchPointViewer | 224 from .WatchPointViewer import WatchPointViewer |
210 # add the watch expression viewer | 225 # add the watch expression viewer |
211 self.watchpointViewer = WatchPointViewer() | 226 self.watchpointViewer = WatchPointViewer() |
212 self.watchpointViewer.setModel(self.debugServer.getWatchPointModel()) | 227 self.watchpointViewer.setModel(self.debugServer.getWatchPointModel()) |
213 index = self.__tabWidget.addTab(self.watchpointViewer, | 228 index = self.__tabWidget.addTab(self.watchpointViewer, |
214 UI.PixmapCache.getIcon("watchpoints.png"), '') | 229 UI.PixmapCache.getIcon("watchpoints.png"), '') |
215 self.__tabWidget.setTabToolTip(index, self.watchpointViewer.windowTitle()) | 230 self.__tabWidget.setTabToolTip( |
231 index, self.watchpointViewer.windowTitle()) | |
216 | 232 |
217 from .ExceptionLogger import ExceptionLogger | 233 from .ExceptionLogger import ExceptionLogger |
218 # add the exception logger | 234 # add the exception logger |
219 self.exceptionLogger = ExceptionLogger() | 235 self.exceptionLogger = ExceptionLogger() |
220 index = self.__tabWidget.addTab(self.exceptionLogger, | 236 index = self.__tabWidget.addTab(self.exceptionLogger, |
221 UI.PixmapCache.getIcon("exceptions.png"), '') | 237 UI.PixmapCache.getIcon("exceptions.png"), '') |
222 self.__tabWidget.setTabToolTip(index, self.exceptionLogger.windowTitle()) | 238 self.__tabWidget.setTabToolTip( |
239 index, self.exceptionLogger.windowTitle()) | |
223 | 240 |
224 if self.embeddedShell: | 241 if self.embeddedShell: |
225 self.__tabWidget.setCurrentWidget(self.shellAssembly) | 242 self.__tabWidget.setCurrentWidget(self.shellAssembly) |
226 else: | 243 else: |
227 if self.embeddedBrowser: | 244 if self.embeddedBrowser: |
230 self.__tabWidget.setCurrentWidget(self.lvWidget) | 247 self.__tabWidget.setCurrentWidget(self.lvWidget) |
231 | 248 |
232 # add the threads viewer | 249 # add the threads viewer |
233 self.__mainLayout.addWidget(QLabel(self.trUtf8("Threads:"))) | 250 self.__mainLayout.addWidget(QLabel(self.trUtf8("Threads:"))) |
234 self.__threadList = QTreeWidget() | 251 self.__threadList = QTreeWidget() |
235 self.__threadList.setHeaderLabels([self.trUtf8("ID"), self.trUtf8("Name"), | 252 self.__threadList.setHeaderLabels( |
236 self.trUtf8("State"), ""]) | 253 [self.trUtf8("ID"), self.trUtf8("Name"), |
254 self.trUtf8("State"), ""]) | |
237 self.__threadList.setSortingEnabled(True) | 255 self.__threadList.setSortingEnabled(True) |
238 self.__mainLayout.addWidget(self.__threadList) | 256 self.__mainLayout.addWidget(self.__threadList) |
239 | 257 |
240 self.__doThreadListUpdate = True | 258 self.__doThreadListUpdate = True |
241 | 259 |
381 | 399 |
382 def handleClientStack(self, stack): | 400 def handleClientStack(self, stack): |
383 """ | 401 """ |
384 Public slot to show the call stack of the program being debugged. | 402 Public slot to show the call stack of the program being debugged. |
385 | 403 |
386 @param stack list of tuples with call stack data (file name, line number, | 404 @param stack list of tuples with call stack data (file name, |
387 function name, formatted argument/values list) | 405 line number, function name, formatted argument/values list) |
388 """ | 406 """ |
389 block = self.stackComboBox.blockSignals(True) | 407 block = self.stackComboBox.blockSignals(True) |
390 self.framenr = 0 | 408 self.framenr = 0 |
391 self.stackComboBox.clear() | 409 self.stackComboBox.clear() |
392 self.currentStack = stack | 410 self.currentStack = stack |
399 | 417 |
400 def setVariablesFilter(self, globalsFilter, localsFilter): | 418 def setVariablesFilter(self, globalsFilter, localsFilter): |
401 """ | 419 """ |
402 Public slot to set the local variables filter. | 420 Public slot to set the local variables filter. |
403 | 421 |
404 @param globalsFilter filter list for global variable types (list of int) | 422 @param globalsFilter filter list for global variable types |
423 (list of int) | |
405 @param localsFilter filter list for local variable types (list of int) | 424 @param localsFilter filter list for local variable types (list of int) |
406 """ | 425 """ |
407 self.globalsFilter = globalsFilter | 426 self.globalsFilter = globalsFilter |
408 self.localsFilter = localsFilter | 427 self.localsFilter = localsFilter |
409 | 428 |
410 def __showSource(self): | 429 def __showSource(self): |
411 """ | 430 """ |
412 Private slot to handle the source button press to show the selected file. | 431 Private slot to handle the source button press to show the selected |
432 file. | |
413 """ | 433 """ |
414 index = self.stackComboBox.currentIndex() | 434 index = self.stackComboBox.currentIndex() |
415 if index > -1 and self.currentStack: | 435 if index > -1 and self.currentStack: |
416 s = self.currentStack[index] | 436 s = self.currentStack[index] |
417 self.sourceFile.emit(s[0], int(s[1])) | 437 self.sourceFile.emit(s[0], int(s[1])) |
442 Private slot to set the local variable filter. | 462 Private slot to set the local variable filter. |
443 """ | 463 """ |
444 filter = self.localsFilterEdit.text() | 464 filter = self.localsFilterEdit.text() |
445 self.debugServer.remoteClientSetFilter(0, filter) | 465 self.debugServer.remoteClientSetFilter(0, filter) |
446 if self.currentStack: | 466 if self.currentStack: |
447 self.debugServer.remoteClientVariables(0, self.localsFilter, self.framenr) | 467 self.debugServer.remoteClientVariables( |
468 0, self.localsFilter, self.framenr) | |
448 | 469 |
449 def handleDebuggingStarted(self): | 470 def handleDebuggingStarted(self): |
450 """ | 471 """ |
451 Public slot to handle the start of a debugging session. | 472 Public slot to handle the start of a debugging session. |
452 | 473 |
486 if thread['broken']: | 507 if thread['broken']: |
487 state = self.trUtf8("waiting at breakpoint") | 508 state = self.trUtf8("waiting at breakpoint") |
488 else: | 509 else: |
489 state = self.trUtf8("running") | 510 state = self.trUtf8("running") |
490 itm = QTreeWidgetItem(self.__threadList, | 511 itm = QTreeWidgetItem(self.__threadList, |
491 ["{0:d}".format(thread['id']), thread['name'], state]) | 512 ["{0:d}".format(thread['id']), |
513 thread['name'], state]) | |
492 if thread['id'] == currentID: | 514 if thread['id'] == currentID: |
493 citm = itm | 515 citm = itm |
494 | 516 |
495 self.__threadList.header().resizeSections(QHeaderView.ResizeToContents) | 517 self.__threadList.header().resizeSections(QHeaderView.ResizeToContents) |
496 self.__threadList.header().setStretchLastSection(True) | 518 self.__threadList.header().setStretchLastSection(True) |
503 def __threadSelected(self, current, previous): | 525 def __threadSelected(self, current, previous): |
504 """ | 526 """ |
505 Private slot to handle the selection of a thread in the thread list. | 527 Private slot to handle the selection of a thread in the thread list. |
506 | 528 |
507 @param current reference to the new current item (QTreeWidgetItem) | 529 @param current reference to the new current item (QTreeWidgetItem) |
508 @param previous reference to the previous current item (QTreeWidgetItem) | 530 @param previous reference to the previous current item |
531 (QTreeWidgetItem) | |
509 """ | 532 """ |
510 if current is not None and self.__doThreadListUpdate: | 533 if current is not None and self.__doThreadListUpdate: |
511 tid = int(current.text(0)) | 534 tid = int(current.text(0)) |
512 self.debugServer.remoteSetThread(tid) | 535 self.debugServer.remoteSetThread(tid) |
513 | 536 |