Fix Driven drawing in LD editor
authorpizza
Fri, 12 Aug 2011 17:04:55 +0200
changeset 550 cfa295862d55
parent 549 b0d6819119c3
child 551 ad74e44f55d9
Fix Driven drawing in LD editor
LDViewer.py
Viewer.py
graphics/GraphicCommons.py
graphics/LD_Objects.py
plcopen/plcopen.py
--- a/LDViewer.py	Mon Jul 04 15:24:44 2011 +0200
+++ b/LDViewer.py	Fri Aug 12 17:04:55 2011 +0200
@@ -23,6 +23,7 @@
 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 import wx
+import time
 from types import *
 
 from Viewer import *
@@ -203,7 +204,7 @@
                 self.Rungs.append(rung)
             elif instance["type"] == "rightPowerRail":
                 rungs = []
-                for connector in instance["connectors"]:
+                for connector in instance["inputs"]:
                     for link in connector["links"]:
                         connected = self.FindElementById(link["refLocalId"])
                         rung = self.FindRung(connected)
@@ -212,14 +213,15 @@
                 if len(rungs) > 1:
                     raise ValueError, _("Ladder element with id %d is on more than one rung.")%instance["id"]
                 element = self.FindElementById(instance["id"])
+                element_connectors = element.GetConnectors()
                 self.Rungs[rungs[0]].SelectElement(element)
-                for connector in element.GetConnectors():
+                for connector in element_connectors["inputs"]:
                     for wire, num in connector.GetWires():
                         self.Rungs[rungs[0]].SelectElement(wire)
-                self.RefreshPosition(element)
+                wx.CallAfter(self.RefreshPosition, element)
             elif instance["type"] in ["contact", "coil"]:
                 rungs = []
-                for link in instance["connectors"]["input"]["links"]:
+                for link in instance["inputs"][0]["links"]:
                     connected = self.FindElementById(link["refLocalId"])
                     rung = self.FindRung(connected)
                     if rung not in rungs:
@@ -227,10 +229,11 @@
                 if len(rungs) > 1:
                     raise ValueError, _("Ladder element with id %d is on more than one rung.")%instance["id"]
                 element = self.FindElementById(instance["id"])
+                element_connectors = element.GetConnectors() 
                 self.Rungs[rungs[0]].SelectElement(element)
-                for wire, num in element.GetConnectors()["input"].GetWires():
+                for wire, num in element_connectors["inputs"][0].GetWires():
                     self.Rungs[rungs[0]].SelectElement(wire)
-                self.RefreshPosition(element)
+                wx.CallAfter(self.RefreshPosition, element)
             elif instance["type"] == "comment":
                 element = self.FindElementById(instance["id"])
                 pos = element.GetPosition()
@@ -244,7 +247,7 @@
                     i += 1
                 if not inserted:
                     self.RungComments.append(element)
-
+            
 #-------------------------------------------------------------------------------
 #                          Search Element functions
 #-------------------------------------------------------------------------------
@@ -259,7 +262,7 @@
         if self.GetDrawingMode() == FREEDRAWING_MODE:
             return Viewer.FindElement(self, pos, exclude_group)
         
-        if self.SelectedElement and not (exclude_group and isinstance(self.SelectedElement, Graphic_Group)):
+        if self.SelectedElement and not isinstance(self.SelectedElement, (Graphic_Group, Wire)):
             if self.SelectedElement.HitTest(pos) or self.SelectedElement.TestHandle(pos) != (0, 0):
                 return self.SelectedElement
         elements = []
@@ -278,11 +281,8 @@
         return None
 
     def SearchElements(self, bbox):
-        if self.GetDrawingMode() == FREEDRAWING_MODE:
-            return Viewer.SearchElements(self, bbox)
-        
         elements = []
-        for element in self.Blocks:
+        for element in self.Blocks.values() + self.Comments.values():
             if element.IsInSelection(bbox):
                 elements.append(element)
         return elements
@@ -381,21 +381,6 @@
                 wx.CallAfter(self.SetCurrentCursor, 0)
         event.Skip()
 
-    def OnViewerLeftDClick(self, event):
-        if self.GetDrawingMode() == FREEDRAWING_MODE:
-            Viewer.OnViewerLeftDClick(self, event)
-        elif self.Mode == MODE_SELECTION and self.SelectedElement:
-            self.SelectedElement.OnLeftDClick(event, self.GetLogicalDC(), self.Scaling)
-            self.SelectedElement.Refresh()
-        event.Skip()
-
-    def OnViewerMotion(self, event):
-        if self.GetDrawingMode() == FREEDRAWING_MODE:
-            Viewer.OnViewerMotion(self, event)
-        elif self.rubberBand.IsShown():
-            self.rubberBand.OnMotion(event, self.GetLogicalDC(), self.Scaling)
-        event.Skip()
-
 #-------------------------------------------------------------------------------
 #                          Keyboard event functions
 #-------------------------------------------------------------------------------
@@ -492,7 +477,7 @@
 #-------------------------------------------------------------------------------
 
     def AddLadderRung(self):
-        dialog = LDElementDialog(self.ParentWindow, "coil")
+        dialog = LDElementDialog(self.ParentWindow, self.Controler, "coil")
         dialog.SetPreviewFont(self.GetFont())
         varlist = []
         vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
@@ -513,6 +498,7 @@
                 starty = bbox.y + bbox.height
             starty += LD_OFFSET[1]
             rung = Graphic_Group(self)
+            
             # Create comment
             id = self.GetNewId()
             comment = Comment(self, _("Comment"), id)
@@ -523,42 +509,50 @@
             self.Controler.AddEditedElementComment(self.TagName, id)
             self.RefreshCommentModel(comment)
             starty += LD_COMMENT_DEFAULTSIZE[1] + LD_OFFSET[1]
+            
             # Create LeftPowerRail
             id = self.GetNewId()
             leftpowerrail = LD_PowerRail(self, LEFTRAIL, id)
             leftpowerrail.SetPosition(startx, starty)
+            leftpowerrail_connectors = leftpowerrail.GetConnectors()
             self.AddBlock(leftpowerrail)
             rung.SelectElement(leftpowerrail)
             self.Controler.AddEditedElementPowerRail(self.TagName, id, LEFTRAIL)
             self.RefreshPowerRailModel(leftpowerrail)
+            
             # Create Coil
             id = self.GetNewId()
             coil = LD_Coil(self, values["type"], values["name"], id)
             coil.SetPosition(startx, starty + (LD_LINE_SIZE - LD_ELEMENT_SIZE[1]) / 2)
+            coil_connectors = coil.GetConnectors()
             self.AddBlock(coil)
             rung.SelectElement(coil)
             self.Controler.AddEditedElementCoil(self.TagName, id)
+            
             # Create Wire between LeftPowerRail and Coil
             wire = Wire(self)
-            start_connector = coil.GetConnectors()["input"]
-            end_connector = leftpowerrail.GetConnectors()[0]
+            start_connector = coil_connectors["inputs"][0]
+            end_connector = leftpowerrail_connectors["outputs"][0]
             start_connector.Connect((wire, 0), False)
             end_connector.Connect((wire, -1), False)
             wire.ConnectStartPoint(None, start_connector)
             wire.ConnectEndPoint(None, end_connector)
             self.AddWire(wire)
             rung.SelectElement(wire)
+            
             # Create RightPowerRail
             id = self.GetNewId()
             rightpowerrail = LD_PowerRail(self, RIGHTRAIL, id)
             rightpowerrail.SetPosition(startx, starty)
+            rightpowerrail_connectors = rightpowerrail.GetConnectors()
             self.AddBlock(rightpowerrail)
             rung.SelectElement(rightpowerrail)
             self.Controler.AddEditedElementPowerRail(self.TagName, id, RIGHTRAIL)
+            
             # Create Wire between LeftPowerRail and Coil
             wire = Wire(self)
-            start_connector = rightpowerrail.GetConnectors()[0]
-            end_connector = coil.GetConnectors()["output"]
+            start_connector = rightpowerrail_connectors["inputs"][0]
+            end_connector = coil_connectors["outputs"][0]
             start_connector.Connect((wire, 0), False)
             end_connector.Connect((wire, -1), False)
             wire.ConnectStartPoint(None, start_connector)
@@ -569,6 +563,7 @@
             self.Rungs.append(rung)
             self.RefreshBuffer()
             self.RefreshScrollBars()
+            self.RefreshVisibleElements()
             self.Refresh(False)
 
     def AddLadderContact(self):
@@ -582,7 +577,7 @@
                 for element in self.SelectedElement.GetElements():
                     wires.append(element)
         if len(wires) > 0:
-            dialog = LDElementDialog(self.ParentWindow, "contact")
+            dialog = LDElementDialog(self.ParentWindow, self.Controler, "contact")
             dialog.SetPreviewFont(self.GetFont())
             varlist = []
             vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
@@ -631,18 +626,18 @@
                 for i, left_element in enumerate(left_elements):
                     wire = Wire(self)
                     wires.append(wire)
-                    connectors["input"].Connect((wire, 0), False)
+                    connectors["inputs"][0].Connect((wire, 0), False)
                     left_element.InsertConnect(left_index[i], (wire, -1), False)
-                    wire.ConnectStartPoint(None, connectors["input"])
+                    wire.ConnectStartPoint(None, connectors["inputs"][0])
                     wire.ConnectEndPoint(None, left_element)
                 for i, right_element in enumerate(right_elements):
                     wire = Wire(self)
                     wires.append(wire)
                     right_wires.append(wire)
                     right_element.InsertConnect(right_index[i], (wire, 0), False)
-                    connectors["output"].Connect((wire, -1), False)
+                    connectors["outputs"][0].Connect((wire, -1), False)
                     wire.ConnectStartPoint(None, right_element)
-                    wire.ConnectEndPoint(None, connectors["output"])
+                    wire.ConnectEndPoint(None, connectors["outputs"][0])
                 right_wires.reverse()
                 for wire in wires:
                     self.AddWire(wire)
@@ -663,6 +658,7 @@
                 self.RefreshRungs(new_bbox.height - old_bbox.height, rungindex + 1)
                 self.RefreshBuffer()
                 self.RefreshScrollBars()
+                self.RefreshVisibleElements()
                 self.Refresh(False)
         else:
             message = wx.MessageDialog(self, _("You must select the wire where a contact should be added!"), _("Error"), wx.OK|wx.ICON_ERROR)
@@ -685,15 +681,8 @@
             right_index = []
             for block in blocks:
                 connectors = block.GetConnectors()
-                block_infos = {"inputs":[],"outputs":[],"lefts":[],"rights":[]}
-                if "inputs" in connectors:
-                    block_infos["inputs"] = connectors["inputs"]
-                if "outputs" in connectors:
-                    block_infos["outputs"] = connectors["outputs"]
-                if "input" in connectors:
-                    block_infos["inputs"] = [connectors["input"]]
-                if "output" in connectors:
-                    block_infos["outputs"] = [connectors["output"]]
+                block_infos = {"lefts":[],"rights":[]}
+                block_infos.update(connectors)
                 for connector in block_infos["inputs"]:
                     for wire, handle in connector.GetWires():
                         found = False
@@ -789,8 +778,6 @@
                         index = 0
                         for left_element in left_elements: 
                             index = max(index, powerrail.GetConnectorIndex(left_element))
-                        if powerrail.IsNullConnector(index + 1):
-                            powerrail.DeleteConnector(index + 1)
                         powerrail.InsertConnector(index + 1)
                         powerrail.RefreshModel()
                         connectors = powerrail.GetConnectors()
@@ -799,12 +786,12 @@
                             new_wire = Wire(self)
                             wires.append(new_wire)
                             right_element.InsertConnect(right_index[i] + 1, (new_wire, 0), False)
-                            connectors[index + 1].Connect((new_wire, -1), False)
+                            connectors["outputs"][index + 1].Connect((new_wire, -1), False)
                             new_wire.ConnectStartPoint(None, right_element)
-                            new_wire.ConnectEndPoint(None, connectors[index + 1])
+                            new_wire.ConnectEndPoint(None, connectors["outputs"][index + 1])
                         right_elements.reverse()
                     elif right_powerrail:
-                        dialog = LDElementDialog(self.ParentWindow, "coil")
+                        dialog = LDElementDialog(self.ParentWindow, self.Controleur, "coil")
                         dialog.SetPreviewFont(self.GetFont())
                         varlist = []
                         vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
@@ -823,11 +810,10 @@
                             index = 0
                             for right_element in right_elements: 
                                 index = max(index, powerrail.GetConnectorIndex(right_element))
-                            if powerrail.IsNullConnector(index + 1):
-                                powerrail.DeleteConnector(index + 1)
                             powerrail.InsertConnector(index + 1)
                             powerrail.RefreshModel()
                             connectors = powerrail.GetConnectors()
+                            
                             # Create Coil
                             id = self.GetNewId()
                             coil = LD_Coil(self, values["type"], values["name"], id)
@@ -837,23 +823,26 @@
                             rung.SelectElement(coil)
                             self.Controler.AddEditedElementCoil(self.TagName, id)
                             coil_connectors = coil.GetConnectors()
+                            
                             # Create Wire between LeftPowerRail and Coil
                             wire = Wire(self)
-                            connectors[index + 1].Connect((wire, 0), False)
-                            coil_connectors["output"].Connect((wire, -1), False)
-                            wire.ConnectStartPoint(None, connectors[index + 1])
-                            wire.ConnectEndPoint(None, coil_connectors["output"])
+                            connectors["inputs"][index + 1].Connect((wire, 0), False)
+                            coil_connectors["outputs"][0].Connect((wire, -1), False)
+                            wire.ConnectStartPoint(None, connectors["inputs"][index + 1])
+                            wire.ConnectEndPoint(None, coil_connectors["outputs"][0])
                             self.AddWire(wire)
                             rung.SelectElement(wire)
                             left_elements.reverse()
+                            
                             for i, left_element in enumerate(left_elements):
                                 # Create Wire between LeftPowerRail and Coil
                                 new_wire = Wire(self)
                                 wires.append(new_wire)
-                                coil_connectors["input"].Connect((new_wire, 0), False)
+                                coil_connectors["inputs"][0].Connect((new_wire, 0), False)
                                 left_element.InsertConnect(left_index[i] + 1, (new_wire, -1), False)
-                                new_wire.ConnectStartPoint(None, coil_connectors["input"])
+                                new_wire.ConnectStartPoint(None, coil_connectors["inputs"][0])
                                 new_wire.ConnectEndPoint(None, left_element)
+                            
                             self.RefreshPosition(coil)
                     else:
                         left_elements.reverse()
@@ -885,6 +874,7 @@
                 self.RefreshRungs(new_bbox.height - old_bbox.height, rungindex + 1)
                 self.RefreshBuffer()
                 self.RefreshScrollBars()
+                self.RefreshVisibleElements()
                 self.Refresh(False)
             else:
                 message = wx.MessageDialog(self, _("The group of block must be coherent!"), _("Error"), wx.OK|wx.ICON_ERROR)
@@ -908,12 +898,13 @@
         if self.GetDrawingMode() == FREEDRAWING_MODE:
             Viewer.DeleteContact(self, contact)
         else:
+            print "Delete"
             rungindex = self.FindRung(contact)
             rung = self.Rungs[rungindex]
             old_bbox = rung.GetBoundingBox()
             connectors = contact.GetConnectors()
-            input_wires = [wire for wire, handle in connectors["input"].GetWires()]
-            output_wires = [wire for wire, handle in connectors["output"].GetWires()]
+            input_wires = [wire for wire, handle in connectors["inputs"][0].GetWires()]
+            output_wires = [wire for wire, handle in connectors["outputs"][0].GetWires()]
             left_elements = [(wire.EndConnected, wire.EndConnected.GetWireIndex(wire)) for wire in input_wires]
             right_elements = [(wire.StartConnected, wire.StartConnected.GetWireIndex(wire)) for wire in output_wires]
             for wire in input_wires:
@@ -969,7 +960,7 @@
 
     def RecursiveDeletion(self, element, rung):
         connectors = element.GetConnectors()
-        input_wires = [wire for wire, handle in connectors["input"].GetWires()]
+        input_wires = [wire for wire, handle in connectors["inputs"][0].GetWires()]
         left_elements = [wire.EndConnected for wire in input_wires]
         rung.SelectElement(element)
         element.Clean()
@@ -999,7 +990,7 @@
                     nbcoils += 1
             if nbcoils > 1:
                 connectors = coil.GetConnectors()
-                output_wires = [wire for wire, handle in connectors["output"].GetWires()]
+                output_wires = [wire for wire, handle in connectors["outputs"][0].GetWires()]
                 right_elements = [wire.StartConnected for wire in output_wires]
                 for wire in output_wires:
                     wire.Clean()
@@ -1013,7 +1004,7 @@
                             index = right_block.GetConnectorIndex(right_element)
                             right_block.DeleteConnector(index)
                             powerrail_connectors = right_block.GetConnectors()
-                            for connector in powerrail_connectors:
+                            for connector in powerrail_connectors["inputs"]:
                                 for wire, handle in connector.GetWires():
                                     block = wire.EndConnected.GetParentBlock()
                                     endpoint = wire.EndConnected.GetPosition(False)
@@ -1078,12 +1069,7 @@
                             left_block.DeleteConnector(index)
                     else:
                         connectors = left_block.GetConnectors()
-                        output_connectors = []
-                        if "outputs" in connectors:
-                            output_connectors = connectors["outputs"]
-                        if "output" in connectors:
-                            output_connectors = [connectors["output"]]
-                        for connector in output_connectors:
+                        for connector in connectors["outputs"]:
                             for wire, handle in connector.GetWires():
                                 self.RefreshPosition(wire.StartConnected.GetParentBlock())
                 for right_element in right_elements:
@@ -1098,58 +1084,49 @@
 #-------------------------------------------------------------------------------
 
     def RefreshPosition(self, element, recursive=True):
+        # If element is LeftPowerRail, no need to update position
         if isinstance(element, LD_PowerRail) and element.GetType() == LEFTRAIL:
             element.RefreshModel()
             return
+        
+        # Extract max position of the elements connected to input
         connectors = element.GetConnectors()
-        input_connectors = []
-        output_connectors = []
-        if isinstance(element, LD_PowerRail) and element.GetType() == RIGHTRAIL:
-            input_connectors = connectors
-            for i, connector in enumerate(input_connectors):
-                for j, (wire, handle) in enumerate(connector.GetWires()):
-                    block = wire.EndConnected.GetParentBlock()
-                    self.RefreshPosition(block, False)
-        else:
-            if "inputs" in connectors:
-                input_connectors = connectors["inputs"]
-            if "outputs" in connectors:
-                output_connectors = connectors["outputs"]
-            if "input" in connectors:
-                input_connectors = [connectors["input"]]
-            if "output" in connectors:
-                output_connectors = [connectors["output"]]
         position = element.GetPosition()
-        minx = 0
+        maxx = 0
         onlyone = []
-        for connector in input_connectors:
+        for connector in connectors["inputs"]:
             onlyone.append(len(connector.GetWires()) == 1)
             for wire, handle in connector.GetWires():
                 onlyone[-1] &= len(wire.EndConnected.GetWires()) == 1
                 leftblock = wire.EndConnected.GetParentBlock()
                 pos = leftblock.GetPosition()
                 size = leftblock.GetSize()
-                minx = max(minx, pos[0] + size[0])
+                maxx = max(maxx, pos[0] + size[0])
+        
+        # Refresh position of element
         if isinstance(element, LD_Coil):
             interval = LD_WIRECOIL_SIZE
         else:
             interval = LD_WIRE_SIZE
         if False in onlyone:
             interval += LD_WIRE_SIZE
-        movex = minx + interval - position[0]
+        movex = maxx + interval - position[0]
         element.Move(movex, 0)
         position = element.GetPosition()
+        
+        # Extract blocks connected to inputs
         blocks = []
-        for i, connector in enumerate(input_connectors):
+        for i, connector in enumerate(connectors["inputs"]):
             for j, (wire, handle) in enumerate(connector.GetWires()):
                 blocks.append(wire.EndConnected.GetParentBlock())
-        for i, connector in enumerate(input_connectors):
+        
+        for i, connector in enumerate(connectors["inputs"]):
             startpoint = connector.GetPosition(False)
             previous_blocks = []
             block_list = []
             start_offset = 0
             if not onlyone[i]:
-                middlepoint = minx + LD_WIRE_SIZE
+                middlepoint = maxx + LD_WIRE_SIZE
             for j, (wire, handle) in enumerate(connector.GetWires()):
                 block = wire.EndConnected.GetParentBlock()
                 if isinstance(element, LD_PowerRail):
@@ -1174,21 +1151,11 @@
                 else:
                     if startpoint.y + offset != endpoint.y:
                         if isinstance(element, LD_PowerRail):
-                            diff = (startpoint.y - endpoint.y) / LD_LINE_SIZE
-                            for k in xrange(abs(diff)):
-                                if diff < 0:
-                                    element.DeleteConnector(i - 1 - k)
-                                else:
-                                    element.InsertConnector(i + k, False)
+                            element.MoveConnector(i, startpoint.y - endpoint.y)
                         elif isinstance(block, LD_PowerRail):
                             index = block.GetConnectorIndex(wire.EndConnected)
                             if index:
-                                diff = (startpoint.y - endpoint.y) / LD_LINE_SIZE
-                                for k in xrange(abs(diff)):
-                                    if diff < 0:
-                                        block.DeleteConnector(index - 1 - k)
-                                    else:
-                                        block.InsertConnector(index + k, False)
+                                block.MoveConnector(index, startpoint.y - endpoint.y)
                         else:
                             block.Move(0, startpoint.y + offset - endpoint.y)
                             self.RefreshPosition(block, False)
@@ -1198,13 +1165,14 @@
                                   wx.Point(middlepoint, endpoint.y), endpoint]
                     else:
                         points = [startpoint, endpoint]
-                wire.SetPoints(points)
+                wire.SetPoints(points, False)
                 previous_blocks.append(block)
                 blocks.remove(block)
                 ExtractNextBlocks(block, block_list)
+        
         element.RefreshModel(False)
         if recursive:
-            for connector in output_connectors:
+            for connector in connectors["outputs"]:
                 for wire, handle in connector.GetWires():
                     self.RefreshPosition(wire.StartConnected.GetParentBlock())
     
@@ -1222,71 +1190,7 @@
 #                          Edit element content functions
 #-------------------------------------------------------------------------------
 
-    def EditContactContent(self, contact):
-        if self.GetDrawingMode() == FREEDRAWING_MODE:
-            Viewer.EditContactContent(self, contact)
-        else:
-            dialog = LDElementDialog(self.ParentWindow, "contact")
-            dialog.SetPreviewFont(self.GetFont())
-            varlist = []
-            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
-            if vars:
-                for var in vars:
-                    if var["Class"] != "Output" and var["Type"] == "BOOL":
-                        varlist.append(var["Name"])
-            dialog.SetVariables(varlist)
-            dialog.SetValues({"name":contact.GetName(),"type":contact.GetType()})
-            if dialog.ShowModal() == wx.ID_OK:
-                values = dialog.GetValues()
-                contact.SetName(values["name"])
-                contact.SetType(values["type"])
-                contact.RefreshModel(False)
-                self.RefreshBuffer()
-                self.RefreshScrollBars()
-                contact.Refresh()
-            dialog.Destroy()
-
-    def EditCoilContent(self, coil):
-        if self.GetDrawingMode() == FREEDRAWING_MODE:
-            Viewer.EditCoilContent(self, coil)
-        else:
-            dialog = LDElementDialog(self.ParentWindow, "coil")
-            dialog.SetPreviewFont(self.GetFont())
-            varlist = []
-            vars = self.Controler.GetEditedElementInterfaceVars(self.TagName, self.Debug)
-            if vars:
-                for var in vars:
-                    if var["Class"] != "Input" and var["Type"] == "BOOL":
-                        varlist.append(var["Name"])
-            returntype = self.Controler.GetEditedElementInterfaceReturnType(self.TagName, self.Debug)
-            if returntype == "BOOL":
-                varlist.append(self.Controler.GetEditedElementName(self.TagName))
-            dialog.SetVariables(varlist)
-            dialog.SetValues({"name":coil.GetName(),"type":coil.GetType()})
-            if dialog.ShowModal() == wx.ID_OK:
-                values = dialog.GetValues()
-                coil.SetName(values["name"])
-                coil.SetType(values["type"])
-                coil.RefreshModel(False)
-                self.RefreshBuffer()
-                self.RefreshScrollBars()
-                coil.Refresh()
-            dialog.Destroy()
-
     def EditPowerRailContent(self, powerrail):
         if self.GetDrawingMode() == FREEDRAWING_MODE:
             Viewer.EditPowerRailContent(self, powerrail)
 
-#-------------------------------------------------------------------------------
-#                          Model update functions
-#-------------------------------------------------------------------------------
-
-    def RefreshBlockModel(self, block):
-        blockid = block.GetId()
-        infos = {}
-        infos["type"] = block.GetType()
-        infos["name"] = block.GetName()
-        infos["x"], infos["y"] = block.GetPosition()
-        infos["width"], infos["height"] = block.GetSize()
-        infos["connectors"] = block.GetConnectors()
-        self.Controler.SetEditedElementBlockInfos(self.TagName, blockid, infos)
--- a/Viewer.py	Mon Jul 04 15:24:44 2011 +0200
+++ b/Viewer.py	Fri Aug 12 17:04:55 2011 +0200
@@ -1925,7 +1925,7 @@
         if dialog.ShowModal() == wx.ID_OK:
             id = self.GetNewId()
             values = dialog.GetValues()
-            powerrail = LD_PowerRail(self, values["type"], id, [True for i in xrange(values["number"])])
+            powerrail = LD_PowerRail(self, values["type"], id, values["number"])
             powerrail.SetPosition(bbox.x, bbox.y)
             powerrail.SetSize(*self.GetScaledSize(values["width"], values["height"]))
             self.AddBlock(powerrail)
--- a/graphics/GraphicCommons.py	Mon Jul 04 15:24:44 2011 +0200
+++ b/graphics/GraphicCommons.py	Fri Aug 12 17:04:55 2011 +0200
@@ -1260,7 +1260,7 @@
         self.Valid = True
         self.Value = None
         self.Forced = False
-        self.Pen = wx.BLACK_PEN
+        self.Selected = False
         self.Errors = {}
         self.RefreshNameSize()
     
@@ -1285,9 +1285,9 @@
             height = CONNECTOR_SIZE
         return wx.Rect(x - abs(movex), y - abs(movey), width + 2 * abs(movex), height + 2 * abs(movey))
     
-    # Change the connector pen
-    def SetPen(self, pen):
-        self.Pen = pen
+    # Change the connector selection
+    def SetSelected(self, selected):
+        self.Selected = selected
     
     # Make a clone of the connector
     def Clone(self, parent = None):
@@ -1575,7 +1575,10 @@
     
     # Draws the connector
     def Draw(self, dc):
-        if len(self.Errors) > 0:
+        if self.Selected:
+            dc.SetPen(wx.Pen(wx.BLUE, 3))
+            dc.SetBrush(wx.WHITE_BRUSH)
+        elif len(self.Errors) > 0:
             dc.SetPen(wx.RED_PEN)
             dc.SetBrush(wx.Brush(wx.Colour(255, 255, 0)))
         else:
@@ -1591,7 +1594,7 @@
             elif self.Forced:
                 dc.SetPen(wx.Pen(wx.BLUE))
             else:
-                dc.SetPen(self.Pen)
+                dc.SetPen(wx.BLACK_PEN)
             dc.SetBrush(wx.WHITE_BRUSH)
         parent_pos = self.ParentBlock.GetPosition()
         
@@ -1616,9 +1619,14 @@
                 # If connector has a falling edge, draw a left arrow
                 dc.DrawLine(xstart, ystart, xstart + 4, ystart - 4)
                 dc.DrawLine(xstart, ystart, xstart + 4, ystart + 4)
-            xend = xstart + CONNECTOR_SIZE * self.Direction[0]
-            yend = ystart + CONNECTOR_SIZE * self.Direction[1]
-            dc.DrawLine(xstart + self.Direction[0], ystart + self.Direction[1], xend, yend)
+            if self.Selected:
+                xend = xstart + (CONNECTOR_SIZE - 2) * self.Direction[0]
+                yend = ystart + (CONNECTOR_SIZE - 2) * self.Direction[1]
+                dc.DrawLine(xstart + 2 * self.Direction[0], ystart + 2 * self.Direction[1], xend, yend)
+            else:
+                xend = xstart + CONNECTOR_SIZE * self.Direction[0]
+                yend = ystart + CONNECTOR_SIZE * self.Direction[1]
+                dc.DrawLine(xstart + self.Direction[0], ystart + self.Direction[1], xend, yend)
         if len(self.Errors) > 0:
             dc.SetPen(self.Pen)
             dc.SetBrush(wx.WHITE_BRUSH)
@@ -1900,25 +1908,25 @@
         # The selected segment is reinitialised
         if segment == None:
             if self.StartConnected:
-                self.StartConnected.SetPen(wx.BLACK_PEN)
+                self.StartConnected.SetSelected(False)
             if self.EndConnected:
-                self.EndConnected.SetPen(wx.BLACK_PEN)
+                self.EndConnected.SetSelected(False)
         # The segment selected is the first
         elif segment == 0:
             if self.StartConnected:
-                self.StartConnected.SetPen(wx.Pen(wx.BLUE))
+                self.StartConnected.SetSelected(True)
             if self.EndConnected:
                 # There is only one segment
                 if len(self.Segments) == 1:
-                    self.EndConnected.SetPen(wx.Pen(wx.BLUE))
+                    self.EndConnected.SetSelected(True)
                 else:
-                    self.EndConnected.SetPen(wx.BLACK_PEN)
+                    self.EndConnected.SetSelected(False)
         # The segment selected is the last
         elif segment == len(self.Segments) - 1:
             if self.StartConnected:
-                self.StartConnected.SetPen(wx.BLACK_PEN)
+                self.StartConnected.SetSelected(False)
             if self.EndConnected:
-                self.EndConnected.SetPen(wx.Pen(wx.BLUE))
+                self.EndConnected.SetSelected(True)
         self.SelectedSegment = segment
         self.Refresh()
     
@@ -2044,7 +2052,7 @@
         return None
     
     # Define the wire points
-    def SetPoints(self, points):
+    def SetPoints(self, points, verify=True):
         if len(points) > 1:
             self.Points = [wx.Point(x, y) for x, y in points]
             # Calculate the start and end directions
@@ -2061,7 +2069,7 @@
             self.Segments = []
             i = 0
             while i < len(self.Points) - 1:
-                if 0 < i < len(self.Points) - 2 and \
+                if verify and 0 < i < len(self.Points) - 2 and \
                    self.Points[i] == self.Points[i + 1] and \
                    self.Segments[-1] == vector(self.Points[i + 1], self.Points[i + 2]):
                     for j in xrange(2):
@@ -2745,11 +2753,13 @@
         dc.DrawPoint(self.Points[-1].x, self.Points[-1].y)
         # Draw the segment selected in red
         if not getattr(dc, "printing", False) and self.SelectedSegment is not None:
-            dc.SetPen(wx.RED_PEN)
-            dc.DrawLine(self.Points[self.SelectedSegment].x, self.Points[self.SelectedSegment].y,
-                        self.Points[self.SelectedSegment + 1].x, self.Points[self.SelectedSegment + 1].y)
+            dc.SetPen(wx.Pen(wx.BLUE, 3))
             if self.SelectedSegment == len(self.Segments) - 1:
-                dc.DrawPoint(self.Points[-1].x, self.Points[-1].y)
+                end = 0
+            else:
+                end = 1
+            dc.DrawLine(self.Points[self.SelectedSegment].x - 1, self.Points[self.SelectedSegment].y,
+                        self.Points[self.SelectedSegment + 1].x + end, self.Points[self.SelectedSegment + 1].y)
         if self.Value is not None and not isinstance(self.Value, BooleanType) and self.Value != "undefined":
             dc.SetFont(self.Parent.GetMiniFont())
             dc.SetTextForeground(wx.NamedColour("purple"))
--- a/graphics/LD_Objects.py	Mon Jul 04 15:24:44 2011 +0200
+++ b/graphics/LD_Objects.py	Fri Aug 12 17:04:55 2011 +0200
@@ -38,21 +38,18 @@
 class LD_PowerRail(Graphic_Element):
     
     # Create a new power rail
-    def __init__(self, parent, type, id = None, connectors = [True]):
+    def __init__(self, parent, type, id=None, connectors=1):
         Graphic_Element.__init__(self, parent)
         self.Type = None
         self.Connectors = []
         self.RealConnectors = None
         self.Id = id
         self.Extensions = [LD_LINE_SIZE / 2, LD_LINE_SIZE / 2]
-        if len(connectors) < 1:
-            connectors = [True]
         self.SetType(type, connectors)
         
     def Flush(self):
         for connector in self.Connectors:
-            if connector is not None:
-                connector.Flush()
+            connector.Flush()
         self.Connectors = []
     
     # Make a clone of this LD_PowerRail
@@ -65,25 +62,21 @@
             powerrail.SetPosition(self.Pos.x, self.Pos.y)
         powerrail.Connectors = []
         for connector in self.Connectors:
-            if connector is not None:
-                powerrail.Connectors.append(connector.Clone(powerrail))
-            else:
-                powerrail.Connectors.append(None)
+            powerrail.Connectors.append(connector.Clone(powerrail))
         return powerrail
     
     def GetConnectorTranslation(self, element):
-        return dict(zip([connector for connector in self.Connectors if connector is not None],
-                        [connector for connector in element.Connectors if connector is not None]))
+        return dict(zip([connector for connector in self.Connectors],
+                        [connector for connector in element.Connectors]))
     
     # Returns the RedrawRect
     def GetRedrawRect(self, movex = 0, movey = 0):
         rect = Graphic_Element.GetRedrawRect(self, movex, movey)
         for connector in self.Connectors:
-            if connector is not None:
-                rect = rect.Union(connector.GetRedrawRect(movex, movey))
+            rect = rect.Union(connector.GetRedrawRect(movex, movey))
         if movex != 0 or movey != 0:
             for connector in self.Connectors:
-                if connector is not None and connector.IsConnected():
+                if connector.IsConnected():
                     rect = rect.Union(connector.GetConnectedRedrawRect(movex, movey))
         return rect
     
@@ -91,7 +84,9 @@
     def SetSize(self, width, height):
         if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
             Graphic_Element.SetSize(self, width, height)
-            self.RefreshConnectors()
+        else:
+            Graphic_Element.SetSize(self, LD_POWERRAIL_WIDTH, height)
+        self.RefreshConnectors()
     
     # Forbids to select a power rail
     def HitTest(self, pt):
@@ -112,8 +107,7 @@
     # Unconnect all connectors
     def Clean(self):
         for connector in self.Connectors:
-            if connector:
-                connector.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
+            connector.UnConnect(delete = self.Parent.GetDrawingMode() == FREEDRAWING_MODE)
                 
     # Refresh the power rail bounding box
     def RefreshBoundingBox(self):
@@ -121,30 +115,24 @@
     
     # Refresh the power rail size
     def RefreshSize(self):
-        self.Size = wx.Size(LD_POWERRAIL_WIDTH, LD_LINE_SIZE * len(self.Connectors))
+        self.Size = wx.Size(LD_POWERRAIL_WIDTH, max(LD_LINE_SIZE * len(self.Connectors), self.Size[1]))
         self.RefreshBoundingBox()
     
     # Returns the block minimum size
     def GetMinSize(self):
-        if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
-            return LD_POWERRAIL_WIDTH, self.Extensions[0] + self.Extensions[1]
-        else:
-            return LD_POWERRAIL_WIDTH, LD_LINE_SIZE * len(self.Connectors)
+        return LD_POWERRAIL_WIDTH, self.Extensions[0] + self.Extensions[1]
     
     # Add a connector or a blank to this power rail at the last place
-    def AddConnector(self, connector = True):
-        self.InsertConnector(len(self.Connectors), connector)
+    def AddConnector(self):
+        self.InsertConnector(len(self.Connectors))
     
     # Add a connector or a blank to this power rail at the place given
-    def InsertConnector(self, idx, connector = True):
-        if connector:
-            if self.Type == LEFTRAIL:
-                connector = Connector(self, "", "BOOL", wx.Point(self.Size[0], 0), EAST)
-            elif self.Type == RIGHTRAIL:
-                connector = Connector(self, "", "BOOL", wx.Point(0, 0), WEST)
-            self.Connectors.insert(idx, connector)
-        else:
-            self.Connectors.insert(idx, None)
+    def InsertConnector(self, idx):
+        if self.Type == LEFTRAIL:
+            connector = Connector(self, "", "BOOL", wx.Point(self.Size[0], 0), EAST)
+        elif self.Type == RIGHTRAIL:
+            connector = Connector(self, "", "BOOL", wx.Point(0, 0), WEST)
+        self.Connectors.insert(idx, connector)
         self.RefreshSize()
         self.RefreshConnectors()
     
@@ -179,12 +167,6 @@
             return self.Connectors.index(connector)
         return None
     
-    # Returns if there is a connector in connectors list at the index given
-    def IsNullConnector(self, idx):
-        if idx < len(self.Connectors):
-            return self.Connectors[idx] == None
-        return False
-    
     # Delete the connector or blank from connectors list at the index given
     def DeleteConnector(self, idx):
         self.Connectors.pop(idx)
@@ -194,40 +176,25 @@
     # Refresh the positions of the power rail connectors
     def RefreshConnectors(self):
         scaling = self.Parent.GetScaling()
-        if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
-            height = self.Size[1] - self.Extensions[0] - self.Extensions[1]
-            interval = float(height) / float(max(len(self.Connectors) - 1, 1))
-            for i, connector in enumerate(self.Connectors):
-                if self.RealConnectors:
-                    position = self.Extensions[0] + int(round(self.RealConnectors[i] * height))
-                else:
-                    position = self.Extensions[0] + int(round(i * interval))
-                if scaling is not None:
-                    position = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y
-                if self.Type == LEFTRAIL:
-                    connector.SetPosition(wx.Point(self.Size[0], position))
-                elif self.Type == RIGHTRAIL:
-                    connector.SetPosition(wx.Point(0, position))
-        else:
-            position = self.Extensions[0]
-            for connector in self.Connectors:
-                if connector:
-                    if scaling is not None:
-                        ypos = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y
-                    else:
-                        ypos = position
-                    if self.Type == LEFTRAIL:
-                        connector.SetPosition(wx.Point(self.Size[0], ypos))
-                    elif self.Type == RIGHTRAIL:
-                        connector.SetPosition(wx.Point(0, ypos))
-                position += LD_LINE_SIZE
+        height = self.Size[1] - self.Extensions[0] - self.Extensions[1]
+        interval = float(height) / float(max(len(self.Connectors) - 1, 1))
+        for i, connector in enumerate(self.Connectors):
+            if self.RealConnectors:
+                position = self.Extensions[0] + int(round(self.RealConnectors[i] * height))
+            else:
+                position = self.Extensions[0] + int(round(i * interval))
+            if scaling is not None:
+                position = round(float(self.Pos.y + position) / float(scaling[1])) * scaling[1] - self.Pos.y
+            if self.Type == LEFTRAIL:
+                connector.SetPosition(wx.Point(self.Size[0], position))
+            elif self.Type == RIGHTRAIL:
+                connector.SetPosition(wx.Point(0, position))
         self.RefreshConnected()
     
     # Refresh the position of wires connected to power rail
     def RefreshConnected(self, exclude = []):
         for connector in self.Connectors:
-            if connector:
-                connector.MoveConnected(exclude)
+            connector.MoveConnected(exclude)
     
     # Returns the power rail connector that starts with the point given if it exists 
     def GetConnector(self, position, name = None):
@@ -235,7 +202,7 @@
         if name:
             # Test each connector if it exists
             for connector in self.Connectors:
-                if connector and name == connector.GetName():
+                if name == connector.GetName():
                     return connector
         return self.FindNearestConnector(position, [connector for connector in self.Connectors if connector is not None])
     
@@ -250,20 +217,20 @@
     # Test if point given is on one of the power rail connectors
     def TestConnector(self, pt, direction = None, exclude = True):
         for connector in self.Connectors:
-            if connector and connector.TestPoint(pt, direction, exclude):
+            if connector.TestPoint(pt, direction, exclude):
                 return connector
         return None
     
     # Returns the power rail type
     def SetType(self, type, connectors):
-        if type != self.Type or len(self.Connectors) != len(connectors):
+        if type != self.Type or len(self.Connectors) != connectors:
             # Create a connector or a blank according to 'connectors' and add it in
             # the connectors list
             self.Type = type
             self.Clean()
             self.Connectors = []
-            for connector in connectors:
-                self.AddConnector(connector)
+            for connector in xrange(connectors):
+                self.AddConnector()
             self.RefreshSize()
     
     # Returns the power rail type
@@ -351,8 +318,7 @@
         # of wires connected to connectors
         if move and self.Type == LEFTRAIL:
             for connector in self.Connectors:
-                if connector:
-                    connector.RefreshWires()
+                connector.RefreshWires()
     
     # Draws power rail
     def Draw(self, dc):
@@ -366,8 +332,7 @@
             dc.DrawRectangle(self.Pos.x, self.Pos.y, LD_POWERRAIL_WIDTH + 1, self.Size[1] + 1)
         # Draw connectors
         for connector in self.Connectors:
-            if connector:
-                connector.Draw(dc)
+            connector.Draw(dc)
         
 
 #-------------------------------------------------------------------------------
--- a/plcopen/plcopen.py	Mon Jul 04 15:24:44 2011 +0200
+++ b/plcopen/plcopen.py	Fri Aug 12 17:04:55 2011 +0200
@@ -1777,11 +1777,11 @@
         if type == "rightPowerRail":
             for connectionPointIn in self.getconnectionPointIn():
                 infos["inputs"].append(_getconnectioninfos(self, connectionPointIn, True))
-            infos["specific_values"]["connectors"] = [True for input in infos["inputs"]]
+            infos["specific_values"]["connectors"] = len(infos["inputs"])
         elif type == "leftPowerRail":
             for connectionPointOut in self.getconnectionPointOut():
                 infos["outputs"].append(_getconnectioninfos(self, connectionPointOut))
-            infos["specific_values"]["connectors"] = [True for output in infos["outputs"]]
+            infos["specific_values"]["connectors"] = len(infos["outputs"])
         return infos
     return getpowerrailinfos