20 # |
20 # |
21 #You should have received a copy of the GNU General Public |
21 #You should have received a copy of the GNU General Public |
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 import re |
25 import math |
26 import math |
26 import time |
27 import time |
27 from types import TupleType |
28 from types import TupleType |
28 from threading import Lock |
29 from threading import Lock |
29 |
30 |
167 "simultaneousDivergence": GetDivergenceCreationFunction(SIMULTANEOUS_DIVERGENCE), |
168 "simultaneousDivergence": GetDivergenceCreationFunction(SIMULTANEOUS_DIVERGENCE), |
168 "simultaneousConvergence": GetDivergenceCreationFunction(SIMULTANEOUS_CONVERGENCE), |
169 "simultaneousConvergence": GetDivergenceCreationFunction(SIMULTANEOUS_CONVERGENCE), |
169 "jump": jumpCreationFunction, |
170 "jump": jumpCreationFunction, |
170 "actionBlock": actionBlockCreationFunction, |
171 "actionBlock": actionBlockCreationFunction, |
171 } |
172 } |
|
173 |
|
174 def sort_blocks(block_infos1, block_infos2): |
|
175 x1, y1 = block_infos1[0].GetPosition() |
|
176 x2, y2 = block_infos2[0].GetPosition() |
|
177 if y1 == y2: |
|
178 return cmp(x1, x2) |
|
179 else: |
|
180 return cmp(y1, y2) |
172 |
181 |
173 #------------------------------------------------------------------------------- |
182 #------------------------------------------------------------------------------- |
174 # Graphic elements Viewer base class |
183 # Graphic elements Viewer base class |
175 #------------------------------------------------------------------------------- |
184 #------------------------------------------------------------------------------- |
176 |
185 |
555 self.PagePen = wx.TRANSPARENT_PEN |
564 self.PagePen = wx.TRANSPARENT_PEN |
556 self.DrawingWire = False |
565 self.DrawingWire = False |
557 self.current_id = 0 |
566 self.current_id = 0 |
558 self.TagName = tagname |
567 self.TagName = tagname |
559 self.Highlights = [] |
568 self.Highlights = [] |
|
569 self.SearchParams = None |
|
570 self.SearchResults = None |
|
571 self.CurrentFindHighlight = None |
560 self.InstancePath = instancepath |
572 self.InstancePath = instancepath |
561 self.StartMousePos = None |
573 self.StartMousePos = None |
562 self.StartScreenPos = None |
574 self.StartScreenPos = None |
563 self.Buffering = False |
575 self.Buffering = False |
564 |
576 |
1104 maxx = int(maxx * self.ViewScale[0]) |
1116 maxx = int(maxx * self.ViewScale[0]) |
1105 maxy = int(maxy * self.ViewScale[1]) |
1117 maxy = int(maxy * self.ViewScale[1]) |
1106 self.Editor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, |
1118 self.Editor.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, |
1107 round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr, |
1119 round(maxx / SCROLLBAR_UNIT) + width_incr, round(maxy / SCROLLBAR_UNIT) + height_incr, |
1108 xstart, ystart, True) |
1120 xstart, ystart, True) |
|
1121 |
|
1122 def EnsureVisible(self, block): |
|
1123 xstart, ystart = self.GetViewStart() |
|
1124 window_size = self.Editor.GetClientSize() |
|
1125 block_bbx = block.GetBoundingBox() |
|
1126 |
|
1127 screen_minx, screen_miny = xstart * SCROLLBAR_UNIT, ystart * SCROLLBAR_UNIT |
|
1128 screen_maxx, screen_maxy = screen_minx + window_size[0], screen_miny + window_size[1] |
|
1129 block_minx = int(block_bbx.x * self.ViewScale[0]) |
|
1130 block_miny = int(block_bbx.y * self.ViewScale[1]) |
|
1131 block_maxx = int(round((block_bbx.x + block_bbx.width) * self.ViewScale[0])) |
|
1132 block_maxy = int(round((block_bbx.y + block_bbx.height) * self.ViewScale[1])) |
|
1133 |
|
1134 xpos, ypos = xstart, ystart |
|
1135 if block_minx < screen_minx and block_maxx < screen_maxx: |
|
1136 xpos -= (screen_minx - block_minx) / SCROLLBAR_UNIT + 1 |
|
1137 elif block_maxx > screen_maxx and block_minx > screen_minx: |
|
1138 xpos += (block_maxx - screen_maxx) / SCROLLBAR_UNIT + 1 |
|
1139 if block_miny < screen_miny and block_maxy < screen_maxy: |
|
1140 ypos -= (screen_miny - block_miny) / SCROLLBAR_UNIT + 1 |
|
1141 elif block_maxy > screen_maxy and block_miny > screen_miny: |
|
1142 ypos += (block_maxy - screen_maxy) / SCROLLBAR_UNIT + 1 |
|
1143 self.Scroll(xpos, ypos) |
1109 |
1144 |
1110 def SelectInGroup(self, element): |
1145 def SelectInGroup(self, element): |
1111 element.SetSelected(True) |
1146 element.SetSelected(True) |
1112 if self.SelectedElement is None: |
1147 if self.SelectedElement is None: |
1113 self.SelectedElement = element |
1148 self.SelectedElement = element |
3000 self.RefreshJumpModel(block) |
3035 self.RefreshJumpModel(block) |
3001 elif isinstance(block, SFC_ActionBlock): |
3036 elif isinstance(block, SFC_ActionBlock): |
3002 self.Controler.AddEditedElementActionBlock(self.TagName, block.GetId()) |
3037 self.Controler.AddEditedElementActionBlock(self.TagName, block.GetId()) |
3003 self.RefreshActionBlockModel(block) |
3038 self.RefreshActionBlockModel(block) |
3004 |
3039 |
3005 |
3040 #------------------------------------------------------------------------------- |
|
3041 # Find and Replace functions |
|
3042 #------------------------------------------------------------------------------- |
|
3043 |
|
3044 def Find(self, direction, search_params): |
|
3045 if self.SearchParams != search_params: |
|
3046 self.ClearHighlights(SEARCH_RESULT_HIGHLIGHT) |
|
3047 |
|
3048 self.SearchParams = search_params |
|
3049 criteria = { |
|
3050 "raw_pattern": search_params["find_pattern"], |
|
3051 "pattern": re.compile(search_params["find_pattern"]), |
|
3052 "case_sensitive": search_params["case_sensitive"], |
|
3053 "regular_expression": search_params["regular_expression"], |
|
3054 "filter": "all"} |
|
3055 |
|
3056 self.SearchResults = [] |
|
3057 blocks = [] |
|
3058 for infos, start, end, text in self.Controler.SearchInPou(self.TagName, criteria, self.Debug): |
|
3059 if infos[1] in ["var_local", "var_input", "var_output", "var_inout"]: |
|
3060 self.SearchResults.append((infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT)) |
|
3061 else: |
|
3062 block = self.Blocks.get(infos[2]) |
|
3063 if block is not None: |
|
3064 blocks.append((block, (infos[1:], start, end, SEARCH_RESULT_HIGHLIGHT))) |
|
3065 blocks.sort(sort_blocks) |
|
3066 self.SearchResults.extend([infos for block, infos in blocks]) |
|
3067 |
|
3068 if len(self.SearchResults) > 0: |
|
3069 if self.CurrentFindHighlight is not None: |
|
3070 old_idx = self.SearchResults.index(self.CurrentFindHighlight) |
|
3071 if self.SearchParams["wrap"]: |
|
3072 idx = (old_idx + direction) % len(self.SearchResults) |
|
3073 else: |
|
3074 idx = max(0, min(old_idx + direction, len(self.SearchResults) - 1)) |
|
3075 if idx != old_idx: |
|
3076 self.RemoveHighlight(*self.CurrentFindHighlight) |
|
3077 self.CurrentFindHighlight = self.SearchResults[idx] |
|
3078 self.AddHighlight(*self.CurrentFindHighlight) |
|
3079 else: |
|
3080 self.CurrentFindHighlight = self.SearchResults[0] |
|
3081 self.AddHighlight(*self.CurrentFindHighlight) |
|
3082 |
|
3083 else: |
|
3084 if self.CurrentFindHighlight is not None: |
|
3085 self.RemoveHighlight(*self.CurrentFindHighlight) |
|
3086 self.CurrentFindHighlight = None |
|
3087 |
3006 #------------------------------------------------------------------------------- |
3088 #------------------------------------------------------------------------------- |
3007 # Highlights showing functions |
3089 # Highlights showing functions |
3008 #------------------------------------------------------------------------------- |
3090 #------------------------------------------------------------------------------- |
3009 |
3091 |
3010 def OnRefreshHighlightsTimer(self, event): |
3092 def OnRefreshHighlightsTimer(self, event): |
3022 |
3104 |
3023 def AddHighlight(self, infos, start, end, highlight_type): |
3105 def AddHighlight(self, infos, start, end, highlight_type): |
3024 EditorPanel.AddHighlight(self, infos, start, end, highlight_type) |
3106 EditorPanel.AddHighlight(self, infos, start, end, highlight_type) |
3025 |
3107 |
3026 self.Highlights.append((infos, start, end, highlight_type)) |
3108 self.Highlights.append((infos, start, end, highlight_type)) |
3027 self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True) |
3109 if infos[0] not in ["var_local", "var_input", "var_output", "var_inout"]: |
3028 |
3110 block = self.Blocks.get(infos[1]) |
|
3111 if block is not None: |
|
3112 self.EnsureVisible(block) |
|
3113 self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True) |
|
3114 |
|
3115 def RemoveHighlight(self, infos, start, end, highlight_type): |
|
3116 EditorPanel.RemoveHighlight(self, infos, start, end, highlight_type) |
|
3117 |
|
3118 if (infos, start, end, highlight_type) in self.Highlights: |
|
3119 self.Highlights.remove((infos, start, end, highlight_type)) |
|
3120 self.RefreshHighlightsTimer.Start(int(REFRESH_HIGHLIGHT_PERIOD * 1000), oneShot=True) |
|
3121 |
3029 def ShowHighlights(self): |
3122 def ShowHighlights(self): |
3030 for infos, start, end, highlight_type in self.Highlights: |
3123 for infos, start, end, highlight_type in self.Highlights: |
3031 if infos[0] in ["comment", "io_variable", "block", "connector", "coil", "contact", "step", "transition", "jump", "action_block"]: |
3124 if infos[0] in ["comment", "io_variable", "block", "connector", "coil", "contact", "step", "transition", "jump", "action_block"]: |
3032 block = self.FindElementById(infos[1]) |
3125 block = self.FindElementById(infos[1]) |
3033 if block is not None: |
3126 if block is not None: |