100 return None |
101 return None |
101 |
102 |
102 def LineStartswith(line, symbols): |
103 def LineStartswith(line, symbols): |
103 return reduce(lambda x, y: x or y, map(lambda x: line.startswith(x), symbols), False) |
104 return reduce(lambda x, y: x or y, map(lambda x: line.startswith(x), symbols), False) |
104 |
105 |
105 class TextViewer(wx.stc.StyledTextCtrl): |
106 class TextViewer(EditorPanel): |
|
107 |
|
108 ID = ID_TEXTVIEWER |
106 |
109 |
107 if wx.VERSION < (2, 6, 0): |
110 if wx.VERSION < (2, 6, 0): |
108 def Bind(self, event, function, id = None): |
111 def Bind(self, event, function, id = None): |
109 if id is not None: |
112 if id is not None: |
110 event(self, id, function) |
113 event(self, id, function) |
111 else: |
114 else: |
112 event(self, function) |
115 event(self, function) |
113 |
116 |
|
117 def _init_Editor(self, prnt): |
|
118 self.Editor = wx.stc.StyledTextCtrl(id=ID_TEXTVIEWERTEXTCTRL, |
|
119 parent=prnt, name="TextViewer", size=wx.Size(0, 0), style=0) |
|
120 |
|
121 self.Editor.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN) |
|
122 self.Editor.CmdKeyAssign(ord('-'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT) |
|
123 |
|
124 self.Editor.SetViewWhiteSpace(False) |
|
125 |
|
126 self.Editor.SetLexer(wx.stc.STC_LEX_CONTAINER) |
|
127 |
|
128 # Global default styles for all languages |
|
129 self.Editor.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) |
|
130 self.Editor.StyleClearAll() # Reset all to be like the default |
|
131 |
|
132 self.Editor.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,size:%(size)d" % faces) |
|
133 self.Editor.SetSelBackground(1, "#E0E0E0") |
|
134 |
|
135 # Highlighting styles |
|
136 self.Editor.StyleSetSpec(STC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces) |
|
137 self.Editor.StyleSetSpec(STC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces) |
|
138 self.Editor.StyleSetSpec(STC_PLC_PARAMETER, "fore:#7F007F,size:%(size)d" % faces) |
|
139 self.Editor.StyleSetSpec(STC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces) |
|
140 self.Editor.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces) |
|
141 self.Editor.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces) |
|
142 self.Editor.StyleSetSpec(STC_PLC_STRING, "fore:#007F00,size:%(size)d" % faces) |
|
143 self.Editor.StyleSetSpec(STC_PLC_JUMP, "fore:#FF7FFF,size:%(size)d" % faces) |
|
144 self.Editor.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces) |
|
145 self.Editor.StyleSetSpec(STC_PLC_SEARCH_RESULT, "fore:#FFFFFF,back:#FFA500,size:%(size)d" % faces) |
|
146 |
|
147 # Indicators styles |
|
148 self.Editor.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE) |
|
149 if self.ParentWindow is not None and self.Controler is not None: |
|
150 self.Editor.IndicatorSetForeground(0, wx.RED) |
|
151 else: |
|
152 self.Editor.IndicatorSetForeground(0, wx.WHITE) |
|
153 |
|
154 # Line numbers in the margin |
|
155 self.Editor.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER) |
|
156 self.Editor.SetMarginWidth(1, 50) |
|
157 |
|
158 # Folding |
|
159 self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN, wx.stc.STC_MARK_BOXMINUS, "white", "#808080") |
|
160 self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER, wx.stc.STC_MARK_BOXPLUS, "white", "#808080") |
|
161 self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERSUB, wx.stc.STC_MARK_VLINE, "white", "#808080") |
|
162 self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERTAIL, wx.stc.STC_MARK_LCORNER, "white", "#808080") |
|
163 self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND, wx.stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080") |
|
164 self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, wx.stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080") |
|
165 self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, wx.stc.STC_MARK_TCORNER, "white", "#808080") |
|
166 |
|
167 # Indentation size |
|
168 self.Editor.SetTabWidth(2) |
|
169 self.Editor.SetUseTabs(0) |
|
170 |
|
171 self.Editor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT| |
|
172 wx.stc.STC_MOD_BEFOREDELETE| |
|
173 wx.stc.STC_PERFORMED_USER) |
|
174 |
|
175 self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, id=ID_TEXTVIEWERTEXTCTRL) |
|
176 self.Editor.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnMarginClick) |
|
177 self.Editor.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) |
|
178 if self.Controler is not None: |
|
179 self.Editor.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) |
|
180 self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWERTEXTCTRL) |
|
181 self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_TEXTVIEWERTEXTCTRL) |
|
182 |
114 def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""): |
183 def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""): |
115 wx.stc.StyledTextCtrl.__init__(self, parent, ID_TEXTVIEWER, size=wx.Size(0, 0), style=0) |
184 if tagname != "" and controler is not None: |
116 |
185 self.VARIABLE_PANEL_TYPE = controler.GetPouType(tagname.split("::")[1]) |
117 self.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN) |
186 |
118 self.CmdKeyAssign(ord('-'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT) |
187 EditorPanel.__init__(self, parent, tagname, window, controler) |
119 |
|
120 self.SetViewWhiteSpace(False) |
|
121 |
|
122 self.SetLexer(wx.stc.STC_LEX_CONTAINER) |
|
123 |
|
124 # Global default styles for all languages |
|
125 self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces) |
|
126 self.StyleClearAll() # Reset all to be like the default |
|
127 |
|
128 self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER, "back:#C0C0C0,size:%(size)d" % faces) |
|
129 self.SetSelBackground(1, "#E0E0E0") |
|
130 |
|
131 # Highlighting styles |
|
132 self.StyleSetSpec(STC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces) |
|
133 self.StyleSetSpec(STC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces) |
|
134 self.StyleSetSpec(STC_PLC_PARAMETER, "fore:#7F007F,size:%(size)d" % faces) |
|
135 self.StyleSetSpec(STC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces) |
|
136 self.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces) |
|
137 self.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces) |
|
138 self.StyleSetSpec(STC_PLC_STRING, "fore:#007F00,size:%(size)d" % faces) |
|
139 self.StyleSetSpec(STC_PLC_JUMP, "fore:#FF7FFF,size:%(size)d" % faces) |
|
140 self.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces) |
|
141 self.StyleSetSpec(STC_PLC_SEARCH_RESULT, "fore:#FFFFFF,back:#FFA500,size:%(size)d" % faces) |
|
142 |
|
143 # Indicators styles |
|
144 self.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE) |
|
145 if window and controler: |
|
146 self.IndicatorSetForeground(0, wx.RED) |
|
147 else: |
|
148 self.IndicatorSetForeground(0, wx.WHITE) |
|
149 |
|
150 # Line numbers in the margin |
|
151 self.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER) |
|
152 self.SetMarginWidth(1, 50) |
|
153 |
|
154 # Folding |
|
155 self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN, wx.stc.STC_MARK_BOXMINUS, "white", "#808080") |
|
156 self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER, wx.stc.STC_MARK_BOXPLUS, "white", "#808080") |
|
157 self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERSUB, wx.stc.STC_MARK_VLINE, "white", "#808080") |
|
158 self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERTAIL, wx.stc.STC_MARK_LCORNER, "white", "#808080") |
|
159 self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND, wx.stc.STC_MARK_BOXPLUSCONNECTED, "white", "#808080") |
|
160 self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, wx.stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080") |
|
161 self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, wx.stc.STC_MARK_TCORNER, "white", "#808080") |
|
162 |
|
163 # Indentation size |
|
164 self.SetTabWidth(2) |
|
165 self.SetUseTabs(0) |
|
166 |
188 |
167 self.Keywords = [] |
189 self.Keywords = [] |
168 self.Variables = {} |
190 self.Variables = {} |
169 self.Functions = {} |
191 self.Functions = {} |
170 self.TypeNames = [] |
192 self.TypeNames = [] |
171 self.Jumps = [] |
193 self.Jumps = [] |
172 self.EnumeratedValues = [] |
194 self.EnumeratedValues = [] |
173 self.DisableEvents = True |
195 self.DisableEvents = True |
174 self.TextSyntax = "ST" |
196 self.TextSyntax = None |
175 self.CurrentAction = None |
197 self.CurrentAction = None |
176 self.TagName = tagname |
|
177 self.Highlights = [] |
198 self.Highlights = [] |
178 self.Debug = debug |
199 self.Debug = debug |
179 self.InstancePath = instancepath |
200 self.InstancePath = instancepath |
180 self.ContextStack = [] |
201 self.ContextStack = [] |
181 self.CallStack = [] |
202 self.CallStack = [] |
182 |
203 |
183 self.ParentWindow = window |
|
184 self.Controler = controler |
|
185 |
|
186 self.RefreshHighlightsTimer = wx.Timer(self, -1) |
204 self.RefreshHighlightsTimer = wx.Timer(self, -1) |
187 self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer) |
205 self.Bind(wx.EVT_TIMER, self.OnRefreshHighlightsTimer, self.RefreshHighlightsTimer) |
188 |
|
189 self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT| |
|
190 wx.stc.STC_MOD_BEFOREDELETE| |
|
191 wx.stc.STC_PERFORMED_USER) |
|
192 |
|
193 self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, id=ID_TEXTVIEWER) |
|
194 self.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnMarginClick) |
|
195 if controler: |
|
196 self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) |
|
197 self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWER) |
|
198 self.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus) |
|
199 self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_TEXTVIEWER) |
|
200 |
206 |
201 def __del__(self): |
207 def __del__(self): |
202 self.RefreshHighlightsTimer.Stop() |
208 self.RefreshHighlightsTimer.Stop() |
203 |
209 |
204 def SetTagName(self, tagname): |
210 def GetTitle(self): |
205 self.TagName = tagname |
211 if self.Debug or self.TagName == "": |
206 |
212 if len(self.InstancePath) > 15: |
207 def GetTagName(self): |
213 return "..." + self.InstancePath[-12:] |
208 return self.TagName |
214 return self.InstancePath |
|
215 return EditorPanel.GetTitle(self) |
209 |
216 |
210 def GetInstancePath(self): |
217 def GetInstancePath(self): |
211 return self.InstancePath |
218 return self.InstancePath |
212 |
219 |
213 def IsViewing(self, tagname): |
220 def IsViewing(self, tagname): |
214 if self.Debug: |
221 if self.Debug or self.TagName == "": |
215 return self.InstancePath == tagname |
222 return self.InstancePath == tagname |
216 else: |
223 else: |
217 return self.TagName == tagname |
224 return self.TagName == tagname |
218 |
225 |
219 def IsDebugging(self): |
226 def IsDebugging(self): |
220 return self.Debug |
227 return self.Debug |
221 |
228 |
222 def SetMode(self, mode): |
229 def GetText(self): |
223 pass |
230 return self.Editor.GetText() |
|
231 |
|
232 def SetText(self, text): |
|
233 self.Editor.SetText(text) |
|
234 |
|
235 def SelectAll(self): |
|
236 self.Editor.SelectAll() |
|
237 |
|
238 def Colourise(self, start, end): |
|
239 self.Editor.Colourise(start, end) |
|
240 |
|
241 def StartStyling(self, pos, mask): |
|
242 self.Editor.StartStyling(pos, mask) |
|
243 |
|
244 def SetStyling(self, length, style): |
|
245 self.Editor.SetStyling(length, style) |
|
246 |
|
247 def GetCurrentPos(self): |
|
248 return self.Editor.GetCurrentPos() |
224 |
249 |
225 def OnModification(self, event): |
250 def OnModification(self, event): |
226 if not self.DisableEvents: |
251 if not self.DisableEvents: |
227 mod_type = event.GetModificationType() |
252 mod_type = event.GetModificationType() |
228 if mod_type&wx.stc.STC_MOD_BEFOREINSERT: |
253 if mod_type&wx.stc.STC_MOD_BEFOREINSERT: |
346 def ResetBuffer(self): |
380 def ResetBuffer(self): |
347 if self.CurrentAction != None: |
381 if self.CurrentAction != None: |
348 self.Controler.EndBuffering() |
382 self.Controler.EndBuffering() |
349 self.CurrentAction = None |
383 self.CurrentAction = None |
350 |
384 |
351 def RefreshView(self): |
385 def GetBufferState(self): |
352 self.ResetBuffer() |
386 if not self.Debug and self.TextSyntax != "ALL": |
353 self.DisableEvents = True |
387 return self.Controler.GetBufferState() |
354 old_cursor_pos = self.GetCurrentPos() |
388 return False, False |
355 old_text = self.GetText() |
389 |
356 new_text = self.Controler.GetEditedElementText(self.TagName, self.Debug) |
390 def Undo(self): |
357 self.SetText(new_text) |
391 if not self.Debug and self.TextSyntax != "ALL": |
358 new_cursor_pos = GetCursorPos(old_text, new_text) |
392 self.Controler.LoadPrevious() |
359 if new_cursor_pos != None: |
393 self.ParentWindow.CloseTabsWithoutModel() |
360 self.GotoPos(new_cursor_pos) |
394 self.ParentWindow.RefreshEditor() |
361 else: |
395 |
362 self.GotoPos(old_cursor_pos) |
396 def Redo(self): |
363 self.ScrollToColumn(0) |
397 if not self.Debug and self.TextSyntax != "ALL": |
364 self.RefreshJumpList() |
398 self.Controler.LoadNext() |
365 self.EmptyUndoBuffer() |
399 self.ParentWindow.CloseTabsWithoutModel() |
366 self.DisableEvents = False |
400 self.ParentWindow.RefreshEditor() |
367 |
401 |
368 self.RefreshVariableTree() |
402 def HasNoModel(self): |
369 |
403 if not self.Debug and self.TextSyntax != "ALL": |
370 self.TypeNames = [typename.upper() for typename in self.Controler.GetDataTypes(self.TagName, True, self.Debug)] |
404 return self.Controler.GetEditedElement(self.TagName) is None |
371 self.EnumeratedValues = [value.upper() for value in self.Controler.GetEnumeratedDataValues()] |
405 return False |
372 |
406 |
373 self.Functions = {} |
407 def RefreshView(self, variablepanel=True): |
374 for category in self.Controler.GetBlockTypes(self.TagName, self.Debug): |
408 EditorPanel.RefreshView(self, variablepanel) |
375 for blocktype in category["list"]: |
409 |
376 blockname = blocktype["name"].upper() |
410 if self.Controler is not None: |
377 if blocktype["type"] == "function" and blockname not in self.Keywords and blockname not in self.Variables.keys(): |
411 self.ResetBuffer() |
378 interface = dict([(name, {}) for name, type, modifier in blocktype["inputs"] + blocktype["outputs"] if name != '']) |
412 self.DisableEvents = True |
379 for param in ["EN", "ENO"]: |
413 old_cursor_pos = self.GetCurrentPos() |
380 if not interface.has_key(param): |
414 old_text = self.GetText() |
381 interface[param] = {} |
415 new_text = self.Controler.GetEditedElementText(self.TagName, self.Debug) |
382 if self.Functions.has_key(blockname): |
416 self.SetText(new_text) |
383 self.Functions[blockname]["interface"].update(interface) |
417 new_cursor_pos = GetCursorPos(old_text, new_text) |
384 self.Functions[blockname]["extensible"] |= blocktype["extensible"] |
418 if new_cursor_pos != None: |
385 else: |
419 self.Editor.GotoPos(new_cursor_pos) |
386 self.Functions[blockname] = {"interface": interface, |
420 else: |
387 "extensible": blocktype["extensible"]} |
421 self.Editor.GotoPos(old_cursor_pos) |
|
422 self.Editor.ScrollToColumn(0) |
|
423 self.RefreshJumpList() |
|
424 self.Editor.EmptyUndoBuffer() |
|
425 self.DisableEvents = False |
|
426 |
|
427 self.RefreshVariableTree() |
|
428 |
|
429 self.TypeNames = [typename.upper() for typename in self.Controler.GetDataTypes(self.TagName, True, self.Debug)] |
|
430 self.EnumeratedValues = [value.upper() for value in self.Controler.GetEnumeratedDataValues()] |
|
431 |
|
432 self.Functions = {} |
|
433 for category in self.Controler.GetBlockTypes(self.TagName, self.Debug): |
|
434 for blocktype in category["list"]: |
|
435 blockname = blocktype["name"].upper() |
|
436 if blocktype["type"] == "function" and blockname not in self.Keywords and blockname not in self.Variables.keys(): |
|
437 interface = dict([(name, {}) for name, type, modifier in blocktype["inputs"] + blocktype["outputs"] if name != '']) |
|
438 for param in ["EN", "ENO"]: |
|
439 if not interface.has_key(param): |
|
440 interface[param] = {} |
|
441 if self.Functions.has_key(blockname): |
|
442 self.Functions[blockname]["interface"].update(interface) |
|
443 self.Functions[blockname]["extensible"] |= blocktype["extensible"] |
|
444 else: |
|
445 self.Functions[blockname] = {"interface": interface, |
|
446 "extensible": blocktype["extensible"]} |
|
447 |
388 self.Colourise(0, -1) |
448 self.Colourise(0, -1) |
389 |
449 |
390 def RefreshVariableTree(self): |
450 def RefreshVariableTree(self): |
391 words = self.TagName.split("::") |
451 words = self.TagName.split("::") |
392 self.Variables = self.GenerateVariableTree([(variable["Name"], variable["Type"], variable["Tree"]) for variable in self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)]) |
452 self.Variables = self.GenerateVariableTree([(variable["Name"], variable["Type"], variable["Tree"]) for variable in self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)]) |
402 tree = {} |
462 tree = {} |
403 for var_name, var_type, (var_tree, var_dimension) in list: |
463 for var_name, var_type, (var_tree, var_dimension) in list: |
404 tree[var_name.upper()] = self.GenerateVariableTree(var_tree) |
464 tree[var_name.upper()] = self.GenerateVariableTree(var_tree) |
405 return tree |
465 return tree |
406 |
466 |
407 def RefreshScaling(self, refresh=True): |
|
408 pass |
|
409 |
|
410 def IsValidVariable(self, name, context): |
467 def IsValidVariable(self, name, context): |
411 return context is not None and context.get(name, None) is not None |
468 return context is not None and context.get(name, None) is not None |
412 |
469 |
413 def IsCallParameter(self, name, call): |
470 def IsCallParameter(self, name, call): |
414 if call is not None: |
471 if call is not None: |
415 return (call["interface"].get(name.upper(), None) is not None or |
472 return (call["interface"].get(name.upper(), None) is not None or |
416 call["extensible"] and EXTENSIBLE_PARAMETER.match(name.upper()) is not None) |
473 call["extensible"] and EXTENSIBLE_PARAMETER.match(name.upper()) is not None) |
417 return False |
474 return False |
418 |
475 |
419 def RefreshLineFolding(self, line_number): |
476 def RefreshLineFolding(self, line_number): |
420 if self.TextSyntax == "ST": |
477 if self.TextSyntax in ["ST", "ALL"]: |
421 level = wx.stc.STC_FOLDLEVELBASE + self.GetLineIndentation(line_number) |
478 level = wx.stc.STC_FOLDLEVELBASE + self.Editor.GetLineIndentation(line_number) |
422 line = self.GetLine(line_number).strip() |
479 line = self.Editor.GetLine(line_number).strip() |
423 if line == "": |
480 if line == "": |
424 if line_number > 0: |
481 if line_number > 0: |
425 if LineStartswith(self.GetLine(line_number - 1).strip(), ST_BLOCK_END_KEYWORDS): |
482 if LineStartswith(self.Editor.GetLine(line_number - 1).strip(), self.BlockEndKeywords): |
426 level = self.GetFoldLevel(self.GetFoldParent(line_number - 1)) & wx.stc.STC_FOLDLEVELNUMBERMASK |
483 level = self.Editor.GetFoldLevel(self.Editor.GetFoldParent(line_number - 1)) & wx.stc.STC_FOLDLEVELNUMBERMASK |
427 else: |
484 else: |
428 level = self.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK |
485 level = self.Editor.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK |
429 if level != wx.stc.STC_FOLDLEVELBASE: |
486 if level != wx.stc.STC_FOLDLEVELBASE: |
430 level |= wx.stc.STC_FOLDLEVELWHITEFLAG |
487 level |= wx.stc.STC_FOLDLEVELWHITEFLAG |
431 elif LineStartswith(line, ST_BLOCK_START_KEYWORDS): |
488 elif LineStartswith(line, self.BlockStartKeywords): |
432 level |= wx.stc.STC_FOLDLEVELHEADERFLAG |
489 level |= wx.stc.STC_FOLDLEVELHEADERFLAG |
433 elif LineStartswith(line, ST_BLOCK_END_KEYWORDS): |
490 elif LineStartswith(line, self.BlockEndKeywords): |
434 if LineStartswith(self.GetLine(line_number - 1).strip(), ST_BLOCK_END_KEYWORDS): |
491 if LineStartswith(self.Editor.GetLine(line_number - 1).strip(), self.BlockEndKeywords): |
435 level = self.GetFoldLevel(self.GetFoldParent(line_number - 1)) & wx.stc.STC_FOLDLEVELNUMBERMASK |
492 level = self.Editor.GetFoldLevel(self.Editor.GetFoldParent(line_number - 1)) & wx.stc.STC_FOLDLEVELNUMBERMASK |
436 else: |
493 else: |
437 level = self.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK |
494 level = self.Editor.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK |
438 self.SetFoldLevel(line_number, level) |
495 self.Editor.SetFoldLevel(line_number, level) |
439 |
496 |
440 def OnStyleNeeded(self, event): |
497 def OnStyleNeeded(self, event): |
441 self.TextChanged = True |
498 self.TextChanged = True |
442 line_number = self.LineFromPosition(self.GetEndStyled()) |
499 line_number = self.Editor.LineFromPosition(self.Editor.GetEndStyled()) |
443 if line_number == 0: |
500 if line_number == 0: |
444 start_pos = last_styled_pos = 0 |
501 start_pos = last_styled_pos = 0 |
445 else: |
502 else: |
446 start_pos = last_styled_pos = self.GetLineEndPosition(line_number - 1) + 1 |
503 start_pos = last_styled_pos = self.Editor.GetLineEndPosition(line_number - 1) + 1 |
447 self.RefreshLineFolding(line_number) |
504 self.RefreshLineFolding(line_number) |
448 end_pos = event.GetPosition() |
505 end_pos = event.GetPosition() |
449 self.StartStyling(start_pos, 0xff) |
506 self.StartStyling(start_pos, 0xff) |
450 |
507 |
451 current_context = self.Variables |
508 current_context = self.Variables |
627 self.ShowHighlights(start_pos, end_pos) |
684 self.ShowHighlights(start_pos, end_pos) |
628 event.Skip() |
685 event.Skip() |
629 |
686 |
630 def OnMarginClick(self, event): |
687 def OnMarginClick(self, event): |
631 if event.GetMargin() == 2: |
688 if event.GetMargin() == 2: |
632 self.ToggleFold(self.LineFromPosition(event.GetPosition())) |
689 line = self.Editor.LineFromPosition(event.GetPosition()) |
|
690 if self.Editor.GetFoldLevel(line) & wx.stc.STC_FOLDLEVELHEADERFLAG: |
|
691 self.Editor.ToggleFold(line) |
633 event.Skip() |
692 event.Skip() |
634 |
693 |
635 def Cut(self): |
694 def Cut(self): |
636 self.ResetBuffer() |
695 self.ResetBuffer() |
637 self.CmdKeyExecute(wx.stc.STC_CMD_CUT) |
696 self.DisableEvents = True |
|
697 self.Editor.CmdKeyExecute(wx.stc.STC_CMD_CUT) |
|
698 self.DisableEvents = False |
638 self.RefreshModel() |
699 self.RefreshModel() |
639 self.RefreshBuffer() |
700 self.RefreshBuffer() |
640 |
701 |
641 def Copy(self): |
702 def Copy(self): |
642 self.CmdKeyExecute(wx.stc.STC_CMD_COPY) |
703 self.Editor.CmdKeyExecute(wx.stc.STC_CMD_COPY) |
643 |
704 |
644 def Paste(self): |
705 def Paste(self): |
645 self.ResetBuffer() |
706 self.ResetBuffer() |
646 self.CmdKeyExecute(wx.stc.STC_CMD_PASTE) |
707 self.DisableEvents = True |
|
708 self.Editor.CmdKeyExecute(wx.stc.STC_CMD_PASTE) |
|
709 self.DisableEvents = False |
647 self.RefreshModel() |
710 self.RefreshModel() |
648 self.RefreshBuffer() |
711 self.RefreshBuffer() |
649 |
712 |
650 def RefreshModel(self): |
713 def RefreshModel(self): |
651 self.RefreshJumpList() |
714 self.RefreshJumpList() |
652 self.Controler.SetEditedElementText(self.TagName, self.GetText()) |
715 self.Controler.SetEditedElementText(self.TagName, self.GetText()) |
653 |
716 |
654 def OnKeyDown(self, event): |
717 def OnKeyDown(self, event): |
655 if self.CallTipActive(): |
718 if self.Controler is not None: |
656 self.CallTipCancel() |
719 |
657 key = event.GetKeyCode() |
720 if self.Editor.CallTipActive(): |
658 key_handled = False |
721 self.Editor.CallTipCancel() |
659 |
722 key = event.GetKeyCode() |
660 # Code completion |
723 key_handled = False |
661 if key == wx.WXK_SPACE and event.ControlDown(): |
724 |
662 |
725 line = self.Editor.GetCurrentLine() |
663 line = self.GetCurrentLine() |
|
664 if line == 0: |
726 if line == 0: |
665 start_pos = 0 |
727 start_pos = 0 |
666 else: |
728 else: |
667 start_pos = self.GetLineEndPosition(line - 1) + 1 |
729 start_pos = self.Editor.GetLineEndPosition(line - 1) + 1 |
668 end_pos = self.GetCurrentPos() |
730 end_pos = self.GetCurrentPos() |
669 |
731 lineText = self.Editor.GetTextRange(start_pos, end_pos).replace("\t", " ") |
670 lineText = self.GetTextRange(start_pos, end_pos).replace("\t", " ") |
|
671 words = lineText.split(" ") |
|
672 words = [word for i, word in enumerate(words) if word != '' or i == len(words) - 1] |
|
673 |
|
674 kw = [] |
|
675 |
732 |
676 if self.TextSyntax == "IL": |
733 # Code completion |
677 if len(words) == 1: |
734 if key == wx.WXK_SPACE and event.ControlDown(): |
678 kw = self.Keywords |
735 |
679 elif len(words) == 2: |
736 words = lineText.split(" ") |
680 if words[0].upper() in ["CAL", "CALC", "CALNC"]: |
737 words = [word for i, word in enumerate(words) if word != '' or i == len(words) - 1] |
681 kw = self.Functions |
738 |
682 elif words[0].upper() in ["JMP", "JMPC", "JMPNC"]: |
739 kw = [] |
683 kw = self.Jumps |
740 |
684 else: |
741 if self.TextSyntax == "IL": |
685 kw = self.Variables.keys() |
742 if len(words) == 1: |
686 else: |
743 kw = self.Keywords |
687 kw = self.Keywords + self.Variables.keys() + self.Functions |
744 elif len(words) == 2: |
688 if len(kw) > 0: |
745 if words[0].upper() in ["CAL", "CALC", "CALNC"]: |
689 if len(words[-1]) > 0: |
746 kw = self.Functions |
690 kw = [keyword for keyword in kw if keyword.startswith(words[-1])] |
747 elif words[0].upper() in ["JMP", "JMPC", "JMPNC"]: |
691 kw.sort() |
748 kw = self.Jumps |
692 self.AutoCompSetIgnoreCase(True) |
749 else: |
693 self.AutoCompShow(len(words[-1]), " ".join(kw)) |
750 kw = self.Variables.keys() |
694 key_handled = True |
751 else: |
695 elif key == wx.WXK_RETURN or key == wx.WXK_NUMPAD_ENTER: |
752 kw = self.Keywords + self.Variables.keys() + self.Functions |
696 if self.TextSyntax == "ST": |
753 if len(kw) > 0: |
697 line = self.GetCurrentLine() |
754 if len(words[-1]) > 0: |
698 indent = self.GetLineIndentation(line) |
755 kw = [keyword for keyword in kw if keyword.startswith(words[-1])] |
699 if LineStartswith(self.GetLine(line).strip(), ST_BLOCK_START_KEYWORDS): |
756 kw.sort() |
700 indent += 2 |
757 self.Editor.AutoCompSetIgnoreCase(True) |
701 self.AddText("\n" + " " * indent) |
758 self.Editor.AutoCompShow(len(words[-1]), " ".join(kw)) |
702 key_handled = True |
759 key_handled = True |
703 elif key == wx.WXK_BACK: |
760 elif key == wx.WXK_RETURN or key == wx.WXK_NUMPAD_ENTER: |
704 if self.TextSyntax == "ST": |
761 if self.TextSyntax in ["ST", "ALL"]: |
705 line = self.GetCurrentLine() |
762 indent = self.Editor.GetLineIndentation(line) |
706 indent = self.GetLineIndentation(line) |
763 if LineStartswith(lineText.strip(), self.BlockStartKeywords): |
707 if self.GetLine(line).strip() == "" and indent > 0: |
764 indent += 2 |
708 self.DelLineLeft() |
765 self.Editor.AddText("\n" + " " * indent) |
709 self.AddText(" " * max(0, indent - 2)) |
|
710 key_handled = True |
766 key_handled = True |
711 if not key_handled: |
767 elif key == wx.WXK_BACK: |
712 event.Skip() |
768 if self.TextSyntax in ["ST", "ALL"]: |
|
769 indent = self.Editor.GetLineIndentation(line) |
|
770 if lineText.strip() == "" and indent > 0: |
|
771 self.Editor.DelLineLeft() |
|
772 self.Editor.AddText(" " * max(0, indent - 2)) |
|
773 key_handled = True |
|
774 if not key_handled: |
|
775 event.Skip() |
713 |
776 |
714 def OnKillFocus(self, event): |
777 def OnKillFocus(self, event): |
715 self.AutoCompCancel() |
778 self.Editor.AutoCompCancel() |
716 event.Skip() |
779 event.Skip() |
717 |
780 |
718 #------------------------------------------------------------------------------- |
781 #------------------------------------------------------------------------------- |
719 # Highlights showing functions |
782 # Highlights showing functions |
720 #------------------------------------------------------------------------------- |
783 #------------------------------------------------------------------------------- |