eric6/UI/LogView.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 7201
6b42677d7043
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2006 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the log viewer widget and the log widget.
8 """
9
10 from __future__ import unicode_literals
11
12 from PyQt5.QtCore import pyqtSignal, Qt, QRegExp
13 from PyQt5.QtGui import QBrush, QTextCursor, QTextDocument
14 from PyQt5.QtWidgets import QTextEdit, QApplication, QMenu, QWidget, \
15 QHBoxLayout, QSizePolicy
16
17 from E5Gui.E5Application import e5App
18
19 from Globals import qVersionTuple
20
21 import UI.PixmapCache
22 import Preferences
23 import Utilities
24
25
26 class LogViewer(QWidget):
27 """
28 Class implementing the containing widget for the log viewer.
29 """
30 def __init__(self, ui, parent=None):
31 """
32 Constructor
33
34 @param ui reference to the main window (UserInterface)
35 @param parent reference to the parent widget (QWidget)
36 """
37 super(LogViewer, self).__init__(parent)
38
39 self.setWindowIcon(UI.PixmapCache.getIcon("eric.png"))
40
41 self.__ui = ui
42
43 self.__logViewer = LogViewerEdit(self)
44 from .SearchWidget import SearchWidget
45 self.__searchWidget = SearchWidget(
46 self.__logViewer, self, hideRegExp=qVersionTuple() < (5, 3, 0))
47 self.__searchWidget.setSizePolicy(
48 QSizePolicy.Fixed, QSizePolicy.Preferred)
49 self.__searchWidget.hide()
50
51 self.__layout = QHBoxLayout(self)
52 self.__layout.setContentsMargins(1, 1, 1, 1)
53 self.__layout.addWidget(self.__logViewer)
54 self.__layout.addWidget(self.__searchWidget)
55
56 self.__searchWidget.searchNext.connect(self.__logViewer.searchNext)
57 self.__searchWidget.searchPrevious.connect(self.__logViewer.searchPrev)
58 self.__logViewer.searchStringFound.connect(
59 self.__searchWidget.searchStringFound)
60
61 def appendToStdout(self, txt):
62 """
63 Public slot to appand text to the "stdout" tab.
64
65 @param txt text to be appended (string)
66 """
67 added = self.__logViewer.appendToStdout(txt)
68 if added:
69 self.__ui.showLogViewer()
70
71 def appendToStderr(self, txt):
72 """
73 Public slot to appand text to the "stderr" tab.
74
75 @param txt text to be appended (string)
76 """
77 added = self.__logViewer.appendToStderr(txt)
78 if added:
79 self.__ui.showLogViewer()
80
81 def preferencesChanged(self):
82 """
83 Public slot to handle a change of the preferences.
84 """
85 self.__logViewer.preferencesChanged()
86
87 def showFind(self, txt=""):
88 """
89 Public method to display the search widget.
90
91 @param txt text to be shown in the combo (string)
92 """
93 self.__searchWidget.showFind(txt)
94
95
96 class LogViewerEdit(QTextEdit):
97 """
98 Class providing a specialized text edit for displaying logging information.
99
100 @signal searchStringFound(found) emitted to indicate the search result
101 (boolean)
102 """
103 searchStringFound = pyqtSignal(bool)
104
105 def __init__(self, parent=None):
106 """
107 Constructor
108
109 @param parent reference to the parent widget (QWidget)
110 """
111 super(LogViewerEdit, self).__init__(parent)
112 self.setAcceptRichText(False)
113 self.setLineWrapMode(QTextEdit.NoWrap)
114 self.setReadOnly(True)
115
116 self.__mainWindow = parent
117 self.__lastSearch = ()
118
119 # create the context menu
120 self.__menu = QMenu(self)
121 self.__menu.addAction(self.tr('Clear'), self.clear)
122 self.__menu.addAction(self.tr('Copy'), self.copy)
123 self.__menu.addSeparator()
124 self.__menu.addAction(self.tr('Find'), self.__find)
125 self.__menu.addSeparator()
126 self.__menu.addAction(self.tr('Select All'), self.selectAll)
127 self.__menu.addSeparator()
128 self.__menu.addAction(self.tr("Configure..."), self.__configure)
129
130 self.setContextMenuPolicy(Qt.CustomContextMenu)
131 self.customContextMenuRequested.connect(self.__handleShowContextMenu)
132
133 self.cNormalFormat = self.currentCharFormat()
134 self.cErrorFormat = self.currentCharFormat()
135 self.cErrorFormat.setForeground(
136 QBrush(Preferences.getUI("LogStdErrColour")))
137
138 self.__stdoutFilter = Preferences.getUI("LogViewerStdoutFilter")
139 self.__stderrFilter = Preferences.getUI("LogViewerStderrFilter")
140 self.__stdxxxFilter = Preferences.getUI("LogViewerStdxxxFilter")
141
142 def __handleShowContextMenu(self, coord):
143 """
144 Private slot to show the context menu.
145
146 @param coord the position of the mouse pointer (QPoint)
147 """
148 coord = self.mapToGlobal(coord)
149 self.__menu.popup(coord)
150
151 def __appendText(self, txt, isErrorMessage=False):
152 """
153 Private method to append text to the end.
154
155 @param txt text to insert (string)
156 @param isErrorMessage flag indicating to insert error text (boolean)
157 """
158 tc = self.textCursor()
159 tc.movePosition(QTextCursor.End)
160 self.setTextCursor(tc)
161 if isErrorMessage:
162 self.setCurrentCharFormat(self.cErrorFormat)
163 else:
164 self.setCurrentCharFormat(self.cNormalFormat)
165 self.insertPlainText(Utilities.filterAnsiSequences(txt))
166 self.ensureCursorVisible()
167
168 def __filterMessage(self, message, isErrorMessage=False):
169 """
170 Private method to filter messages.
171
172 @param message message to be checked (string)
173 @param isErrorMessage flag indicating to check an error message
174 (boolean)
175 @return flag indicating that the message should be filtered out
176 (boolean)
177 """
178 message = Utilities.filterAnsiSequences(message)
179
180 if isErrorMessage:
181 filters = self.__stderrFilter + self.__stdxxxFilter
182 else:
183 filters = self.__stdoutFilter + self.__stdxxxFilter
184 for msgFilter in filters:
185 if msgFilter in message:
186 return True
187
188 return False
189
190 def appendToStdout(self, txt):
191 """
192 Public slot to appand text to the "stdout" tab.
193
194 @param txt text to be appended (string)
195 @return flag indicating text was appended (boolean)
196 """
197 if self.__filterMessage(txt, isErrorMessage=False):
198 return False
199
200 self.__appendText(txt, isErrorMessage=False)
201 QApplication.processEvents()
202 return True
203
204 def appendToStderr(self, txt):
205 """
206 Public slot to appand text to the "stderr" tab.
207
208 @param txt text to be appended (string)
209 @return flag indicating text was appended (boolean)
210 """
211 if self.__filterMessage(txt, isErrorMessage=True):
212 return False
213
214 self.__appendText(txt, isErrorMessage=True)
215 QApplication.processEvents()
216 return True
217
218 def preferencesChanged(self):
219 """
220 Public slot to handle a change of the preferences.
221 """
222 self.cErrorFormat.setForeground(
223 QBrush(Preferences.getUI("LogStdErrColour")))
224
225 self.__stdoutFilter = Preferences.getUI("LogViewerStdoutFilter")
226 self.__stderrFilter = Preferences.getUI("LogViewerStderrFilter")
227 self.__stdxxxFilter = Preferences.getUI("LogViewerStdxxxFilter")
228
229 def __configure(self):
230 """
231 Private method to open the configuration dialog.
232 """
233 e5App().getObject("UserInterface").showPreferences("logViewerPage")
234
235 def __find(self):
236 """
237 Private slot to show the find widget.
238 """
239 txt = self.textCursor().selectedText()
240 self.__mainWindow.showFind(txt)
241
242 def searchNext(self, txt, caseSensitive, wholeWord, regexp):
243 """
244 Public method to search the next occurrence of the given text.
245
246 @param txt text to search for
247 @type str
248 @param caseSensitive flag indicating to perform a case sensitive
249 search
250 @type bool
251 @param wholeWord flag indicating to search for whole words
252 only
253 @type bool
254 @param regexp flag indicating a regular expression search
255 @type bool
256 """
257 self.__lastSearch = (txt, caseSensitive, wholeWord, regexp)
258 flags = QTextDocument.FindFlags()
259 if caseSensitive:
260 flags |= QTextDocument.FindCaseSensitively
261 if wholeWord:
262 flags |= QTextDocument.FindWholeWords
263 if regexp:
264 ok = self.find(QRegExp(
265 txt,
266 Qt.CaseSensitive if caseSensitive else Qt.CaseInsensitive),
267 flags
268 )
269 else:
270 ok = self.find(txt, flags)
271 self.searchStringFound.emit(ok)
272
273 def searchPrev(self, txt, caseSensitive, wholeWord, regexp):
274 """
275 Public method to search the previous occurrence of the given text.
276
277 @param txt text to search for
278 @type str
279 @param caseSensitive flag indicating to perform a case sensitive
280 search
281 @type bool
282 @param wholeWord flag indicating to search for whole words
283 only
284 @type bool
285 @param regexp flag indicating a regular expression search
286 @type bool
287 """
288 self.__lastSearch = (txt, caseSensitive, wholeWord, regexp)
289 flags = QTextDocument.FindFlags(QTextDocument.FindBackward)
290 if caseSensitive:
291 flags |= QTextDocument.FindCaseSensitively
292 if wholeWord:
293 flags |= QTextDocument.FindWholeWords
294 if regexp:
295 ok = self.find(QRegExp(
296 txt,
297 Qt.CaseSensitive if caseSensitive else Qt.CaseInsensitive),
298 flags
299 )
300 else:
301 ok = self.find(txt, flags)
302 self.searchStringFound.emit(ok)
303
304 def keyPressEvent(self, evt):
305 """
306 Protected method handling key press events.
307
308 @param evt key press event (QKeyEvent)
309 """
310 if evt.modifiers() == Qt.ControlModifier:
311 if evt.key() == Qt.Key_F:
312 self.__find()
313 evt.accept()
314 return
315 elif evt.key() == Qt.Key_C:
316 self.copy()
317 evt.accept()
318 return
319 elif evt.key() == Qt.Key_A:
320 self.selectAll()
321 evt.accept()
322 return
323 elif evt.modifiers() == Qt.NoModifier:
324 if evt.key() == Qt.Key_F3 and self.__lastSearch:
325 self.searchNext(*self.__lastSearch)
326 evt.accept()
327 return
328 elif evt.modifiers() == Qt.ShiftModifier and self.__lastSearch:
329 if evt.key() == Qt.Key_F3 and self.__lastSearch:
330 self.searchPrev(*self.__lastSearch)
331 evt.accept()
332 return

eric ide

mercurial