eric6/Debugger/DebugViewer.py

branch
multi_processing
changeset 7377
cc920e534ac0
parent 7376
21df384d6150
child 7379
72a72fd56494
--- a/eric6/Debugger/DebugViewer.py	Wed Jan 29 19:38:13 2020 +0100
+++ b/eric6/Debugger/DebugViewer.py	Thu Jan 30 19:37:03 2020 +0100
@@ -23,7 +23,7 @@
 
 import os
 
-from PyQt5.QtCore import pyqtSignal
+from PyQt5.QtCore import pyqtSignal, Qt
 from PyQt5.QtWidgets import (
     QWidget, QVBoxLayout, QHBoxLayout, QLineEdit, QSizePolicy, QPushButton,
     QComboBox, QLabel, QTreeWidget, QTreeWidgetItem, QHeaderView, QFrame
@@ -69,7 +69,7 @@
         self.setLayout(self.__mainLayout)
         
         # add the viewer showing the connected debug backends
-        self.__debuggersLayout = QHBoxLayout(self)
+        self.__debuggersLayout = QHBoxLayout()
         self.__debuggersLayout.addWidget(QLabel(self.tr("Debuggers:")))
         self.__debuggersCombo = QComboBox(self)
         self.__debuggersCombo.setSizePolicy(
@@ -77,7 +77,7 @@
         self.__debuggersLayout.addWidget(self.__debuggersCombo)
         self.__mainLayout.addLayout(self.__debuggersLayout)
         
-        self.__debuggersCombo.currentTextChanged.connect(
+        self.__debuggersCombo.currentIndexChanged[str].connect(
             self.__debuggerSelected)
         
         # add a line to separate debugger selector from debugger specific parts
@@ -264,11 +264,29 @@
         self.currentStack = None
         self.framenr = 0
         
-        self.debugServer.clientStack.connect(self.handleClientStack)
-        
         self.__autoViewSource = Preferences.getDebugger("AutoViewSourceCode")
         self.sourceButton.setVisible(not self.__autoViewSource)
         
+        # connect somer debug server signals
+        self.debugServer.clientStack.connect(
+            self.handleClientStack)
+        self.debugServer.clientThreadList.connect(
+            self.showThreadList)
+        self.debugServer.clientDebuggerIds.connect(
+            self.showDebuggersList)
+        self.debugServer.passiveDebugStarted.connect(
+            self.handleDebuggingStarted)
+        self.debugServer.clientLine.connect(
+            self.__clientLine)
+        
+        self.debugServer.clientException.connect(
+            self.exceptionLogger.addException)
+        self.debugServer.passiveDebugStarted.connect(
+            self.exceptionLogger.debuggingStarted)
+        
+        self.debugServer.clientLine.connect(
+            self.breakpointViewer.highlightBreakpoint)
+    
     def handlePreferencesChanged(self):
         """
         Public slot to handle the preferencesChanged signal.
@@ -283,9 +301,15 @@
         @param debugUI reference to the DebugUI object (DebugUI)
         """
         self.debugUI = debugUI
-        self.debugUI.clientStack.connect(self.handleClientStack)
         self.callStackViewer.setDebugger(debugUI)
         
+        # connect some debugUI signals
+        self.debugUI.clientStack.connect(self.handleClientStack)
+        self.debugUI.debuggingStarted.connect(
+            self.exceptionLogger.debuggingStarted)
+        self.debugUI.debuggingStarted.connect(
+            self.handleDebuggingStarted)
+    
     def handleResetUI(self):
         """
         Public method to reset the SBVviewer.
@@ -371,24 +395,45 @@
         else:
             self.__tabWidget.setCurrentWidget(self.lvWidget)
         
-    def handleClientStack(self, stack):
+    def handleClientStack(self, stack, debuggerId):
         """
         Public slot to show the call stack of the program being debugged.
         
         @param stack list of tuples with call stack data (file name,
             line number, function name, formatted argument/values list)
+        @type list of tuples of (str, str, str, str)
+        @param debuggerId ID of the debugger backend
+        @type str
         """
-        block = self.stackComboBox.blockSignals(True)
-        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('{0}:{1}:{2}'.format(*s))
-        self.stackComboBox.blockSignals(block)
+        if debuggerId == self.__debuggersCombo.currentText():
+            block = self.stackComboBox.blockSignals(True)
+            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('{0}:{1}:{2}'.format(*s))
+            self.stackComboBox.blockSignals(block)
+    
+    def __clientLine(self, fn, line, debuggerId):
+        """
+        Private method to handle a change to the current line.
         
+        @param fn filename
+        @type str
+        @param line linenumber
+        @type int
+        @param debuggerId ID of the debugger backend
+        @type str
+        """
+        if debuggerId:
+            index = self.__debuggersCombo.findText(debuggerId, Qt.MatchExactly)
+            if index >= 0:
+                self.__debuggersCombo.setItemIcon(
+                    index, UI.PixmapCache.getIcon("exceptions.png"))
+    
     def setVariablesFilter(self, globalsFilter, localsFilter):
         """
         Public slot to set the local variables filter.
@@ -471,41 +516,68 @@
         """
         self.__tabWidget.setCurrentWidget(widget)
         
-    def showThreadList(self, currentID, threadList):
+    def showThreadList(self, currentID, threadList, debuggerId):
         """
         Public method to show the thread list.
         
-        @param currentID id of the current thread (integer)
+        @param currentID id of the current thread
+        @type int
         @param threadList list of dictionaries containing the thread data
+        @type list of dict
+        @param debuggerId ID of the debugger backend
+        @type str
         """
-        citm = None
+        debugStatus = -1    # i.e. running
         
-        self.__threadList.clear()
-        for thread in threadList:
-            if thread.get('except', False):
-                state = self.tr("waiting at exception")
-                icon = "exceptions.png"
-            elif thread['broken']:
-                state = self.tr("waiting at breakpoint")
-                icon = "mediaPlaybackPause.png"
-            else:
-                state = self.tr("running")
-                icon = "mediaPlaybackStart.png"
-            itm = QTreeWidgetItem(self.__threadList,
-                                  ["{0:d}".format(thread['id']),
-                                   thread['name'], state])
-            itm.setIcon(0, UI.PixmapCache.getIcon(icon))
-            if thread['id'] == currentID:
-                citm = itm
+        if debuggerId == self.__debuggersCombo.currentText():
+            citm = None
+            
+            self.__threadList.clear()
+            for thread in threadList:
+                if thread.get('except', False):
+                    state = self.tr("waiting at exception")
+                    icon = "exceptions.png"
+                    debugStatus = 1
+                elif thread['broken']:
+                    state = self.tr("waiting at breakpoint")
+                    icon = "mediaPlaybackPause.png"
+                    if debugStatus < 1:
+                        debugStatus = 0
+                else:
+                    state = self.tr("running")
+                    icon = "mediaPlaybackStart.png"
+                itm = QTreeWidgetItem(self.__threadList,
+                                      ["{0:d}".format(thread['id']),
+                                       thread['name'], state])
+                itm.setIcon(0, UI.PixmapCache.getIcon(icon))
+                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
+        else:
+            for thread in threadList:
+                if thread.get('except', False):
+                    debugStatus = 1
+                elif thread['broken']:
+                    if debugStatus < 1:
+                        debugStatus = 0
         
-        self.__threadList.header().resizeSections(QHeaderView.ResizeToContents)
-        self.__threadList.header().setStretchLastSection(True)
-        
-        if citm:
-            self.__doThreadListUpdate = False
-            self.__threadList.setCurrentItem(citm)
-            self.__doThreadListUpdate = True
-        
+        if debugStatus == -1:
+            icon = "mediaPlaybackStart.png"
+        elif debugStatus == 0:
+            icon = "mediaPlaybackPause.png"
+        else:
+            icon = "exceptions.png"
+        self.__debuggersCombo.setItemIcon(self.__debuggersCombo.currentIndex(),
+                                          UI.PixmapCache.getIcon(icon))
+    
     def __threadSelected(self, current, previous):
         """
         Private slot to handle the selection of a thread in the thread list.

eric ide

mercurial