Viewer.py
changeset 27 dae55dd9ee14
parent 13 69075340d6a9
child 28 fc23e1f415d8
--- a/Viewer.py	Sat Jul 07 11:35:17 2007 +0200
+++ b/Viewer.py	Mon Jul 09 11:10:14 2007 +0200
@@ -23,17 +23,19 @@
 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 from wxPython.wx import *
-from wxPython.stc import * 
-from wxPython.grid import *
 import wx
 
 from plcopen.structures import *
 from graphics.GraphicCommons import *
-from graphics.SFC_Objects import *
 from graphics.FBD_Objects import *
 from graphics.LD_Objects import *
-
-import re
+from graphics.SFC_Objects import *
+
+from Dialogs import *
+
+SCROLLBAR_UNIT = 10
+WINDOW_BORDER = 10
+SCROLL_ZONE = 10
 
 #-------------------------------------------------------------------------------
 #                       Graphic elements Viewer base class
@@ -107,7 +109,7 @@
     
     # Create a new Viewer
     def __init__(self, parent, window, controler):
-        wx.ScrolledWindow.__init__(self, parent, style=wx.SUNKEN_BORDER)
+        wx.ScrolledWindow.__init__(self, parent, style=wx.SUNKEN_BORDER | wx.HSCROLL | wx.VSCROLL)
         self._init_menus()
         # Adding a rubberband to Viewer
         self.rubberBand = RubberBand(drawingSurface=self)
@@ -133,6 +135,8 @@
         EVT_RIGHT_UP(self, self.OnViewerRightUp)
         EVT_MOTION(self, self.OnViewerMotion)
         EVT_CHAR(self, self.OnChar)
+        EVT_SCROLLWIN(self, self.OnMoveWindow)
+        EVT_SIZE(self, self.OnMoveWindow)
     
     # Returns a new id
     def GetNewId(self):
@@ -143,6 +147,11 @@
     def __del__(self):
         self.ResetView()
 
+    def GetLogicalDC(self):
+        dc = wxClientDC(self)
+        self.DoPrepareDC(dc)
+        return dc
+
 #-------------------------------------------------------------------------------
 #                              Reset functions
 #-------------------------------------------------------------------------------
@@ -167,6 +176,10 @@
             self.SelectedElement = None
             self.Refresh()
 
+    # Return current drawing mode
+    def GetDrawingMode(self):
+        return self.Parent.GetDrawingMode()
+
 #-------------------------------------------------------------------------------
 #                          Refresh functions
 #-------------------------------------------------------------------------------
@@ -184,8 +197,27 @@
             instance = self.Controler.GetCurrentElementEditingInstanceInfos(exclude=ids)
             if instance:
                 self.loadInstance(instance, ids)
+        self.RefreshScrollBar()
         self.Refresh()
     
+    def RefreshScrollBar(self):
+        xstart, ystart = self.GetViewStart()
+        window_size = self.GetClientSize()
+        maxx = maxy = 0
+        for element in self.Elements:
+            posx, posy = element.GetPosition()
+            width, height = element.GetSize()
+            maxx = max(maxx, posx + width)
+            maxy = max(maxy, posy + height)
+        maxx = max(maxx + WINDOW_BORDER, xstart * SCROLLBAR_UNIT + window_size[0])
+        maxy = max(maxy + WINDOW_BORDER, ystart * SCROLLBAR_UNIT + window_size[1])
+        if self.rubberBand.IsShown():
+            extent = self.rubberBand.GetCurrentExtent()
+            maxx = max(maxx, extent.x + extent.width)
+            maxy = max(maxy, extent.y + extent.height)
+        self.SetScrollbars(SCROLLBAR_UNIT, SCROLLBAR_UNIT, 
+            maxx / SCROLLBAR_UNIT, maxy / SCROLLBAR_UNIT, xstart, ystart)
+    
     # Load instance from given informations
     def loadInstance(self, instance, ids):
         ids.append(instance["id"])
@@ -432,7 +464,7 @@
                 connected = self.FindElementById(refLocalId)
                 if connected:
                     points = link["points"]
-                    end_connector = connected.GetConnector(wxPoint(points[-1][0], points[-1][1]))
+                    end_connector = connected.GetConnector(wxPoint(points[-1][0], points[-1][1]), link["formalParameter"])
                     if end_connector:
                         wire = Wire(self)
                         wire.SetPoints(points)
@@ -629,18 +661,180 @@
 #-------------------------------------------------------------------------------
 
     def OnViewerLeftDown(self, event):
+        if self.Mode == MODE_SELECTION:
+            dc = self.GetLogicalDC()
+            pos = event.GetLogicalPosition(dc)
+            if event.ControlDown() and self.SelectedElement:
+                element = self.FindElement(pos, True)
+                if element:
+                    if isinstance(self.SelectedElement, Graphic_Group):
+                        self.SelectedElement.SetSelected(False)
+                        self.SelectedElement.SelectElement(element)
+                    elif self.SelectedElement:
+                        group = Graphic_Group(self)
+                        group.SelectElement(self.SelectedElement)
+                        group.SelectElement(element)
+                        self.SelectedElement = group
+                    elements = self.SelectedElement.GetElements()
+                    if len(elements) == 0:
+                        self.SelectedElement = element
+                    elif len(elements) == 1:
+                        self.SelectedElement = elements[0]
+                    self.SelectedElement.SetSelected(True)
+            else:
+                element = self.FindElement(pos)
+                if self.SelectedElement and self.SelectedElement != element:
+                    self.SelectedElement.SetSelected(False)
+                    self.SelectedElement = None
+                    self.Refresh()
+                if element:
+                    self.SelectedElement = element
+                    self.SelectedElement.OnLeftDown(event, dc, self.Scaling)
+                    self.Refresh()
+                else:
+                    self.rubberBand.Reset()
+                    self.rubberBand.OnLeftDown(event, dc, self.Scaling)
+        elif self.Mode in [MODE_BLOCK, MODE_VARIABLE, MODE_CONNECTION, MODE_COMMENT, 
+                           MODE_CONTACT, MODE_COIL, MODE_POWERRAIL, MODE_INITIALSTEP, 
+                           MODE_STEP, MODE_TRANSITION, MODE_DIVERGENCE, MODE_JUMP, MODE_ACTION]:
+            self.rubberBand.Reset()
+            self.rubberBand.OnLeftDown(event, self.GetLogicalDC(), self.Scaling)
+        elif self.Mode == MODE_WIRE:
+            pos = GetScaledEventPosition(event, self.GetLogicalDC(), self.Scaling)
+            connector = self.FindBlockConnector(pos)
+            if connector:
+                if (connector.GetDirection() == EAST):
+                    wire = Wire(self, [wxPoint(pos.x, pos.y), EAST], [wxPoint(pos.x, pos.y), WEST])
+                else:
+                    wire = Wire(self, [wxPoint(pos.x, pos.y), WEST], [wxPoint(pos.x, pos.y), EAST])
+                wire.oldPos = pos
+                wire.Handle = (HANDLE_POINT, 0)
+                wire.ProcessDragging(0, 0)
+                wire.Handle = (HANDLE_POINT, 1)
+                self.Wires.append(wire)
+                self.Elements.append(wire)
+                if self.SelectedElement:
+                    self.SelectedElement.SetSelected(False)
+                self.SelectedElement = wire
+            elif self.SelectedElement:
+                self.SelectedElement.SetSelected(False)
+                self.SelectedElement = None
+            self.Refresh()
         event.Skip()
 
     def OnViewerLeftUp(self, event):
+        if self.rubberBand.IsShown():
+            if self.Mode == MODE_SELECTION:
+                elements = self.SearchElements(self.rubberBand.GetCurrentExtent())
+                self.rubberBand.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)
+                if len(elements) > 0:
+                    self.SelectedElement = Graphic_Group(self)
+                    self.SelectedElement.SetElements(elements)
+                    self.SelectedElement.SetSelected(True)
+                    self.Refresh()
+            else:
+                bbox = self.rubberBand.GetCurrentExtent()
+                self.rubberBand.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)                
+                if self.Mode == MODE_BLOCK:
+                    wxCallAfter(self.AddNewBlock, bbox)
+                elif self.Mode == MODE_VARIABLE:
+                    wxCallAfter(self.AddNewVariable, bbox)
+                elif self.Mode == MODE_CONNECTION:
+                    wxCallAfter(self.AddNewConnection, bbox)
+                elif self.Mode == MODE_COMMENT:
+                    wxCallAfter(self.AddNewComment, bbox)
+                elif self.Mode == MODE_CONTACT:
+                    wxCallAfter(self.AddNewContact, bbox)
+                elif self.Mode == MODE_COIL:
+                    wxCallAfter(self.AddNewContact, bbox)
+                elif self.Mode == MODE_POWERRAIL:
+                    wxCallAfter(self.AddNewPowerRail, bbox)
+                elif self.Mode == MODE_INITIALSTEP:
+                    wxCallAfter(self.AddNewInitialStep, bbox)
+                elif self.Mode == MODE_STEP:
+                    wxCallAfter(self.AddNewStep, bbox)
+                elif self.Mode == MODE_TRANSITION:
+                    wxCallAfter(self.AddNewTransition, bbox)
+                elif self.Mode == MODE_DIVERGENCE:
+                    wxCallAfter(self.AddNewDivergence, bbox)
+                elif self.Mode == MODE_JUMP:
+                    wxCallAfter(self.AddNewJump, bbox)
+                elif self.Mode == MODE_ACTION:
+                    wxCallAfter(self.AddNewActionBlock, bbox)
+        elif self.Mode == MODE_SELECTION and self.SelectedElement:
+            self.SelectedElement.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)
+            wxCallAfter(self.SetCursor, wxNullCursor)
+            self.ReleaseMouse()
+            self.Refresh()
+        elif self.Mode == MODE_WIRE and self.SelectedElement:
+            dc = self.GetLogicalDC()
+            pos = GetScaledEventPosition(event, dc, self.Scaling)
+            connector = self.FindBlockConnector(pos, False)
+            if connector and connector != self.SelectedElement.StartConnected:
+                self.SelectedElement.ResetPoints()
+                self.SelectedElement.OnMotion(event, dc, self.Scaling)
+                self.SelectedElement.GeneratePoints()
+                self.SelectedElement.RefreshModel()
+                self.SelectedElement.SetSelected(True)
+            else:
+                self.SelectedElement.Delete()
+                self.SelectedElement = None
+            self.Refresh()
+        if not self.SavedMode:
+            wxCallAfter(self.Parent.ResetCurrentMode)
         event.Skip()
     
     def OnViewerRightUp(self, event):
+        pos = event.GetPosition()
+        element = self.FindElement(pos)
+        if element:
+            if self.SelectedElement and self.SelectedElement != element:
+                self.SelectedElement.SetSelected(False)
+            self.SelectedElement = element
+            self.SelectedElement.SetSelected(True)
+            self.SelectedElement.OnRightUp(event, self.GetLogicalDC(), self.Scaling)
+            wxCallAfter(self.SetCursor, wxNullCursor)
+            self.ReleaseMouse()
+            self.Refresh()
         event.Skip()
     
     def OnViewerLeftDClick(self, event):
+        if self.Mode == MODE_SELECTION and self.SelectedElement:
+            self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
+            self.Refresh()
         event.Skip()
     
     def OnViewerMotion(self, event):
+        if self.rubberBand.IsShown():
+            self.rubberBand.OnMotion(event, self.GetLogicalDC(), self.Scaling)
+        elif self.Mode == MODE_SELECTION and self.SelectedElement:
+            self.SelectedElement.OnMotion(event, self.GetLogicalDC(), self.Scaling)
+            self.Refresh()
+        elif self.Mode == MODE_WIRE and self.SelectedElement:
+            dc = self.GetLogicalDC()
+            pos = GetScaledEventPosition(event, dc, self.Scaling)
+            connector = self.FindBlockConnector(pos, False)
+            if not connector or self.SelectedElement.EndConnected == None:
+                self.SelectedElement.ResetPoints()
+                self.SelectedElement.OnMotion(event, dc, self.Scaling)
+                self.SelectedElement.GeneratePoints()
+                self.Refresh()
+        if (event.Dragging() and self.SelectedElement) or self.rubberBand.IsShown():
+            position = event.GetPosition()
+            move_window = wxPoint()
+            window_size = self.GetClientSize()
+            xstart, ystart = self.GetViewStart()
+            if position.x < SCROLL_ZONE and xstart > 0:
+                move_window.x = -1
+            elif position.x > window_size[0] - SCROLL_ZONE:
+                move_window.x = 1
+            if position.y < SCROLL_ZONE and ystart > 0:
+                move_window.y = -1
+            elif position.y > window_size[1] - SCROLL_ZONE:
+                move_window.y = 1
+            if move_window.x != 0 or move_window.y != 0:
+                self.Scroll(xstart + move_window.x, ystart + move_window.y)
+            self.RefreshScrollBar()
         event.Skip()
 
 #-------------------------------------------------------------------------------
@@ -648,7 +842,206 @@
 #-------------------------------------------------------------------------------
 
     def OnChar(self, event):
-        event.Skip()
+        keycode = event.GetKeyCode()
+        if self.Scaling:
+            scaling = self.Scaling
+        else:
+            scaling = (8, 8)
+        if keycode == WXK_DELETE and self.SelectedElement:
+            self.SelectedElement.Clean()
+            self.SelectedElement.Delete()
+            self.SelectedElement = None
+        elif keycode == WXK_LEFT and self.SelectedElement:
+            self.SelectedElement.Move(-scaling[0], 0)
+        elif keycode == WXK_RIGHT and self.SelectedElement:
+            self.SelectedElement.Move(scaling[0], 0)
+        elif keycode == WXK_UP and self.SelectedElement:
+            self.SelectedElement.Move(0, -scaling[1])
+        elif keycode == WXK_DOWN and self.SelectedElement:
+            self.SelectedElement.Move(0, scaling[1])
+        self.Refresh()
+        event.Skip()
+
+#-------------------------------------------------------------------------------
+#                          Model adding functions
+#-------------------------------------------------------------------------------
+
+    def AddNewBlock(self, bbox):
+        dialog = BlockPropertiesDialog(self.Parent)
+        dialog.SetBlockList(self.Controler.GetBlockTypes())
+        dialog.SetMinBlockSize((bbox.width, bbox.height))
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            if "name" in values:
+                block = FBD_Block(self, values["type"], values["name"], id, values["extension"])
+            else:
+                block = FBD_Block(self, values["type"], "", id, values["extension"])
+            block.SetPosition(bbox.x, bbox.y)
+            block.SetSize(values["width"], values["height"])
+            self.Blocks.append(block)
+            self.Elements.append(block)
+            self.Controler.AddCurrentElementEditingBlock(id)
+            self.RefreshBlockModel(block)
+            self.Refresh()
+        dialog.Destroy()
+    
+    def AddNewVariable(self, bbox):
+        dialog = VariablePropertiesDialog(self.Parent)
+        dialog.SetMinVariableSize((bbox.width, bbox.height))
+        varlist = []
+        vars = self.Controler.GetCurrentElementEditingInterfaceVars()
+        if vars:
+            for var in vars:
+                varlist.append((var["Name"], var["Class"], var["Type"]))
+        returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
+        if returntype:
+            varlist.append((self.Controler.GetCurrentElementEditingName(), "Output", returntype))
+        dialog.SetVariables(varlist)
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            variable = FBD_Variable(self, values["type"], values["name"], values["value_type"], id)
+            variable.SetPosition(bbox.x, bbox.y)
+            variable.SetSize(values["width"], values["height"])
+            self.Blocks.append(variable)
+            self.Elements.append(variable)
+            self.Controler.AddCurrentElementEditingVariable(id, values["type"])
+            self.RefreshVariableModel(variable)
+            self.Refresh()
+        dialog.Destroy()
+
+    def AddNewConnection(self, bbox):
+        dialog = ConnectionPropertiesDialog(self.Parent)
+        dialog.SetMinConnectionSize((bbox.width, bbox.height))
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            connection = FBD_Connector(self, values["type"], values["name"], id)
+            connection.SetPosition(bbox.x, bbox.y)
+            connection.SetSize(values["width"], values["height"])
+            self.Blocks.append(connection)
+            self.Elements.append(connection)
+            self.Controler.AddCurrentElementEditingConnection(id, values["type"])
+            self.RefreshConnectionModel(connection)
+            self.Refresh()
+        dialog.Destroy()
+
+    def AddNewComment(self, bbox):
+        dialog = wxTextEntryDialog(self.Parent, "Add a new comment", "Please enter comment text", "", wxOK|wxCANCEL|wxTE_MULTILINE)
+        if dialog.ShowModal() == wxID_OK:
+            value = dialog.GetValue()
+            id = self.GetNewId()
+            comment = Comment(self, value, id)
+            comment.SetPosition(bbox.x, bbox.y)
+            min_width, min_height = comment.GetMinSize()
+            comment.SetSize(max(min_width,bbox.width),max(min_height,bbox.height))
+            self.Elements.append(comment)
+            self.Controler.AddCurrentElementEditingComment(id)
+            self.RefreshCommentModel(comment)
+            self.Refresh()
+        dialog.Destroy()
+
+    def AddNewContact(self, bbox):
+        dialog = LDElementDialog(self.Parent, "contact")
+        varlist = []
+        vars = self.Controler.GetCurrentElementEditingInterfaceVars()
+        if vars:
+            for var in vars:
+                if var["Class"] != "Output" and var["Type"] == "BOOL":
+                    varlist.append(var["Name"])
+        dialog.SetVariables(varlist)
+        dialog.SetValues({"name":"","type":CONTACT_NORMAL})
+        dialog.SetElementSize(bbox.width, bbox.height)
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            contact = LD_Contact(self, values["type"], values["name"], id)
+            contact.SetPosition(bbox.x, bbox.y)
+            contact.SetSize(values["width"], values["height"])
+            self.Blocks.append(contact)
+            self.Elements.append(contact)
+            self.Controler.AddCurrentElementEditingContact(id)
+            self.RefreshContactModel(contact)
+            self.Refresh()
+        dialog.Destroy()
+
+    def AddNewCoil(self, bbox):
+        dialog = LDElementDialog(self.Parent, "coil")
+        varlist = []
+        vars = self.Controler.GetCurrentElementEditingInterfaceVars()
+        if vars:
+            for var in vars:
+                if var["Class"] != "Input" and var["Type"] == "BOOL":
+                    varlist.append(var["Name"])
+        returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
+        if returntype == "BOOL":
+            varlist.append(self.Controler.GetCurrentElementEditingName())
+        dialog.SetVariables(varlist)
+        dialog.SetValues({"name":"","type":COIL_NORMAL})
+        dialog.SetElementSize(bbox.width, bbox.height)
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            coil = LD_Coil(self, values["type"], values["name"], id)
+            coil.SetPosition(bbox.x, bbox.y)
+            coil.SetSize(values["width"], values["height"])
+            self.Blocks.append(coil)
+            self.Elements.append(coil)
+            self.Controler.AddCurrentElementEditingCoil(id)
+            self.RefreshCoilModel(contact)
+            self.Refresh()
+        dialog.Destroy()
+
+    def AddNewPowerRail(self, bbox):
+        dialog = LDPowerRailDialog(self.Parent)
+        dialog.SetMinSize((bbox.width, bbox.height))
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            powerrail = LD_PowerRail(self, values["type"], id, [True for i in xrange(values["number"])])
+            powerrail.SetPosition(bbox.x, bbox.y)
+            powerrail.SetSize(values["width"], values["height"])
+            self.Blocks.append(powerrail)
+            self.Elements.append(powerrail)
+            self.Controler.AddCurrentElementEditingPowerRail(id, values["type"])
+            self.RefreshPowerRailModel(powerrail)
+            self.Refresh()
+        dialog.Destroy()
+
+    def AddNewTransition(self, bbox):
+        dialog = TransitionContentDialog(self.Parent)
+        dialog.SetTransitions(self.Controler.GetCurrentElementEditingTransitions())
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            transition = SFC_Transition(self, values["type"], values["value"], id)
+            transition.SetPosition(bbox.x, bbox.y)
+            min_width, min_height = transition.GetMinSize()
+            transition.SetSize(max(bbox.width, min_width), max(bbox.height, min_height))
+            self.Blocks.append(transition)
+            self.Elements.append(transition)
+            self.Controler.AddCurrentElementEditingTransition(id)
+            self.RefreshTransitionModel(transition)
+            self.Refresh()
+        dialog.Destroy()
+
+    def AddNewDivergence(self, bbox):
+        dialog = DivergenceCreateDialog(self.Parent)
+        dialog.SetMinSize((bbox.width, bbox.height))
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            divergence = SFC_Divergence(self, values["type"], values["number"], id)
+            divergence.SetPosition(bbox.x, bbox.y)
+            min_width, min_height = divergence.GetMinSize()
+            divergence.SetSize(max(bbox.width, min_width), max(bbox.height, min_height))
+            self.Blocks.append(divergence)
+            self.Elements.append(divergence)
+            self.Controler.AddCurrentElementEditingDivergence(id, values["type"])
+            self.RefreshDivergenceModel(divergence)
+            self.Refresh()
+        dialog.Destroy()
 
 #-------------------------------------------------------------------------------
 #                          Model update functions
@@ -764,6 +1157,146 @@
         infos["connector"] = actionblock.GetConnector()
         self.Controler.SetCurrentElementEditingActionBlockInfos(actionblockid, infos)
 
+
+#-------------------------------------------------------------------------------
+#                          Model delete functions
+#-------------------------------------------------------------------------------
+
+
+    def DeleteBlock(self, block):
+        elements = []
+        for output in block.GetConnectors()["outputs"]:
+            for element in output.GetConnectedBlocks():
+                if element not in elements:
+                    elements.append(element)
+        block.Clean()
+        self.Blocks.remove(block)
+        self.Elements.remove(block)
+        self.Controler.RemoveCurrentElementEditingInstance(block.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteVariable(self, variable):
+        connectors = variable.GetConnectors()
+        if connectors["output"]:
+            elements = connectors["output"].GetConnectedBlocks()
+        else:
+            elements = []
+        variable.Clean()
+        self.Blocks.remove(variable)
+        self.Elements.remove(variable)
+        self.Controler.RemoveCurrentElementEditingInstance(variable.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteConnection(self, connection):
+        if connection.GetType() == CONTINUATION:
+            elements = connection.GetConnector().GetConnectedBlocks()
+        else:
+            elements = []
+        connection.Clean()
+        self.Blocks.remove(connection)
+        self.Elements.remove(connection)
+        self.Controler.RemoveCurrentElementEditingInstance(connection.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteComment(self, comment):
+        self.Elements.remove(comment)
+        self.Controler.RemoveCurrentElementEditingInstance(comment.GetId())
+
+    def DeleteWire(self, wire):
+        connected = wire.GetConnected()
+        wire.Clean()
+        self.Wires.remove(wire)
+        self.Elements.remove(wire)
+        for connector in connected:
+            connector.RefreshParentBlock()
+
+    def DeleteContact(self, contact):
+        connectors = contact.GetConnectors()
+        elements = connectors["output"].GetConnectedBlocks()
+        contact.Clean()
+        self.Blocks.remove(contact)
+        self.Elements.remove(contact)
+        self.Controler.RemoveCurrentElementEditingInstance(contact.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteCoil(self, coil):
+        connectors = coil.GetConnectors()
+        elements = connectors["output"].GetConnectedBlocks()
+        coil.Clean()
+        self.Blocks.remove(coil)
+        self.Elements.remove(coil)
+        self.Controler.RemoveCurrentElementEditingInstance(coil.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeletePowerRail(self, powerrail):
+        elements = []
+        if powerrail.GetType() == LEFTRAIL:
+            for connector in powerrail.GetConnectors():
+                for element in connector.GetConnectedBlocks():
+                    if element not in elements:
+                        elements.append(element)
+        powerrrail.Clean()
+        self.Blocks.remove(powerrrail)
+        self.Elements.remove(powerrrail)
+        self.Controler.RemoveCurrentElementEditingInstance(powerrrail.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+#-------------------------------------------------------------------------------
+#                          Edit element content functions
+#-------------------------------------------------------------------------------
+
+    def EditBlockContent(self, block):
+        dialog = BlockPropertiesDialog(self.Parent)
+        dialog.SetBlockList(self.Controler.GetBlockTypes())
+        dialog.SetMinBlockSize(block.GetSize())
+        values = {"name" : block.GetName(), "type" : block.GetType()}
+        values["extension"] = block.GetExtension()
+        dialog.SetValues(values)
+        if dialog.ShowModal() == wxID_OK:
+            values = dialog.GetValues()
+            if "name" in values:
+                block.SetName(values["name"])
+            block.SetSize(values["width"], values["height"])
+            block.SetType(values["type"], values["extension"])
+            self.RefreshBlockModel(block)
+            self.Refresh()
+        dialog.Destroy()
+
+    def EditVariableContent(self, variable):
+        dialog = VariablePropertiesDialog(self.Parent)
+        dialog.SetMinVariableSize(variable.GetSize())
+        varlist = []
+        vars = self.Controler.GetCurrentElementEditingInterfaceVars()
+        if vars:
+            for var in vars:
+                varlist.append((var["Name"], var["Class"], var["Type"]))
+        returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
+        if returntype:
+            varlist.append((self.Controler.GetCurrentElementEditingName(), "Output", returntype))
+        dialog.SetVariables(varlist)
+        values = {"name" : variable.GetName(), "type" : variable.GetType()}
+        dialog.SetValues(values)
+        if dialog.ShowModal() == wxID_OK:
+            old_type = variable.GetType()
+            values = dialog.GetValues()
+            variable.SetName(values["name"])
+            variable.SetType(values["type"], values["value_type"])
+            variable.SetSize(values["width"], values["height"])
+            if old_type != values["type"]:
+                id = variable.GetId()
+                self.Controler.RemoveCurrentElementEditingInstance(id)
+                self.Controler.AddCurrentElementEditingVariable(id, values["type"])
+            self.RefreshVariableModel(variable)
+            self.Refresh()
+        dialog.Destroy()
+
+
 #-------------------------------------------------------------------------------
 #                            Editing functions
 #-------------------------------------------------------------------------------
@@ -781,8 +1314,12 @@
 #                            Drawing functions
 #-------------------------------------------------------------------------------
 
+    def OnMoveWindow(self, event):
+        self.RefreshScrollBar()
+        event.Skip()
+
     def OnPaint(self, event):
-        dc = wxClientDC(self)
+        dc = self.GetLogicalDC()
         dc.Clear()
         dc.SetPen(wxPen(wxColour(230, 230, 230)))
         if self.Scaling and self.DrawGrid:
@@ -799,778 +1336,8 @@
                 element.Draw(dc)
         if self.SelectedElement:
             self.SelectedElement.Draw(dc)
-        event.Skip()
-
-
-#-------------------------------------------------------------------------------
-#                         Textual programs Viewer class
-#-------------------------------------------------------------------------------
-
-
-NEWLINE = "\n"
-NUMBERS = [str(i) for i in xrange(10)]
-LETTERS = ['_']
-for i in xrange(26):
-    LETTERS.append(chr(ord('a') + i))
-    LETTERS.append(chr(ord('A') + i))
-
-[wxSTC_PLC_WORD, wxSTC_PLC_COMMENT, wxSTC_PLC_NUMBER, wxSTC_PLC_VARIABLE, 
- wxSTC_PLC_FUNCTION, wxSTC_PLC_JUMP] = range(6)
-[SPACE, WORD, NUMBER, COMMENT] = range(4)
-
-[wxID_TEXTVIEWER,
-] = [wx.NewId() for _init_ctrls in range(1)]
-
-if wx.Platform == '__WXMSW__':
-    faces = { 'times': 'Times New Roman',
-              'mono' : 'Courier New',
-              'helv' : 'Arial',
-              'other': 'Comic Sans MS',
-              'size' : 10,
-             }
-else:
-    faces = { 'times': 'Times',
-              'mono' : 'Courier',
-              'helv' : 'Helvetica',
-              'other': 'new century schoolbook',
-              'size' : 12,
-             }
-re_texts = {}
-re_texts["letter"] = "[A-Za-z]"
-re_texts["digit"] = "[0-9]"
-re_texts["identifier"] = "((?:%(letter)s|(?:_(?:%(letter)s|%(digit)s)))(?:_?(?:%(letter)s|%(digit)s))*)"%re_texts
-IDENTIFIER_MODEL = re.compile(re_texts["identifier"])
-LABEL_MODEL = re.compile("[ \t\n]%(identifier)s:[ \t\n]"%re_texts)
-
-class TextViewer(wxStyledTextCtrl):
-    
-    def __init__(self, parent, window, controler):
-        wxStyledTextCtrl.__init__(self, parent, wxID_TEXTVIEWER, style=0)
-        
-        self.CmdKeyAssign(ord('+'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMIN)
-        self.CmdKeyAssign(ord('-'), wxSTC_SCMOD_CTRL, wxSTC_CMD_ZOOMOUT)
-        
-        self.SetViewWhiteSpace(False)
-        
-        self.SetLexer(wxSTC_LEX_CONTAINER)
-        
-        # Global default styles for all languages
-        self.StyleSetSpec(wxSTC_STYLE_DEFAULT, "face:%(mono)s,size:%(size)d" % faces)
-        self.StyleClearAll()  # Reset all to be like the default
-        
-        self.StyleSetSpec(wxSTC_STYLE_LINENUMBER,  "back:#C0C0C0,size:%(size)d" % faces)
-        self.SetSelBackground(1, "#E0E0E0")
-        
-        # Highlighting styles
-        self.StyleSetSpec(wxSTC_PLC_WORD, "fore:#00007F,bold,size:%(size)d" % faces)
-        self.StyleSetSpec(wxSTC_PLC_VARIABLE, "fore:#7F0000,size:%(size)d" % faces)
-        self.StyleSetSpec(wxSTC_PLC_FUNCTION, "fore:#7F7F00,size:%(size)d" % faces)
-        self.StyleSetSpec(wxSTC_PLC_COMMENT, "fore:#7F7F7F,size:%(size)d" % faces)
-        self.StyleSetSpec(wxSTC_PLC_NUMBER, "fore:#007F7F,size:%(size)d" % faces)
-        self.StyleSetSpec(wxSTC_PLC_JUMP, "fore:#007F00,size:%(size)d" % faces)
-        
-        # Indicators styles
-        self.IndicatorSetStyle(0, wxSTC_INDIC_SQUIGGLE)
-        self.IndicatorSetForeground(0, wxRED)
-        
-        # Line numbers in the margin
-        self.SetMarginType(1, wxSTC_MARGIN_NUMBER)
-        self.SetMarginWidth(1, 50)
-        
-        # Indentation size
-        self.SetTabWidth(2)
-        self.SetUseTabs(0)
-        
-        self.Keywords = []
-        self.Variables = []
-        self.Functions = []
-        self.Jumps = []
-        self.TextChanged = False
-        self.TextSyntax = "ST"
-        
-        self.Controler = controler
-
-        EVT_KEY_DOWN(self, self.OnKeyDown)
-        EVT_STC_STYLENEEDED(self, wxID_TEXTVIEWER, self.OnStyleNeeded)
-        EVT_KILL_FOCUS(self, self.OnKillFocus)
-    
-    def SetTextSyntax(self, syntax):
-        self.TextSyntax = syntax
-    
-    def SetKeywords(self, keywords):
-        self.Keywords = [keyword.upper() for keyword in keywords]
-        self.Colourise(0, -1)
-    
-    def SetVariables(self, variables):
-        self.Variables = [variable.upper() for variable in variables]
-        self.Colourise(0, -1)
-    
-    def SetFunctions(self, blocktypes):
-        self.Functions = []
-        for category in blocktypes:
-            for blocktype in category["list"]:
-                if blocktype["name"] not in self.Keywords and blocktype["name"] not in self.Variables:
-                    self.Functions.append(blocktype["name"].upper())
-        self.Colourise(0, -1)
-    
-    def RefreshJumpList(self):
-        self.Jumps = [jump.upper() for jump in LABEL_MODEL.findall(self.GetText())]
-        self.Colourise(0, -1)
-    
-    def RefreshView(self):
-        self.SetText(self.Controler.GetCurrentElementEditingText())
-        self.RefreshJumpList()
-    
-    def OnStyleNeeded(self, event):
-        self.TextChanged = True
-        line = self.LineFromPosition(self.GetEndStyled())
-        if line == 0:
-            start_pos = 0
-        else:
-            start_pos = self.GetLineEndPosition(line - 1) + 1
-        end_pos = event.GetPosition()
-        self.StartStyling(start_pos, 0xff)
-        
-        i = start_pos
-        state = SPACE
-        line = ""
-        word = ""
-        while i < end_pos:
-            char = chr(self.GetCharAt(i)).upper()
-            line += char
-            if char == NEWLINE:
-                if state == COMMENT:
-                    self.SetStyling(i - start_pos + 1, wxSTC_PLC_COMMENT)
-                elif state == NUMBER:
-                    self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER)
-                elif state == WORD:
-                    if word in self.Keywords:
-                        self.SetStyling(i - start_pos, wxSTC_PLC_WORD)
-                    elif word in self.Variables:
-                        self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE)
-                    elif word in self.Functions:
-                        self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION)
-                    elif word in self.Jumps:
-                        self.SetStyling(i - start_pos, wxSTC_PLC_JUMP)
-                    else:
-                        self.SetStyling(i - start_pos, 31)
-                        if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i:
-                            self.StartStyling(start_pos, wxSTC_INDICS_MASK)
-                            self.SetStyling(i - start_pos, wxSTC_INDIC0_MASK)
-                            self.StartStyling(i, 0xff)    
-                else:
-                    self.SetStyling(i - start_pos, 31)
-                start_pos = i
-                state = SPACE
-                line = ""
-            elif line.endswith("(*") and state != COMMENT:
-                self.SetStyling(i - start_pos - 1, 31)
-                start_pos = i
-                state = COMMENT
-            elif state == COMMENT:
-                if line.endswith("*)"):
-                    self.SetStyling(i - start_pos + 2, wxSTC_PLC_COMMENT)
-                    start_pos = i + 1
-                    state = SPACE
-            elif char in LETTERS:
-                if state == NUMBER:
-                    word = "#"
-                    state = WORD
-                elif state == SPACE:
-                    self.SetStyling(i - start_pos, 31)
-                    word = char
-                    start_pos = i
-                    state = WORD
-                else:
-                    word += char
-            elif char in NUMBERS or char == '.' and state != WORD:
-                if state == SPACE:
-                    self.SetStyling(i - start_pos, 31)
-                    start_pos = i
-                    state = NUMBER
-                if state == WORD and char != '.':
-                    word += char
-            else:
-                if state == WORD:
-                    if word in self.Keywords:
-                        self.SetStyling(i - start_pos, wxSTC_PLC_WORD)
-                    elif word in self.Variables:
-                        self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE)
-                    elif word in self.Functions:
-                        self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION)
-                    elif word in self.Jumps:
-                        self.SetStyling(i - start_pos, wxSTC_PLC_JUMP)
-                    else:
-                        self.SetStyling(i - start_pos, 31)
-                        if self.GetCurrentPos() < start_pos or self.GetCurrentPos() > i:
-                            self.StartStyling(start_pos, wxSTC_INDICS_MASK)
-                            self.SetStyling(i - start_pos, wxSTC_INDIC0_MASK)
-                            self.StartStyling(i, 0xff)
-                    word = ""
-                    start_pos = i
-                    state = SPACE
-                elif state == NUMBER:
-                    self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER)
-                    start_pos = i
-                    state = SPACE
-            i += 1
-        if state == COMMENT:
-            self.SetStyling(i - start_pos + 2, wxSTC_PLC_COMMENT)
-        elif state == NUMBER:
-            self.SetStyling(i - start_pos, wxSTC_PLC_NUMBER)
-        elif state == WORD:
-            if word in self.Keywords:
-                self.SetStyling(i - start_pos, wxSTC_PLC_WORD)
-            elif word in self.Variables:
-                self.SetStyling(i - start_pos, wxSTC_PLC_VARIABLE)
-            elif word in self.Functions:
-                self.SetStyling(i - start_pos, wxSTC_PLC_FUNCTION)
-            elif word in self.Jumps:
-                self.SetStyling(i - start_pos, wxSTC_PLC_JUMP)
-            else:
-                self.SetStyling(i - start_pos, 31)
-        else:
-            self.SetStyling(i - start_pos, 31)
-        event.Skip()
-    
-    def Cut(self):
-        self.CmdKeyExecute(wxSTC_CMD_CUT)
-        
-    def Copy(self):
-        self.CmdKeyExecute(wxSTC_CMD_COPY)
-    
-    def Paste(self):
-        self.CmdKeyExecute(wxSTC_CMD_PASTE)
-    
-    def RefreshModel(self):
-        if self.TextChanged:
-            self.RefreshJumpList()
-            self.Controler.SetCurrentElementEditingText(self.GetText())
-    
-    def OnKeyDown(self, event):
-        if self.CallTipActive():
-            self.CallTipCancel()
-        key = event.KeyCode()
-
-        # Code completion
-        if key == WXK_SPACE and event.ControlDown():
-            
-            line = self.GetCurrentLine()
-            if line == 0:
-                start_pos = 0
-            else:
-                start_pos = self.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 = []
-            
-            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
-            else:
-                kw = self.Keywords + self.Variables + self.Functions
-            if len(kw) > 0:
-                kw.sort()
-                self.AutoCompSetIgnoreCase(True)
-                self.AutoCompShow(len(words[-1]), " ".join(kw))
-        else:
-            self.TextChanged = False
-            wxCallAfter(self.RefreshModel)
-            event.Skip()
-
-    def OnKillFocus(self, event):
-        self.AutoCompCancel()
-        event.Skip()
-
-
-#-------------------------------------------------------------------------------
-#                            Resource Editor class
-#-------------------------------------------------------------------------------
-
-class ResourceTable(wxPyGridTableBase):
-    
-    """
-    A custom wxGrid Table using user supplied data
-    """
-    def __init__(self, parent, data, colnames):
-        # The base class must be initialized *first*
-        wxPyGridTableBase.__init__(self)
-        self.data = data
-        self.colnames = colnames
-        self.Parent = parent
-        
-        self.ColAlignements = []
-        self.ColSizes = []
-        # XXX
-        # we need to store the row length and collength to
-        # see if the table has changed size
-        self._rows = self.GetNumberRows()
-        self._cols = self.GetNumberCols()
-    
-    def GetColAlignements(self):
-        return self.ColAlignements
-    
-    def SetColAlignements(self, list):
-        self.ColAlignements = list
-
-    def GetColSizes(self):
-        return self.ColSizes
-    
-    def SetColSizes(self, list):
-        self.ColSizes = list
-
-    def GetNumberCols(self):
-        return len(self.colnames)
-        
-    def GetNumberRows(self):
-        return len(self.data)
-
-    def GetColLabelValue(self, col):
-        if col < len(self.colnames):
-            return self.colnames[col]
-
-    def GetRowLabelValues(self, row):
-        return row
-
-    def GetValue(self, row, col):
-        if row < self.GetNumberRows():
-            name = str(self.data[row].get(self.GetColLabelValue(col), ""))
-            return name
-    
-    def GetValueByName(self, row, colname):
-        return self.data[row].get(colname)
-
-    def SetValue(self, row, col, value):
-        if col < len(self.colnames):
-            self.data[row][self.GetColLabelValue(col)] = value
-    
-    def SetValueByName(self, row, colname, value):
-        if colname in self.colnames:
-            self.data[row][colname] = value
-    
-    def ResetView(self, grid):
-        """
-        (wxGrid) -> Reset the grid view.   Call this to
-        update the grid if rows and columns have been added or deleted
-        """
-        grid.BeginBatch()
-        for current, new, delmsg, addmsg in [
-            (self._rows, self.GetNumberRows(), wxGRIDTABLE_NOTIFY_ROWS_DELETED, wxGRIDTABLE_NOTIFY_ROWS_APPENDED),
-            (self._cols, self.GetNumberCols(), wxGRIDTABLE_NOTIFY_COLS_DELETED, wxGRIDTABLE_NOTIFY_COLS_APPENDED),
-        ]:
-            if new < current:
-                msg = wxGridTableMessage(self,delmsg,new,current-new)
-                grid.ProcessTableMessage(msg)
-            elif new > current:
-                msg = wxGridTableMessage(self,addmsg,new-current)
-                grid.ProcessTableMessage(msg)
-                self.UpdateValues(grid)
-        grid.EndBatch()
-
-        self._rows = self.GetNumberRows()
-        self._cols = self.GetNumberCols()
-        # update the column rendering scheme
-        self._updateColAttrs(grid)
-
-        # update the scrollbars and the displayed part of the grid
-        grid.AdjustScrollbars()
-        grid.ForceRefresh()
-
-    def UpdateValues(self, grid):
-        """Update all displayed values"""
-        # This sends an event to the grid table to update all of the values
-        msg = wxGridTableMessage(self, wxGRIDTABLE_REQUEST_VIEW_GET_VALUES)
-        grid.ProcessTableMessage(msg)
-
-    def _updateColAttrs(self, grid):
-        """
-        wxGrid -> update the column attributes to add the
-        appropriate renderer given the column name.
-
-        Otherwise default to the default renderer.
-        """
-        
-        for col in range(self.GetNumberCols()):
-            attr = wxGridCellAttr()
-            attr.SetAlignment(self.ColAlignements[col], wxALIGN_CENTRE)
-            grid.SetColAttr(col, attr)
-            grid.SetColSize(col, self.ColSizes[col])
-        
-        for row in range(self.GetNumberRows()):
-            for col in range(self.GetNumberCols()):
-                editor = None
-                renderer = None
-                colname = self.GetColLabelValue(col)
-                grid.SetReadOnly(row, col, False)
-                if colname in ["Name","Interval"]:
-                    editor = wxGridCellTextEditor()
-                    renderer = wxGridCellStringRenderer()
-                    if colname == "Interval" and self.GetValueByName(row, "Single") != "":
-                        grid.SetReadOnly(row, col, True)
-                elif colname == "Single":
-                    editor = wxGridCellChoiceEditor()
-                    editor.SetParameters(self.Parent.VariableList)
-                    if self.GetValueByName(row, "Interval") != "":
-                        grid.SetReadOnly(row, col, True)
-                elif colname == "Type":
-                    editor = wxGridCellChoiceEditor()
-                    editor.SetParameters(self.Parent.TypeList)
-                elif colname == "Priority":
-                    editor = wxGridCellNumberEditor()
-                    editor.SetParameters("0,65535")
-                elif colname == "Task":
-                    editor = wxGridCellChoiceEditor()
-                    editor.SetParameters(self.Parent.TaskList)
-                    
-                grid.SetCellEditor(row, col, editor)
-                grid.SetCellRenderer(row, col, renderer)
-                
-                grid.SetCellBackgroundColour(row, col, wxWHITE)
-    
-    def SetData(self, data):
-        self.data = data
-    
-    def GetData(self):
-        return self.data
-    
-    def GetCurrentIndex(self):
-        return self.CurrentIndex
-    
-    def SetCurrentIndex(self, index):
-        self.CurrentIndex = index
-    
-    def AppendRow(self, row_content):
-        self.data.append(row_content)
-
-    def RemoveRow(self, row_index):
-        self.data.pop(row_index)
-        
-    def MoveRow(self, row_index, move, grid):
-        new_index = max(0, min(row_index + move, len(self.data) - 1))
-        if new_index != row_index:
-            self.data.insert(new_index, self.data.pop(row_index))
-            grid.SetGridCursor(new_index, grid.GetGridCursorCol())
-
-    def Empty(self):
-        self.data = []
-        self.editors = []
-
-[wxID_RESOURCEEDITOR, wxID_RESOURCEEDITORSTATICTEXT1,
- wxID_RESOURCEEDITORSTATICTEXT2, wxID_RESOURCEEDITORINSTANCESGRID,
- wxID_RESOURCEEDITORTASKSGRID, wxID_RESOURCEEDITORADDINSTANCEBUTTON,
- wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, wxID_RESOURCEEDITORUPINSTANCEBUTTON,
- wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, wxID_RESOURCEEDITORADDTASKBUTTON,
- wxID_RESOURCEEDITORDELETETASKBUTTON, wxID_RESOURCEEDITORUPTASKBUTTON,
- wxID_RESOURCEEDITORDOWNTASKBUTTON,
-] = [wx.NewId() for _init_ctrls in range(13)]
-
-class ResourceEditor(wx.Panel):
-    
-    def _init_coll_InstancesSizer_Growables(self, parent):
-        # generated method, don't edit
-
-        parent.AddGrowableCol(0)
-        parent.AddGrowableRow(1)
-
-    def _init_coll_InstancesSizer_Items(self, parent):
-        # generated method, don't edit
-
-        parent.AddSizer(self.InstancesButtonsSizer, 0, border=0, flag=wxGROW)
-        parent.AddWindow(self.InstancesGrid, 0, border=0, flag=wxGROW)
-
-    def _init_coll_InstancesButtonsSizer_Growables(self, parent):
-        # generated method, don't edit
-
-        parent.AddGrowableCol(0)
-        parent.AddGrowableRow(0)
-
-    def _init_coll_InstancesButtonsSizer_Items(self, parent):
-        # generated method, don't edit
-
-        parent.AddWindow(self.staticText2, 0, border=0, flag=wxALIGN_BOTTOM)
-        parent.AddWindow(self.AddInstanceButton, 0, border=0, flag=0)
-        parent.AddWindow(self.DeleteInstanceButton, 0, border=0, flag=0)
-        parent.AddWindow(self.UpInstanceButton, 0, border=0, flag=0)
-        parent.AddWindow(self.DownInstanceButton, 0, border=0, flag=0)
-
-    def _init_coll_TasksSizer_Growables(self, parent):
-        # generated method, don't edit
-
-        parent.AddGrowableCol(0)
-        parent.AddGrowableRow(1)
-
-    def _init_coll_TasksSizer_Items(self, parent):
-        # generated method, don't edit
-
-        parent.AddSizer(self.TasksButtonsSizer, 0, border=0, flag=wxGROW)
-        parent.AddWindow(self.TasksGrid, 0, border=0, flag=wxGROW)
-
-    def _init_coll_TasksButtonsSizer_Growables(self, parent):
-        # generated method, don't edit
-
-        parent.AddGrowableCol(0)
-        parent.AddGrowableRow(0)
-
-    def _init_coll_TasksButtonsSizer_Items(self, parent):
-        # generated method, don't edit
-
-        parent.AddWindow(self.staticText1, 0, border=0, flag=wxALIGN_BOTTOM)
-        parent.AddWindow(self.AddTaskButton, 0, border=0, flag=0)
-        parent.AddWindow(self.DeleteTaskButton, 0, border=0, flag=0)
-        parent.AddWindow(self.UpTaskButton, 0, border=0, flag=0)
-        parent.AddWindow(self.DownTaskButton, 0, border=0, flag=0)
-
-    def _init_coll_MainGridSizer_Items(self, parent):
-        # generated method, don't edit
-
-        parent.AddSizer(self.TasksSizer, 0, border=0, flag=wxGROW)
-        parent.AddSizer(self.InstancesSizer, 0, border=0, flag=wxGROW)
-
-    def _init_coll_MainGridSizer_Growables(self, parent):
-        # generated method, don't edit
-
-        parent.AddGrowableCol(0)
-        parent.AddGrowableRow(0)
-        parent.AddGrowableRow(1)
-
-    def _init_sizers(self):
-        # generated method, don't edit
-        self.MainGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
-
-        self.InstancesSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
-
-        self.InstancesButtonsSizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
-
-        self.TasksSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
-
-        self.TasksButtonsSizer = wx.FlexGridSizer(cols=5, hgap=5, rows=1, vgap=0)
-
-        self._init_coll_MainGridSizer_Growables(self.MainGridSizer)
-        self._init_coll_MainGridSizer_Items(self.MainGridSizer)
-        self._init_coll_InstancesSizer_Growables(self.InstancesSizer)
-        self._init_coll_InstancesSizer_Items(self.InstancesSizer)
-        self._init_coll_InstancesButtonsSizer_Growables(self.InstancesButtonsSizer)
-        self._init_coll_InstancesButtonsSizer_Items(self.InstancesButtonsSizer)
-        self._init_coll_TasksSizer_Growables(self.TasksSizer)
-        self._init_coll_TasksSizer_Items(self.TasksSizer)
-        self._init_coll_TasksButtonsSizer_Growables(self.TasksButtonsSizer)
-        self._init_coll_TasksButtonsSizer_Items(self.TasksButtonsSizer)
-
-        self.SetSizer(self.MainGridSizer)
-
-    def _init_ctrls(self, prnt):
-        # generated method, don't edit
-        wx.Panel.__init__(self, id=wxID_RESOURCEEDITOR, name='', parent=prnt,
-              pos=wx.Point(0, 0), size=wx.Size(-1, -1),
-              style=wx.SUNKEN_BORDER)
-        
-        self.staticText1 = wx.StaticText(id=wxID_RESOURCEEDITORSTATICTEXT1,
-              label=u'Tasks:', name='staticText2', parent=self, pos=wx.Point(0,
-              0), size=wx.Size(60, 17), style=wxALIGN_CENTER)
-
-        self.TasksGrid = wx.grid.Grid(id=wxID_RESOURCEEDITORTASKSGRID,
-              name='TasksGrid', parent=self, pos=wx.Point(0, 0), 
-              size=wx.Size(-1, -1), style=wxVSCROLL)
-        self.TasksGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
-              'Sans'))
-        self.TasksGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
-              False, 'Sans'))
-        EVT_GRID_CELL_CHANGE(self.TasksGrid, self.OnTasksGridCellChange)
-
-        self.AddTaskButton = wx.Button(id=wxID_RESOURCEEDITORADDTASKBUTTON, label='Add Task',
-              name='AddTaskButton', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(102, 32), style=0)
-        EVT_BUTTON(self, wxID_RESOURCEEDITORADDTASKBUTTON, self.OnAddTaskButton)
-
-        self.DeleteTaskButton = wx.Button(id=wxID_RESOURCEEDITORDELETETASKBUTTON, label='Delete Task',
-              name='DeleteTaskButton', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(102, 32), style=0)
-        EVT_BUTTON(self, wxID_RESOURCEEDITORDELETETASKBUTTON, self.OnDeleteTaskButton)
-
-        self.UpTaskButton = wx.Button(id=wxID_RESOURCEEDITORUPTASKBUTTON, label='^',
-              name='UpTaskButton', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(32, 32), style=0)
-        EVT_BUTTON(self, wxID_RESOURCEEDITORUPTASKBUTTON, self.OnUpTaskButton)
-
-        self.DownTaskButton = wx.Button(id=wxID_RESOURCEEDITORDOWNTASKBUTTON, label='v',
-              name='DownTaskButton', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(32, 32), style=0)
-        EVT_BUTTON(self, wxID_RESOURCEEDITORDOWNTASKBUTTON, self.OnDownTaskButton)
-
-        self.staticText2 = wx.StaticText(id=wxID_RESOURCEEDITORSTATICTEXT2,
-              label=u'Instances:', name='staticText1', parent=self,
-              pos=wx.Point(0, 0), size=wx.Size(85, 17), style=wxALIGN_CENTER)
-
-        self.InstancesGrid = wx.grid.Grid(id=wxID_RESOURCEEDITORINSTANCESGRID,
-              name='InstancesGrid', parent=self, pos=wx.Point(0, 0), 
-              size=wx.Size(-1, -1), style=wxVSCROLL)
-        self.InstancesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
-              'Sans'))
-        self.InstancesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
-              False, 'Sans'))
-        EVT_GRID_CELL_CHANGE(self.InstancesGrid, self.OnInstancesGridCellChange)
-
-        self.AddInstanceButton = wx.Button(id=wxID_RESOURCEEDITORADDINSTANCEBUTTON, label='Add Instance',
-              name='AddInstanceButton', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(122, 32), style=0)
-        EVT_BUTTON(self, wxID_RESOURCEEDITORADDINSTANCEBUTTON, self.OnAddInstanceButton)
-
-        self.DeleteInstanceButton = wx.Button(id=wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, label='Delete Instance',
-              name='DeleteInstanceButton', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(122, 32), style=0)
-        EVT_BUTTON(self, wxID_RESOURCEEDITORDELETEINSTANCEBUTTON, self.OnDeleteInstanceButton)
-
-        self.UpInstanceButton = wx.Button(id=wxID_RESOURCEEDITORUPINSTANCEBUTTON, label='^',
-              name='UpInstanceButton', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(32, 32), style=0)
-        EVT_BUTTON(self, wxID_RESOURCEEDITORUPINSTANCEBUTTON, self.OnUpInstanceButton)
-
-        self.DownInstanceButton = wx.Button(id=wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, label='v',
-              name='DownInstanceButton', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(32, 32), style=0)
-        EVT_BUTTON(self, wxID_RESOURCEEDITORDOWNINSTANCEBUTTON, self.OnDownInstanceButton)
-
-        self._init_sizers()
-
-    def __init__(self, parent, window, controler):
-        self._init_ctrls(parent)
-        
-        self.Parent = window
-        self.Controler = controler
-        
-        self.TasksDefaultValue = {"Name" : "", "Single" : "", "Interval" : "", "Priority" : 0}
-        self.TasksTable = ResourceTable(self, [], ["Name", "Single", "Interval", "Priority"])
-        self.TasksTable.SetColAlignements([wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_RIGHT, wxALIGN_RIGHT])
-        self.TasksTable.SetColSizes([200, 100, 100, 100])
-        self.TasksGrid.SetTable(self.TasksTable)
-        self.TasksGrid.SetRowLabelSize(0)
-        self.TasksTable.ResetView(self.TasksGrid)
-
-        self.InstancesDefaultValue = {"Name" : "", "Type" : "", "Task" : ""}
-        self.InstancesTable = ResourceTable(self, [], ["Name", "Type", "Task"])
-        self.InstancesTable.SetColAlignements([wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT])
-        self.InstancesTable.SetColSizes([200, 150, 150])
-        self.InstancesGrid.SetTable(self.InstancesTable)
-        self.InstancesGrid.SetRowLabelSize(0)
-        self.InstancesTable.ResetView(self.InstancesGrid)
-
-    def SetMode(self, mode):
-        pass
-
-    def RefreshTypeList(self):
-        self.TypeList = ""
-        blocktypes = self.Controler.GetBlockResource()
-        for blocktype in blocktypes:
-            self.TypeList += ",%s"%blocktype
-
-    def RefreshTaskList(self):
-        self.TaskList = ""
-        for row in xrange(self.TasksTable.GetNumberRows()):
-            self.TaskList += ",%s"%self.TasksTable.GetValueByName(row, "Name")
-
-    def RefreshVariableList(self):
-        self.VariableList = ""
-        for variable in self.Controler.GetCurrentResourceEditingVariables():
-            self.VariableList += ",%s"%variable
-        
-    def RefreshModel(self):
-        self.Controler.SetCurrentResourceEditingInfos(self.TasksTable.GetData(), self.InstancesTable.GetData())
-
-    def RefreshView(self):
-        tasks, instances = self.Controler.GetCurrentResourceEditingInfos()
-        self.TasksTable.SetData(tasks)
-        self.InstancesTable.SetData(instances)
-        self.RefreshTypeList()
-        self.RefreshTaskList()
-        self.RefreshVariableList()
-        self.InstancesTable.ResetView(self.InstancesGrid)
-        self.TasksTable.ResetView(self.TasksGrid)
-
-    def OnAddTaskButton(self, event):
-        self.TasksTable.AppendRow(self.TasksDefaultValue.copy())
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
-
-    def OnDeleteTaskButton(self, event):
-        row = self.TasksGrid.GetGridCursorRow()
-        self.TasksTable.RemoveRow(row)
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
-
-    def OnUpTaskButton(self, event):
-        row = self.TasksGrid.GetGridCursorRow()
-        self.TasksTable.MoveRow(row, -1, self.TasksGrid)
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
-
-    def OnDownTaskButton(self, event):
-        row = self.TasksGrid.GetGridCursorRow()
-        self.TasksTable.MoveRow(row, 1, self.TasksGrid)
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
-
-    def OnAddInstanceButton(self, event):
-        self.InstancesTable.AppendRow(self.InstancesDefaultValue.copy())
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
-
-    def OnDeleteInstanceButton(self, event):
-        row = self.InstancesGrid.GetGridCursorRow()
-        self.InstancesTable.RemoveRow(row)
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
-
-    def OnUpInstanceButton(self, event):
-        row = self.InstancesGrid.GetGridCursorRow()
-        self.InstancesTable.MoveRow(row, -1, self.InstancesGrid)
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
-
-    def OnDownInstanceButton(self, event):
-        row = self.InstancesGrid.GetGridCursorRow()
-        self.InstancesTable.MoveRow(row, 1, self.InstancesGrid)
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
-
-    def OnTasksGridCellChange(self, event):
-        row, col = event.GetRow(), event.GetCol()
-        if self.TasksTable.GetColLabelValue(event.GetCol()) == "Name":
-            tasklist = self.TaskList.split(",")
-            for i in xrange(self.TasksTable.GetNumberRows()):
-                task = self.TasksTable.GetValueByName(i, "Name")
-                if task in tasklist:
-                    tasklist.remove(task)
-            tasklist.remove("")
-            if len(tasklist) > 0:
-                old_name = tasklist[0]
-                new_name = self.TasksTable.GetValue(row, col)
-                for i in xrange(self.InstancesTable.GetNumberRows()):
-                    if self.InstancesTable.GetValueByName(i, "Task") == old_name:
-                        self.InstancesTable.SetValueByName(i, "Task", new_name)
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
-
-    def OnInstancesGridCellChange(self, event):
-        self.RefreshModel()
-        self.RefreshView()
-        event.Skip()
+        if self.rubberBand.IsShown():
+            self.rubberBand.Draw()
+        event.Skip()
+
+