src/eric7/Debugger/ExceptionLogger.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8881
54e42bc2437a
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2002 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the Exception Logger widget.
8 """
9
10 import contextlib
11
12 from PyQt6.QtCore import pyqtSignal, Qt
13 from PyQt6.QtWidgets import QTreeWidget, QTreeWidgetItem, QMenu
14
15 from EricWidgets.EricApplication import ericApp
16
17
18 class ExceptionLogger(QTreeWidget):
19 """
20 Class implementing the Exception Logger widget.
21
22 This class displays a log of all exceptions having occured during
23 a debugging session.
24
25 @signal sourceFile(string, int) emitted to open a source file at a line
26 """
27 sourceFile = pyqtSignal(str, int)
28
29 def __init__(self, parent=None):
30 """
31 Constructor
32
33 @param parent the parent widget of this widget
34 """
35 super().__init__(parent)
36 self.setObjectName("ExceptionLogger")
37
38 self.setWindowTitle(self.tr("Exceptions"))
39
40 self.setWordWrap(True)
41 self.setRootIsDecorated(True)
42 self.setHeaderLabels([self.tr("Exception")])
43 self.setSortingEnabled(False)
44
45 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
46 self.customContextMenuRequested.connect(self.__showContextMenu)
47 self.itemDoubleClicked.connect(self.__itemDoubleClicked)
48
49 self.setWhatsThis(self.tr(
50 """<b>Exceptions Logger</b>"""
51 """<p>This windows shows a trace of all exceptions, that have"""
52 """ occured during the last debugging session. Initially only"""
53 """ the exception type and exception message are shown. After"""
54 """ the expansion of this entry, the complete call stack as"""
55 """ reported by the client is show with the most recent call"""
56 """ first.</p>"""
57 ))
58
59 self.menu = QMenu(self)
60 self.menu.addAction(self.tr("Show source"), self.__openSource)
61 self.menu.addAction(self.tr("Clear"), self.clear)
62 self.menu.addSeparator()
63 self.menu.addAction(self.tr("Configure..."), self.__configure)
64
65 self.backMenu = QMenu(self)
66 self.backMenu.addAction(self.tr("Clear"), self.clear)
67 self.backMenu.addSeparator()
68 self.backMenu.addAction(self.tr("Configure..."), self.__configure)
69
70 def __itemDoubleClicked(self, itm):
71 """
72 Private slot to handle the double click of an item.
73
74 @param itm the item that was double clicked(QTreeWidgetItem), ignored
75 """
76 self.__openSource()
77
78 def __showContextMenu(self, coord):
79 """
80 Private slot to show the context menu of the listview.
81
82 @param coord the global coordinates of the mouse pointer (QPoint)
83 """
84 itm = self.itemAt(coord)
85 coord = self.mapToGlobal(coord)
86 if itm is None:
87 self.backMenu.popup(coord)
88 else:
89 self.menu.popup(coord)
90
91 def addException(self, exceptionType, exceptionMessage, stackTrace,
92 debuggerId):
93 """
94 Public slot to handle the arrival of a new exception.
95
96 @param exceptionType type of exception raised
97 @type str
98 @param exceptionMessage message given by the exception
99 @type str
100 @param stackTrace list of stack entries
101 @type list
102 @param debuggerId ID of the debugger backend
103 @type str
104 """
105 itm = QTreeWidgetItem(self)
106 if exceptionType is None:
107 itm.setText(
108 0, self.tr('{0}: An unhandled exception occured.'
109 ' See the shell window for details.')
110 .format(debuggerId))
111 return
112
113 text = (
114 self.tr("{0}: {1}").format(debuggerId, exceptionType)
115 if not exceptionMessage else
116 self.tr("{0}: {1}, {2}").format(debuggerId, exceptionType,
117 exceptionMessage)
118 )
119
120 itm.setText(0, text)
121 itm.setToolTip(0, text)
122
123 # now add the call stack, most recent call first
124 for entry in stackTrace:
125 excitm = QTreeWidgetItem(itm)
126 excitm.setText(0, "{0}, {1:d}".format(entry[0], entry[1]))
127
128 def debuggingStarted(self):
129 """
130 Public slot to clear the listview upon starting a new debugging
131 session.
132 """
133 self.clear()
134
135 def __openSource(self):
136 """
137 Private slot to handle a double click on an entry.
138 """
139 itm = self.currentItem()
140
141 if itm.parent() is None:
142 return
143
144 entry = itm.text(0)
145 entryList = entry.split(",")
146 with contextlib.suppress(IndexError, ValueError):
147 self.sourceFile.emit(entryList[0], int(entryList[1]))
148
149 def __configure(self):
150 """
151 Private method to open the configuration dialog.
152 """
153 ericApp().getObject("UserInterface").showPreferences(
154 "debuggerGeneralPage")

eric ide

mercurial