21 #You should have received a copy of the GNU General Public |
21 #You should have received a copy of the GNU General Public |
22 #License along with this library; if not, write to the Free Software |
22 #License along with this library; if not, write to the Free Software |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
24 |
24 |
25 from datetime import datetime |
25 from datetime import datetime |
|
26 from time import time as gettime |
26 |
27 |
27 import wx |
28 import wx |
28 |
29 |
29 from graphics import DebugViewer, REFRESH_PERIOD |
30 from graphics import DebugViewer, REFRESH_PERIOD |
30 from targets.typemapping import LogLevelsCount, LogLevels |
31 from targets.typemapping import LogLevelsCount, LogLevels |
31 from util.BitmapLibrary import GetBitmap |
32 from util.BitmapLibrary import GetBitmap |
32 |
33 |
33 SPEED_VALUES = [10, 5, 2, 1, 0, -1, -2, -5, -10] |
34 THUMB_SIZE_RATIO = 1. / 8. |
34 |
35 |
35 class MyScrollBar(wx.Panel): |
36 class MyScrollBar(wx.Panel): |
36 |
37 |
37 def __init__(self, parent, size): |
38 def __init__(self, parent, size): |
38 wx.Panel.__init__(self, parent, size=size) |
39 wx.Panel.__init__(self, parent, size=size) |
40 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) |
41 self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp) |
41 self.Bind(wx.EVT_MOTION, self.OnMotion) |
42 self.Bind(wx.EVT_MOTION, self.OnMotion) |
42 self.Bind(wx.EVT_PAINT, self.OnPaint) |
43 self.Bind(wx.EVT_PAINT, self.OnPaint) |
43 self.Bind(wx.EVT_SIZE, self.OnResize) |
44 self.Bind(wx.EVT_SIZE, self.OnResize) |
44 |
45 |
45 self.ThumbPosition = SPEED_VALUES.index(0) |
46 self.ThumbPosition = 0. # -1 <= ThumbPosition <= 1 |
46 self.ThumbScrolling = False |
47 self.ThumbScrollingStartPos = None |
47 |
48 |
48 def GetRangeRect(self): |
49 def GetRangeRect(self): |
49 width, height = self.GetClientSize() |
50 width, height = self.GetClientSize() |
50 return wx.Rect(0, width, width, height - 2 * width) |
51 return wx.Rect(0, width, width, height - 2 * width) |
51 |
52 |
52 def GetThumbRect(self): |
53 def GetThumbRect(self): |
53 width, height = self.GetClientSize() |
54 width, height = self.GetClientSize() |
54 range_rect = self.GetRangeRect() |
55 range_rect = self.GetRangeRect() |
|
56 thumb_size = range_rect.height * THUMB_SIZE_RATIO |
|
57 thumb_range = range_rect.height - thumb_size |
|
58 thumb_center_position = (thumb_size + (self.ThumbPosition + 1) * thumb_range) / 2. |
|
59 thumb_start = int(thumb_center_position - thumb_size / 2.) |
|
60 thumb_end = int(thumb_center_position + thumb_size / 2.) |
|
61 return wx.Rect(1, range_rect.y + thumb_start, width - 1, thumb_end - thumb_start) |
|
62 |
|
63 def RefreshThumbPosition(self, thumb_position=None): |
|
64 if thumb_position is None: |
|
65 thumb_position = self.ThumbPosition |
55 if self.Parent.IsMessagePanelTop(): |
66 if self.Parent.IsMessagePanelTop(): |
56 thumb_start = 0 |
67 thumb_position = max(0., thumb_position) |
57 else: |
|
58 thumb_start = int(float(self.ThumbPosition * range_rect.height) / len(SPEED_VALUES)) |
|
59 if self.Parent.IsMessagePanelBottom(): |
68 if self.Parent.IsMessagePanelBottom(): |
60 thumb_end = range_rect.height |
69 thumb_position = min(0., thumb_position) |
61 else: |
70 if thumb_position != self.ThumbPosition: |
62 thumb_end = int(float((self.ThumbPosition + 1) * range_rect.height) / len(SPEED_VALUES)) |
71 self.ThumbPosition = thumb_position |
63 return wx.Rect(1, range_rect.y + thumb_start, width - 1, thumb_end - thumb_start) |
72 self.Parent.SetScrollSpeed(self.ThumbPosition) |
|
73 self.Refresh() |
64 |
74 |
65 def OnLeftDown(self, event): |
75 def OnLeftDown(self, event): |
66 self.CaptureMouse() |
76 self.CaptureMouse() |
67 posx, posy = event.GetPosition() |
77 posx, posy = event.GetPosition() |
68 width, height = self.GetClientSize() |
78 width, height = self.GetClientSize() |
69 range_rect = self.GetRangeRect() |
79 range_rect = self.GetRangeRect() |
70 thumb_rect = self.GetThumbRect() |
80 thumb_rect = self.GetThumbRect() |
71 if range_rect.InsideXY(posx, posy): |
81 if range_rect.InsideXY(posx, posy): |
72 if thumb_rect.InsideXY(posx, posy): |
82 if thumb_rect.InsideXY(posx, posy): |
73 self.ThumbScrolling = True |
83 self.ThumbScrollingStartPos = wx.Point(posx, posy) |
74 elif posy < thumb_rect.y: |
84 elif posy < thumb_rect.y: |
75 self.Parent.ScrollPageUp() |
85 self.Parent.ScrollToLast() |
76 elif posy > thumb_rect.y + thumb_rect.height: |
86 elif posy > thumb_rect.y + thumb_rect.height: |
77 self.Parent.ScrollPageDown() |
87 self.Parent.ScrollToFirst() |
78 elif posy < width: |
88 elif posy < width: |
79 self.Parent.SetScrollSpeed(1) |
89 pass |
80 elif posy > height - width: |
90 elif posy > height - width: |
81 self.Parent.SetScrollSpeed(-1) |
91 pass |
82 event.Skip() |
92 event.Skip() |
83 |
93 |
84 def OnLeftUp(self, event): |
94 def OnLeftUp(self, event): |
85 self.ThumbScrolling = False |
95 self.ThumbScrollingStartPos = None |
86 self.ThumbPosition = SPEED_VALUES.index(0) |
96 self.RefreshThumbPosition(0.) |
87 self.Parent.SetScrollSpeed(SPEED_VALUES[self.ThumbPosition]) |
|
88 self.Refresh() |
|
89 if self.HasCapture(): |
97 if self.HasCapture(): |
90 self.ReleaseMouse() |
98 self.ReleaseMouse() |
91 event.Skip() |
99 event.Skip() |
92 |
100 |
93 def OnMotion(self, event): |
101 def OnMotion(self, event): |
94 if event.Dragging() and self.ThumbScrolling: |
102 if event.Dragging() and self.ThumbScrollingStartPos is not None: |
95 posx, posy = event.GetPosition() |
103 posx, posy = event.GetPosition() |
96 width, height = self.GetClientSize() |
104 width, height = self.GetClientSize() |
97 range_rect = self.GetRangeRect() |
105 range_rect = self.GetRangeRect() |
98 if range_rect.InsideXY(posx, posy): |
106 thumb_size = range_rect.height * THUMB_SIZE_RATIO |
99 new_thumb_position = int(float(posy - range_rect.y) * len(SPEED_VALUES) / range_rect.height) |
107 thumb_range = range_rect.height - thumb_size |
100 thumb_rect = self.GetThumbRect() |
108 self.RefreshThumbPosition( |
101 if self.ThumbPosition == SPEED_VALUES.index(0): |
109 max(-1., min((posy - self.ThumbScrollingStartPos.y) * 2. / thumb_range, 1.))) |
102 if thumb_rect.y == width: |
|
103 new_thumb_position = max(new_thumb_position, SPEED_VALUES.index(0)) |
|
104 if thumb_rect.y + thumb_rect.height == height - width: |
|
105 new_thumb_position = min(new_thumb_position, SPEED_VALUES.index(0)) |
|
106 if new_thumb_position != self.ThumbPosition: |
|
107 self.ThumbPosition = new_thumb_position |
|
108 self.Parent.SetScrollSpeed(SPEED_VALUES[new_thumb_position]) |
|
109 self.Refresh() |
|
110 event.Skip() |
110 event.Skip() |
111 |
111 |
112 def OnResize(self, event): |
112 def OnResize(self, event): |
113 self.Refresh() |
113 self.Refresh() |
114 event.Skip() |
114 event.Skip() |
116 def OnPaint(self, event): |
116 def OnPaint(self, event): |
117 dc = wx.BufferedPaintDC(self) |
117 dc = wx.BufferedPaintDC(self) |
118 dc.Clear() |
118 dc.Clear() |
119 dc.BeginDrawing() |
119 dc.BeginDrawing() |
120 |
120 |
|
121 width, height = self.GetClientSize() |
|
122 |
|
123 thumb_rect = self.GetThumbRect() |
|
124 exclusion_rect = wx.Rect(thumb_rect.x, thumb_rect.y, |
|
125 thumb_rect.width, thumb_rect.height) |
|
126 if self.Parent.IsMessagePanelTop(): |
|
127 exclusion_rect.y, exclusion_rect.height = width, exclusion_rect.y + exclusion_rect.height - width |
|
128 if self.Parent.IsMessagePanelBottom(): |
|
129 exclusion_rect.height = height - width - exclusion_rect.y |
|
130 if exclusion_rect != thumb_rect: |
|
131 colour = wx.NamedColour("LIGHT GREY") |
|
132 dc.SetPen(wx.Pen(colour)) |
|
133 dc.SetBrush(wx.Brush(colour)) |
|
134 |
|
135 dc.DrawRectangle(exclusion_rect.x, exclusion_rect.y, |
|
136 exclusion_rect.width, exclusion_rect.height) |
|
137 |
121 dc.SetPen(wx.GREY_PEN) |
138 dc.SetPen(wx.GREY_PEN) |
122 dc.SetBrush(wx.GREY_BRUSH) |
139 dc.SetBrush(wx.GREY_BRUSH) |
123 |
|
124 width, height = self.GetClientSize() |
|
125 |
140 |
126 dc.DrawPolygon([wx.Point(width / 2, 1), |
141 dc.DrawPolygon([wx.Point(width / 2, 1), |
127 wx.Point(1, width - 2), |
142 wx.Point(1, width - 2), |
128 wx.Point(width - 1, width - 2)]) |
143 wx.Point(width - 1, width - 2)]) |
129 |
144 |
130 dc.DrawPolygon([wx.Point(width / 2, height - 1), |
145 dc.DrawPolygon([wx.Point(width / 2, height - 1), |
131 wx.Point(2, height - width + 1), |
146 wx.Point(2, height - width + 1), |
132 wx.Point(width - 1, height - width + 1)]) |
147 wx.Point(width - 1, height - width + 1)]) |
133 |
148 |
134 thumb_rect = self.GetThumbRect() |
|
135 dc.DrawRectangle(thumb_rect.x, thumb_rect.y, |
149 dc.DrawRectangle(thumb_rect.x, thumb_rect.y, |
136 thumb_rect.width, thumb_rect.height) |
150 thumb_rect.width, thumb_rect.height) |
137 |
151 |
138 dc.EndDrawing() |
152 dc.EndDrawing() |
139 event.Skip() |
153 event.Skip() |
211 for level in levels: |
225 for level in levels: |
212 self.MessageFilter.Append(_(level)) |
226 self.MessageFilter.Append(_(level)) |
213 self.Bind(wx.EVT_COMBOBOX, self.OnMessageFilterChanged, self.MessageFilter) |
227 self.Bind(wx.EVT_COMBOBOX, self.OnMessageFilterChanged, self.MessageFilter) |
214 filter_sizer.AddWindow(self.MessageFilter, 1, border=5, flag=wx.RIGHT|wx.GROW) |
228 filter_sizer.AddWindow(self.MessageFilter, 1, border=5, flag=wx.RIGHT|wx.GROW) |
215 |
229 |
216 self.SearchMessage = wx.SearchCtrl(self) |
230 self.SearchMessage = wx.SearchCtrl(self, style=wx.TE_PROCESS_ENTER) |
217 self.SearchMessage.ShowSearchButton(True) |
231 self.SearchMessage.ShowSearchButton(True) |
218 self.Bind(wx.EVT_TEXT, self.OnSearchMessageChanged, self.SearchMessage) |
232 self.SearchMessage.ShowCancelButton(True) |
|
233 self.Bind(wx.EVT_TEXT_ENTER, self.OnSearchMessageChanged, self.SearchMessage) |
219 self.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, |
234 self.Bind(wx.EVT_SEARCHCTRL_SEARCH_BTN, |
220 self.OnSearchMessageButtonClick, self.SearchMessage) |
235 self.OnSearchMessageSearchButtonClick, self.SearchMessage) |
|
236 self.Bind(wx.EVT_SEARCHCTRL_CANCEL_BTN, |
|
237 self.OnSearchMessageCancelButtonClick, self.SearchMessage) |
221 filter_sizer.AddWindow(self.SearchMessage, 3, flag=wx.GROW) |
238 filter_sizer.AddWindow(self.SearchMessage, 3, flag=wx.GROW) |
222 |
239 |
223 message_panel_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0) |
240 message_panel_sizer = wx.FlexGridSizer(cols=3, hgap=0, rows=1, vgap=0) |
224 message_panel_sizer.AddGrowableCol(1) |
241 message_panel_sizer.AddGrowableCol(1) |
225 message_panel_sizer.AddGrowableRow(0) |
242 message_panel_sizer.AddGrowableRow(0) |
226 main_sizer.AddSizer(message_panel_sizer, border=5, flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.GROW) |
243 main_sizer.AddSizer(message_panel_sizer, border=5, flag=wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.GROW) |
227 |
244 |
228 buttons_sizer = wx.BoxSizer(wx.VERTICAL) |
245 buttons_sizer = wx.BoxSizer(wx.VERTICAL) |
229 for label, callback in [(_("First"), self.OnFirstButton)] + \ |
246 for label, callback in [("+" + text, self.GenerateOnDurationButton(duration)) |
230 [("+" + text, self.GenerateOnDurationButton(duration)) |
|
231 for text, duration in CHANGE_TIMESTAMP_BUTTONS] +\ |
247 for text, duration in CHANGE_TIMESTAMP_BUTTONS] +\ |
232 [("-" + text, self.GenerateOnDurationButton(-duration)) |
248 [("-" + text, self.GenerateOnDurationButton(-duration)) |
233 for text, duration in REVERSE_CHANGE_TIMESTAMP_BUTTONS] + \ |
249 for text, duration in REVERSE_CHANGE_TIMESTAMP_BUTTONS]: |
234 [(_("Last"), self.OnLastButton)]: |
|
235 button = wx.Button(self, label=label) |
250 button = wx.Button(self, label=label) |
236 self.Bind(wx.EVT_BUTTON, callback, button) |
251 self.Bind(wx.EVT_BUTTON, callback, button) |
237 buttons_sizer.AddWindow(button, 1, wx.ALIGN_CENTER_VERTICAL) |
252 buttons_sizer.AddWindow(button, 1, wx.ALIGN_CENTER_VERTICAL) |
238 message_panel_sizer.AddSizer(buttons_sizer, flag=wx.GROW) |
253 message_panel_sizer.AddSizer(buttons_sizer, flag=wx.GROW) |
239 |
254 |
240 self.MessagePanel = wx.Panel(self) |
255 self.MessagePanel = wx.Panel(self) |
241 if wx.Platform == '__WXMSW__': |
256 if wx.Platform == '__WXMSW__': |
242 self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New') |
257 self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New') |
243 else: |
258 else: |
244 self.Font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier') |
259 self.Font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier') |
|
260 self.MessagePanel.Bind(wx.EVT_MOUSEWHEEL, self.OnMessagePanelMouseWheel) |
245 self.MessagePanel.Bind(wx.EVT_PAINT, self.OnMessagePanelPaint) |
261 self.MessagePanel.Bind(wx.EVT_PAINT, self.OnMessagePanelPaint) |
246 self.MessagePanel.Bind(wx.EVT_SIZE, self.OnMessagePanelResize) |
262 self.MessagePanel.Bind(wx.EVT_SIZE, self.OnMessagePanelResize) |
247 message_panel_sizer.AddWindow(self.MessagePanel, flag=wx.GROW) |
263 message_panel_sizer.AddWindow(self.MessagePanel, flag=wx.GROW) |
248 |
264 |
249 self.MessageScrollBar = MyScrollBar(self, wx.Size(16, -1)) |
265 self.MessageScrollBar = MyScrollBar(self, wx.Size(16, -1)) |
318 self.LogMessages.append(new_message) |
336 self.LogMessages.append(new_message) |
319 if self.CurrentMessage is None or self.CurrentMessage == old_length - 1: |
337 if self.CurrentMessage is None or self.CurrentMessage == old_length - 1: |
320 self.CurrentMessage = len(self.LogMessages) - 1 |
338 self.CurrentMessage = len(self.LogMessages) - 1 |
321 self.NewDataAvailable(None) |
339 self.NewDataAvailable(None) |
322 |
340 |
323 def GetNextMessage(self, msgidx, levels=range(4)): |
341 def FilterLogMessage(self, message): |
|
342 return message.Level in self.CurrentFilter and message.Message.find(self.CurrentSearchValue) != -1 |
|
343 |
|
344 def GetNextMessage(self, msgidx): |
324 while msgidx < len(self.LogMessages) - 1: |
345 while msgidx < len(self.LogMessages) - 1: |
325 message = self.LogMessages[msgidx + 1] |
346 message = self.LogMessages[msgidx + 1] |
326 if message.Level in levels: |
347 if self.FilterLogMessage(message): |
327 return message, msgidx + 1 |
348 return message, msgidx + 1 |
328 msgidx += 1 |
349 msgidx += 1 |
329 return None, None |
350 return None, None |
330 |
351 |
331 def GetPreviousMessage(self, msgidx, levels=range(4)): |
352 def GetPreviousMessage(self, msgidx): |
332 message = None |
353 message = None |
333 while 0 < msgidx < len(self.LogMessages): |
354 while 0 < msgidx < len(self.LogMessages): |
334 message = self.LogMessages[msgidx - 1] |
355 message = self.LogMessages[msgidx - 1] |
335 if message.Level in levels: |
356 if self.FilterLogMessage(message): |
336 return message, msgidx - 1 |
357 return message, msgidx - 1 |
337 msgidx -= 1 |
358 msgidx -= 1 |
338 if len(self.LogMessages) > 0: |
359 if len(self.LogMessages) > 0: |
339 message = self.LogMessages[0] |
360 message = self.LogMessages[0] |
340 while message is not None: |
361 while message is not None: |
383 offset = 5 |
404 offset = 5 |
384 while offset < height and message is not None: |
405 while offset < height and message is not None: |
385 message.Draw(dc, offset, width, draw_date) |
406 message.Draw(dc, offset, width, draw_date) |
386 offset += message.GetHeight(draw_date) |
407 offset += message.GetHeight(draw_date) |
387 |
408 |
388 previous_message, message_idx = self.GetPreviousMessage(message_idx, self.CurrentFilter) |
409 previous_message, message_idx = self.GetPreviousMessage(message_idx) |
389 if previous_message is not None: |
410 if previous_message is not None: |
390 draw_date = message.Date != previous_message.Date |
411 draw_date = message.Date != previous_message.Date |
391 message = previous_message |
412 message = previous_message |
392 |
413 |
393 dc.EndDrawing() |
414 dc.EndDrawing() |
394 |
415 |
395 self.MessageScrollBar.Refresh() |
416 self.MessageScrollBar.RefreshThumbPosition() |
396 |
|
397 def OnMessageFilterChanged(self, event): |
|
398 self.CurrentFilter = self.LevelFilters[self.MessageFilter.GetSelection()] |
|
399 if len(self.LogMessages) > 0: |
|
400 self.CurrentMessage = len(self.LogMessages) - 1 |
|
401 message = self.LogMessages[self.CurrentMessage] |
|
402 while message is not None and message.Level not in self.CurrentFilter: |
|
403 message, self.CurrentMessage = self.GetPreviousMessage(self.CurrentMessage, self.CurrentFilter) |
|
404 self.RefreshView() |
|
405 event.Skip() |
|
406 |
417 |
407 def IsMessagePanelTop(self, message_idx=None): |
418 def IsMessagePanelTop(self, message_idx=None): |
408 if message_idx is None: |
419 if message_idx is None: |
409 message_idx = self.CurrentMessage |
420 message_idx = self.CurrentMessage |
410 if message_idx is not None: |
421 if message_idx is not None: |
411 return self.GetNextMessage(message_idx, self.CurrentFilter)[0] is None |
422 return self.GetNextMessage(message_idx)[0] is None |
412 return True |
423 return True |
413 |
424 |
414 def IsMessagePanelBottom(self, message_idx=None): |
425 def IsMessagePanelBottom(self, message_idx=None): |
415 if message_idx is None: |
426 if message_idx is None: |
416 message_idx = self.CurrentMessage |
427 message_idx = self.CurrentMessage |
419 offset = 5 |
430 offset = 5 |
420 message = self.LogMessages[message_idx] |
431 message = self.LogMessages[message_idx] |
421 draw_date = True |
432 draw_date = True |
422 while message is not None and offset < height: |
433 while message is not None and offset < height: |
423 offset += message.GetHeight(draw_date) |
434 offset += message.GetHeight(draw_date) |
424 previous_message, message_idx = self.GetPreviousMessage(message_idx, self.CurrentFilter) |
435 previous_message, message_idx = self.GetPreviousMessage(message_idx) |
425 if previous_message is not None: |
436 if previous_message is not None: |
426 draw_date = message.Date != previous_message.Date |
437 draw_date = message.Date != previous_message.Date |
427 message = previous_message |
438 message = previous_message |
428 return offset < height |
439 return offset < height |
429 return True |
440 return True |
430 |
441 |
431 def ScrollMessagePanel(self, scroll): |
442 def ScrollMessagePanel(self, scroll): |
432 if self.CurrentMessage is not None: |
443 if self.CurrentMessage is not None: |
433 message = self.LogMessages[self.CurrentMessage] |
444 message = self.LogMessages[self.CurrentMessage] |
434 while scroll > 0 and message is not None: |
445 while scroll > 0 and message is not None: |
435 message, msgidx = self.GetNextMessage(self.CurrentMessage, self.CurrentFilter) |
446 message, msgidx = self.GetNextMessage(self.CurrentMessage) |
436 if message is not None: |
447 if message is not None: |
437 self.CurrentMessage = msgidx |
448 self.CurrentMessage = msgidx |
438 scroll -= 1 |
449 scroll -= 1 |
439 while scroll < 0 and message is not None and not self.IsMessagePanelBottom(): |
450 while scroll < 0 and message is not None and not self.IsMessagePanelBottom(): |
440 message, msgidx = self.GetPreviousMessage(self.CurrentMessage, self.CurrentFilter) |
451 message, msgidx = self.GetPreviousMessage(self.CurrentMessage) |
441 if message is not None: |
452 if message is not None: |
442 self.CurrentMessage = msgidx |
453 self.CurrentMessage = msgidx |
443 scroll += 1 |
454 scroll += 1 |
444 self.RefreshView() |
455 self.RefreshView() |
445 |
456 |
446 def OnSearchMessageChanged(self, event): |
457 def ResetMessagePanel(self): |
447 event.Skip() |
|
448 |
|
449 def OnSearchMessageButtonClick(self, event): |
|
450 event.Skip() |
|
451 |
|
452 def OnFirstButton(self, event): |
|
453 if len(self.LogMessages) > 0: |
458 if len(self.LogMessages) > 0: |
454 self.CurrentMessage = len(self.LogMessages) - 1 |
459 self.CurrentMessage = len(self.LogMessages) - 1 |
455 message = self.LogMessages[self.CurrentMessage] |
460 message = self.LogMessages[self.CurrentMessage] |
456 if message.Level not in self.CurrentFilter: |
461 while message is not None and not self.FilterLogMessage(message): |
457 message, self.CurrentMessage = self.GetPreviousMessage(self.CurrentMessage, self.CurrentFilter) |
462 message, self.CurrentMessage = self.GetPreviousMessage(self.CurrentMessage) |
458 self.RefreshView() |
463 self.RefreshView() |
459 event.Skip() |
464 |
460 |
465 def OnMessageFilterChanged(self, event): |
461 def OnLastButton(self, event): |
466 self.CurrentFilter = self.LevelFilters[self.MessageFilter.GetSelection()] |
|
467 self.ResetMessagePanel() |
|
468 event.Skip() |
|
469 |
|
470 def OnSearchMessageChanged(self, event): |
|
471 self.CurrentSearchValue = self.SearchMessage.GetValue() |
|
472 self.ResetMessagePanel() |
|
473 event.Skip() |
|
474 |
|
475 def OnSearchMessageSearchButtonClick(self, event): |
|
476 self.CurrentSearchValue = self.SearchMessage.GetValue() |
|
477 self.ResetMessagePanel() |
|
478 event.Skip() |
|
479 |
|
480 def OnSearchMessageCancelButtonClick(self, event): |
|
481 self.CurrentSearchValue = "" |
|
482 self.SearchMessage.SetValue("") |
|
483 self.ResetMessagePanel() |
|
484 event.Skip() |
|
485 |
|
486 def GenerateOnDurationButton(self, duration): |
|
487 def OnDurationButton(event): |
|
488 event.Skip() |
|
489 return OnDurationButton |
|
490 |
|
491 def OnMessagePanelMouseWheel(self, event): |
|
492 self.ScrollMessagePanel(event.GetWheelRotation() / event.GetWheelDelta()) |
|
493 event.Skip() |
|
494 |
|
495 def OnMessagePanelPaint(self, event): |
|
496 self.RefreshView() |
|
497 event.Skip() |
|
498 |
|
499 def OnMessagePanelResize(self, event): |
|
500 if self.IsMessagePanelBottom(): |
|
501 self.ScrollToFirst() |
|
502 else: |
|
503 self.RefreshView() |
|
504 event.Skip() |
|
505 |
|
506 def OnScrollTimer(self, event): |
|
507 if self.ScrollSpeed != 0.: |
|
508 speed_norm = abs(self.ScrollSpeed) |
|
509 period = REFRESH_PERIOD / speed_norm |
|
510 self.ScrollMessagePanel(-speed_norm / self.ScrollSpeed) |
|
511 self.LastStartTime = gettime() |
|
512 self.ScrollTimer.Start(int(period * 1000), True) |
|
513 event.Skip() |
|
514 |
|
515 def SetScrollSpeed(self, speed): |
|
516 if speed == 0.: |
|
517 self.ScrollTimer.Stop() |
|
518 else: |
|
519 speed_norm = abs(speed) |
|
520 period = REFRESH_PERIOD / speed_norm |
|
521 current_time = gettime() |
|
522 if self.LastStartTime is not None: |
|
523 elapsed_time = current_time - self.LastStartTime |
|
524 if elapsed_time > period: |
|
525 self.ScrollMessagePanel(-speed_norm / speed) |
|
526 self.LastStartTime = current_time |
|
527 else: |
|
528 period -= elapsed_time |
|
529 else: |
|
530 self.LastStartTime = current_time |
|
531 self.ScrollTimer.Start(int(period * 1000), True) |
|
532 self.ScrollSpeed = speed |
|
533 |
|
534 def ScrollToLast(self): |
|
535 if len(self.LogMessages) > 0: |
|
536 self.CurrentMessage = len(self.LogMessages) - 1 |
|
537 message = self.LogMessages[self.CurrentMessage] |
|
538 if not self.FilterLogMessage(message): |
|
539 message, self.CurrentMessage = self.GetPreviousMessage(self.CurrentMessage) |
|
540 self.RefreshView() |
|
541 |
|
542 def ScrollToFirst(self): |
462 if len(self.LogMessages) > 0: |
543 if len(self.LogMessages) > 0: |
463 message_idx = 0 |
544 message_idx = 0 |
464 message = self.LogMessages[message_idx] |
545 message = self.LogMessages[message_idx] |
465 if message.Level not in self.CurrentFilter: |
546 if not self.FilterLogMessage(message): |
466 next_message, msgidx = self.GetNextMessage(message_idx, self.CurrentFilter) |
547 next_message, msgidx = self.GetNextMessage(message_idx) |
467 if next_message is not None: |
548 if next_message is not None: |
468 message_idx = msgidx |
549 message_idx = msgidx |
469 message = next_message |
550 message = next_message |
470 while message is not None: |
551 while message is not None: |
471 message, msgidx = self.GetPreviousMessage(message_idx, self.CurrentFilter) |
552 message, msgidx = self.GetPreviousMessage(message_idx) |
472 if message is not None: |
553 if message is not None: |
473 message_idx = msgidx |
554 message_idx = msgidx |
474 message = self.LogMessages[message_idx] |
555 message = self.LogMessages[message_idx] |
475 if message.Level in self.CurrentFilter: |
556 if self.FilterLogMessage(message): |
476 while message is not None: |
557 while message is not None: |
477 message, msgidx = self.GetNextMessage(message_idx, self.CurrentFilter) |
558 message, msgidx = self.GetNextMessage(message_idx) |
478 if message is not None: |
559 if message is not None: |
479 if not self.IsMessagePanelBottom(msgidx): |
560 if not self.IsMessagePanelBottom(msgidx): |
480 break |
561 break |
481 message_idx = msgidx |
562 message_idx = msgidx |
482 self.CurrentMessage = message_idx |
563 self.CurrentMessage = message_idx |
483 else: |
564 else: |
484 self.CurrentMessage = None |
565 self.CurrentMessage = None |
485 self.RefreshView() |
566 self.RefreshView() |
486 event.Skip() |
|
487 |
|
488 def GenerateOnDurationButton(self, duration): |
|
489 def OnDurationButton(event): |
|
490 event.Skip() |
|
491 return OnDurationButton |
|
492 |
|
493 def OnMessagePanelPaint(self, event): |
|
494 self.RefreshView() |
|
495 event.Skip() |
|
496 |
|
497 def OnMessagePanelResize(self, event): |
|
498 self.RefreshView() |
|
499 event.Skip() |
|
500 |
|
501 def OnScrollTimer(self, event): |
|
502 if self.ScrollSpeed != 0: |
|
503 speed_norm = abs(self.ScrollSpeed) |
|
504 if speed_norm <= 5: |
|
505 self.ScrollMessagePanel(speed_norm / self.ScrollSpeed) |
|
506 period = REFRESH_PERIOD * 5000 / speed_norm |
|
507 else: |
|
508 self.ScrollMessagePanel(self.ScrollSpeed / 5) |
|
509 period = REFRESH_PERIOD * 1000 |
|
510 self.ScrollTimer.Start(period, True) |
|
511 event.Skip() |
|
512 |
|
513 def SetScrollSpeed(self, speed): |
|
514 if speed == 0: |
|
515 self.ScrollTimer.Stop() |
|
516 else: |
|
517 if not self.ScrollTimer.IsRunning(): |
|
518 speed_norm = abs(speed) |
|
519 if speed_norm <= 5: |
|
520 self.ScrollMessagePanel(speed_norm / speed) |
|
521 period = REFRESH_PERIOD * 5000 / speed_norm |
|
522 else: |
|
523 period = REFRESH_PERIOD * 1000 |
|
524 self.ScrollMessagePanel(speed / 5) |
|
525 self.ScrollTimer.Start(period, True) |
|
526 self.ScrollSpeed = speed |
|
527 |
|
528 def ScrollPageUp(self): |
|
529 pass |
|
530 |
|
531 def ScrollPageDown(self): |
|
532 pass |
|