TextViewer.py
changeset 566 6014ef82a98a
parent 549 b0d6819119c3
child 582 aa41547baa2a
equal deleted inserted replaced
565:94c11207aa6f 566:6014ef82a98a
    26 import wx.stc
    26 import wx.stc
    27 from types import *
    27 from types import *
    28 
    28 
    29 import re
    29 import re
    30 
    30 
       
    31 from graphics.GraphicCommons import ERROR_HIGHLIGHT, SEARCH_RESULT_HIGHLIGHT, REFRESH_HIGHLIGHT_PERIOD
       
    32 
    31 #-------------------------------------------------------------------------------
    33 #-------------------------------------------------------------------------------
    32 #                         Textual programs Viewer class
    34 #                         Textual programs Viewer class
    33 #-------------------------------------------------------------------------------
    35 #-------------------------------------------------------------------------------
    34 
    36 
    35 
    37 
    40     LETTERS.append(chr(ord('a') + i))
    42     LETTERS.append(chr(ord('a') + i))
    41     LETTERS.append(chr(ord('A') + i))
    43     LETTERS.append(chr(ord('A') + i))
    42 
    44 
    43 [STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_STRING, 
    45 [STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_STRING, 
    44  STC_PLC_VARIABLE, STC_PLC_PARAMETER, STC_PLC_FUNCTION, STC_PLC_JUMP, 
    46  STC_PLC_VARIABLE, STC_PLC_PARAMETER, STC_PLC_FUNCTION, STC_PLC_JUMP, 
    45  STC_PLC_ERROR] = range(9)
    47  STC_PLC_ERROR, STC_PLC_SEARCH_RESULT] = range(10)
    46 [SPACE, WORD, NUMBER, STRING, WSTRING, COMMENT] = range(6)
    48 [SPACE, WORD, NUMBER, STRING, WSTRING, COMMENT] = range(6)
    47 
    49 
    48 [ID_TEXTVIEWER,
    50 [ID_TEXTVIEWER,
    49 ] = [wx.NewId() for _init_ctrls in range(1)]
    51 ] = [wx.NewId() for _init_ctrls in range(1)]
    50 
    52 
    68 re_texts["identifier"] = "((?:%(letter)s|(?:_(?:%(letter)s|%(digit)s)))(?:_?(?:%(letter)s|%(digit)s))*)"%re_texts
    70 re_texts["identifier"] = "((?:%(letter)s|(?:_(?:%(letter)s|%(digit)s)))(?:_?(?:%(letter)s|%(digit)s))*)"%re_texts
    69 IDENTIFIER_MODEL = re.compile(re_texts["identifier"])
    71 IDENTIFIER_MODEL = re.compile(re_texts["identifier"])
    70 LABEL_MODEL = re.compile("[ \t\n]%(identifier)s:[ \t\n]"%re_texts)
    72 LABEL_MODEL = re.compile("[ \t\n]%(identifier)s:[ \t\n]"%re_texts)
    71 EXTENSIBLE_PARAMETER = re.compile("IN[1-9][0-9]*$")
    73 EXTENSIBLE_PARAMETER = re.compile("IN[1-9][0-9]*$")
    72 
    74 
       
    75 HIGHLIGHT_TYPES = {
       
    76     ERROR_HIGHLIGHT: STC_PLC_ERROR,
       
    77     SEARCH_RESULT_HIGHLIGHT: STC_PLC_SEARCH_RESULT,
       
    78 }
       
    79 
    73 def GetCursorPos(old, new):
    80 def GetCursorPos(old, new):
    74     old_length = len(old)
    81     old_length = len(old)
    75     new_length = len(new)
    82     new_length = len(new)
    76     common_length = min(old_length, new_length)
    83     common_length = min(old_length, new_length)
    77     i = 0
    84     i = 0
   126         self.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces)
   133         self.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces)
   127         self.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
   134         self.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
   128         self.StyleSetSpec(STC_PLC_STRING, "fore:#007F00,size:%(size)d" % faces)
   135         self.StyleSetSpec(STC_PLC_STRING, "fore:#007F00,size:%(size)d" % faces)
   129         self.StyleSetSpec(STC_PLC_JUMP, "fore:#FF7FFF,size:%(size)d" % faces)
   136         self.StyleSetSpec(STC_PLC_JUMP, "fore:#FF7FFF,size:%(size)d" % faces)
   130         self.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
   137         self.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
       
   138         self.StyleSetSpec(STC_PLC_SEARCH_RESULT, "fore:#FFFFFF,back:#FFA500,size:%(size)d" % faces)
   131         
   139         
   132         # Indicators styles
   140         # Indicators styles
   133         self.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE)
   141         self.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE)
   134         if window and controler:
   142         if window and controler:
   135             self.IndicatorSetForeground(0, wx.RED)
   143             self.IndicatorSetForeground(0, wx.RED)
   152         self.EnumeratedValues = []
   160         self.EnumeratedValues = []
   153         self.DisableEvents = True
   161         self.DisableEvents = True
   154         self.TextSyntax = "ST"
   162         self.TextSyntax = "ST"
   155         self.CurrentAction = None
   163         self.CurrentAction = None
   156         self.TagName = tagname
   164         self.TagName = tagname
   157         self.Errors = []
   165         self.Highlights = []
   158         self.Debug = debug
   166         self.Debug = debug
   159         self.InstancePath = instancepath
   167         self.InstancePath = instancepath
   160         self.ContextStack = []
   168         self.ContextStack = []
   161         self.CallStack = []
   169         self.CallStack = []
   162         
   170         
   163         self.ParentWindow = window
   171         self.ParentWindow = window
   164         self.Controler = controler
   172         self.Controler = controler
       
   173 
       
   174         self.RefreshHighlightsTimer = wx.Timer(self, -1)
       
   175         self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
   165 
   176 
   166         self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|
   177         self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|
   167                              wx.stc.STC_MOD_BEFOREDELETE|
   178                              wx.stc.STC_MOD_BEFOREDELETE|
   168                              wx.stc.STC_PERFORMED_USER)
   179                              wx.stc.STC_PERFORMED_USER)
   169 
   180 
   171         if controler:
   182         if controler:
   172             self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
   183             self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
   173             self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWER)
   184             self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWER)
   174             self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
   185             self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
   175             self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_TEXTVIEWER)
   186             self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_TEXTVIEWER)
       
   187     
       
   188     def __del__(self):
       
   189         self.RefreshHighlightsTimer.Stop()
   176     
   190     
   177     def SetTagName(self, tagname):
   191     def SetTagName(self, tagname):
   178         self.TagName = tagname
   192         self.TagName = tagname
   179         
   193         
   180     def GetTagName(self):
   194     def GetTagName(self):
   566                 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER)
   580                 self.SetStyling(current_pos - last_styled_pos, STC_PLC_NUMBER)
   567             else:
   581             else:
   568                 self.SetStyling(current_pos - last_styled_pos, 31)
   582                 self.SetStyling(current_pos - last_styled_pos, 31)
   569         else:
   583         else:
   570             self.SetStyling(current_pos - start_pos, 31)
   584             self.SetStyling(current_pos - start_pos, 31)
   571         self.ShowErrors(start_pos, end_pos)
   585         self.ShowHighlights(start_pos, end_pos)
   572         event.Skip()
   586         event.Skip()
   573     
   587     
   574     def Cut(self):
   588     def Cut(self):
   575         self.ResetBuffer()
   589         self.ResetBuffer()
   576         self.CmdKeyExecute(wx.stc.STC_CMD_CUT)
   590         self.CmdKeyExecute(wx.stc.STC_CMD_CUT)
   635     def OnKillFocus(self, event):
   649     def OnKillFocus(self, event):
   636         self.AutoCompCancel()
   650         self.AutoCompCancel()
   637         event.Skip()
   651         event.Skip()
   638 
   652 
   639 #-------------------------------------------------------------------------------
   653 #-------------------------------------------------------------------------------
   640 #                        Errors showing functions
   654 #                        Highlights showing functions
   641 #-------------------------------------------------------------------------------
   655 #-------------------------------------------------------------------------------
   642 
   656 
   643     def ClearErrors(self):
   657     def OnRefreshHighlightsTimer(self, event):
   644         self.Errors = []
       
   645         self.RefreshView()
   658         self.RefreshView()
   646 
   659         event.Skip()
   647     def AddShownError(self, infos, start, end):
   660 
   648         if infos[0] == "body":
   661     def ClearHighlights(self, highlight_type=None):
   649             self.Errors.append((infos[1], start, end))
   662         if highlight_type is None:
   650 
   663             self.Highlights = []
   651     def ShowErrors(self, start_pos, end_pos):
   664         else:
   652         for indent, start, end in self.Errors:
   665             highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
       
   666             if highlight_type is not None:
       
   667                 self.Highlights = [(infos, start, end, highlight) for (infos, start, end, highlight) in self.Highlights if highlight != highlight_type]
       
   668         self.RefreshView()
       
   669 
       
   670     def AddHighlight(self, infos, start, end, highlight_type):
       
   671         highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
       
   672         if infos[0] == "body" and highlight_type is not None:
       
   673             self.Highlights.append((infos[1], start, end, highlight_type))
       
   674             self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
       
   675 
       
   676     def ShowHighlights(self, start_pos, end_pos):
       
   677         for indent, start, end, highlight_type in self.Highlights:
   653             if start[0] == 0:
   678             if start[0] == 0:
   654                 error_start_pos = start[1] - indent
   679                 highlight_start_pos = start[1] - indent
   655             else:
   680             else:
   656                 error_start_pos = self.GetLineEndPosition(start[0] - 1) + start[1] - indent + 1
   681                 highlight_start_pos = self.GetLineEndPosition(start[0] - 1) + start[1] - indent + 1
   657             if end[0] == 0:
   682             if end[0] == 0:
   658                 error_end_pos = end[1] - indent + 1
   683                 highlight_end_pos = end[1] - indent + 1
   659             else:
   684             else:
   660                 error_end_pos = self.GetLineEndPosition(end[0] - 1) + end[1] - indent + 2
   685                 highlight_end_pos = self.GetLineEndPosition(end[0] - 1) + end[1] - indent + 2
   661             if start_pos <= error_start_pos <= end_pos or start_pos <= error_end_pos <= end_pos:
   686             if highlight_start_pos < end_pos and highlight_end_pos > start_pos:
   662                 self.StartStyling(error_start_pos, 0xff)
   687                 self.StartStyling(highlight_start_pos, 0xff)
   663                 self.SetStyling(error_end_pos - error_start_pos, STC_PLC_ERROR)
   688                 self.SetStyling(highlight_end_pos - highlight_start_pos, highlight_type)
       
   689