Debugger/DebugViewer.py

changeset 2988
f53c03574697
parent 2953
703452a2876f
child 3021
801289962f4e
child 3057
10516539f238
equal deleted inserted replaced
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

eric ide

mercurial