controls/LogViewer.py
changeset 986 b663f099da8a
parent 984 2d03056993f6
child 987 7ca88194ae89
equal deleted inserted replaced
985:cd8dadcef426 986:b663f099da8a
    32 from targets.typemapping import LogLevelsCount, LogLevels
    32 from targets.typemapping import LogLevelsCount, LogLevels
    33 from util.BitmapLibrary import GetBitmap
    33 from util.BitmapLibrary import GetBitmap
    34 
    34 
    35 THUMB_SIZE_RATIO = 1. / 8.
    35 THUMB_SIZE_RATIO = 1. / 8.
    36 
    36 
       
    37 def ArrowPoints(direction, width, height, offset):
       
    38     if direction == wx.TOP:
       
    39         return [wx.Point(1, offset + height - 2),
       
    40                 wx.Point(width / 2, offset + 1),
       
    41                 wx.Point(width - 1, offset + height - 2)]
       
    42     else:
       
    43         return [wx.Point(1, offset - height + 1),
       
    44                 wx.Point(width / 2, offset - 2),
       
    45                 wx.Point(width - 1, offset - height + 1)]
       
    46 
    37 class LogScrollBar(wx.Panel):
    47 class LogScrollBar(wx.Panel):
    38     
    48     
    39     def __init__(self, parent, size):
    49     def __init__(self, parent, size):
    40         wx.Panel.__init__(self, parent, size=size)
    50         wx.Panel.__init__(self, parent, size=size)
    41         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
    51         self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
    85             elif posy < thumb_rect.y:
    95             elif posy < thumb_rect.y:
    86                 self.Parent.ScrollToLast()
    96                 self.Parent.ScrollToLast()
    87             elif posy > thumb_rect.y + thumb_rect.height:
    97             elif posy > thumb_rect.y + thumb_rect.height:
    88                 self.Parent.ScrollToFirst()
    98                 self.Parent.ScrollToFirst()
    89         elif posy < width:
    99         elif posy < width:
    90             self.Parent.ScrollMessagePanelByTimestamp(1)
   100             self.Parent.ScrollMessagePanelByPage(1)
    91         elif posy > height - width:
   101         elif posy > height - width:
    92             self.Parent.ScrollMessagePanelByTimestamp(-1)
   102             self.Parent.ScrollMessagePanelByPage(-1)
    93         event.Skip()
   103         event.Skip()
    94         
   104         
    95     def OnLeftUp(self, event):
   105     def OnLeftUp(self, event):
    96         self.ThumbScrollingStartPos = None
   106         self.ThumbScrollingStartPos = None
    97         self.RefreshThumbPosition(0.)
   107         self.RefreshThumbPosition(0.)
   118         dc = wx.BufferedPaintDC(self)
   128         dc = wx.BufferedPaintDC(self)
   119         dc.Clear()
   129         dc.Clear()
   120         dc.BeginDrawing()
   130         dc.BeginDrawing()
   121         
   131         
   122         width, height = self.GetClientSize()
   132         width, height = self.GetClientSize()
       
   133         
       
   134         dc.SetPen(wx.Pen(wx.NamedColour("GREY"), 2))
       
   135         dc.SetBrush(wx.GREY_BRUSH)
       
   136         
       
   137         dc.DrawLines(ArrowPoints(wx.TOP, width, width * 0.75, 2 * width))
       
   138         dc.DrawLines(ArrowPoints(wx.TOP, width, width * 0.75, 2 * width + 6))
       
   139         
       
   140         dc.DrawLines(ArrowPoints(wx.BOTTOM, width, width * 0.75, height - 2 * width))
       
   141         dc.DrawLines(ArrowPoints(wx.BOTTOM, width, width * 0.75, height - 2 * width - 6))
   123         
   142         
   124         thumb_rect = self.GetThumbRect()
   143         thumb_rect = self.GetThumbRect()
   125         exclusion_rect = wx.Rect(thumb_rect.x, thumb_rect.y,
   144         exclusion_rect = wx.Rect(thumb_rect.x, thumb_rect.y,
   126                                  thumb_rect.width, thumb_rect.height)
   145                                  thumb_rect.width, thumb_rect.height)
   127         if self.Parent.IsMessagePanelTop():
   146         if self.Parent.IsMessagePanelTop():
   137                              exclusion_rect.width, exclusion_rect.height)
   156                              exclusion_rect.width, exclusion_rect.height)
   138         
   157         
   139         dc.SetPen(wx.GREY_PEN)
   158         dc.SetPen(wx.GREY_PEN)
   140         dc.SetBrush(wx.GREY_BRUSH)
   159         dc.SetBrush(wx.GREY_BRUSH)
   141         
   160         
   142         dc.DrawPolygon([wx.Point(width / 2, 1),
   161         dc.DrawPolygon(ArrowPoints(wx.TOP, width, width, 0))
   143                         wx.Point(1, width - 2),
   162         
   144                         wx.Point(width - 1, width - 2)])
   163         dc.DrawPolygon(ArrowPoints(wx.BOTTOM, width, width, height))
   145         
       
   146         dc.DrawPolygon([wx.Point(width / 2, height - 1),
       
   147                         wx.Point(2, height - width + 1),
       
   148                         wx.Point(width - 1, height - width + 1)])
       
   149             
   164             
   150         dc.DrawRectangle(thumb_rect.x, thumb_rect.y, 
   165         dc.DrawRectangle(thumb_rect.x, thumb_rect.y, 
   151                          thumb_rect.width, thumb_rect.height)
   166                          thumb_rect.width, thumb_rect.height)
   152         
   167         
   153         dc.EndDrawing()
   168         dc.EndDrawing()
   249 HOUR = 60 * MINUTE
   264 HOUR = 60 * MINUTE
   250 DAY = 24 * HOUR
   265 DAY = 24 * HOUR
   251 
   266 
   252 CHANGE_TIMESTAMP_BUTTONS = [(_("1d"), DAY),
   267 CHANGE_TIMESTAMP_BUTTONS = [(_("1d"), DAY),
   253                             (_("1h"), HOUR),
   268                             (_("1h"), HOUR),
   254                             (_("1m"), MINUTE)]
   269                             (_("1m"), MINUTE),
       
   270                             (_("1s"), SECOND)]
   255 
   271 
   256 class LogViewer(DebugViewer, wx.Panel):
   272 class LogViewer(DebugViewer, wx.Panel):
   257     
   273     
   258     def __init__(self, parent, window):
   274     def __init__(self, parent, window):
   259         wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
   275         wx.Panel.__init__(self, parent, style=wx.TAB_TRAVERSAL|wx.SUNKEN_BORDER)
   294         if wx.Platform == '__WXMSW__':
   310         if wx.Platform == '__WXMSW__':
   295             self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New')
   311             self.Font = wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier New')
   296         else:
   312         else:
   297             self.Font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier')
   313             self.Font = wx.Font(12, wx.SWISS, wx.NORMAL, wx.NORMAL, faceName='Courier')
   298         self.MessagePanel.Bind(wx.EVT_LEFT_UP, self.OnMessagePanelLeftUp)
   314         self.MessagePanel.Bind(wx.EVT_LEFT_UP, self.OnMessagePanelLeftUp)
       
   315         self.MessagePanel.Bind(wx.EVT_LEFT_DCLICK, self.OnMessagePanelLeftDCLick)
   299         self.MessagePanel.Bind(wx.EVT_MOUSEWHEEL, self.OnMessagePanelMouseWheel)
   316         self.MessagePanel.Bind(wx.EVT_MOUSEWHEEL, self.OnMessagePanelMouseWheel)
   300         self.MessagePanel.Bind(wx.EVT_PAINT, self.OnMessagePanelPaint)
   317         self.MessagePanel.Bind(wx.EVT_PAINT, self.OnMessagePanelPaint)
   301         self.MessagePanel.Bind(wx.EVT_SIZE, self.OnMessagePanelResize)
   318         self.MessagePanel.Bind(wx.EVT_SIZE, self.OnMessagePanelResize)
   302         message_panel_sizer.AddWindow(self.MessagePanel, flag=wx.GROW)
   319         message_panel_sizer.AddWindow(self.MessagePanel, flag=wx.GROW)
   303         
   320         
   520                 if message is not None:
   537                 if message is not None:
   521                     self.CurrentMessage = msgidx
   538                     self.CurrentMessage = msgidx
   522                     scroll += 1
   539                     scroll += 1
   523             self.RefreshView()
   540             self.RefreshView()
   524     
   541     
       
   542     def ScrollMessagePanelByPage(self, page):
       
   543         if self.CurrentMessage is not None:
       
   544             width, height = self.MessagePanel.GetClientSize()
       
   545             message_per_page = max(1, (height - DATE_INFO_SIZE) / MESSAGE_INFO_SIZE - 1)
       
   546             self.ScrollMessagePanel(page * message_per_page)
       
   547     
   525     def ScrollMessagePanelByTimestamp(self, seconds):
   548     def ScrollMessagePanelByTimestamp(self, seconds):
   526         if self.CurrentMessage is not None:
   549         if self.CurrentMessage is not None:
   527             current_message = self.LogMessages[self.CurrentMessage]
   550             current_message = self.LogMessages[self.CurrentMessage]
   528             message, msgidx = self.GetMessageByTimestamp(current_message.Timestamp + seconds)
   551             message, msgidx = self.GetMessageByTimestamp(current_message.Timestamp + seconds)
   529             if message is None or self.IsMessagePanelBottom(msgidx):
   552             if message is None or self.IsMessagePanelBottom(msgidx):
   571             posx, posy = event.GetPosition()
   594             posx, posy = event.GetPosition()
   572             for button in self.LeftButtons + self.RightButtons:
   595             for button in self.LeftButtons + self.RightButtons:
   573                 if button.HitTest(posx, posy):
   596                 if button.HitTest(posx, posy):
   574                     button.ProcessCallback()
   597                     button.ProcessCallback()
   575                     break
   598                     break
       
   599         event.Skip()
       
   600     
       
   601     def OnMessagePanelLeftDCLick(self, event):
       
   602         if self.CurrentMessage is not None:
       
   603             posx, posy = event.GetPosition()
       
   604             width, height = self.MessagePanel.GetClientSize()
       
   605             message_idx = self.CurrentMessage
       
   606             message = self.LogMessages[message_idx]
       
   607             draw_date = True
       
   608             offset = 5
       
   609             
       
   610             while offset < height and message is not None:
       
   611                 if draw_date:
       
   612                     offset += DATE_INFO_SIZE
       
   613 
       
   614                 if offset <= posy < offset + MESSAGE_INFO_SIZE:
       
   615                     self.CurrentSearchValue = message.Message
       
   616                     self.SearchMessage.SetValue(message.Message)
       
   617                     self.ResetMessagePanel()
       
   618                     break
       
   619                 
       
   620                 offset += MESSAGE_INFO_SIZE
       
   621                 
       
   622                 previous_message, message_idx = self.GetPreviousMessage(message_idx)
       
   623                 if previous_message is not None:
       
   624                     draw_date = message.Date != previous_message.Date
       
   625                 message = previous_message
   576         event.Skip()
   626         event.Skip()
   577     
   627     
   578     def OnMessagePanelMouseWheel(self, event):
   628     def OnMessagePanelMouseWheel(self, event):
   579         self.ScrollMessagePanel(event.GetWheelRotation() / event.GetWheelDelta())
   629         self.ScrollMessagePanel(event.GetWheelRotation() / event.GetWheelDelta())
   580         event.Skip()
   630         event.Skip()