TextViewer.py
changeset 566 6014ef82a98a
parent 549 b0d6819119c3
child 582 aa41547baa2a
--- a/TextViewer.py	Fri Sep 30 17:16:02 2011 +0200
+++ b/TextViewer.py	Sun Oct 09 19:51:14 2011 +0200
@@ -28,6 +28,8 @@
 
 import re
 
+from graphics.GraphicCommons import ERROR_HIGHLIGHT, SEARCH_RESULT_HIGHLIGHT, REFRESH_HIGHLIGHT_PERIOD
+
 #-------------------------------------------------------------------------------
 #                         Textual programs Viewer class
 #-------------------------------------------------------------------------------
@@ -42,7 +44,7 @@
 
 [STC_PLC_WORD, STC_PLC_COMMENT, STC_PLC_NUMBER, STC_PLC_STRING, 
  STC_PLC_VARIABLE, STC_PLC_PARAMETER, STC_PLC_FUNCTION, STC_PLC_JUMP, 
- STC_PLC_ERROR] = range(9)
+ STC_PLC_ERROR, STC_PLC_SEARCH_RESULT] = range(10)
 [SPACE, WORD, NUMBER, STRING, WSTRING, COMMENT] = range(6)
 
 [ID_TEXTVIEWER,
@@ -70,6 +72,11 @@
 LABEL_MODEL = re.compile("[ \t\n]%(identifier)s:[ \t\n]"%re_texts)
 EXTENSIBLE_PARAMETER = re.compile("IN[1-9][0-9]*$")
 
+HIGHLIGHT_TYPES = {
+    ERROR_HIGHLIGHT: STC_PLC_ERROR,
+    SEARCH_RESULT_HIGHLIGHT: STC_PLC_SEARCH_RESULT,
+}
+
 def GetCursorPos(old, new):
     old_length = len(old)
     new_length = len(new)
@@ -128,6 +135,7 @@
         self.StyleSetSpec(STC_PLC_STRING, "fore:#007F00,size:%(size)d" % faces)
         self.StyleSetSpec(STC_PLC_JUMP, "fore:#FF7FFF,size:%(size)d" % faces)
         self.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
+        self.StyleSetSpec(STC_PLC_SEARCH_RESULT, "fore:#FFFFFF,back:#FFA500,size:%(size)d" % faces)
         
         # Indicators styles
         self.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE)
@@ -154,7 +162,7 @@
         self.TextSyntax = "ST"
         self.CurrentAction = None
         self.TagName = tagname
-        self.Errors = []
+        self.Highlights = []
         self.Debug = debug
         self.InstancePath = instancepath
         self.ContextStack = []
@@ -163,6 +171,9 @@
         self.ParentWindow = window
         self.Controler = controler
 
+        self.RefreshHighlightsTimer = wx.Timer(self, -1)
+        self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer)
+
         self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|
                              wx.stc.STC_MOD_BEFOREDELETE|
                              wx.stc.STC_PERFORMED_USER)
@@ -174,6 +185,9 @@
             self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
             self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_TEXTVIEWER)
     
+    def __del__(self):
+        self.RefreshHighlightsTimer.Stop()
+    
     def SetTagName(self, tagname):
         self.TagName = tagname
         
@@ -568,7 +582,7 @@
                 self.SetStyling(current_pos - last_styled_pos, 31)
         else:
             self.SetStyling(current_pos - start_pos, 31)
-        self.ShowErrors(start_pos, end_pos)
+        self.ShowHighlights(start_pos, end_pos)
         event.Skip()
     
     def Cut(self):
@@ -637,27 +651,39 @@
         event.Skip()
 
 #-------------------------------------------------------------------------------
-#                        Errors showing functions
+#                        Highlights showing functions
 #-------------------------------------------------------------------------------
 
-    def ClearErrors(self):
-        self.Errors = []
+    def OnRefreshHighlightsTimer(self, event):
         self.RefreshView()
-
-    def AddShownError(self, infos, start, end):
-        if infos[0] == "body":
-            self.Errors.append((infos[1], start, end))
-
-    def ShowErrors(self, start_pos, end_pos):
-        for indent, start, end in self.Errors:
+        event.Skip()
+
+    def ClearHighlights(self, highlight_type=None):
+        if highlight_type is None:
+            self.Highlights = []
+        else:
+            highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
+            if highlight_type is not None:
+                self.Highlights = [(infos, start, end, highlight) for (infos, start, end, highlight) in self.Highlights if highlight != highlight_type]
+        self.RefreshView()
+
+    def AddHighlight(self, infos, start, end, highlight_type):
+        highlight_type = HIGHLIGHT_TYPES.get(highlight_type, None)
+        if infos[0] == "body" and highlight_type is not None:
+            self.Highlights.append((infos[1], start, end, highlight_type))
+            self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
+
+    def ShowHighlights(self, start_pos, end_pos):
+        for indent, start, end, highlight_type in self.Highlights:
             if start[0] == 0:
-                error_start_pos = start[1] - indent
-            else:
-                error_start_pos = self.GetLineEndPosition(start[0] - 1) + start[1] - indent + 1
+                highlight_start_pos = start[1] - indent
+            else:
+                highlight_start_pos = self.GetLineEndPosition(start[0] - 1) + start[1] - indent + 1
             if end[0] == 0:
-                error_end_pos = end[1] - indent + 1
-            else:
-                error_end_pos = self.GetLineEndPosition(end[0] - 1) + end[1] - indent + 2
-            if start_pos <= error_start_pos <= end_pos or start_pos <= error_end_pos <= end_pos:
-                self.StartStyling(error_start_pos, 0xff)
-                self.SetStyling(error_end_pos - error_start_pos, STC_PLC_ERROR)
+                highlight_end_pos = end[1] - indent + 1
+            else:
+                highlight_end_pos = self.GetLineEndPosition(end[0] - 1) + end[1] - indent + 2
+            if highlight_start_pos < end_pos and highlight_end_pos > start_pos:
+                self.StartStyling(highlight_start_pos, 0xff)
+                self.SetStyling(highlight_end_pos - highlight_start_pos, highlight_type)
+