--- a/Viewer.py Wed Aug 01 12:44:51 2012 +0200
+++ b/Viewer.py Fri Aug 10 00:32:05 2012 +0200
@@ -22,6 +22,7 @@
#License along with this library; if not, write to the Free Software
#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+import re
import math
import time
from types import TupleType
@@ -170,6 +171,14 @@
"actionBlock": actionBlockCreationFunction,
}
+def sort_blocks(block_infos1, block_infos2):
+ x1, y1 = block_infos1[0].GetPosition()
+ x2, y2 = block_infos2[0].GetPosition()
+ if y1 == y2:
+ return cmp(x1, x2)
+ else:
+ return cmp(y1, y2)
+
#-------------------------------------------------------------------------------
# Graphic elements Viewer base class
#-------------------------------------------------------------------------------
@@ -557,6 +566,9 @@
self.current_id = 0
self.TagName = tagname
self.Highlights = []
+ self.SearchParams = None
+ self.SearchResults = None
+ self.CurrentFindHighlight = None
self.InstancePath = instancepath
self.StartMousePos = None
self.StartScreenPos = None
@@ -1107,6 +1119,29 @@
round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr,
xstart, ystart, True)
+ def EnsureVisible(self, block):
+ xstart, ystart = self.GetViewStart()
+ window_size = self.Editor.GetClientSize()
+ block_bbx = block.GetBoundingBox()
+
+ screen_minx, screen_miny = xstart * SCROLLBAR_UNIT, ystart * SCROLLBAR_UNIT
+ screen_maxx, screen_maxy = screen_minx + window_size[0], screen_miny + window_size[1]
+ block_minx = int(block_bbx.x * self.ViewScale[0])
+ block_miny = int(block_bbx.y * self.ViewScale[1])
+ block_maxx = int(round((block_bbx.x + block_bbx.width) * self.ViewScale[0]))
+ block_maxy = int(round((block_bbx.y + block_bbx.height) * self.ViewScale[1]))
+
+ xpos, ypos = xstart, ystart
+ if block_minx < screen_minx and block_maxx < screen_maxx:
+ xpos -= (screen_minx - block_minx) / SCROLLBAR_UNIT + 1
+ elif block_maxx > screen_maxx and block_minx > screen_minx:
+ xpos += (block_maxx - screen_maxx) / SCROLLBAR_UNIT + 1
+ if block_miny < screen_miny and block_maxy < screen_maxy:
+ ypos -= (screen_miny - block_miny) / SCROLLBAR_UNIT + 1
+ elif block_maxy > screen_maxy and block_miny > screen_miny:
+ ypos += (block_maxy - screen_maxy) / SCROLLBAR_UNIT + 1
+ self.Scroll(xpos, ypos)
+
def SelectInGroup(self, element):
element.SetSelected(True)
if self.SelectedElement is None:
@@ -3002,7 +3037,54 @@
self.Controler.AddEditedElementActionBlock(self.TagName, block.GetId())
self.RefreshActionBlockModel(block)
-
+#-------------------------------------------------------------------------------
+# Find and Replace functions
+#-------------------------------------------------------------------------------
+
+ def Find(self, direction, search_params):
+ if self.SearchParams != search_params:
+ self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT)
+
+ self.SearchParams = search_params
+ criteria = {
+ "raw_pattern": search_params["find_pattern"],
+ "pattern": re.compile(search_params["find_pattern"]),
+ "case_sensitive": search_params["case_sensitive"],
+ "regular_expression": search_params["regular_expression"],
+ "filter": "all"}
+
+ self.SearchResults = []
+ blocks = []
+ for infos, start, end, text in self.Controler.SearchInPou(self.TagName, criteria, self.Debug):
+ if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]:
+ self.SearchResults.append((infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT))
+ else:
+ block = self.Blocks.get(infos[2])
+ if block is not None:
+ blocks.append((block, (infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT)))
+ blocks.sort(sort_blocks)
+ self.SearchResults.extend([infos for block, infos in blocks])
+
+ if len(self.SearchResults) > 0:
+ if self.CurrentFindHighlight is not None:
+ old_idx = self.SearchResults.index(self.CurrentFindHighlight)
+ if self.SearchParams["wrap"]:
+ idx = (old_idx + direction) % len(self.SearchResults)
+ else:
+ idx = max(0, min(old_idx + direction, len(self.SearchResults) - 1))
+ if idx != old_idx:
+ self.RemoveHighlight(*self.CurrentFindHighlight)
+ self.CurrentFindHighlight = self.SearchResults[idx]
+ self.AddHighlight(*self.CurrentFindHighlight)
+ else:
+ self.CurrentFindHighlight = self.SearchResults[0]
+ self.AddHighlight(*self.CurrentFindHighlight)
+
+ else:
+ if self.CurrentFindHighlight is not None:
+ self.RemoveHighlight(*self.CurrentFindHighlight)
+ self.CurrentFindHighlight = None
+
#-------------------------------------------------------------------------------
# Highlights showing functions
#-------------------------------------------------------------------------------
@@ -3024,8 +3106,19 @@
EditorPanel.AddHighlight(self, infos, start, end, highlight_type)
self.Highlights.append((infos, start, end, highlight_type))
- self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
-
+ if infos[0] not in ["var_local", "var_input", "var_output", "var_inout"]:
+ block = self.Blocks.get(infos[1])
+ if block is not None:
+ self.EnsureVisible(block)
+ self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
+
+ def RemoveHighlight(self, infos, start, end, highlight_type):
+ EditorPanel.RemoveHighlight(self, infos, start, end, highlight_type)
+
+ if (infos, start, end, highlight_type) in self.Highlights:
+ self.Highlights.remove((infos, start, end, highlight_type))
+ self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True)
+
def ShowHighlights(self):
for infos, start, end, highlight_type in self.Highlights:
if infos[0] in ["comment", "io_variable", "block", "connector", "coil", "contact", "step", "transition", "jump", "action_block"]: