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 from time import time as gettime |
|
27 import numpy |
27 |
28 |
28 import wx |
29 import wx |
29 |
30 |
30 from graphics import DebugViewer, REFRESH_PERIOD |
31 from graphics import DebugViewer, REFRESH_PERIOD |
31 from targets.typemapping import LogLevelsCount, LogLevels |
32 from targets.typemapping import LogLevelsCount, LogLevels |
84 elif posy < thumb_rect.y: |
85 elif posy < thumb_rect.y: |
85 self.Parent.ScrollToLast() |
86 self.Parent.ScrollToLast() |
86 elif posy > thumb_rect.y + thumb_rect.height: |
87 elif posy > thumb_rect.y + thumb_rect.height: |
87 self.Parent.ScrollToFirst() |
88 self.Parent.ScrollToFirst() |
88 elif posy < width: |
89 elif posy < width: |
89 pass |
90 self.Parent.ScrollMessagePanelByTimestamp(1) |
90 elif posy > height - width: |
91 elif posy > height - width: |
91 pass |
92 self.Parent.ScrollMessagePanelByTimestamp(-1) |
92 event.Skip() |
93 event.Skip() |
93 |
94 |
94 def OnLeftUp(self, event): |
95 def OnLeftUp(self, event): |
95 self.ThumbScrollingStartPos = None |
96 self.ThumbScrollingStartPos = None |
96 self.RefreshThumbPosition(0.) |
97 self.RefreshThumbPosition(0.) |
159 |
160 |
160 def __init__(self, tv_sec, tv_nsec, level, level_bitmap, msg): |
161 def __init__(self, tv_sec, tv_nsec, level, level_bitmap, msg): |
161 self.Date = datetime.fromtimestamp(tv_sec) |
162 self.Date = datetime.fromtimestamp(tv_sec) |
162 self.Seconds = self.Date.second + tv_nsec * 1e-9 |
163 self.Seconds = self.Date.second + tv_nsec * 1e-9 |
163 self.Date = self.Date.replace(second=0) |
164 self.Date = self.Date.replace(second=0) |
|
165 self.Timestamp = tv_sec + tv_nsec * 1e-9 |
164 self.Level = level |
166 self.Level = level |
165 self.LevelBitmap = level_bitmap |
167 self.LevelBitmap = level_bitmap |
166 self.Message = msg |
168 self.Message = msg |
167 self.DrawDate = True |
169 self.DrawDate = True |
168 |
170 |
287 |
288 |
288 def ResetLogMessages(self): |
289 def ResetLogMessages(self): |
289 self.previous_log_count = [None]*LogLevelsCount |
290 self.previous_log_count = [None]*LogLevelsCount |
290 self.OldestMessages = [] |
291 self.OldestMessages = [] |
291 self.LogMessages = [] |
292 self.LogMessages = [] |
|
293 self.LogMessagesTimestamp = numpy.array([]) |
292 self.CurrentMessage = None |
294 self.CurrentMessage = None |
293 self.HasNewData = False |
295 self.HasNewData = False |
294 |
296 |
295 def SetLogSource(self, log_source): |
297 def SetLogSource(self, log_source): |
296 self.LogSource = log_source |
298 self.LogSource = log_source |
332 if len(new_messages) > 0: |
334 if len(new_messages) > 0: |
333 self.HasNewData = True |
335 self.HasNewData = True |
334 old_length = len(self.LogMessages) |
336 old_length = len(self.LogMessages) |
335 for new_message in new_messages: |
337 for new_message in new_messages: |
336 self.LogMessages.append(new_message) |
338 self.LogMessages.append(new_message) |
|
339 self.LogMessagesTimestamp = numpy.append(self.LogMessagesTimestamp, [new_message.Timestamp]) |
337 if self.CurrentMessage is None or self.CurrentMessage == old_length - 1: |
340 if self.CurrentMessage is None or self.CurrentMessage == old_length - 1: |
338 self.CurrentMessage = len(self.LogMessages) - 1 |
341 self.CurrentMessage = len(self.LogMessages) - 1 |
339 self.NewDataAvailable(None) |
342 self.NewDataAvailable(None) |
340 |
343 |
341 def FilterLogMessage(self, message): |
344 def FilterLogMessage(self, message, timestamp=None): |
342 return message.Level in self.CurrentFilter and message.Message.find(self.CurrentSearchValue) != -1 |
345 return (message.Level in self.CurrentFilter and |
|
346 message.Message.find(self.CurrentSearchValue) != -1 and |
|
347 (timestamp is None or message.Timestamp < timestamp)) |
|
348 |
|
349 def GetMessageByTimestamp(self, timestamp): |
|
350 if self.CurrentMessage is not None: |
|
351 msgidx = numpy.argmin(abs(self.LogMessagesTimestamp - timestamp)) |
|
352 message = self.LogMessages[msgidx] |
|
353 if self.FilterLogMessage(message) and message.Timestamp > timestamp: |
|
354 return self.GetPreviousMessage(msgidx, timestamp) |
|
355 return message, msgidx |
|
356 return None, None |
343 |
357 |
344 def GetNextMessage(self, msgidx): |
358 def GetNextMessage(self, msgidx): |
345 while msgidx < len(self.LogMessages) - 1: |
359 while msgidx < len(self.LogMessages) - 1: |
346 message = self.LogMessages[msgidx + 1] |
360 message = self.LogMessages[msgidx + 1] |
347 if self.FilterLogMessage(message): |
361 if self.FilterLogMessage(message): |
348 return message, msgidx + 1 |
362 return message, msgidx + 1 |
349 msgidx += 1 |
363 msgidx += 1 |
350 return None, None |
364 return None, None |
351 |
365 |
352 def GetPreviousMessage(self, msgidx): |
366 def GetPreviousMessage(self, msgidx, timestamp=None): |
353 message = None |
367 message = None |
354 while 0 < msgidx < len(self.LogMessages): |
368 while 0 < msgidx < len(self.LogMessages): |
355 message = self.LogMessages[msgidx - 1] |
369 message = self.LogMessages[msgidx - 1] |
356 if self.FilterLogMessage(message): |
370 if self.FilterLogMessage(message, timestamp): |
357 return message, msgidx - 1 |
371 return message, msgidx - 1 |
358 msgidx -= 1 |
372 msgidx -= 1 |
359 if len(self.LogMessages) > 0: |
373 if len(self.LogMessages) > 0: |
360 message = self.LogMessages[0] |
374 message = self.LogMessages[0] |
361 while message is not None: |
375 while message is not None: |
373 for idx, msg in self.OldestMessages: |
387 for idx, msg in self.OldestMessages: |
374 if msg is not None and (message is None or msg > message): |
388 if msg is not None and (message is None or msg > message): |
375 message = msg |
389 message = msg |
376 if message is not None: |
390 if message is not None: |
377 self.LogMessages.insert(0, message) |
391 self.LogMessages.insert(0, message) |
|
392 self.LogMessagesTimestamp = numpy.insert(self.LogMessagesTimestamp, [0], [message.Timestamp]) |
378 if self.CurrentMessage is not None: |
393 if self.CurrentMessage is not None: |
379 self.CurrentMessage += 1 |
394 self.CurrentMessage += 1 |
380 else: |
395 else: |
381 self.CurrentMessage = 0 |
396 self.CurrentMessage = 0 |
382 if self.FilterLogMessage(message): |
397 if self.FilterLogMessage(message, timestamp): |
383 return message, 0 |
398 return message, 0 |
384 return None, None |
399 return None, None |
385 |
400 |
386 def RefreshNewData(self, *args, **kwargs): |
401 def RefreshNewData(self, *args, **kwargs): |
387 if self.HasNewData: |
402 if self.HasNewData: |
452 if message is not None: |
467 if message is not None: |
453 self.CurrentMessage = msgidx |
468 self.CurrentMessage = msgidx |
454 scroll += 1 |
469 scroll += 1 |
455 self.RefreshView() |
470 self.RefreshView() |
456 |
471 |
|
472 def ScrollMessagePanelByTimestamp(self, seconds): |
|
473 if self.CurrentMessage is not None: |
|
474 current_message = self.LogMessages[self.CurrentMessage] |
|
475 message, msgidx = self.GetMessageByTimestamp(current_message.Timestamp + seconds) |
|
476 if message is None or self.IsMessagePanelBottom(msgidx): |
|
477 self.ScrollToFirst() |
|
478 else: |
|
479 self.CurrentMessage = msgidx |
|
480 self.Refresh() |
|
481 |
457 def ResetMessagePanel(self): |
482 def ResetMessagePanel(self): |
458 if len(self.LogMessages) > 0: |
483 if len(self.LogMessages) > 0: |
459 self.CurrentMessage = len(self.LogMessages) - 1 |
484 self.CurrentMessage = len(self.LogMessages) - 1 |
460 message = self.LogMessages[self.CurrentMessage] |
485 message = self.LogMessages[self.CurrentMessage] |
461 while message is not None and not self.FilterLogMessage(message): |
486 while message is not None and not self.FilterLogMessage(message): |
483 self.ResetMessagePanel() |
508 self.ResetMessagePanel() |
484 event.Skip() |
509 event.Skip() |
485 |
510 |
486 def GenerateOnDurationButton(self, duration): |
511 def GenerateOnDurationButton(self, duration): |
487 def OnDurationButton(event): |
512 def OnDurationButton(event): |
|
513 self.ScrollMessagePanelByTimestamp(duration) |
488 event.Skip() |
514 event.Skip() |
489 return OnDurationButton |
515 return OnDurationButton |
490 |
516 |
491 def OnMessagePanelMouseWheel(self, event): |
517 def OnMessagePanelMouseWheel(self, event): |
492 self.ScrollMessagePanel(event.GetWheelRotation() / event.GetWheelDelta()) |
518 self.ScrollMessagePanel(event.GetWheelRotation() / event.GetWheelDelta()) |