def __init__(self, debugServer, docked, vm, parent = None, embeddedShell = True, embeddedBrowser = True): """ Constructor @param debugServer reference to the debug server object @param docked flag indicating a dock window @param vm reference to the viewmanager object @param parent parent widget (QWidget) @param embeddedShell flag indicating whether the shell should be included. This flag is set to False by those layouts, that have the interpreter shell in a separate window. @param embeddedBrowser flag indicating whether the file browser should be included. This flag is set to False by those layouts, that have the file browser in a separate window or embedded in the project browser instead. """ QWidget.__init__(self, parent) self.debugServer = debugServer self.debugUI = None self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.__mainLayout = QVBoxLayout() self.__mainLayout.setMargin(0) self.setLayout(self.__mainLayout) self.__tabWidget = E4TabWidget() self.__mainLayout.addWidget(self.__tabWidget) self.embeddedShell = embeddedShell if embeddedShell: # add the interpreter shell self.shell = Shell(debugServer, vm) index = self.__tabWidget.addTab(self.shell, UI.PixmapCache.getIcon("shell.png"), '') self.__tabWidget.setTabToolTip(index, self.shell.windowTitle()) self.embeddedBrowser = embeddedBrowser if embeddedBrowser: from UI.Browser import Browser # add the browser self.browser = Browser() index = self.__tabWidget.addTab(self.browser, UI.PixmapCache.getIcon("browser.png"), '') self.__tabWidget.setTabToolTip(index, self.browser.windowTitle()) # add the global variables viewer self.glvWidget = QWidget() self.glvWidgetVLayout = QVBoxLayout(self.glvWidget) self.glvWidgetVLayout.setMargin(0) self.glvWidgetVLayout.setSpacing(3) self.glvWidget.setLayout(self.glvWidgetVLayout) self.globalsViewer = VariablesViewer(self.glvWidget, True) self.glvWidgetVLayout.addWidget(self.globalsViewer) self.glvWidgetHLayout = QHBoxLayout() self.glvWidgetHLayout.setMargin(3) self.globalsFilterEdit = QLineEdit(self.glvWidget) self.globalsFilterEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.glvWidgetHLayout.addWidget(self.globalsFilterEdit) self.globalsFilterEdit.setToolTip(\ self.trUtf8("Enter regular expression patterns separated by ';' to define " "variable filters. ")) self.globalsFilterEdit.setWhatsThis(\ self.trUtf8("Enter regular expression patterns separated by ';' to define " "variable filters. All variables and class attributes matched by one of " "the expressions are not shown in the list above.")) self.setGlobalsFilterButton = QPushButton(self.trUtf8('Set'), self.glvWidget) self.glvWidgetHLayout.addWidget(self.setGlobalsFilterButton) self.glvWidgetVLayout.addLayout(self.glvWidgetHLayout) index = self.__tabWidget.addTab(self.glvWidget, UI.PixmapCache.getIcon("globalVariables.png"), '') self.__tabWidget.setTabToolTip(index, self.globalsViewer.windowTitle()) self.connect(self.setGlobalsFilterButton, SIGNAL('clicked()'), self.__setGlobalsFilter) self.connect(self.globalsFilterEdit, SIGNAL('returnPressed()'), self.__setGlobalsFilter) # add the local variables viewer self.lvWidget = QWidget() self.lvWidgetVLayout = QVBoxLayout(self.lvWidget) self.lvWidgetVLayout.setMargin(0) self.lvWidgetVLayout.setSpacing(3) self.lvWidget.setLayout(self.lvWidgetVLayout) self.lvWidgetHLayout1 = QHBoxLayout() self.lvWidgetHLayout1.setMargin(3) self.stackComboBox = QComboBox(self.lvWidget) self.stackComboBox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.lvWidgetHLayout1.addWidget(self.stackComboBox) self.sourceButton = QPushButton(self.trUtf8('Source'), self.lvWidget) self.lvWidgetHLayout1.addWidget(self.sourceButton) self.sourceButton.setEnabled(False) self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout1) self.localsViewer = VariablesViewer(self.lvWidget, False) self.lvWidgetVLayout.addWidget(self.localsViewer) self.lvWidgetHLayout2 = QHBoxLayout() self.lvWidgetHLayout2.setMargin(3) self.localsFilterEdit = QLineEdit(self.lvWidget) self.localsFilterEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.lvWidgetHLayout2.addWidget(self.localsFilterEdit) self.localsFilterEdit.setToolTip(\ self.trUtf8("Enter regular expression patterns separated by ';' to define " "variable filters. ")) self.localsFilterEdit.setWhatsThis(\ self.trUtf8("Enter regular expression patterns separated by ';' to define " "variable filters. All variables and class attributes matched by one of " "the expressions are not shown in the list above.")) self.setLocalsFilterButton = QPushButton(self.trUtf8('Set'), self.lvWidget) self.lvWidgetHLayout2.addWidget(self.setLocalsFilterButton) self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout2) index = self.__tabWidget.addTab(self.lvWidget, UI.PixmapCache.getIcon("localVariables.png"), '') self.__tabWidget.setTabToolTip(index, self.localsViewer.windowTitle()) self.connect(self.sourceButton, SIGNAL('clicked()'), self.__showSource) self.connect(self.stackComboBox, SIGNAL('activated(int)'), self.__frameSelected) self.connect(self.setLocalsFilterButton, SIGNAL('clicked()'), self.__setLocalsFilter) self.connect(self.localsFilterEdit, SIGNAL('returnPressed()'), self.__setLocalsFilter) # add the breakpoint viewer self.breakpointViewer = BreakPointViewer() self.breakpointViewer.setModel(self.debugServer.getBreakPointModel()) index = self.__tabWidget.addTab(self.breakpointViewer, UI.PixmapCache.getIcon("breakpoints.png"), '') self.__tabWidget.setTabToolTip(index, self.breakpointViewer.windowTitle()) self.connect(self.breakpointViewer, SIGNAL("sourceFile"), self, SIGNAL("sourceFile")) # add the watch expression viewer self.watchpointViewer = WatchPointViewer() self.watchpointViewer.setModel(self.debugServer.getWatchPointModel()) index = self.__tabWidget.addTab(self.watchpointViewer, UI.PixmapCache.getIcon("watchpoints.png"), '') self.__tabWidget.setTabToolTip(index, self.watchpointViewer.windowTitle()) # add the exception logger self.exceptionLogger = ExceptionLogger() index = self.__tabWidget.addTab(self.exceptionLogger, UI.PixmapCache.getIcon("exceptions.png"), '') self.__tabWidget.setTabToolTip(index, self.exceptionLogger.windowTitle()) if self.embeddedShell: self.__tabWidget.setCurrentWidget(self.shell) else: if self.embeddedBrowser: self.__tabWidget.setCurrentWidget(self.browser) else: self.__tabWidget.setCurrentWidget(self.lvWidget) # add the threads viewer self.__mainLayout.addWidget(QLabel(self.trUtf8("Threads:"))) self.__threadList = QTreeWidget() self.__threadList.setHeaderLabels([self.trUtf8("ID"), self.trUtf8("Name"), self.trUtf8("State"), ""]) self.__threadList.setSortingEnabled(True) self.__mainLayout.addWidget(self.__threadList) self.__doThreadListUpdate = True self.connect(self.__threadList, SIGNAL('currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)'), self.__threadSelected) self.__mainLayout.setStretchFactor(self.__tabWidget, 5) self.__mainLayout.setStretchFactor(self.__threadList, 1) self.currPage = None self.currentStack = None self.framenr = 0 self.connect(self.debugServer, SIGNAL('clientStack'), self.handleClientStack) self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode") self.sourceButton.setVisible(not self.__autoViewSource)
class DebugViewer(QWidget): """ Class implementing a widget conatining various debug related views. The individual tabs contain the interpreter shell (optional), the filesystem browser (optional), the two variables viewers (global and local), a breakpoint viewer, a watch expression viewer and the exception logger. Additionally a list of all threads is shown. @signal sourceFile(string, int) emitted to open a source file at a line """ def __init__(self, debugServer, docked, vm, parent = None, embeddedShell = True, embeddedBrowser = True): """ Constructor @param debugServer reference to the debug server object @param docked flag indicating a dock window @param vm reference to the viewmanager object @param parent parent widget (QWidget) @param embeddedShell flag indicating whether the shell should be included. This flag is set to False by those layouts, that have the interpreter shell in a separate window. @param embeddedBrowser flag indicating whether the file browser should be included. This flag is set to False by those layouts, that have the file browser in a separate window or embedded in the project browser instead. """ QWidget.__init__(self, parent) self.debugServer = debugServer self.debugUI = None self.setWindowIcon(UI.PixmapCache.getIcon("eric.png")) self.__mainLayout = QVBoxLayout() self.__mainLayout.setMargin(0) self.setLayout(self.__mainLayout) self.__tabWidget = E4TabWidget() self.__mainLayout.addWidget(self.__tabWidget) self.embeddedShell = embeddedShell if embeddedShell: # add the interpreter shell self.shell = Shell(debugServer, vm) index = self.__tabWidget.addTab(self.shell, UI.PixmapCache.getIcon("shell.png"), '') self.__tabWidget.setTabToolTip(index, self.shell.windowTitle()) self.embeddedBrowser = embeddedBrowser if embeddedBrowser: from UI.Browser import Browser # add the browser self.browser = Browser() index = self.__tabWidget.addTab(self.browser, UI.PixmapCache.getIcon("browser.png"), '') self.__tabWidget.setTabToolTip(index, self.browser.windowTitle()) # add the global variables viewer self.glvWidget = QWidget() self.glvWidgetVLayout = QVBoxLayout(self.glvWidget) self.glvWidgetVLayout.setMargin(0) self.glvWidgetVLayout.setSpacing(3) self.glvWidget.setLayout(self.glvWidgetVLayout) self.globalsViewer = VariablesViewer(self.glvWidget, True) self.glvWidgetVLayout.addWidget(self.globalsViewer) self.glvWidgetHLayout = QHBoxLayout() self.glvWidgetHLayout.setMargin(3) self.globalsFilterEdit = QLineEdit(self.glvWidget) self.globalsFilterEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.glvWidgetHLayout.addWidget(self.globalsFilterEdit) self.globalsFilterEdit.setToolTip(\ self.trUtf8("Enter regular expression patterns separated by ';' to define " "variable filters. ")) self.globalsFilterEdit.setWhatsThis(\ self.trUtf8("Enter regular expression patterns separated by ';' to define " "variable filters. All variables and class attributes matched by one of " "the expressions are not shown in the list above.")) self.setGlobalsFilterButton = QPushButton(self.trUtf8('Set'), self.glvWidget) self.glvWidgetHLayout.addWidget(self.setGlobalsFilterButton) self.glvWidgetVLayout.addLayout(self.glvWidgetHLayout) index = self.__tabWidget.addTab(self.glvWidget, UI.PixmapCache.getIcon("globalVariables.png"), '') self.__tabWidget.setTabToolTip(index, self.globalsViewer.windowTitle()) self.connect(self.setGlobalsFilterButton, SIGNAL('clicked()'), self.__setGlobalsFilter) self.connect(self.globalsFilterEdit, SIGNAL('returnPressed()'), self.__setGlobalsFilter) # add the local variables viewer self.lvWidget = QWidget() self.lvWidgetVLayout = QVBoxLayout(self.lvWidget) self.lvWidgetVLayout.setMargin(0) self.lvWidgetVLayout.setSpacing(3) self.lvWidget.setLayout(self.lvWidgetVLayout) self.lvWidgetHLayout1 = QHBoxLayout() self.lvWidgetHLayout1.setMargin(3) self.stackComboBox = QComboBox(self.lvWidget) self.stackComboBox.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.lvWidgetHLayout1.addWidget(self.stackComboBox) self.sourceButton = QPushButton(self.trUtf8('Source'), self.lvWidget) self.lvWidgetHLayout1.addWidget(self.sourceButton) self.sourceButton.setEnabled(False) self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout1) self.localsViewer = VariablesViewer(self.lvWidget, False) self.lvWidgetVLayout.addWidget(self.localsViewer) self.lvWidgetHLayout2 = QHBoxLayout() self.lvWidgetHLayout2.setMargin(3) self.localsFilterEdit = QLineEdit(self.lvWidget) self.localsFilterEdit.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed) self.lvWidgetHLayout2.addWidget(self.localsFilterEdit) self.localsFilterEdit.setToolTip(\ self.trUtf8("Enter regular expression patterns separated by ';' to define " "variable filters. ")) self.localsFilterEdit.setWhatsThis(\ self.trUtf8("Enter regular expression patterns separated by ';' to define " "variable filters. All variables and class attributes matched by one of " "the expressions are not shown in the list above.")) self.setLocalsFilterButton = QPushButton(self.trUtf8('Set'), self.lvWidget) self.lvWidgetHLayout2.addWidget(self.setLocalsFilterButton) self.lvWidgetVLayout.addLayout(self.lvWidgetHLayout2) index = self.__tabWidget.addTab(self.lvWidget, UI.PixmapCache.getIcon("localVariables.png"), '') self.__tabWidget.setTabToolTip(index, self.localsViewer.windowTitle()) self.connect(self.sourceButton, SIGNAL('clicked()'), self.__showSource) self.connect(self.stackComboBox, SIGNAL('activated(int)'), self.__frameSelected) self.connect(self.setLocalsFilterButton, SIGNAL('clicked()'), self.__setLocalsFilter) self.connect(self.localsFilterEdit, SIGNAL('returnPressed()'), self.__setLocalsFilter) # add the breakpoint viewer self.breakpointViewer = BreakPointViewer() self.breakpointViewer.setModel(self.debugServer.getBreakPointModel()) index = self.__tabWidget.addTab(self.breakpointViewer, UI.PixmapCache.getIcon("breakpoints.png"), '') self.__tabWidget.setTabToolTip(index, self.breakpointViewer.windowTitle()) self.connect(self.breakpointViewer, SIGNAL("sourceFile"), self, SIGNAL("sourceFile")) # add the watch expression viewer self.watchpointViewer = WatchPointViewer() self.watchpointViewer.setModel(self.debugServer.getWatchPointModel()) index = self.__tabWidget.addTab(self.watchpointViewer, UI.PixmapCache.getIcon("watchpoints.png"), '') self.__tabWidget.setTabToolTip(index, self.watchpointViewer.windowTitle()) # add the exception logger self.exceptionLogger = ExceptionLogger() index = self.__tabWidget.addTab(self.exceptionLogger, UI.PixmapCache.getIcon("exceptions.png"), '') self.__tabWidget.setTabToolTip(index, self.exceptionLogger.windowTitle()) if self.embeddedShell: self.__tabWidget.setCurrentWidget(self.shell) else: if self.embeddedBrowser: self.__tabWidget.setCurrentWidget(self.browser) else: self.__tabWidget.setCurrentWidget(self.lvWidget) # add the threads viewer self.__mainLayout.addWidget(QLabel(self.trUtf8("Threads:"))) self.__threadList = QTreeWidget() self.__threadList.setHeaderLabels([self.trUtf8("ID"), self.trUtf8("Name"), self.trUtf8("State"), ""]) self.__threadList.setSortingEnabled(True) self.__mainLayout.addWidget(self.__threadList) self.__doThreadListUpdate = True self.connect(self.__threadList, SIGNAL('currentItemChanged(QTreeWidgetItem*, QTreeWidgetItem*)'), self.__threadSelected) self.__mainLayout.setStretchFactor(self.__tabWidget, 5) self.__mainLayout.setStretchFactor(self.__threadList, 1) self.currPage = None self.currentStack = None self.framenr = 0 self.connect(self.debugServer, SIGNAL('clientStack'), self.handleClientStack) self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode") self.sourceButton.setVisible(not self.__autoViewSource) def preferencesChanged(self): """ Public slot to handle the preferencesChanged signal. """ self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode") self.sourceButton.setVisible(not self.__autoViewSource) def setDebugger(self, debugUI): """ Public method to set a reference to the Debug UI. @param debugUI reference to the DebugUI objectTrees """ self.debugUI = debugUI self.connect(self.debugUI, SIGNAL('clientStack'), self.handleClientStack) def handleResetUI(self): """ Public method to reset the SBVviewer. """ self.globalsViewer.handleResetUI() self.localsViewer.handleResetUI() self.stackComboBox.clear() self.sourceButton.setEnabled(False) self.currentStack = None self.__threadList.clear() if self.embeddedShell: self.__tabWidget.setCurrentWidget(self.shell) else: if self.embeddedBrowser: self.__tabWidget.setCurrentWidget(self.browser) else: self.__tabWidget.setCurrentWidget(self.lvWidget) self.breakpointViewer.handleResetUI() def handleRawInput(self): """ Pulic slot to handle the switch to the shell in raw input mode. """ if self.embeddedShell: self.saveCurrentPage() self.__tabWidget.setCurrentWidget(self.shell) def showVariables(self, vlist, globals): """ Public method to show the variables in the respective window. @param vlist list of variables to display @param globals flag indicating global/local state """ if globals: self.globalsViewer.showVariables(vlist, self.framenr) else: self.localsViewer.showVariables(vlist, self.framenr) def showVariable(self, vlist, globals): """ Public method to show the variables in the respective window. @param vlist list of variables to display @param globals flag indicating global/local state """ if globals: self.globalsViewer.showVariable(vlist) else: self.localsViewer.showVariable(vlist) def showVariablesTab(self, globals): """ Public method to make a variables tab visible. @param globals flag indicating global/local state """ if globals: self.__tabWidget.setCurrentWidget(self.glvWidget) else: self.__tabWidget.setCurrentWidget(self.lvWidget) def saveCurrentPage(self): """ Public slot to save the current page. """ self.currPage = self.__tabWidget.currentWidget() def restoreCurrentPage(self): """ Public slot to restore the previously saved page. """ if self.currPage is not None: self.__tabWidget.setCurrentWidget(self.currPage) def handleClientStack(self, stack): """ Public slot to show the call stack of the program being debugged. """ self.framenr = 0 self.stackComboBox.clear() self.currentStack = stack self.sourceButton.setEnabled(len(stack) > 0) for s in stack: # just show base filename to make it readable s = (os.path.basename(s[0]), s[1], s[2]) self.stackComboBox.addItem('%s:%s:%s' % s) def setVariablesFilter(self, globalsFilter, localsFilter): """ Public slot to set the local variables filter. @param globalsFilter filter list for global variable types (list of int) @param localsFilter filter list for local variable types (list of int) """ self.globalsFilter = globalsFilter self.localsFilter = localsFilter def __showSource(self): """ Private slot to handle the source button press to show the selected file. """ s = self.currentStack[self.stackComboBox.currentIndex()] self.emit(SIGNAL('sourceFile'), s[0], int(s[1])) def __frameSelected(self, frmnr): """ Private slot to handle the selection of a new stack frame number. @param frmnr frame number (0 is the current frame) (int) """ self.framenr = frmnr self.debugServer.remoteClientVariables(0, self.localsFilter, frmnr) if self.__autoViewSource: self.__showSource() def __setGlobalsFilter(self): """ Private slot to set the global variable filter """ filter = unicode(self.globalsFilterEdit.text()) self.debugServer.remoteClientSetFilter(1, filter) if self.currentStack: self.debugServer.remoteClientVariables(2, self.globalsFilter) def __setLocalsFilter(self): """ Private slot to set the local variable filter """ filter = unicode(self.localsFilterEdit.text()) self.debugServer.remoteClientSetFilter(0, filter) if self.currentStack: self.debugServer.remoteClientVariables(0, self.localsFilter, self.framenr) def handleDebuggingStarted(self): """ Public slot to handle the start of a debugging session. This slot sets the variables filter expressions. """ self.__setGlobalsFilter() self.__setLocalsFilter() self.showVariablesTab(False) def currentWidget(self): """ Public method to get a reference to the current widget. @return reference to the current widget (QWidget) """ return self.__tabWidget.currentWidget() def setCurrentWidget(self, widget): """ Public slot to set the current page based on the given widget. @param widget reference to the widget (QWidget) """ self.__tabWidget.setCurrentWidget(widget) def showThreadList(self, currentID, threadList): """ Public method to show the thread list. @param currentID id of the current thread (integer) @param threadList list of dictionaries containing the thread data """ citm = None self.__threadList.clear() for thread in threadList: if thread['broken']: state = self.trUtf8("waiting at breakpoint") else: state = self.trUtf8("running") itm = QTreeWidgetItem(self.__threadList, ["%d" % thread['id'], thread['name'], state]) if thread['id'] == currentID: citm = itm self.__threadList.header().resizeSections(QHeaderView.ResizeToContents) self.__threadList.header().setStretchLastSection(True) if citm: self.__doThreadListUpdate = False self.__threadList.setCurrentItem(citm) self.__doThreadListUpdate = True def __threadSelected(self, current, previous): """ Private slot to handle the selection of a thread in the thread list. @param current reference to the new current item (QTreeWidgetItem) @param previous reference to the previous current item (QTreeWidgetItem) """ if current is not None and self.__doThreadListUpdate: tid, ok = current.text(0).toLong() if ok: self.debugServer.remoteSetThread(tid)