eric6/E5Gui/E5ErrorMessage.py

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

eric ide

mercurial