LDViewer.py
changeset 0 b622defdfd98
child 2 93bc4c2cf376
equal deleted inserted replaced
-1:000000000000 0:b622defdfd98
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 #This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
       
     5 #based on the plcopen standard.
       
     6 #
       
     7 #Copyright (C): Edouard TISSERANT and Laurent BESSARD
       
     8 #
       
     9 #See COPYING file for copyrights details.
       
    10 #
       
    11 #This library is free software; you can redistribute it and/or
       
    12 #modify it under the terms of the GNU Lesser General Public
       
    13 #License as published by the Free Software Foundation; either
       
    14 #version 2.1 of the License, or (at your option) any later version.
       
    15 #
       
    16 #This library is distributed in the hope that it will be useful,
       
    17 #but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    18 #MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    19 #Lesser General Public License for more details.
       
    20 #
       
    21 #You should have received a copy of the GNU Lesser General Public
       
    22 #License along with this library; if not, write to the Free Software
       
    23 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
       
    24 
       
    25 from wxPython.wx import *
       
    26 import wx
       
    27 from types import *
       
    28 
       
    29 from plcopen.structures import *
       
    30 from graphics.GraphicCommons import *
       
    31 from graphics.FBD_Objects import *
       
    32 from Viewer import *
       
    33 
       
    34 def ExtractNextBlocks(block, block_list):
       
    35     current_list = [block]
       
    36     while len(current_list) > 0:
       
    37         next_list = []
       
    38         for current in current_list:
       
    39             connectors = current.GetConnectors()
       
    40             input_connectors = []
       
    41             if isinstance(current, LD_PowerRail) and current.GetType() == RIGHTRAIL:
       
    42                 input_connectors = connectors
       
    43             else:
       
    44                 if "inputs" in connectors:
       
    45                     input_connectors = connectors["inputs"]
       
    46                 if "input" in connectors:
       
    47                     input_connectors = [connectors["input"]]
       
    48             for connector in input_connectors:
       
    49                 for wire, handle in connector.GetWires():
       
    50                     next = wire.EndConnected.GetParentBlock()
       
    51                     if not isinstance(next, LD_PowerRail) and next not in block_list:
       
    52                         block_list.append(next)
       
    53                         next_list.append(next)
       
    54         current_list = next_list
       
    55     
       
    56 def CalcBranchSize(elements, stop):
       
    57     branch_size = 0
       
    58     stop_list = [stop]
       
    59     ExtractNextBlocks(stop, stop_list)
       
    60     element_tree = {}
       
    61     for element in elements:
       
    62         if element not in element_tree:
       
    63             element_tree[element] = {"parents":["start"], "children":[], "weight":None}
       
    64             GenerateTree(element, element_tree, stop_list)
       
    65         elif element_tree[element]:
       
    66             element_tree[element]["parents"].append("start")
       
    67     for element, values in element_tree.items():
       
    68         if values and values["children"] == ["stop"]:
       
    69             CalcWeight(element, element_tree)
       
    70             if values["weight"]:
       
    71                 branch_size += values["weight"]
       
    72             else:
       
    73                 return 1
       
    74     return branch_size
       
    75 
       
    76 def RemoveElement(remove, element_tree):
       
    77     if remove in element_tree and element_tree[remove]:
       
    78         for child in element_tree[remove]["children"]:
       
    79             if child != "stop":
       
    80                 RemoveElement(child, element_tree)
       
    81         element_tree[remove] = None
       
    82 
       
    83 def GenerateTree(element, element_tree, stop_list):
       
    84     if element in element_tree:
       
    85         connectors = element.GetConnectors()
       
    86         input_connectors = []
       
    87         if isinstance(element, LD_PowerRail) and element.GetType() == RIGHTRAIL:
       
    88             input_connectors = connectors
       
    89         else:
       
    90             if "inputs" in connectors:
       
    91                 input_connectors = connectors["inputs"]
       
    92             if "input" in connectors:
       
    93                 input_connectors = [connectors["input"]]
       
    94         for connector in input_connectors:
       
    95             for wire, handle in connector.GetWires():
       
    96                 next = wire.EndConnected.GetParentBlock()
       
    97                 if isinstance(next, LD_PowerRail) and next.GetType() == LEFTRAIL or next in stop_list:
       
    98                     for remove in element_tree[element]["children"]:
       
    99                         RemoveElement(remove, element_tree)
       
   100                     element_tree[element]["children"] = ["stop"]
       
   101                 elif element_tree[element]["children"] == ["stop"]:
       
   102                     element_tree[next] = None
       
   103                 elif next not in element_tree or element_tree[next]:
       
   104                     element_tree[element]["children"].append(next)
       
   105                     if next in element_tree:
       
   106                         element_tree[next]["parents"].append(element)
       
   107                     else:
       
   108                         element_tree[next] = {"parents":[element], "children":[], "weight":None}
       
   109                         GenerateTree(next, element_tree, stop_list)
       
   110 
       
   111 def CalcWeight(element, element_tree):
       
   112     weight = 0
       
   113     parts = None
       
   114     if element in element_tree:
       
   115         for parent in element_tree[element]["parents"]:
       
   116             if parent == "start":
       
   117                 weight += 1
       
   118             elif parent in element_tree:
       
   119                 if not parts:
       
   120                     parts = len(element_tree[parent]["children"])
       
   121                 else:
       
   122                     parts = min(parts, len(element_tree[parent]["children"]))
       
   123                 if not element_tree[parent]["weight"]:
       
   124                     CalcWeight(parent, element_tree)
       
   125                 if element_tree[parent]["weight"]:
       
   126                     weight += element_tree[parent]["weight"]
       
   127                 else:
       
   128                     element_tree[element]["weight"] = None
       
   129                     return
       
   130             else:
       
   131                 element_tree[element]["weight"] = None
       
   132                 return
       
   133         if not parts:
       
   134             parts = 1
       
   135         element_tree[element]["weight"] = max(1, weight / parts)
       
   136 
       
   137 
       
   138 #-------------------------------------------------------------------------------
       
   139 #                     Ladder Diagram Graphic elements Viewer class
       
   140 #-------------------------------------------------------------------------------
       
   141 
       
   142 """
       
   143 Class derived from Viewer class that implements a Viewer of Ladder Diagram
       
   144 """
       
   145 
       
   146 class LD_Viewer(Viewer):
       
   147 
       
   148     def __init__(self, parent, window, controler):
       
   149         Viewer.__init__(self, parent, window, controler)
       
   150         self.Rungs = []
       
   151         self.Comments = []
       
   152 
       
   153 #-------------------------------------------------------------------------------
       
   154 #                          Refresh functions
       
   155 #-------------------------------------------------------------------------------
       
   156 
       
   157     def RefreshView(self):
       
   158         Viewer.RefreshView(self)
       
   159         for i, rung in enumerate(self.Rungs):
       
   160             bbox = rung.GetBoundingBox()
       
   161             if i < len(self.Comments):
       
   162                 pos = self.Comments[i].GetPosition()
       
   163                 if pos[1] > bbox.y:
       
   164                     self.Comment.insert(i, None)
       
   165             else:
       
   166                 self.Comment.insert(i, None)
       
   167     
       
   168     def loadInstance(self, instance, ids):
       
   169         Viewer.loadInstance(self, instance, ids)
       
   170         if instance["type"] == "leftPowerRail":
       
   171             element = self.FindElementById(instance["id"])
       
   172             rung = Graphic_Group(self)
       
   173             rung.SelectElement(element)
       
   174             self.Rungs.append(rung)
       
   175         elif instance["type"] == "rightPowerRail":
       
   176             rungs = []
       
   177             for connector in instance["connectors"]:
       
   178                 for link in connector["links"]:
       
   179                     connected = self.FindElementById(link["refLocalId"])
       
   180                     rung = self.FindRung(connected)
       
   181                     if rung not in rungs:
       
   182                         rungs.append(rung)
       
   183             if len(rungs) > 1:
       
   184                 raise "ValueError", "Ladder element with id %d is on more than one rung."%instance["id"]
       
   185             element = self.FindElementById(instance["id"])
       
   186             self.Rungs[rungs[0]].SelectElement(element)
       
   187             for connector in element.GetConnectors():
       
   188                 for wire, num in connector.GetWires():
       
   189                     self.Rungs[rungs[0]].SelectElement(wire)
       
   190             self.RefreshPosition(element)
       
   191         elif instance["type"] in ["contact", "coil"]:
       
   192             rungs = []
       
   193             for link in instance["connectors"]["input"]["links"]:
       
   194                 connected = self.FindElementById(link["refLocalId"])
       
   195                 rung = self.FindRung(connected)
       
   196                 if rung not in rungs:
       
   197                     rungs.append(rung)
       
   198             if len(rungs) > 1:
       
   199                 raise "ValueError", "Ladder element with id %d is on more than one rung."%instance["id"]
       
   200             element = self.FindElementById(instance["id"])
       
   201             self.Rungs[rungs[0]].SelectElement(element)
       
   202             for wire, num in element.GetConnectors()["input"].GetWires():
       
   203                 self.Rungs[rungs[0]].SelectElement(wire)
       
   204             self.RefreshPosition(element)
       
   205         elif instance["type"] == "comment":
       
   206             element = self.FindElementById(instance["id"])
       
   207             pos = element.GetPosition()
       
   208             i = 0
       
   209             inserted = False
       
   210             while i < len(self.Comments) and not inserted: 
       
   211                 ipos = self.Comments[i].GetPosition()
       
   212                 if pos[1] < ipos[1]:
       
   213                     self.Comments.insert(i, element)
       
   214                     inserted = True
       
   215                 i += 1
       
   216             if not inserted:
       
   217                 self.Comments.append(element)
       
   218 
       
   219 #-------------------------------------------------------------------------------
       
   220 #                          Search Element functions
       
   221 #-------------------------------------------------------------------------------
       
   222 
       
   223     def FindRung(self, element):
       
   224         for i, rung in enumerate(self.Rungs):
       
   225             if rung.IsElementIn(element):
       
   226                 return i
       
   227         return None
       
   228 
       
   229     def FindElement(self, pos):
       
   230         elements = []
       
   231         for element in self.Elements:
       
   232             if element.HitTest(pos) or element.TestHandle(pos) != (0, 0):
       
   233                 elements.append(element)
       
   234         if len(elements) == 1:
       
   235             return elements[0]
       
   236         elif len(elements) > 1:
       
   237             group = Graphic_Group(self)
       
   238             for element in elements:
       
   239                 if element in self.Blocks:
       
   240                     return element
       
   241                 group.SelectElement(element)
       
   242             return group
       
   243         return None
       
   244 
       
   245     def SearchElements(self, bbox):
       
   246         elements = []
       
   247         for element in self.Blocks:
       
   248             element_bbox = element.GetBoundingBox()
       
   249             if element_bbox.x >= bbox.x and element_bbox.y >= bbox.y and element_bbox.x + element_bbox.width <= bbox.x + bbox.width and element_bbox.y + element_bbox.height <= bbox.y + bbox.height:
       
   250                 elements.append(element)
       
   251         return elements
       
   252 
       
   253 #-------------------------------------------------------------------------------
       
   254 #                          Mouse event functions
       
   255 #-------------------------------------------------------------------------------
       
   256 
       
   257     def OnViewerLeftDown(self, event):
       
   258         if self.Mode == MODE_SELECTION:
       
   259             pos = event.GetPosition()
       
   260             element = self.FindElement(pos)
       
   261             if self.SelectedElement:
       
   262                 if self.SelectedElement in self.Elements:
       
   263                     if self.SelectedElement != element:
       
   264                         if self.SelectedElement in self.Wires:
       
   265                             self.SelectedElement.SetSelectedSegment(None)
       
   266                         else:
       
   267                             self.SelectedElement.SetSelected(False)
       
   268                     else:
       
   269                         self.SelectedElement = None
       
   270                 elif element and element not in self.Elements:
       
   271                     if self.SelectedElement.GetElements() != element.GetElements():
       
   272                         for elt in self.SelectedElement.GetElements():
       
   273                             if elt in self.Wires:
       
   274                                 elt.SetSelectedSegment(None)
       
   275                         self.SelectedElement.SetSelected(False)
       
   276                         self.SelectedElement = None
       
   277                 else:
       
   278                     for elt in self.SelectedElement.GetElements():
       
   279                         if elt in self.Wires:
       
   280                             elt.SetSelectedSegment(None)
       
   281                     self.SelectedElement.SetSelected(False)
       
   282                     self.SelectedElement = None
       
   283                 self.Refresh()
       
   284             if element:
       
   285                 self.SelectedElement = element
       
   286                 self.SelectedElement.OnLeftDown(event, self.Scaling)
       
   287                 self.Refresh()
       
   288             else:
       
   289                 self.rubberBand.Reset()
       
   290                 self.rubberBand.OnLeftDown(event, self.Scaling)
       
   291         event.Skip()
       
   292 
       
   293     def OnViewerLeftUp(self, event):
       
   294         if self.rubberBand.IsShown():
       
   295             if self.Mode == MODE_SELECTION:
       
   296                 elements = self.SearchElements(self.rubberBand.GetCurrentExtent())
       
   297                 self.rubberBand.OnLeftUp(event, self.Scaling)
       
   298                 if len(elements) > 0:
       
   299                     self.SelectedElement = Graphic_Group(self)
       
   300                     self.SelectedElement.SetElements(elements)
       
   301                     self.SelectedElement.SetSelected(True)
       
   302                     self.Refresh()
       
   303         elif self.Mode == MODE_SELECTION and self.SelectedElement:
       
   304             if self.SelectedElement in self.Elements:
       
   305                 if self.SelectedElement in self.Wires:
       
   306                     result = self.SelectedElement.TestSegment(event.GetPosition(), True)
       
   307                     if result and result[1] in [EAST, WEST]:
       
   308                         self.SelectedElement.SetSelectedSegment(result[0])
       
   309                 else:
       
   310                     self.SelectedElement.OnLeftUp(event, self.Scaling)
       
   311             else:
       
   312                 for element in self.SelectedElement.GetElements():
       
   313                     if element in self.Wires:
       
   314                         result = element.TestSegment(event.GetPosition(), True)
       
   315                         if result and result[1] in [EAST, WEST]:
       
   316                             element.SetSelectedSegment(result[0])
       
   317                     else:
       
   318                         element.OnLeftUp(event, self.Scaling)
       
   319             wxCallAfter(self.SetCursor, wxNullCursor)
       
   320             self.ReleaseMouse()
       
   321             self.Refresh()
       
   322         event.Skip()
       
   323 
       
   324     def OnViewerRightUp(self, event):
       
   325         pos = event.GetPosition()
       
   326         element = self.FindElement(pos)
       
   327         if element:
       
   328             if self.SelectedElement and self.SelectedElement != element:
       
   329                 self.SelectedElement.SetSelected(False)
       
   330             self.SelectedElement = element
       
   331             if self.SelectedElement in self.Wires:
       
   332                 self.SelectedElement.SetSelectedSegment(0)
       
   333             else:
       
   334                 self.SelectedElement.SetSelected(True)
       
   335                 self.SelectedElement.OnRightUp(event, self.Scaling)
       
   336             wxCallAfter(self.SetCursor, wxNullCursor)
       
   337             self.ReleaseMouse()
       
   338             self.Refresh()
       
   339         event.Skip()
       
   340 
       
   341     def OnViewerLeftDClick(self, event):
       
   342         if self.Mode == MODE_SELECTION and self.SelectedElement:
       
   343             self.SelectedElement.OnLeftDClick(event, self.Scaling)
       
   344             self.Refresh()
       
   345         event.Skip()
       
   346 
       
   347     def OnViewerMotion(self, event):
       
   348         if self.rubberBand.IsShown():
       
   349             self.rubberBand.OnMotion(event, self.Scaling)
       
   350         event.Skip()
       
   351 
       
   352 #-------------------------------------------------------------------------------
       
   353 #                          Keyboard event functions
       
   354 #-------------------------------------------------------------------------------
       
   355 
       
   356     def OnChar(self, event):
       
   357         keycode = event.GetKeyCode()
       
   358         if keycode == WXK_DELETE and self.SelectedElement:
       
   359             if self.SelectedElement in self.Blocks:
       
   360                 self.SelectedElement.Delete()
       
   361             elif self.SelectedElement in self.Wires:
       
   362                 self.DeleteWire(self.SelectedElement)
       
   363             elif self.SelectedElement not in self.Elements:
       
   364                 all_wires = True
       
   365                 for element in self.SelectedElement.GetElements():
       
   366                     all_wires &= element in self.Wires
       
   367                 if all_wires:
       
   368                     self.DeleteWire(self.SelectedElement)
       
   369                 else:
       
   370                     self.SelectedElement.Delete()
       
   371         self.Refresh()
       
   372         event.Skip()
       
   373 
       
   374 #-------------------------------------------------------------------------------
       
   375 #                          Adding element functions
       
   376 #-------------------------------------------------------------------------------
       
   377 
       
   378     def AddRung(self):
       
   379         dialog = LDElementDialog(self.Parent, "coil")
       
   380         varlist = []
       
   381         vars = self.Controler.GetCurrentElementEditingInterfaceVars()
       
   382         if vars:
       
   383             for var in vars:
       
   384                 if var["Type"] != "Input" and var["Value"] == "BOOL":
       
   385                     varlist.append(var["Name"])
       
   386         returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
       
   387         if returntype == "BOOL":
       
   388             varlist.append(self.Controler.GetCurrentElementEditingName())
       
   389         dialog.SetVariables(varlist)
       
   390         dialog.SetValues({"name":"","type":COIL_NORMAL})
       
   391         if dialog.ShowModal() == wxID_OK:
       
   392             values = dialog.GetValues()
       
   393             startx, starty = LD_OFFSET[0], 0
       
   394             if len(self.Rungs) > 0:
       
   395                 bbox = self.Rungs[-1].GetBoundingBox()
       
   396                 starty = bbox.y + bbox.height
       
   397             starty += LD_OFFSET[1]
       
   398             rung = Graphic_Group(self)
       
   399             # Create comment
       
   400             id = self.GetNewId()
       
   401             comment = Comment(self, "Commentaire", id)
       
   402             comment.SetPosition(startx, starty)
       
   403             comment.SetSize(LD_COMMENT_DEFAULTSIZE[0], LD_COMMENT_DEFAULTSIZE[1])
       
   404             self.Elements.append(comment)
       
   405             self.Comments.append(comment)
       
   406             self.Controler.AddCurrentElementEditingComment(id)
       
   407             self.RefreshCommentModel(comment)
       
   408             starty += LD_COMMENT_DEFAULTSIZE[1] + LD_OFFSET[1]
       
   409             # Create LeftPowerRail
       
   410             id = self.GetNewId()
       
   411             leftpowerrail = LD_PowerRail(self, LEFTRAIL, id)
       
   412             leftpowerrail.SetPosition(startx, starty)
       
   413             self.Elements.append(leftpowerrail)
       
   414             self.Blocks.append(leftpowerrail)
       
   415             rung.SelectElement(leftpowerrail)
       
   416             self.Controler.AddCurrentElementEditingPowerRail(id, LEFTRAIL)
       
   417             self.RefreshPowerRailModel(leftpowerrail)
       
   418             # Create Coil
       
   419             id = self.GetNewId()
       
   420             coil = LD_Coil(self, values["type"], values["name"], id)
       
   421             coil.SetPosition(startx, starty + (LD_LINE_SIZE - LD_ELEMENT_SIZE[1]) / 2)
       
   422             self.Elements.append(coil)
       
   423             self.Blocks.append(coil)
       
   424             rung.SelectElement(coil)
       
   425             self.Controler.AddCurrentElementEditingCoil(id)
       
   426             # Create Wire between LeftPowerRail and Coil
       
   427             wire = Wire(self)
       
   428             start_connector = coil.GetConnectors()["input"]
       
   429             end_connector = leftpowerrail.GetConnectors()[0]
       
   430             start_connector.Connect((wire, 0), False)
       
   431             end_connector.Connect((wire, -1), False)
       
   432             wire.ConnectStartPoint(None, start_connector)
       
   433             wire.ConnectEndPoint(None, end_connector)
       
   434             self.Wires.append(wire)
       
   435             self.Elements.append(wire)
       
   436             rung.SelectElement(wire)
       
   437             # Create RightPowerRail
       
   438             id = self.GetNewId()
       
   439             rightpowerrail = LD_PowerRail(self, RIGHTRAIL, id)
       
   440             rightpowerrail.SetPosition(startx, starty)
       
   441             self.Elements.append(rightpowerrail)
       
   442             self.Blocks.append(rightpowerrail)
       
   443             rung.SelectElement(rightpowerrail)
       
   444             self.Controler.AddCurrentElementEditingPowerRail(id, RIGHTRAIL)
       
   445             # Create Wire between LeftPowerRail and Coil
       
   446             wire = Wire(self)
       
   447             start_connector = rightpowerrail.GetConnectors()[0]
       
   448             end_connector = coil.GetConnectors()["output"]
       
   449             start_connector.Connect((wire, 0), False)
       
   450             end_connector.Connect((wire, -1), False)
       
   451             wire.ConnectStartPoint(None, start_connector)
       
   452             wire.ConnectEndPoint(None, end_connector)
       
   453             self.Wires.append(wire)
       
   454             self.Elements.append(wire)
       
   455             rung.SelectElement(wire)
       
   456             self.RefreshPosition(coil)
       
   457             self.Rungs.append(rung)
       
   458             self.Refresh()
       
   459 
       
   460     def AddContact(self):
       
   461         wires = []
       
   462         if self.SelectedElement in self.Wires:
       
   463             left_element = self.SelectedElement.EndConnected
       
   464             if not isinstance(left_element.GetParentBlock(), LD_Coil):
       
   465                 wires.append(self.SelectedElement)
       
   466         elif self.SelectedElement and self.SelectedElement not in self.Elements:
       
   467             if False not in [element in self.Wires for element in self.SelectedElement.GetElements()]:
       
   468                 for element in self.SelectedElement.GetElements():
       
   469                     wires.append(element)
       
   470         if len(wires) > 0:
       
   471             dialog = LDElementDialog(self.Parent, "contact")
       
   472             varlist = []
       
   473             vars = self.Controler.GetCurrentElementEditingInterfaceVars()
       
   474             if vars:
       
   475                 for var in vars:
       
   476                     if var["Type"] != "Output" and var["Value"] == "BOOL":
       
   477                         varlist.append(var["Name"])
       
   478             dialog.SetVariables(varlist)
       
   479             dialog.SetValues({"name":"","type":CONTACT_NORMAL})
       
   480             if dialog.ShowModal() == wxID_OK:
       
   481                 values = dialog.GetValues()
       
   482                 points = wires[0].GetSelectedSegmentPoints()
       
   483                 id = self.GetNewId()
       
   484                 contact = LD_Contact(self, values["type"], values["name"], id)
       
   485                 contact.SetPosition(0, points[0].y - (LD_ELEMENT_SIZE[1] + 1) / 2)
       
   486                 self.Elements.append(contact)
       
   487                 self.Blocks.append(contact)
       
   488                 self.Controler.AddCurrentElementEditingContact(id)
       
   489                 rungindex = self.FindRung(wires[0])
       
   490                 rung = self.Rungs[rungindex]
       
   491                 old_bbox = rung.GetBoundingBox()
       
   492                 rung.SelectElement(contact)
       
   493                 connectors = contact.GetConnectors()
       
   494                 left_elements = []
       
   495                 right_elements = []
       
   496                 left_index = []
       
   497                 right_index = []
       
   498                 for wire in wires:
       
   499                     if wire.EndConnected not in left_elements:
       
   500                         left_elements.append(wire.EndConnected)
       
   501                         left_index.append(wire.EndConnected.GetWireIndex(wire))
       
   502                     else:
       
   503                         idx = left_elements.index(wire.EndConnected)
       
   504                         left_index[idx] = min(left_index[idx], wire.EndConnected.GetWireIndex(wire))
       
   505                     if wire.StartConnected not in right_elements:
       
   506                         right_elements.append(wire.StartConnected)
       
   507                         right_index.append(wire.StartConnected.GetWireIndex(wire))
       
   508                     else:
       
   509                         idx = right_elements.index(wire.StartConnected)
       
   510                         right_index[idx] = min(right_index[idx], wire.StartConnected.GetWireIndex(wire))
       
   511                     wire.SetSelectedSegment(None)
       
   512                     wire.Clean()
       
   513                     rung.SelectElement(wire)
       
   514                     self.Wires.remove(wire)
       
   515                     self.Elements.remove(wire)
       
   516                 wires = []
       
   517                 right_wires = []
       
   518                 for i, left_element in enumerate(left_elements):
       
   519                     wire = Wire(self)
       
   520                     wires.append(wire)
       
   521                     connectors["input"].Connect((wire, 0), False)
       
   522                     left_element.InsertConnect(left_index[i], (wire, -1), False)
       
   523                     wire.ConnectStartPoint(None, connectors["input"])
       
   524                     wire.ConnectEndPoint(None, left_element)
       
   525                 for i, right_element in enumerate(right_elements):
       
   526                     wire = Wire(self)
       
   527                     wires.append(wire)
       
   528                     right_wires.append(wire)
       
   529                     right_element.InsertConnect(right_index[i], (wire, 0), False)
       
   530                     connectors["output"].Connect((wire, -1), False)
       
   531                     wire.ConnectStartPoint(None, right_element)
       
   532                     wire.ConnectEndPoint(None, connectors["output"])
       
   533                 right_wires.reverse()
       
   534                 for wire in wires:
       
   535                     self.Wires.append(wire)
       
   536                     self.Elements.append(wire)
       
   537                     rung.SelectElement(wire)
       
   538                 self.RefreshPosition(contact)
       
   539                 if len(right_wires) > 1:
       
   540                     group = Graphic_Group(self)
       
   541                     group.SetSelected(False)
       
   542                     for wire in right_wires:
       
   543                         wire.SetSelectedSegment(-1)
       
   544                         group.SelectElement(wire)
       
   545                     self.SelectedElement = group
       
   546                 else:
       
   547                     right_wires[0].SetSelectedSegment(-1)
       
   548                     self.SelectedElement = right_wires[0]
       
   549                 rung.RefreshBoundingBox()
       
   550                 new_bbox = rung.GetBoundingBox()
       
   551                 self.RefreshRungs(new_bbox.height - old_bbox.height, rungindex + 1)
       
   552                 self.Refresh()
       
   553 
       
   554     def AddBranch(self):
       
   555         blocks = []
       
   556         if self.SelectedElement in self.Blocks:
       
   557             blocks = [self.SelectedElement]
       
   558         elif self.SelectedElement not in self.Elements:
       
   559             elements = self.SelectedElement.GetElements()
       
   560             for element in elements:
       
   561                 if isinstance(element, (LD_PowerRail, LD_Coil)):
       
   562                     return
       
   563                 blocks.append(element)
       
   564         if len(blocks) > 0:
       
   565             blocks_infos = []
       
   566             left_elements = []
       
   567             left_index = []
       
   568             right_elements = []
       
   569             right_index = []
       
   570             for block in blocks:
       
   571                 connectors = block.GetConnectors()
       
   572                 block_infos = {"inputs":[],"outputs":[],"lefts":[],"rights":[]}
       
   573                 if "inputs" in connectors:
       
   574                     block_infos["inputs"] = connectors["inputs"]
       
   575                 if "outputs" in connectors:
       
   576                     block_infos["outputs"] = connectors["outputs"]
       
   577                 if "input" in connectors:
       
   578                     block_infos["inputs"] = [connectors["input"]]
       
   579                 if "output" in connectors:
       
   580                     block_infos["outputs"] = [connectors["output"]]
       
   581                 for connector in block_infos["inputs"]:
       
   582                     for wire, handle in connector.GetWires():
       
   583                         found = False
       
   584                         for infos in blocks_infos:
       
   585                             if wire.EndConnected in infos["outputs"]:
       
   586                                 for left_element in infos["lefts"]:
       
   587                                     if left_element not in block_infos["lefts"]:
       
   588                                         block_infos["lefts"].append(left_element)
       
   589                                 found = True
       
   590                         if not found and wire.EndConnected not in block_infos["lefts"]:
       
   591                             block_infos["lefts"].append(wire.EndConnected)
       
   592                             if wire.EndConnected not in left_elements:
       
   593                                 left_elements.append(wire.EndConnected)
       
   594                                 left_index.append(wire.EndConnected.GetWireIndex(wire))
       
   595                             else:
       
   596                                 index = left_elements.index(wire.EndConnected)
       
   597                                 left_index[index] = max(left_index[index], wire.EndConnected.GetWireIndex(wire))
       
   598                 for connector in block_infos["outputs"]:
       
   599                     for wire, handle in connector.GetWires():
       
   600                         found = False
       
   601                         for infos in blocks_infos:
       
   602                             if wire.StartConnected in infos["inputs"]:
       
   603                                 for right_element in infos["rights"]:
       
   604                                     if right_element not in block_infos["rights"]:
       
   605                                         block_infos["rights"].append(right_element)
       
   606                                 found = True
       
   607                         if not found and wire.StartConnected not in block_infos["rights"]:
       
   608                             block_infos["rights"].append(wire.StartConnected)
       
   609                             if wire.StartConnected not in right_elements:
       
   610                                 right_elements.append(wire.StartConnected)
       
   611                                 right_index.append(wire.StartConnected.GetWireIndex(wire))
       
   612                             else:
       
   613                                 index = right_elements.index(wire.StartConnected)
       
   614                                 right_index[index] = max(right_index[index], wire.StartConnected.GetWireIndex(wire))
       
   615                 for connector in block_infos["inputs"]:
       
   616                     for infos in blocks_infos:
       
   617                         if connector in infos["rights"]:
       
   618                             infos["rights"].remove(connector)
       
   619                             if connector in right_elements:
       
   620                                 index = right_elements.index(connector)
       
   621                                 right_elements.pop(index)
       
   622                                 right_index.pop(index)
       
   623                             for right_element in block_infos["rights"]:
       
   624                                 if right_element not in infos["rights"]:
       
   625                                     infos["rights"].append(right_element)
       
   626                 for connector in block_infos["outputs"]:
       
   627                     for infos in blocks_infos:
       
   628                         if connector in infos["lefts"]:
       
   629                             infos["lefts"].remove(connector)
       
   630                             if connector in left_elements:
       
   631                                 index = left_elements.index(connector)
       
   632                                 left_elements.pop(index)
       
   633                                 left_index.pop(index)
       
   634                             for left_element in block_infos["lefts"]:
       
   635                                 if left_element not in infos["lefts"]:
       
   636                                     infos["lefts"].append(left_element)
       
   637                 blocks_infos.append(block_infos)
       
   638             for infos in blocks_infos:
       
   639                 left_elements = [element for element in infos["lefts"]]
       
   640                 for left_element in left_elements:
       
   641                     if isinstance(left_element.GetParentBlock(), LD_PowerRail):
       
   642                         infos["lefts"].remove(left_element)
       
   643                         if "LD_PowerRail" not in infos["lefts"]:
       
   644                             infos["lefts"].append("LD_PowerRail")
       
   645                 right_elements = [element for element in infos["rights"]]
       
   646                 for right_element in right_elements:
       
   647                     if isinstance(right_element.GetParentBlock(), LD_PowerRail):
       
   648                         infos["rights"].remove(tight_element)
       
   649                         if "LD_PowerRail" not in infos["rights"]:
       
   650                             infos["rights"].append("LD_PowerRail")
       
   651                 infos["lefts"].sort()
       
   652                 infos["rights"].sort()
       
   653             lefts = blocks_infos[0]["lefts"]
       
   654             rights = blocks_infos[0]["rights"]
       
   655             good = True
       
   656             for infos in blocks_infos[1:]:
       
   657                 good &= infos["lefts"] == lefts
       
   658                 good &= infos["rights"] == rights
       
   659             if good:
       
   660                 rungindex = self.FindRung(blocks[0])
       
   661                 rung = self.Rungs[rungindex]
       
   662                 old_bbox = rung.GetBoundingBox()
       
   663                 left_powerrail = True
       
   664                 right_powerrail = True
       
   665                 for element in left_elements:
       
   666                     left_powerrail &= isinstance(element.GetParentBlock(), LD_PowerRail)
       
   667                 for element in right_elements:
       
   668                     right_powerrail &= isinstance(element.GetParentBlock(), LD_PowerRail)
       
   669                 if not left_powerrail or not right_powerrail:
       
   670                     if left_powerrail:
       
   671                         powerrail = left_elements[0].GetParentBlock()
       
   672                         index = 0
       
   673                         for left_element in left_elements: 
       
   674                             index = max(index, powerrail.GetConnectorIndex(left_element))
       
   675                         if powerrail.IsNullConnector(index + 1):
       
   676                             powerrail.DeleteConnector(index + 1)
       
   677                         powerrail.InsertConnector(index + 1)
       
   678                         powerrail.RefreshModel()
       
   679                         connectors = powerrail.GetConnectors()
       
   680                         for i, right_element in enumerate(right_elements):
       
   681                             new_wire = Wire(self)
       
   682                             right_element.InsertConnect(right_index[i] + 1, (new_wire, 0), False)
       
   683                             connectors[index + 1].Connect((new_wire, -1), False)
       
   684                             new_wire.ConnectStartPoint(None, right_element)
       
   685                             new_wire.ConnectEndPoint(None, connectors[index + 1])
       
   686                             self.Wires.append(new_wire)
       
   687                             self.Elements.append(new_wire)
       
   688                             rung.SelectElement(new_wire)
       
   689                         right_elements.reverse()
       
   690                     elif right_powerrail:
       
   691                         pass
       
   692                     else:
       
   693                         left_elements.reverse()
       
   694                         right_elements.reverse()
       
   695                         wires = []
       
   696                         for i, left_element in enumerate(left_elements):
       
   697                             for j, right_element in enumerate(right_elements):
       
   698                                 exist = False
       
   699                                 for wire, handle in right_element.GetWires():
       
   700                                     exist |= wire.EndConnected == left_element
       
   701                                 if not exist:
       
   702                                     new_wire = Wire(self)
       
   703                                     wires.append(new_wire)
       
   704                                     right_element.InsertConnect(right_index[j] + 1, (new_wire, 0), False)
       
   705                                     left_element.InsertConnect(left_index[i] + 1, (new_wire, -1), False)
       
   706                                     new_wire.ConnectStartPoint(None, right_element)
       
   707                                     new_wire.ConnectEndPoint(None, left_element)
       
   708                         wires.reverse()
       
   709                         for wire in wires:
       
   710                             self.Wires.append(wire)
       
   711                             self.Elements.append(wire)
       
   712                             rung.SelectElement(wire)
       
   713                         right_elements.reverse()
       
   714                 for block in blocks:
       
   715                     self.RefreshPosition(block)
       
   716                 for right_element in right_elements:
       
   717                     self.RefreshPosition(right_element.GetParentBlock())
       
   718                 self.SelectedElement.RefreshBoundingBox()
       
   719                 rung.RefreshBoundingBox()
       
   720                 new_bbox = rung.GetBoundingBox()
       
   721                 self.RefreshRungs(new_bbox.height - old_bbox.height, rungindex + 1)
       
   722                 self.Refresh()
       
   723 
       
   724 #-------------------------------------------------------------------------------
       
   725 #                          Delete element functions
       
   726 #-------------------------------------------------------------------------------
       
   727 
       
   728     def DeleteContact(self, contact):
       
   729         rungindex = self.FindRung(contact)
       
   730         rung = self.Rungs[rungindex]
       
   731         old_bbox = rung.GetBoundingBox()
       
   732         connectors = contact.GetConnectors()
       
   733         input_wires = [wire for wire, handle in connectors["input"].GetWires()]
       
   734         output_wires = [wire for wire, handle in connectors["output"].GetWires()]
       
   735         left_elements = [(wire.EndConnected, wire.EndConnected.GetWireIndex(wire)) for wire in input_wires]
       
   736         right_elements = [(wire.StartConnected, wire.StartConnected.GetWireIndex(wire)) for wire in output_wires]
       
   737         for wire in input_wires:
       
   738             wire.Clean()
       
   739             rung.SelectElement(wire)
       
   740             self.Wires.remove(wire)
       
   741             self.Elements.remove(wire)
       
   742         for wire in output_wires:
       
   743             wire.Clean()
       
   744             rung.SelectElement(wire)
       
   745             self.Wires.remove(wire)
       
   746             self.Elements.remove(wire)
       
   747         rung.SelectElement(contact)
       
   748         contact.Clean()
       
   749         left_elements.reverse()
       
   750         right_elements.reverse()
       
   751         powerrail = len(left_elements) == 1 and isinstance(left_elements[0][0].GetParentBlock(), LD_PowerRail)
       
   752         for left_element, left_index in left_elements:
       
   753             for right_element, right_index in right_elements:
       
   754                 wire_removed = []
       
   755                 for wire, handle in right_element.GetWires():
       
   756                     if wire.EndConnected == left_element:
       
   757                         wire_removed.append(wire)
       
   758                     elif isinstance(wire.EndConnected.GetParentBlock(), LD_PowerRail) and powerrail:
       
   759                         left_powerrail = wire.EndConnected.GetParentBlock()
       
   760                         index = left_powerrail.GetConnectorIndex(wire.EndConnected)
       
   761                         left_powerrail.DeleteConnector(index)
       
   762                         wire_removed.append(wire)
       
   763                 for wire in wire_removed:
       
   764                     wire.Clean()
       
   765                     self.Wires.remove(wire)
       
   766                     self.Elements.remove(wire)
       
   767                     rung.SelectElement(wire)
       
   768         wires = []
       
   769         for left_element, left_index in left_elements:
       
   770             for right_element, right_index in right_elements:
       
   771                 wire = Wire(self)
       
   772                 wires.append(wire)
       
   773                 right_element.InsertConnect(right_index, (wire, 0), False)
       
   774                 left_element.InsertConnect(left_index, (wire, -1), False)
       
   775                 wire.ConnectStartPoint(None, right_element)
       
   776                 wire.ConnectEndPoint(None, left_element)
       
   777         wires.reverse()
       
   778         for wire in wires:
       
   779             self.Wires.append(wire)
       
   780             self.Elements.append(wire)
       
   781             rung.SelectElement(wire)
       
   782         right_elements.reverse()
       
   783         for right_element, right_index in right_elements:
       
   784             self.RefreshPosition(right_element.GetParentBlock())
       
   785         self.Blocks.remove(contact)
       
   786         self.Elements.remove(contact)
       
   787         self.Controler.RemoveCurrentElementEditingInstance(contact.GetId())
       
   788         rung.RefreshBoundingBox()
       
   789         new_bbox = rung.GetBoundingBox()
       
   790         self.RefreshRungs(new_bbox.height - old_bbox.height, rungindex + 1)
       
   791         self.SelectedElement = None
       
   792 
       
   793     def DeleteCoil(self, coil):
       
   794         rungindex = self.FindRung(coil)
       
   795         rung = self.Rungs[rungindex]
       
   796         bbox = rung.GetBoundingBox()
       
   797         for element in rung.GetElements():
       
   798             if element in self.Wires:
       
   799                 element.Clean()
       
   800                 self.Wires.remove(element)
       
   801                 self.Elements.remove(element)
       
   802         for element in rung.GetElements():
       
   803             if element in self.Blocks:
       
   804                 self.Controler.RemoveCurrentElementEditingInstance(element.GetId())
       
   805                 self.Blocks.remove(element)
       
   806                 self.Elements.remove(element)
       
   807         self.Controler.RemoveCurrentElementEditingInstance(self.Comments[rungindex].GetId())
       
   808         self.Elements.remove(self.Comments[rungindex])
       
   809         self.Comments.pop(rungindex)
       
   810         self.Rungs.pop(rungindex)
       
   811         if rungindex < len(self.Rungs):
       
   812             next_bbox = self.Rungs[rungindex].GetBoundingBox()
       
   813             self.RefreshRungs(bbox.y - next_bbox.y, rungindex)
       
   814         self.SelectedElement = None
       
   815 
       
   816     def DeleteWire(self, wire):
       
   817         wires = []
       
   818         left_elements = []
       
   819         right_elements = []
       
   820         if wire in self.Wires:
       
   821             wires = [wire]
       
   822         elif wire not in self.Elements:
       
   823             for element in wire.GetElements():
       
   824                 if element in self.Wires:
       
   825                     wires.append(element)
       
   826                 else:
       
   827                     wires = []
       
   828                     break
       
   829         if len(wires) > 0:
       
   830             rungindex = self.FindRung(wires[0])
       
   831             rung = self.Rungs[rungindex]
       
   832             old_bbox = rung.GetBoundingBox()
       
   833             for wire in wires:
       
   834                 connections = wire.GetSelectedSegmentConnections()
       
   835                 left_block = wire.EndConnected.GetParentBlock()
       
   836                 if wire.EndConnected not in left_elements:
       
   837                     left_elements.append(wire.EndConnected)
       
   838                 if wire.StartConnected not in right_elements:
       
   839                     right_elements.append(wire.StartConnected)
       
   840                 if connections == (False, False) or connections == (False, True) and isinstance(left_block, LD_PowerRail):
       
   841                     wire.Clean()
       
   842                     self.Wires.remove(wire)
       
   843                     self.Elements.remove(wire)
       
   844                     rung.SelectElement(wire)
       
   845             for left_element in left_elements:
       
   846                 left_block = left_element.GetParentBlock()
       
   847                 if isinstance(left_block, LD_PowerRail):
       
   848                     if len(left_element.GetWires()) == 0:
       
   849                         index = left_block.GetConnectorIndex(left_element)
       
   850                         left_block.DeleteConnector(index)
       
   851                 else:
       
   852                     connectors = left_block.GetConnectors()
       
   853                     output_connectors = []
       
   854                     if "outputs" in connectors:
       
   855                         output_connectors = connectors["outputs"]
       
   856                     if "output" in connectors:
       
   857                         output_connectors = [connectors["output"]]
       
   858                     for connector in output_connectors:
       
   859                         for wire, handle in connector.GetWires():
       
   860                             self.RefreshPosition(wire.StartConnected.GetParentBlock())
       
   861             for right_element in right_elements:
       
   862                 self.RefreshPosition(right_element.GetParentBlock())
       
   863             rung.RefreshBoundingBox()
       
   864             new_bbox = rung.GetBoundingBox()
       
   865             self.RefreshRungs(new_bbox.height - old_bbox.height, rungindex + 1)
       
   866             self.SelectedElement = None
       
   867 
       
   868 #-------------------------------------------------------------------------------
       
   869 #                        Refresh element position functions
       
   870 #-------------------------------------------------------------------------------
       
   871 
       
   872     def RefreshPosition(self, element):
       
   873         if isinstance(element, LD_PowerRail) and element.GetType() == LEFTRAIL:
       
   874             element.RefreshModel()
       
   875             return
       
   876         connectors = element.GetConnectors()
       
   877         input_connectors = []
       
   878         output_connectors = []
       
   879         if isinstance(element, LD_PowerRail) and element.GetType() == RIGHTRAIL:
       
   880             input_connectors = connectors
       
   881         else:
       
   882             if "inputs" in connectors:
       
   883                 input_connectors = connectors["inputs"]
       
   884             if "outputs" in connectors:
       
   885                 output_connectors = connectors["outputs"]
       
   886             if "input" in connectors:
       
   887                 input_connectors = [connectors["input"]]
       
   888             if "output" in connectors:
       
   889                 output_connectors = [connectors["output"]]
       
   890         position = element.GetPosition()
       
   891         minx = 0
       
   892         onlyone = []
       
   893         for connector in input_connectors:
       
   894             onlyone.append(len(connector.GetWires()) == 1)
       
   895             for wire, handle in connector.GetWires():
       
   896                 onlyone[-1] &= len(wire.EndConnected.GetWires()) == 1
       
   897                 leftblock = wire.EndConnected.GetParentBlock()
       
   898                 pos = leftblock.GetPosition()
       
   899                 size = leftblock.GetSize()
       
   900                 minx = max(minx, pos[0] + size[0])
       
   901         if isinstance(element, LD_Coil):
       
   902             interval = LD_WIRECOIL_SIZE
       
   903         else:
       
   904             interval = LD_WIRE_SIZE
       
   905         if False in onlyone:
       
   906             interval += LD_WIRE_SIZE
       
   907         movex = minx + interval - position[0]
       
   908         element.Move(movex, 0)
       
   909         for i, connector in enumerate(input_connectors):
       
   910             startpoint = connector.GetPosition(False)
       
   911             previous_blocks = []
       
   912             block_list = []
       
   913             start_offset = 0
       
   914             if not onlyone[i]:
       
   915                 middlepoint = minx + LD_WIRE_SIZE
       
   916             for j, (wire, handle) in enumerate(connector.GetWires()):
       
   917                 block = wire.EndConnected.GetParentBlock()
       
   918                 endpoint = wire.EndConnected.GetPosition(False)
       
   919                 if j == 0:
       
   920                     if not onlyone[i] and wire.EndConnected.GetWireIndex(wire) > 0:
       
   921                         start_offset = endpoint.y - startpoint.y
       
   922                     offset = start_offset
       
   923                 else:
       
   924                     offset = start_offset + LD_LINE_SIZE * CalcBranchSize(previous_blocks, block)
       
   925                 if block in block_list:
       
   926                     wires = wire.EndConnected.GetWires()
       
   927                     endmiddlepoint = wires[0][0].StartConnected.GetPosition(False)[0] - LD_WIRE_SIZE
       
   928                     points = [startpoint, wxPoint(middlepoint, startpoint.y),
       
   929                               wxPoint(middlepoint, startpoint.y + offset),
       
   930                               wxPoint(endmiddlepoint, startpoint.y + offset),
       
   931                               wxPoint(endmiddlepoint, endpoint.y), endpoint]
       
   932                 else:
       
   933                     if startpoint.y + offset != endpoint.y:
       
   934                         if isinstance(block, LD_PowerRail):
       
   935                             index = block.GetConnectorIndex(wire.EndConnected)
       
   936                             if index:
       
   937                                 diff = (startpoint.y - endpoint.y) / LD_LINE_SIZE
       
   938                                 for k in xrange(abs(diff)):
       
   939                                     if diff < 0:
       
   940                                         block.DeleteConnector(index - 1 - k)
       
   941                                     else:
       
   942                                         block.InsertConnector(index + k, False)
       
   943                         else:
       
   944                             block.Move(0, startpoint.y + offset - endpoint.y)
       
   945                             self.RefreshPosition(block)
       
   946                         endpoint = wire.EndConnected.GetPosition(False)
       
   947                     if not onlyone[i]:
       
   948                         points = [startpoint, wxPoint(middlepoint, startpoint.y),
       
   949                                   wxPoint(middlepoint, endpoint.y), endpoint]
       
   950                     else:
       
   951                         points = [startpoint, endpoint]
       
   952                 wire.SetPoints(points)
       
   953                 previous_blocks.append(block)
       
   954                 ExtractNextBlocks(block, block_list)
       
   955         element.RefreshModel(False)
       
   956         for connector in output_connectors:
       
   957             for wire, handle in connector.GetWires():
       
   958                 self.RefreshPosition(wire.StartConnected.GetParentBlock())
       
   959     
       
   960     def RefreshRungs(self, movey, fromidx):
       
   961         if movey != 0:
       
   962             for i in xrange(fromidx, len(self.Rungs)):
       
   963                 self.Comments[i].Move(0, movey)
       
   964                 self.Comments[i].RefreshModel()
       
   965                 self.Rungs[i].Move(0, movey)
       
   966                 for element in self.Rungs[i].GetElements():
       
   967                     if element in self.Blocks:
       
   968                         self.RefreshPosition(element)
       
   969 
       
   970 #-------------------------------------------------------------------------------
       
   971 #                          Edit element content functions
       
   972 #-------------------------------------------------------------------------------
       
   973 
       
   974     def EditContactContent(self, contact):
       
   975         dialog = LDElementDialog(self.Parent, "contact")
       
   976         varlist = []
       
   977         vars = self.Controler.GetCurrentElementEditingInterfaceVars()
       
   978         if vars:
       
   979             for var in vars:
       
   980                 if var["Type"] != "Output" and var["Value"] == "BOOL":
       
   981                     varlist.append(var["Name"])
       
   982         dialog.SetVariables(varlist)
       
   983         dialog.SetValues({"name":contact.GetName(),"type":contact.GetType()})
       
   984         if dialog.ShowModal() == wxID_OK:
       
   985             values = dialog.GetValues()
       
   986             contact.SetName(values["name"])
       
   987             contact.SetType(values["type"])
       
   988             contact.RefreshModel(False)
       
   989             self.Refresh()
       
   990         dialog.Destroy()
       
   991 
       
   992     def EditCoilContent(self, coil):
       
   993         dialog = LDElementDialog(self.Parent, "coil")
       
   994         varlist = []
       
   995         vars = self.Controler.GetCurrentElementEditingInterfaceVars()
       
   996         if vars:
       
   997             for var in vars:
       
   998                 if var["Type"] != "Input" and var["Value"] == "BOOL":
       
   999                     varlist.append(var["Name"])
       
  1000         returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
       
  1001         if returntype == "BOOL":
       
  1002             varlist.append(self.Controler.GetCurrentElementEditingName())
       
  1003         dialog.SetVariables(varlist)
       
  1004         dialog.SetValues({"name":coil.GetName(),"type":coil.GetType()})
       
  1005         if dialog.ShowModal() == wxID_OK:
       
  1006             values = dialog.GetValues()
       
  1007             coil.SetName(values["name"])
       
  1008             coil.SetType(values["type"])
       
  1009             coil.RefreshModel(False)
       
  1010             self.Refresh()
       
  1011         dialog.Destroy()
       
  1012 
       
  1013 #-------------------------------------------------------------------------------
       
  1014 #                        Edit Ladder Element Properties Dialog
       
  1015 #-------------------------------------------------------------------------------
       
  1016 
       
  1017 [wxID_LDELEMENTDIALOG, wxID_LDELEMENTDIALOGMAINPANEL, 
       
  1018  wxID_LDELEMENTDIALOGNAME, wxID_LDELEMENTDIALOGRADIOBUTTON1, 
       
  1019  wxID_LDELEMENTDIALOGRADIOBUTTON2, wxID_LDELEMENTDIALOGRADIOBUTTON3,
       
  1020  wxID_LDELEMENTDIALOGRADIOBUTTON4, wxID_LDELEMENTDIALOGPREVIEW,
       
  1021  wxID_LDELEMENTDIALOGSTATICTEXT1, wxID_LDELEMENTDIALOGSTATICTEXT2, 
       
  1022  wxID_LDELEMENTDIALOGSTATICTEXT3, 
       
  1023 ] = [wx.NewId() for _init_ctrls in range(11)]
       
  1024 
       
  1025 class LDElementDialog(wx.Dialog):
       
  1026     def _init_coll_flexGridSizer1_Items(self, parent):
       
  1027         # generated method, don't edit
       
  1028 
       
  1029         parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
       
  1030 
       
  1031     def _init_sizers(self):
       
  1032         # generated method, don't edit
       
  1033         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
       
  1034 
       
  1035         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
       
  1036 
       
  1037         self.SetSizer(self.flexGridSizer1)
       
  1038 
       
  1039     def _init_ctrls(self, prnt, title, labels):
       
  1040         # generated method, don't edit
       
  1041         wx.Dialog.__init__(self, id=wxID_LDELEMENTDIALOG,
       
  1042               name='VariablePropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
       
  1043               size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE,
       
  1044               title=title)
       
  1045         self.SetClientSize(wx.Size(350, 260))
       
  1046 
       
  1047         self.MainPanel = wx.Panel(id=wxID_LDELEMENTDIALOGMAINPANEL,
       
  1048               name='MainPanel', parent=self, pos=wx.Point(0, 0),
       
  1049               size=wx.Size(340, 200), style=wx.TAB_TRAVERSAL)
       
  1050         self.MainPanel.SetAutoLayout(True)
       
  1051 
       
  1052         self.staticText1 = wx.StaticText(id=wxID_LDELEMENTDIALOGSTATICTEXT1,
       
  1053               label='Type:', name='staticText1', parent=self.MainPanel,
       
  1054               pos=wx.Point(24, 24), size=wx.Size(70, 17), style=0)
       
  1055 
       
  1056         self.staticText2 = wx.StaticText(id=wxID_LDELEMENTDIALOGSTATICTEXT2,
       
  1057               label='Name:', name='staticText2', parent=self.MainPanel,
       
  1058               pos=wx.Point(24, 150), size=wx.Size(70, 17), style=0)
       
  1059 
       
  1060         self.staticText3 = wx.StaticText(id=wxID_LDELEMENTDIALOGSTATICTEXT3,
       
  1061               label='Preview:', name='staticText3', parent=self.MainPanel,
       
  1062               pos=wx.Point(174, 24), size=wx.Size(100, 17), style=0)
       
  1063 
       
  1064         self.radioButton1 = wx.RadioButton(id=wxID_LDELEMENTDIALOGRADIOBUTTON1,
       
  1065               label=labels[0], name='radioButton1', parent=self.MainPanel,
       
  1066               pos=wx.Point(24, 48), size=wx.Size(114, 24), style=0)
       
  1067         EVT_RADIOBUTTON(self, wxID_LDELEMENTDIALOGRADIOBUTTON1, self.OnTypeChanged)
       
  1068         self.radioButton1.SetValue(True)
       
  1069 
       
  1070         self.radioButton2 = wx.RadioButton(id=wxID_LDELEMENTDIALOGRADIOBUTTON2,
       
  1071               label=labels[1], name='radioButton2', parent=self.MainPanel, 
       
  1072               pos=wx.Point(24, 72), size=wx.Size(128, 24), style=0)
       
  1073         EVT_RADIOBUTTON(self, wxID_LDELEMENTDIALOGRADIOBUTTON2, self.OnTypeChanged)
       
  1074 
       
  1075         self.radioButton3 = wx.RadioButton(id=wxID_LDELEMENTDIALOGRADIOBUTTON3,
       
  1076               label=labels[2], name='radioButton3', parent=self.MainPanel,
       
  1077               pos=wx.Point(24, 96), size=wx.Size(114, 24), style=0)
       
  1078         EVT_RADIOBUTTON(self, wxID_LDELEMENTDIALOGRADIOBUTTON3, self.OnTypeChanged)
       
  1079 
       
  1080         self.radioButton4 = wx.RadioButton(id=wxID_LDELEMENTDIALOGRADIOBUTTON4,
       
  1081               label=labels[3], name='radioButton4', parent=self.MainPanel, 
       
  1082               pos=wx.Point(24, 120), size=wx.Size(128, 24), style=0)
       
  1083         EVT_RADIOBUTTON(self, wxID_LDELEMENTDIALOGRADIOBUTTON4, self.OnTypeChanged)
       
  1084 
       
  1085         self.Name = wx.Choice(id=wxID_LDELEMENTDIALOGNAME,
       
  1086               name='Name', parent=self.MainPanel, pos=wx.Point(24, 174),
       
  1087               size=wx.Size(145, 24), style=0)
       
  1088         EVT_CHOICE(self, wxID_LDELEMENTDIALOGNAME, self.OnNameChanged)
       
  1089 
       
  1090         self.Preview = wx.Panel(id=wxID_LDELEMENTDIALOGPREVIEW,
       
  1091               name='Preview', parent=self.MainPanel, pos=wx.Point(174, 48),
       
  1092               size=wx.Size(150, 150), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
       
  1093         self.Preview.SetBackgroundColour(wxColour(255,255,255))
       
  1094 
       
  1095         self._init_sizers()
       
  1096 
       
  1097     def __init__(self, parent, type):
       
  1098         self.Type = type
       
  1099         if type == "contact":
       
  1100             self._init_ctrls(parent, "Edit Contact Values", ['Normal','Reverse','Rising Edge','Falling Edge'])
       
  1101             self.Element = LD_Contact(self.Preview, CONTACT_NORMAL, "")
       
  1102         elif type == "coil":
       
  1103             self._init_ctrls(parent, "Edit Coil Values", ['Normal','Reverse','Set','Reset'])
       
  1104             self.Element = LD_Coil(self.Preview, COIL_NORMAL, "")
       
  1105         self.Element.SetPosition((150 - LD_ELEMENT_SIZE[0]) / 2, (150 - LD_ELEMENT_SIZE[1]) / 2)
       
  1106 
       
  1107         self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
       
  1108         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
       
  1109 
       
  1110         EVT_PAINT(self, self.OnPaint)
       
  1111 
       
  1112     def SetVariables(self, vars):
       
  1113         self.Name.Clear()
       
  1114         for name in vars:
       
  1115             self.Name.Append(name)
       
  1116         self.Name.Enable(self.Name.GetCount() > 0)
       
  1117 
       
  1118     def SetValues(self, values):
       
  1119         for name, value in values.items():
       
  1120             if name == "name":
       
  1121                 self.Element.SetName(value)
       
  1122                 self.Name.SetStringSelection(value)
       
  1123             elif name == "type":
       
  1124                 self.Element.SetType(value)
       
  1125                 if self.Type == "contact":
       
  1126                     if value == CONTACT_NORMAL:
       
  1127                         self.radioButton1.SetValue(True)
       
  1128                     elif value == CONTACT_REVERSE:
       
  1129                         self.radioButton2.SetValue(True)
       
  1130                     elif value == CONTACT_RISING:
       
  1131                         self.radioButton3.SetValue(True)
       
  1132                     elif value == CONTACT_FALLING:
       
  1133                         self.radioButton4.SetValue(True)
       
  1134                 elif self.Type == "coil":
       
  1135                     if value == COIL_NORMAL:
       
  1136                         self.radioButton1.SetValue(True)
       
  1137                     elif value == COIL_REVERSE:
       
  1138                         self.radioButton2.SetValue(True)
       
  1139                     elif value == COIL_SET:
       
  1140                         self.radioButton3.SetValue(True)
       
  1141                     elif value == COIL_RESET:
       
  1142                         self.radioButton4.SetValue(True)
       
  1143 
       
  1144     def GetValues(self):
       
  1145         values = {}
       
  1146         values["name"] = self.Element.GetName()
       
  1147         values["type"] = self.Element.GetType()
       
  1148         return values
       
  1149 
       
  1150     def OnTypeChanged(self, event):
       
  1151         if self.Type == "contact":
       
  1152             if self.radioButton1.GetValue():
       
  1153                 self.Element.SetType(CONTACT_NORMAL)
       
  1154             elif self.radioButton2.GetValue():
       
  1155                 self.Element.SetType(CONTACT_REVERSE)
       
  1156             elif self.radioButton3.GetValue():
       
  1157                 self.Element.SetType(CONTACT_RISING)
       
  1158             elif self.radioButton4.GetValue():
       
  1159                 self.Element.SetType(CONTACT_FALLING)
       
  1160         elif self.Type == "coil":
       
  1161             if self.radioButton1.GetValue():
       
  1162                 self.Element.SetType(COIL_NORMAL)
       
  1163             elif self.radioButton2.GetValue():
       
  1164                 self.Element.SetType(COIL_REVERSE)
       
  1165             elif self.radioButton3.GetValue():
       
  1166                 self.Element.SetType(COIL_SET)
       
  1167             elif self.radioButton4.GetValue():
       
  1168                 self.Element.SetType(COIL_RESET)
       
  1169         self.RefreshPreview()
       
  1170         event.Skip()
       
  1171 
       
  1172     def OnNameChanged(self, event):
       
  1173         self.Element.SetName(self.Name.GetStringSelection())
       
  1174         self.RefreshPreview()
       
  1175         event.Skip()
       
  1176 
       
  1177     def RefreshPreview(self):
       
  1178         dc = wxClientDC(self.Preview)
       
  1179         dc.Clear()
       
  1180         self.Element.Draw(dc)
       
  1181 
       
  1182     def OnPaint(self, event):
       
  1183         self.RefreshPreview()
       
  1184         event.Skip()