eric7/E5Gui/EricErrorMessage.py

branch
eric7
changeset 8358
144a6b854f70
parent 8357
a081458cc57b
child 8359
0e29e54e9269
equal deleted inserted replaced
8357:a081458cc57b 8358:144a6b854f70
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2013 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a specialized error message dialog.
8 """
9
10 import contextlib
11
12 from PyQt6.QtCore import (
13 qInstallMessageHandler, Qt, Q_ARG, QSettings, QtMsgType, QThread,
14 QMetaObject
15 )
16 from PyQt6.QtWidgets import QErrorMessage, QDialog
17
18 from E5Gui.EricApplication import ericApp
19
20 import Globals
21 import Utilities
22 import Preferences
23
24
25 _msgHandlerDialog = None
26 _origMsgHandler = None
27
28 _filterSettings = QSettings(
29 QSettings.Format.IniFormat,
30 QSettings.Scope.UserScope,
31 Globals.settingsNameOrganization,
32 "eric7messagefilters")
33 _defaultFilters = [
34 "QFont::",
35 "QCocoaMenu::removeMenuItem",
36 "QCocoaMenu::insertNative",
37 ",type id:",
38 "Remote debugging server started successfully",
39 "Uncaught SecurityError:",
40 "Content Security Policy",
41 "QXcbClipboard:",
42 "QXcbConnection: XCB error",
43 "libpng warning: iCCP:",
44 "Uncaught ReferenceError: $ is not defined",
45 ]
46
47
48 def filterMessage(message):
49 """
50 Module function to filter messages.
51
52 @param message message to be checked
53 @type str
54 @return flag indicating that the message should be filtered out
55 @rtype bool
56 """
57 return any(
58 filterStr in message
59 for filterStr in Globals.toList(_filterSettings.value(
60 "MessageFilters", [])) + _defaultFilters
61 )
62
63
64 class EricErrorMessage(QErrorMessage):
65 """
66 Class implementing a specialized error message dialog.
67 """
68 def __init__(self, parent=None):
69 """
70 Constructor
71
72 @param parent reference to the parent widget
73 @type QWidget
74 """
75 super().__init__(parent)
76
77 def showMessage(self, message, msgType=""):
78 """
79 Public method to show a message.
80
81 @param message error message to be shown
82 @type str
83 @param msgType type of the error message
84 @type str
85 """
86 if not filterMessage(message):
87 if msgType:
88 super().showMessage(message, msgType)
89 else:
90 super().showMessage(message)
91
92 def editMessageFilters(self):
93 """
94 Public method to edit the list of message filters.
95 """
96 from .EricErrorMessageFilterDialog import EricErrorMessageFilterDialog
97 dlg = EricErrorMessageFilterDialog(
98 Globals.toList(_filterSettings.value(
99 "MessageFilters", [])))
100 if dlg.exec() == QDialog.DialogCode.Accepted:
101 filters = dlg.getFilters()
102 _filterSettings.setValue("MessageFilters", filters)
103
104
105 def messageHandler(msgType, context, message):
106 """
107 Module function handling messages.
108
109 @param msgType type of the message
110 @type int, QtMsgType
111 @param context context information
112 @type QMessageLogContext
113 @param message message to be shown
114 @type bytes
115 """
116 if _msgHandlerDialog:
117 if msgType.value < Preferences.getUI("MinimumMessageTypeSeverity"):
118 # severity is lower than configured
119 # just ignore the message
120 return
121
122 with contextlib.suppress(RuntimeError):
123 if msgType == QtMsgType.QtDebugMsg:
124 messageType = "Debug Message:"
125 elif msgType == QtMsgType.QtInfoMsg:
126 messageType = "Info Message:"
127 elif msgType == QtMsgType.QtWarningMsg:
128 messageType = "Warning:"
129 elif msgType == QtMsgType.QtCriticalMsg:
130 messageType = "Critical:"
131 elif msgType == QtMsgType.QtFatalMsg:
132 messageType = "Fatal Error:"
133 if isinstance(message, bytes):
134 message = Utilities.decodeBytes(message)
135 if filterMessage(message):
136 return
137 message = (
138 message.replace("\r\n", "<br/>")
139 .replace("\n", "<br/>")
140 .replace("\r", "<br/>")
141 )
142 msg = (
143 (
144 "<p><b>{0}</b></p><p>{1}</p><p>File: {2}</p>"
145 "<p>Line: {3}</p><p>Function: {4}</p>"
146 ).format(messageType, Utilities.html_uencode(message),
147 context.file, context.line, context.function)
148 if context.file is not None else
149 "<p><b>{0}</b></p><p>{1}</p>".format(
150 messageType, Utilities.html_uencode(message))
151 )
152 if QThread.currentThread() == ericApp().thread():
153 _msgHandlerDialog.showMessage(msg)
154 else:
155 QMetaObject.invokeMethod(
156 _msgHandlerDialog,
157 "showMessage",
158 Qt.ConnectionType.QueuedConnection,
159 Q_ARG(str, msg))
160 return
161 elif _origMsgHandler:
162 _origMsgHandler(msgType, message)
163 return
164
165 if msgType == QtMsgType.QtDebugMsg:
166 messageType = "Debug Message"
167 elif msgType == QtMsgType.QtInfoMsg:
168 messageType = "Info Message:"
169 elif msgType == QtMsgType.QtWarningMsg:
170 messageType = "Warning"
171 elif msgType == QtMsgType.QtCriticalMsg:
172 messageType = "Critical"
173 elif msgType == QtMsgType.QtFatalMsg:
174 messageType = "Fatal Error"
175 if isinstance(message, bytes):
176 message = message.decode()
177 print("{0}: {1} in {2} at line {3} ({4})".format(
178 messageType, message, context.file, context.line,
179 context.function))
180
181
182 def qtHandler():
183 """
184 Module function to install an EricErrorMessage dialog as the global
185 message handler.
186
187 @return reference to the message handler dialog
188 @rtype EricErrorMessage
189 """
190 global _msgHandlerDialog, _origMsgHandler
191
192 if _msgHandlerDialog is None:
193 # Install an EricErrorMessage dialog as the global message handler.
194 _msgHandlerDialog = EricErrorMessage()
195 _origMsgHandler = qInstallMessageHandler(messageHandler)
196
197 return _msgHandlerDialog
198
199
200 def editMessageFilters():
201 """
202 Module function to edit the list of message filters.
203 """
204 if _msgHandlerDialog:
205 _msgHandlerDialog.editMessageFilters()
206 else:
207 print("No message handler installed.")
208
209
210 def messageHandlerInstalled():
211 """
212 Module function to check, if a message handler was installed.
213
214 @return flag indicating an installed message handler
215 @rtype bool
216 """
217 return _msgHandlerDialog is not None
218
219 #
220 # eflag: noqa = M801

eric ide

mercurial