TextViewer.py
changeset 586 9aa96a36cf33
parent 582 aa41547baa2a
child 589 e3a1d9a59c97
--- a/TextViewer.py	Mon Nov 07 10:55:17 2011 +0100
+++ b/TextViewer.py	Tue Nov 08 21:59:22 2011 +0100
@@ -29,7 +29,8 @@
 import re
 
 from graphics.GraphicCommons import ERROR_HIGHLIGHT, SEARCH_RESULT_HIGHLIGHT, REFRESH_HIGHLIGHT_PERIOD
-from plcopen.structures import ST_BLOCK_START_KEYWORDS, ST_BLOCK_END_KEYWORDS
+from plcopen.structures import ST_BLOCK_START_KEYWORDS, ST_BLOCK_END_KEYWORDS, IEC_BLOCK_START_KEYWORDS, IEC_BLOCK_END_KEYWORDS
+from controls import EditorPanel
 
 #-------------------------------------------------------------------------------
 #                         Textual programs Viewer class
@@ -48,8 +49,8 @@
  STC_PLC_ERROR, STC_PLC_SEARCH_RESULT] = range(10)
 [SPACE, WORD, NUMBER, STRING, WSTRING, COMMENT] = range(6)
 
-[ID_TEXTVIEWER,
-] = [wx.NewId() for _init_ctrls in range(1)]
+[ID_TEXTVIEWER, ID_TEXTVIEWERTEXTCTRL,
+] = [wx.NewId() for _init_ctrls in range(2)]
 
 if wx.Platform == '__WXMSW__':
     faces = { 'times': 'Times New Roman',
@@ -102,7 +103,9 @@
 def LineStartswith(line, symbols):
     return reduce(lambda x, y: x or y, map(lambda x: line.startswith(x), symbols), False)
 
-class TextViewer(wx.stc.StyledTextCtrl):
+class TextViewer(EditorPanel):
+    
+    ID = ID_TEXTVIEWER
     
     if wx.VERSION < (2, 6, 0):
         def Bind(self, event, function, id = None):
@@ -111,58 +114,77 @@
             else:
                 event(self, function)
     
+    def _init_Editor(self, prnt):
+        self.Editor = wx.stc.StyledTextCtrl(id=ID_TEXTVIEWERTEXTCTRL, 
+                parent=prnt, name="TextViewer", size=wx.Size(0, 0), style=0)
+        
+        self.Editor.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN)
+        self.Editor.CmdKeyAssign(ord('-'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT)
+        
+        self.Editor.SetViewWhiteSpace(False)
+        
+        self.Editor.SetLexer(wx.stc.STC_LEX_CONTAINER)
+        
+        # Global default styles for all languages
+        self.Editor.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
+        self.Editor.StyleClearAll()  # Reset all to be like the default
+        
+        self.Editor.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,  "back:#C0C0C0,size:%(size)d" % faces)
+        self.Editor.SetSelBackground(1, "#E0E0E0")
+        
+        # Highlighting styles
+        self.Editor.StyleSetSpec(STC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
+        self.Editor.StyleSetSpec(STC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces)
+        self.Editor.StyleSetSpec(STC_PLC_PARAMETER, "fore:#7F007F,size:%(size)d" % faces)
+        self.Editor.StyleSetSpec(STC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces)
+        self.Editor.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces)
+        self.Editor.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
+        self.Editor.StyleSetSpec(STC_PLC_STRING, "fore:#007F00,size:%(size)d" % faces)
+        self.Editor.StyleSetSpec(STC_PLC_JUMP, "fore:#FF7FFF,size:%(size)d" % faces)
+        self.Editor.StyleSetSpec(STC_PLC_ERROR, "fore:#FF0000,back:#FFFF00,size:%(size)d" % faces)
+        self.Editor.StyleSetSpec(STC_PLC_SEARCH_RESULT, "fore:#FFFFFF,back:#FFA500,size:%(size)d" % faces)
+        
+        # Indicators styles
+        self.Editor.IndicatorSetStyle(0, wx.stc.STC_INDIC_SQUIGGLE)
+        if self.ParentWindow is not None and self.Controler is not None:
+            self.Editor.IndicatorSetForeground(0, wx.RED)
+        else:
+            self.Editor.IndicatorSetForeground(0, wx.WHITE)
+        
+        # Line numbers in the margin
+        self.Editor.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
+        self.Editor.SetMarginWidth(1, 50)
+        
+        # Folding
+        self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN,    wx.stc.STC_MARK_BOXMINUS,          "white", "#808080")
+        self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER,        wx.stc.STC_MARK_BOXPLUS,           "white", "#808080")
+        self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERSUB,     wx.stc.STC_MARK_VLINE,             "white", "#808080")
+        self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERTAIL,    wx.stc.STC_MARK_LCORNER,           "white", "#808080")
+        self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND,     wx.stc.STC_MARK_BOXPLUSCONNECTED,  "white", "#808080")
+        self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, wx.stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
+        self.Editor.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, wx.stc.STC_MARK_TCORNER,           "white", "#808080")
+        
+        # Indentation size
+        self.Editor.SetTabWidth(2)
+        self.Editor.SetUseTabs(0)
+        
+        self.Editor.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|
+                                    wx.stc.STC_MOD_BEFOREDELETE|
+                                    wx.stc.STC_PERFORMED_USER)
+
+        self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, id=ID_TEXTVIEWERTEXTCTRL)
+        self.Editor.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
+        self.Editor.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
+        if self.Controler is not None:
+            self.Editor.Bind(wx.EVT_KILL_FOCUS, self.OnKillFocus)
+            self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWERTEXTCTRL)
+            self.Bind(wx.stc.EVT_STC_MODIFIED, self.OnModification, id=ID_TEXTVIEWERTEXTCTRL)
+        
     def __init__(self, parent, tagname, window, controler, debug = False, instancepath = ""):
-        wx.stc.StyledTextCtrl.__init__(self, parent, ID_TEXTVIEWER, size=wx.Size(0, 0), style=0)
-        
-        self.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN)
-        self.CmdKeyAssign(ord('-'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT)
-        
-        self.SetViewWhiteSpace(False)
-        
-        self.SetLexer(wx.stc.STC_LEX_CONTAINER)
-        
-        # Global default styles for all languages
-        self.StyleSetSpec(wx.stc.STC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
-        self.StyleClearAll()  # Reset all to be like the default
-        
-        self.StyleSetSpec(wx.stc.STC_STYLE_LINENUMBER,  "back:#C0C0C0,size:%(size)d" % faces)
-        self.SetSelBackground(1, "#E0E0E0")
-        
-        # Highlighting styles
-        self.StyleSetSpec(STC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
-        self.StyleSetSpec(STC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces)
-        self.StyleSetSpec(STC_PLC_PARAMETER, "fore:#7F007F,size:%(size)d" % faces)
-        self.StyleSetSpec(STC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces)
-        self.StyleSetSpec(STC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces)
-        self.StyleSetSpec(STC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
-        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)
-        if window and controler:
-            self.IndicatorSetForeground(0, wx.RED)
-        else:
-            self.IndicatorSetForeground(0, wx.WHITE)
-        
-        # Line numbers in the margin
-        self.SetMarginType(1, wx.stc.STC_MARGIN_NUMBER)
-        self.SetMarginWidth(1, 50)
-        
-        # Folding
-        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPEN,    wx.stc.STC_MARK_BOXMINUS,          "white", "#808080")
-        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDER,        wx.stc.STC_MARK_BOXPLUS,           "white", "#808080")
-        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERSUB,     wx.stc.STC_MARK_VLINE,             "white", "#808080")
-        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERTAIL,    wx.stc.STC_MARK_LCORNER,           "white", "#808080")
-        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEREND,     wx.stc.STC_MARK_BOXPLUSCONNECTED,  "white", "#808080")
-        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDEROPENMID, wx.stc.STC_MARK_BOXMINUSCONNECTED, "white", "#808080")
-        self.MarkerDefine(wx.stc.STC_MARKNUM_FOLDERMIDTAIL, wx.stc.STC_MARK_TCORNER,           "white", "#808080")
-        
-        # Indentation size
-        self.SetTabWidth(2)
-        self.SetUseTabs(0)
+        if tagname != "" and controler is not None:
+            self.VARIABLE_PANEL_TYPE = controler.GetPouType(tagname.split("::")[1])
+        
+        EditorPanel.__init__(self, parent, tagname, window, controler)
         
         self.Keywords = []
         self.Variables = {}
@@ -171,47 +193,32 @@
         self.Jumps = []
         self.EnumeratedValues = []
         self.DisableEvents = True
-        self.TextSyntax = "ST"
+        self.TextSyntax = None
         self.CurrentAction = None
-        self.TagName = tagname
         self.Highlights = []
         self.Debug = debug
         self.InstancePath = instancepath
         self.ContextStack = []
         self.CallStack = []
         
-        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)
-
-        self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, id=ID_TEXTVIEWER)
-        self.Bind(wx.stc.EVT_STC_MARGINCLICK, self.OnMarginClick)
-        if controler:
-            self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
-            self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWER)
-            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
-        
-    def GetTagName(self):
-        return self.TagName
+    def GetTitle(self):
+        if self.Debug or self.TagName == "":
+            if len(self.InstancePath) > 15:
+                return "..." + self.InstancePath[-12:]
+            return self.InstancePath
+        return EditorPanel.GetTitle(self)
     
     def GetInstancePath(self):
         return self.InstancePath
     
     def IsViewing(self, tagname):
-        if self.Debug:
+        if self.Debug or self.TagName == "":
             return self.InstancePath == tagname
         else:
             return self.TagName == tagname
@@ -219,8 +226,26 @@
     def IsDebugging(self):
         return self.Debug
     
-    def SetMode(self, mode):
-        pass
+    def GetText(self):
+        return self.Editor.GetText()
+    
+    def SetText(self, text):
+        self.Editor.SetText(text)
+    
+    def SelectAll(self):
+        self.Editor.SelectAll()
+    
+    def Colourise(self, start, end):
+        self.Editor.Colourise(start, end)
+    
+    def StartStyling(self, pos, mask):
+        self.Editor.StartStyling(pos, mask)
+    
+    def SetStyling(self, length, style):
+        self.Editor.SetStyling(length, style)
+    
+    def GetCurrentPos(self):
+        return self.Editor.GetCurrentPos()
     
     def OnModification(self, event):
         if not self.DisableEvents:
@@ -272,7 +297,7 @@
                         message = _("\"%s\" element for this pou already exists!")%blockname
                     else:
                         self.Controler.AddEditedElementPouVar(self.TagName, values[0], blockname)
-                        self.ParentWindow.RefreshVariablePanel(self.TagName)
+                        self.RefreshVariablePanel()
                         self.RefreshVariableTree()
                 blockinfo = self.Controler.GetBlockType(values[0], blockinputs, self.Debug)
                 hint = ',\n    '.join(
@@ -293,7 +318,7 @@
                         else:
                             var_type = LOCATIONDATATYPES.get(values[0][2], ["BOOL"])[0]
                         self.Controler.AddEditedElementPouVar(self.TagName, var_type, var_name, values[0], values[4])
-                        self.ParentWindow.RefreshVariablePanel(self.TagName)
+                        self.RefreshVariablePanel()
                         self.RefreshVariableTree()
                         event.SetDragText(var_name)
                 else:
@@ -313,11 +338,20 @@
     
     def SetTextSyntax(self, syntax):
         self.TextSyntax = syntax
-        if syntax == "ST":
-            self.SetMarginType(2, wx.stc.STC_MARGIN_SYMBOL)
-            self.SetMarginMask(2, wx.stc.STC_MASK_FOLDERS)
-            self.SetMarginSensitive(2, 1)
-            self.SetMarginWidth(2, 12)
+        if syntax in ["ST", "ALL"]:
+            self.Editor.SetMarginType(2, wx.stc.STC_MARGIN_SYMBOL)
+            self.Editor.SetMarginMask(2, wx.stc.STC_MASK_FOLDERS)
+            self.Editor.SetMarginSensitive(2, 1)
+            self.Editor.SetMarginWidth(2, 12)
+            if syntax == "ST":
+                self.BlockStartKeywords = ST_BLOCK_START_KEYWORDS
+                self.BlockEndKeywords = ST_BLOCK_START_KEYWORDS
+            else:
+                self.BlockStartKeywords = IEC_BLOCK_START_KEYWORDS
+                self.BlockEndKeywords = IEC_BLOCK_START_KEYWORDS
+        else:
+            self.BlockStartKeywords = []
+            self.BlockEndKeywords = []
     
     def SetKeywords(self, keywords):
         self.Keywords = [keyword.upper() for keyword in keywords]
@@ -348,43 +382,69 @@
             self.Controler.EndBuffering()
             self.CurrentAction = None
     
-    def RefreshView(self):
-        self.ResetBuffer()
-        self.DisableEvents = True
-        old_cursor_pos = self.GetCurrentPos()
-        old_text = self.GetText()
-        new_text = self.Controler.GetEditedElementText(self.TagName, self.Debug)
-        self.SetText(new_text)
-        new_cursor_pos = GetCursorPos(old_text, new_text)
-        if new_cursor_pos != None:
-            self.GotoPos(new_cursor_pos)
-        else:
-            self.GotoPos(old_cursor_pos)
-        self.ScrollToColumn(0)
-        self.RefreshJumpList()
-        self.EmptyUndoBuffer()
-        self.DisableEvents = False
-        
-        self.RefreshVariableTree()
-        
-        self.TypeNames = [typename.upper() for typename in self.Controler.GetDataTypes(self.TagName, True, self.Debug)]
-        self.EnumeratedValues = [value.upper() for value in self.Controler.GetEnumeratedDataValues()]
-        
-        self.Functions = {}
-        for category in self.Controler.GetBlockTypes(self.TagName, self.Debug):
-            for blocktype in category["list"]:
-                blockname = blocktype["name"].upper()
-                if blocktype["type"] == "function" and blockname not in self.Keywords and blockname not in self.Variables.keys():
-                    interface = dict([(name, {}) for name, type, modifier in blocktype["inputs"] + blocktype["outputs"] if name != ''])
-                    for param in ["EN", "ENO"]:
-                        if not interface.has_key(param):
-                            interface[param] = {}
-                    if self.Functions.has_key(blockname):
-                        self.Functions[blockname]["interface"].update(interface)
-                        self.Functions[blockname]["extensible"] |= blocktype["extensible"]
-                    else:
-                        self.Functions[blockname] = {"interface": interface,
-                                                     "extensible": blocktype["extensible"]}
+    def GetBufferState(self):
+        if not self.Debug and self.TextSyntax != "ALL":
+            return self.Controler.GetBufferState()
+        return False, False
+    
+    def Undo(self):
+        if not self.Debug and self.TextSyntax != "ALL":
+            self.Controler.LoadPrevious()
+            self.ParentWindow.CloseTabsWithoutModel()
+            self.ParentWindow.RefreshEditor()
+            
+    def Redo(self):
+        if not self.Debug and self.TextSyntax != "ALL":
+            self.Controler.LoadNext()
+            self.ParentWindow.CloseTabsWithoutModel()
+            self.ParentWindow.RefreshEditor()
+    
+    def HasNoModel(self):
+        if not self.Debug and self.TextSyntax != "ALL":
+            return self.Controler.GetEditedElement(self.TagName) is None
+        return False
+    
+    def RefreshView(self, variablepanel=True):
+        EditorPanel.RefreshView(self, variablepanel)
+        
+        if self.Controler is not None:
+            self.ResetBuffer()
+            self.DisableEvents = True
+            old_cursor_pos = self.GetCurrentPos()
+            old_text = self.GetText()
+            new_text = self.Controler.GetEditedElementText(self.TagName, self.Debug)
+            self.SetText(new_text)
+            new_cursor_pos = GetCursorPos(old_text, new_text)
+            if new_cursor_pos != None:
+                self.Editor.GotoPos(new_cursor_pos)
+            else:
+                self.Editor.GotoPos(old_cursor_pos)
+            self.Editor.ScrollToColumn(0)
+            self.RefreshJumpList()
+            self.Editor.EmptyUndoBuffer()
+            self.DisableEvents = False
+            
+            self.RefreshVariableTree()
+            
+            self.TypeNames = [typename.upper() for typename in self.Controler.GetDataTypes(self.TagName, True, self.Debug)]
+            self.EnumeratedValues = [value.upper() for value in self.Controler.GetEnumeratedDataValues()]
+            
+            self.Functions = {}
+            for category in self.Controler.GetBlockTypes(self.TagName, self.Debug):
+                for blocktype in category["list"]:
+                    blockname = blocktype["name"].upper()
+                    if blocktype["type"] == "function" and blockname not in self.Keywords and blockname not in self.Variables.keys():
+                        interface = dict([(name, {}) for name, type, modifier in blocktype["inputs"] + blocktype["outputs"] if name != ''])
+                        for param in ["EN", "ENO"]:
+                            if not interface.has_key(param):
+                                interface[param] = {}
+                        if self.Functions.has_key(blockname):
+                            self.Functions[blockname]["interface"].update(interface)
+                            self.Functions[blockname]["extensible"] |= blocktype["extensible"]
+                        else:
+                            self.Functions[blockname] = {"interface": interface,
+                                                         "extensible": blocktype["extensible"]}
+        
         self.Colourise(0, -1)
             
     def RefreshVariableTree(self):
@@ -404,9 +464,6 @@
             tree[var_name.upper()] = self.GenerateVariableTree(var_tree)
         return tree
     
-    def RefreshScaling(self, refresh=True):
-        pass
-    
     def IsValidVariable(self, name, context):
         return context is not None and context.get(name, None) is not None
 
@@ -417,33 +474,33 @@
         return False
     
     def RefreshLineFolding(self, line_number):
-        if self.TextSyntax == "ST":
-            level = wx.stc.STC_FOLDLEVELBASE + self.GetLineIndentation(line_number)
-            line = self.GetLine(line_number).strip()
+        if self.TextSyntax in ["ST", "ALL"]:
+            level = wx.stc.STC_FOLDLEVELBASE + self.Editor.GetLineIndentation(line_number)
+            line = self.Editor.GetLine(line_number).strip()
             if line == "":
                 if line_number > 0:
-                    if LineStartswith(self.GetLine(line_number - 1).strip(), ST_BLOCK_END_KEYWORDS):
-                        level = self.GetFoldLevel(self.GetFoldParent(line_number - 1)) & wx.stc.STC_FOLDLEVELNUMBERMASK
+                    if LineStartswith(self.Editor.GetLine(line_number - 1).strip(), self.BlockEndKeywords):
+                        level = self.Editor.GetFoldLevel(self.Editor.GetFoldParent(line_number - 1)) & wx.stc.STC_FOLDLEVELNUMBERMASK
                     else:
-                        level = self.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK
+                        level = self.Editor.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK
                 if level != wx.stc.STC_FOLDLEVELBASE:
                     level |=  wx.stc.STC_FOLDLEVELWHITEFLAG 
-            elif LineStartswith(line, ST_BLOCK_START_KEYWORDS):
+            elif LineStartswith(line, self.BlockStartKeywords):
                 level |= wx.stc.STC_FOLDLEVELHEADERFLAG
-            elif LineStartswith(line, ST_BLOCK_END_KEYWORDS):
-                if LineStartswith(self.GetLine(line_number - 1).strip(), ST_BLOCK_END_KEYWORDS):
-                    level = self.GetFoldLevel(self.GetFoldParent(line_number - 1)) & wx.stc.STC_FOLDLEVELNUMBERMASK
+            elif LineStartswith(line, self.BlockEndKeywords):
+                if LineStartswith(self.Editor.GetLine(line_number - 1).strip(), self.BlockEndKeywords):
+                    level = self.Editor.GetFoldLevel(self.Editor.GetFoldParent(line_number - 1)) & wx.stc.STC_FOLDLEVELNUMBERMASK
                 else:
-                    level = self.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK
-            self.SetFoldLevel(line_number, level)
+                    level = self.Editor.GetFoldLevel(line_number - 1) & wx.stc.STC_FOLDLEVELNUMBERMASK
+            self.Editor.SetFoldLevel(line_number, level)
     
     def OnStyleNeeded(self, event):
         self.TextChanged = True
-        line_number = self.LineFromPosition(self.GetEndStyled())
+        line_number = self.Editor.LineFromPosition(self.Editor.GetEndStyled())
         if line_number == 0:
             start_pos = last_styled_pos = 0
         else:
-            start_pos = last_styled_pos = self.GetLineEndPosition(line_number - 1) + 1
+            start_pos = last_styled_pos = self.Editor.GetLineEndPosition(line_number - 1) + 1
         self.RefreshLineFolding(line_number)
         end_pos = event.GetPosition()
         self.StartStyling(start_pos, 0xff)
@@ -456,7 +513,7 @@
         line = ""
         word = ""
         while current_pos < end_pos:
-            char = chr(self.GetCharAt(current_pos)).upper()
+            char = chr(self.Editor.GetCharAt(current_pos)).upper()
             line += char
             if char == NEWLINE:
                 self.ContextStack = []
@@ -629,21 +686,27 @@
     
     def OnMarginClick(self, event):
         if event.GetMargin() == 2:
-            self.ToggleFold(self.LineFromPosition(event.GetPosition()))
+            line = self.Editor.LineFromPosition(event.GetPosition())
+            if self.Editor.GetFoldLevel(line) & wx.stc.STC_FOLDLEVELHEADERFLAG:
+                self.Editor.ToggleFold(line)
         event.Skip()
         
     def Cut(self):
         self.ResetBuffer()
-        self.CmdKeyExecute(wx.stc.STC_CMD_CUT)
+        self.DisableEvents = True
+        self.Editor.CmdKeyExecute(wx.stc.STC_CMD_CUT)
+        self.DisableEvents = False
         self.RefreshModel()
         self.RefreshBuffer()
     
     def Copy(self):
-        self.CmdKeyExecute(wx.stc.STC_CMD_COPY)
+        self.Editor.CmdKeyExecute(wx.stc.STC_CMD_COPY)
     
     def Paste(self):
         self.ResetBuffer()
-        self.CmdKeyExecute(wx.stc.STC_CMD_PASTE)
+        self.DisableEvents = True
+        self.Editor.CmdKeyExecute(wx.stc.STC_CMD_PASTE)
+        self.DisableEvents = False
         self.RefreshModel()
         self.RefreshBuffer()
     
@@ -652,67 +715,67 @@
         self.Controler.SetEditedElementText(self.TagName, self.GetText())
     
     def OnKeyDown(self, event):
-        if self.CallTipActive():
-            self.CallTipCancel()
-        key = event.GetKeyCode()
-        key_handled = False
-        
-        # Code completion
-        if key == wx.WXK_SPACE and event.ControlDown():
-            
-            line = self.GetCurrentLine()
+        if self.Controler is not None:
+        
+            if self.Editor.CallTipActive():
+                self.Editor.CallTipCancel()
+            key = event.GetKeyCode()
+            key_handled = False
+
+            line = self.Editor.GetCurrentLine()
             if line == 0:
                 start_pos = 0
             else:
-                start_pos = self.GetLineEndPosition(line - 1) + 1
+                start_pos = self.Editor.GetLineEndPosition(line - 1) + 1
             end_pos = self.GetCurrentPos()
-
-            lineText = self.GetTextRange(start_pos, end_pos).replace("\t", " ")
-            words = lineText.split(" ")
-            words = [word for i, word in enumerate(words) if word != '' or i == len(words) - 1]
-                        
-            kw = []
+            lineText = self.Editor.GetTextRange(start_pos, end_pos).replace("\t", " ")
             
-            if self.TextSyntax == "IL":
-                if len(words) == 1:
-                    kw = self.Keywords
-                elif len(words) == 2:
-                    if words[0].upper() in ["CAL", "CALC", "CALNC"]:
-                        kw = self.Functions
-                    elif words[0].upper() in ["JMP", "JMPC", "JMPNC"]:
-                        kw = self.Jumps
-                    else:
-                        kw = self.Variables.keys()
-            else:
-                kw = self.Keywords + self.Variables.keys() + self.Functions
-            if len(kw) > 0:
-                if len(words[-1]) > 0:
-                    kw = [keyword for keyword in kw if keyword.startswith(words[-1])]
-                kw.sort()
-                self.AutoCompSetIgnoreCase(True)
-                self.AutoCompShow(len(words[-1]), " ".join(kw))
-            key_handled = True
-        elif key == wx.WXK_RETURN or key == wx.WXK_NUMPAD_ENTER:
-            if self.TextSyntax == "ST":
-                line = self.GetCurrentLine()
-                indent = self.GetLineIndentation(line)
-                if LineStartswith(self.GetLine(line).strip(), ST_BLOCK_START_KEYWORDS):
-                    indent += 2
-                self.AddText("\n" + " " * indent)
+            # Code completion
+            if key == wx.WXK_SPACE and event.ControlDown():
+                
+                words = lineText.split(" ")
+                words = [word for i, word in enumerate(words) if word != '' or i == len(words) - 1]
+                            
+                kw = []
+                
+                if self.TextSyntax == "IL":
+                    if len(words) == 1:
+                        kw = self.Keywords
+                    elif len(words) == 2:
+                        if words[0].upper() in ["CAL", "CALC", "CALNC"]:
+                            kw = self.Functions
+                        elif words[0].upper() in ["JMP", "JMPC", "JMPNC"]:
+                            kw = self.Jumps
+                        else:
+                            kw = self.Variables.keys()
+                else:
+                    kw = self.Keywords + self.Variables.keys() + self.Functions
+                if len(kw) > 0:
+                    if len(words[-1]) > 0:
+                        kw = [keyword for keyword in kw if keyword.startswith(words[-1])]
+                    kw.sort()
+                    self.Editor.AutoCompSetIgnoreCase(True)
+                    self.Editor.AutoCompShow(len(words[-1]), " ".join(kw))
                 key_handled = True
-        elif key == wx.WXK_BACK:
-            if self.TextSyntax == "ST":
-                line = self.GetCurrentLine()
-                indent = self.GetLineIndentation(line)
-                if self.GetLine(line).strip() == "" and indent > 0:
-                    self.DelLineLeft()
-                    self.AddText(" " * max(0, indent - 2))
+            elif key == wx.WXK_RETURN or key == wx.WXK_NUMPAD_ENTER:
+                if self.TextSyntax in ["ST", "ALL"]:
+                    indent = self.Editor.GetLineIndentation(line)
+                    if LineStartswith(lineText.strip(), self.BlockStartKeywords):
+                        indent += 2
+                    self.Editor.AddText("\n" + " " * indent)
                     key_handled = True
-        if not key_handled:
-            event.Skip()
+            elif key == wx.WXK_BACK:
+                if self.TextSyntax in ["ST", "ALL"]:
+                    indent = self.Editor.GetLineIndentation(line)
+                    if lineText.strip() == "" and indent > 0:
+                        self.Editor.DelLineLeft()
+                        self.Editor.AddText(" " * max(0, indent - 2))
+                        key_handled = True
+            if not key_handled:
+                event.Skip()
 
     def OnKillFocus(self, event):
-        self.AutoCompCancel()
+        self.Editor.AutoCompCancel()
         event.Skip()
 
 #-------------------------------------------------------------------------------