Adding support for concurrent overriden standard function
authorlbessard
Tue, 10 Jul 2007 09:52:53 +0200
changeset 28 fc23e1f415d8
parent 27 dae55dd9ee14
child 29 3b7e23a323a6
Adding support for concurrent overriden standard function
Adding support for generate initial values
Adding support for expression into FBD variables
Dialogs.py
LDViewer.py
PLCControler.py
PLCGenerator.py
PLCOpenEditor.py
SFCViewer.py
Viewer.py
graphics/FBD_Objects.py
graphics/GraphicCommons.py
graphics/LD_Objects.py
plcopen/structures.py
test.xml
--- a/Dialogs.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/Dialogs.py	Tue Jul 10 09:52:53 2007 +0200
@@ -126,14 +126,20 @@
         EVT_PAINT(self, self.OnPaint)
         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
     
-    def FindTreeItem(self, root, name):
+    def FindTreeItem(self, root, name, inputs = None):
         if root.IsOk():
-            if self.TypeTree.GetItemText(root) == name:
+            pydata = self.TypeTree.GetPyData(root)
+            if inputs and "inputs" in pydata:
+                print inputs, pydata["inputs"]
+                same_inputs = pydata["inputs"] == inputs
+            else:
+                same_inputs = True
+            if self.TypeTree.GetItemText(root) == name and same_inputs:
                 return root
             else:
                 item, root_cookie = self.TypeTree.GetFirstChild(root)
                 while item.IsOk():
-                    result = self.FindTreeItem(item, name)
+                    result = self.FindTreeItem(item, name, inputs)
                     if result:
                         return result
                     item, root_cookie = self.TypeTree.GetNextChild(root, root_cookie)
@@ -155,13 +161,13 @@
 
     def SetBlockList(self, blocktypes):
         root = self.TypeTree.AddRoot("")
-        self.TypeTree.SetPyData(root, CATEGORY)
+        self.TypeTree.SetPyData(root, {"type" : CATEGORY})
         for category in blocktypes:
             category_item = self.TypeTree.AppendItem(root, category["name"])
-            self.TypeTree.SetPyData(category_item, CATEGORY)
+            self.TypeTree.SetPyData(category_item, {"type" : CATEGORY})
             for blocktype in category["list"]:
                 blocktype_item = self.TypeTree.AppendItem(category_item, blocktype["name"])
-                self.TypeTree.SetPyData(blocktype_item, BLOCK)
+                self.TypeTree.SetPyData(blocktype_item, {"type" : BLOCK, "inputs" : tuple([type for name, type, modifier in blocktype["inputs"]])})
 
     def SetMinBlockSize(self, size):
         self.MinBlockSize = size
@@ -169,7 +175,10 @@
     def SetValues(self, values):
         for name, value in values.items():
             if name == "type":
-                item = self.FindTreeItem(self.TypeTree.GetRootItem(), value)
+                inputs = None
+                if "inputs" in values:
+                    inputs = values["inputs"]
+                item = self.FindTreeItem(self.TypeTree.GetRootItem(), value, inputs)
                 if item:
                     self.TypeTree.SelectItem(item)
             elif name == "name":
@@ -180,7 +189,9 @@
 
     def GetValues(self):
         values = {}
-        values["type"] = self.TypeTree.GetItemText(self.TypeTree.GetSelection())
+        item = self.TypeTree.GetSelection()
+        values["type"] = self.TypeTree.GetItemText(item)
+        values["inputs"] = self.TypeTree.GetPyData(item)["inputs"]
         if self.Name.GetValue() != "":
             values["name"] = self.Name.GetValue()
         values["width"], values["height"] = self.Block.GetSize()
@@ -190,8 +201,9 @@
     def OnTypeTreeItemSelected(self, event):
         self.Name.SetValue("")
         selected = event.GetItem()
-        if self.TypeTree.GetPyData(selected) != CATEGORY:
-            blocktype = GetBlockType(self.TypeTree.GetItemText(selected))
+        pydata = self.TypeTree.GetPyData(selected)
+        if pydata["type"] != CATEGORY:
+            blocktype = GetBlockType(self.TypeTree.GetItemText(selected), pydata["inputs"])
             if blocktype:
                 self.Inputs.SetValue(len(blocktype["inputs"]))
                 self.Inputs.Enable(blocktype["extensible"])
@@ -231,12 +243,13 @@
         dc = wxClientDC(self.Preview)
         dc.Clear()
         item = self.TypeTree.GetSelection()
-        if self.TypeTree.GetPyData(item) == CATEGORY:
+        pydata = self.TypeTree.GetPyData(item)
+        if pydata["type"] == CATEGORY:
             self.Block = None
         else:
             blocktype = self.TypeTree.GetItemText(item)
             if blocktype:
-                self.Block = FBD_Block(self.Preview, blocktype, self.Name.GetValue(), extension = self.Inputs.GetValue())
+                self.Block = FBD_Block(self.Preview, blocktype, self.Name.GetValue(), extension = self.Inputs.GetValue(), inputs = pydata["inputs"])
                 width, height = self.MinBlockSize
                 min_width, min_height = self.Block.GetMinSize()
                 width, height = max(min_width, width), max(min_height, height)
@@ -260,9 +273,10 @@
 
 [wxID_VARIABLEPROPERTIESDIALOG, wxID_VARIABLEPROPERTIESDIALOGMAINPANEL, 
  wxID_VARIABLEPROPERTIESDIALOGNAME, wxID_VARIABLEPROPERTIESDIALOGCLASS, 
- wxID_VARIABLEPROPERTIESDIALOGPREVIEW, wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT1,
- wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT2, wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, 
-] = [wx.NewId() for _init_ctrls in range(8)]
+ wxID_VARIABLEPROPERTIESDIALOGPREVIEW, wxID_VARIABLEPROPERTIESDIALOGEXPRESSION,
+ wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT1, wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT2,
+ wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT4,
+] = [wx.NewId() for _init_ctrls in range(10)]
 
 class VariablePropertiesDialog(wx.Dialog):
     def _init_coll_flexGridSizer1_Items(self, parent):
@@ -282,9 +296,9 @@
         # generated method, don't edit
         wx.Dialog.__init__(self, id=wxID_VARIABLEPROPERTIESDIALOG,
               name='VariablePropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
-              size=wx.Size(400, 320), style=wx.DEFAULT_DIALOG_STYLE,
+              size=wx.Size(400, 380), style=wx.DEFAULT_DIALOG_STYLE,
               title='Variable Properties')
-        self.SetClientSize(wx.Size(400, 320))
+        self.SetClientSize(wx.Size(400, 380))
 
         self.MainPanel = wx.Panel(id=wxID_VARIABLEPROPERTIESDIALOGMAINPANEL,
               name='MainPanel', parent=self, pos=wx.Point(0, 0),
@@ -296,25 +310,34 @@
               pos=wx.Point(24, 24), size=wx.Size(70, 17), style=0)
 
         self.staticText2 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT2,
-              label='Name:', name='staticText2', parent=self.MainPanel,
+              label='Expression:', name='staticText2', parent=self.MainPanel,
+              pos=wx.Point(24, 90), size=wx.Size(100, 17), style=0)
+
+        self.staticText3 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT3,
+              label='Name:', name='staticText3', parent=self.MainPanel,
               pos=wx.Point(204, 24), size=wx.Size(70, 17), style=0)
 
-        self.staticText3 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT3,
-              label='Preview:', name='staticText3', parent=self.MainPanel,
-              pos=wx.Point(24, 78), size=wx.Size(100, 17), style=0)
+        self.staticText4 = wx.StaticText(id=wxID_VARIABLEPROPERTIESDIALOGSTATICTEXT4,
+              label='Preview:', name='staticText4', parent=self.MainPanel,
+              pos=wx.Point(24, 144), size=wx.Size(100, 17), style=0)
 
         self.Class = wx.Choice(id=wxID_VARIABLEPROPERTIESDIALOGCLASS,
               name='Class', parent=self.MainPanel, pos=wx.Point(24, 48),
               size=wx.Size(145, 24), style=0)
         EVT_CHOICE(self, wxID_VARIABLEPROPERTIESDIALOGCLASS, self.OnClassChanged)
         
-        self.Name = wx.Choice(id=wxID_VARIABLEPROPERTIESDIALOGNAME,
+        self.Name = wx.ListBox(id=wxID_VARIABLEPROPERTIESDIALOGNAME,
               name='Name', parent=self.MainPanel, pos=wx.Point(204, 48),
+              size=wx.Size(145, 90), style=wx.LB_SINGLE)
+        EVT_LISTBOX(self, wxID_VARIABLEPROPERTIESDIALOGNAME, self.OnNameChanged)
+
+        self.Expression = wx.TextCtrl(id=wxID_VARIABLEPROPERTIESDIALOGEXPRESSION,
+              name='Expression', parent=self.MainPanel, pos=wx.Point(24, 114),
               size=wx.Size(145, 24), style=0)
-        EVT_CHOICE(self, wxID_VARIABLEPROPERTIESDIALOGNAME, self.OnNameChanged)
+        EVT_TEXT(self, wxID_VARIABLEPROPERTIESDIALOGEXPRESSION, self.OnExpressionChanged)
 
         self.Preview = wx.Panel(id=wxID_VARIABLEPROPERTIESDIALOGPREVIEW,
-              name='Preview', parent=self.MainPanel, pos=wx.Point(24, 104),
+              name='Preview', parent=self.MainPanel, pos=wx.Point(24, 170),
               size=wx.Size(350, 150), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
         self.Preview.SetBackgroundColour(wxColour(255,255,255))
 
@@ -338,8 +361,9 @@
     def RefreshNameList(self):
         selected = self.Name.GetStringSelection()
         self.Name.Clear()
+        self.Name.Append("")
         for name, var_type, value_type in self.VarList:
-            if var_type in ["Local","Temp"]:
+            if var_type in ["Local","Temp","Global","External"]:
                 self.Name.Append(name)
             elif var_type == "Input" and self.Class.GetStringSelection() == "Input":
                 self.Name.Append(name)
@@ -349,6 +373,8 @@
                 self.Name.Append(name)
         if self.Name.FindString(selected) != wxNOT_FOUND:
             self.Name.SetStringSelection(selected)
+        else:
+            self.Name.SetStringSelection("")
         self.Name.Enable(self.Name.GetCount() > 0)
             
     def SetMinVariableSize(self, size):
@@ -367,8 +393,13 @@
                     self.Class.SetStringSelection("Output")
                 if value == INOUT:
                     self.Class.SetStringSelection("InOut")
-            elif name == "name":
-                self.Name.SetStringSelection(value)
+            elif name == "name" and value != "":
+                if self.Name.FindString(value) != wxNOT_FOUND:
+                    self.Name.SetStringSelection(value)
+                    self.Expression.Enable(False)
+                else:
+                    self.Expression.SetValue(value)
+                    self.Name.Enable(False)
         self.RefreshPreview()
         
     def GetValues(self):
@@ -380,7 +411,11 @@
             values["type"] = OUTPUT
         elif classtype == "InOut":
             values["type"] = INOUT
-        values["name"] = self.Name.GetStringSelection()
+        expression = self.Expression.GetValue()
+        if self.Expression.IsEnabled() and expression != "":
+            values["name"] = expression
+        else:
+            values["name"] = self.Name.GetStringSelection()
         values["value_type"] = ""
         for var_name, var_type, value_type in self.VarList:
             if var_name == values["name"]:
@@ -390,17 +425,37 @@
 
     def OnClassChanged(self, event):
         self.RefreshNameList()
+        if self.Class.GetStringSelection() == "Input":
+            self.Expression.Enable(True)
+        else:
+            self.Expression.Enable(False)
         self.RefreshPreview()
         event.Skip()
 
     def OnNameChanged(self, event):
-        self.RefreshPreview()
-        event.Skip()
-        
+        if self.Name.GetStringSelection() != "":
+            self.Expression.Enable(False)
+        elif self.Class.GetStringSelection() == "Input":
+            self.Expression.Enable(True)
+        self.RefreshPreview()
+        event.Skip()
+    
+    def OnExpressionChanged(self, event):
+        if self.Expression.GetValue() != "":
+            self.Name.Enable(False)
+        else:
+            self.Name.Enable(True)
+        self.RefreshPreview()
+        event.Skip()
+    
     def RefreshPreview(self):
         dc = wxClientDC(self.Preview)
         dc.Clear()
-        name = self.Name.GetStringSelection()
+        expression = self.Expression.GetValue()
+        if self.Expression.IsEnabled() and expression != "":
+            name = expression
+        else:
+            name = self.Name.GetStringSelection()
         type = ""
         for var_name, var_type, value_type in self.VarList:
             if var_name == name:
@@ -510,7 +565,18 @@
             
     def SetMinConnectionSize(self, size):
         self.MinConnectionSize = size
-        
+    
+    def SetValues(self, values):
+        for name, value in values.items():
+            if name == "type":
+                if value == CONNECTOR:
+                    self.radioButton1.SetValue(True)
+                elif value == CONTINUATION:
+                    self.radioButton2.SetValue(True)
+            elif name == "name":
+                self.Name.SetValue(value)
+        self.RefreshPreview()
+    
     def GetValues(self):
         values = {}
         if self.radioButton1.GetValue():
@@ -650,9 +716,9 @@
 
         EVT_PAINT(self, self.OnPaint)
 
-    def SetElementSize(self, width, height):
+    def SetElementSize(self, size):
         min_width, min_height = self.Element.GetMinSize()
-        width, height = max(min_width, width), max(min_height, height)
+        width, height = max(min_width, size[0]), max(min_height, size[1])
         self.Element.SetSize(width, height)
         self.Element.SetPosition((150 - width) / 2, (150 - height) / 2)
 
@@ -825,7 +891,7 @@
 
     def SetMinSize(self, size):
         self.PowerRailMinSize = size
-        self.RefreshPreview()
+        self.RefreshPreview()    
 
     def GetValues(self):
         values = {}
--- a/LDViewer.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/LDViewer.py	Tue Jul 10 09:52:53 2007 +0200
@@ -1165,41 +1165,51 @@
 #-------------------------------------------------------------------------------
 
     def EditContactContent(self, contact):
-        dialog = LDElementDialog(self.Parent, "contact")
-        varlist = []
-        vars = self.Controler.GetCurrentElementEditingInterfaceVars()
-        if vars:
-            for var in vars:
-                if var["Class"] != "Output" and var["Type"] == "BOOL":
-                    varlist.append(var["Name"])
-        dialog.SetVariables(varlist)
-        dialog.SetValues({"name":contact.GetName(),"type":contact.GetType()})
-        if dialog.ShowModal() == wxID_OK:
-            values = dialog.GetValues()
-            contact.SetName(values["name"])
-            contact.SetType(values["type"])
-            contact.RefreshModel(False)
-            self.Refresh()
-        dialog.Destroy()
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            Viewer.EditContactContent(self, contact)
+        else:
+            dialog = LDElementDialog(self.Parent, "contact")
+            varlist = []
+            vars = self.Controler.GetCurrentElementEditingInterfaceVars()
+            if vars:
+                for var in vars:
+                    if var["Class"] != "Output" and var["Type"] == "BOOL":
+                        varlist.append(var["Name"])
+            dialog.SetVariables(varlist)
+            dialog.SetValues({"name":contact.GetName(),"type":contact.GetType()})
+            if dialog.ShowModal() == wxID_OK:
+                values = dialog.GetValues()
+                contact.SetName(values["name"])
+                contact.SetType(values["type"])
+                contact.RefreshModel(False)
+                self.Refresh()
+            dialog.Destroy()
 
     def EditCoilContent(self, coil):
-        dialog = LDElementDialog(self.Parent, "coil")
-        varlist = []
-        vars = self.Controler.GetCurrentElementEditingInterfaceVars()
-        if vars:
-            for var in vars:
-                if var["Class"] != "Input" and var["Type"] == "BOOL":
-                    varlist.append(var["Name"])
-        returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
-        if returntype == "BOOL":
-            varlist.append(self.Controler.GetCurrentElementEditingName())
-        dialog.SetVariables(varlist)
-        dialog.SetValues({"name":coil.GetName(),"type":coil.GetType()})
-        if dialog.ShowModal() == wxID_OK:
-            values = dialog.GetValues()
-            coil.SetName(values["name"])
-            coil.SetType(values["type"])
-            coil.RefreshModel(False)
-            self.Refresh()
-        dialog.Destroy()
-
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            Viewer.EditCoilContent(self, coil)
+        else:
+            dialog = LDElementDialog(self.Parent, "coil")
+            varlist = []
+            vars = self.Controler.GetCurrentElementEditingInterfaceVars()
+            if vars:
+                for var in vars:
+                    if var["Class"] != "Input" and var["Type"] == "BOOL":
+                        varlist.append(var["Name"])
+            returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
+            if returntype == "BOOL":
+                varlist.append(self.Controler.GetCurrentElementEditingName())
+            dialog.SetVariables(varlist)
+            dialog.SetValues({"name":coil.GetName(),"type":coil.GetType()})
+            if dialog.ShowModal() == wxID_OK:
+                values = dialog.GetValues()
+                coil.SetName(values["name"])
+                coil.SetType(values["type"])
+                coil.RefreshModel(False)
+                self.Refresh()
+            dialog.Destroy()
+
+    def EditPowerRailContent(self, powerrail):
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            Viewer.EditPowerRailContent(self, powerrail)
+
--- a/PLCControler.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/PLCControler.py	Tue Jul 10 09:52:53 2007 +0200
@@ -370,14 +370,14 @@
 
     def GenerateProgram(self, filepath):
         if self.Project:
-            try:
-                program = GenerateCurrentProgram(self.Project)
-                programfile = open(filepath, "w")
-                programfile.write(program)
-                programfile.close()
-                return True
-            except:
-                pass
+            #try:
+            program = GenerateCurrentProgram(self.Project)
+            programfile = open(filepath, "w")
+            programfile.write(program)
+            programfile.close()
+            return True
+            #except:
+            #    pass
         return False
 
 #-------------------------------------------------------------------------------
--- a/PLCGenerator.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/PLCGenerator.py	Tue Jul 10 09:52:53 2007 +0200
@@ -66,7 +66,7 @@
     
     def IsAlreadyDefined(self, name):
         for list_type, retain, constant, vars in self.Interface:
-            for var_type, var_name in vars:
+            for var_type, var_name, var_initial in vars:
                 if name == var_name:
                     return True
         return False
@@ -78,7 +78,12 @@
             variables = []
             for var in varlist["value"].getVariable():
                 type = var.getType().getValue()
-                variables.append((type, var.getName()))
+                initial = var.getInitialValue()
+                if initial:
+                    initial_value = initial.getValue()
+                else:
+                    initial_value = None
+                variables.append((type, var.getName(), initial_value))
             self.Interface.append((varTypeNames[varlist["name"]], varlist["value"].getRetain(), 
                             varlist["value"].getConstant(), variables))
     
@@ -138,7 +143,7 @@
                 if self.Interface[-1][0] != "VAR" or self.Interface[-1][1] or self.Interface[-1][2]:
                     self.Interface.append(("VAR", False, False, []))
                 if not self.IsAlreadyDefined(name):
-                    self.Interface[-1][3].append((type, name))
+                    self.Interface[-1][3].append((type, name, None))
                     vars = []
                     for variable in instance.inputVariables.getVariable():
                         connections = variable.connectionPointIn.getConnections()
@@ -428,7 +433,7 @@
         while self.IsAlreadyDefined(name):
             i += 1
             name = "%s%d"%(edge, i)
-        self.Interface[-1][3].append((edge, name))
+        self.Interface[-1][3].append((edge, name, None))
         self.Program += "  %s(CLK := %s);\n"%(name, text)
         return "%s.Q"%name
     
@@ -445,8 +450,11 @@
             if constant:
                 program += " CONSTANT"
             program += "\n"
-            for var_type, var_name in variables:
-                program += "    %s : %s;\n"%(var_name, var_type)
+            for var_type, var_name, var_initial in variables:
+                if var_initial != None:
+                    program += "    %s : %s := %s;\n"%(var_name, var_type, {"TRUE":"0","FALSE":"1"}.get(str(var_initial).upper(),str(var_initial)))
+                else:
+                    program += "    %s : %s;\n"%(var_name, var_type)
             program += "  END_VAR\n"
         program += "\n"
         program += self.Program
--- a/PLCOpenEditor.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/PLCOpenEditor.py	Tue Jul 10 09:52:53 2007 +0200
@@ -426,7 +426,7 @@
         
         self.CurrentToolBar = []
         self.CurrentLanguage = ""
-        self.DrawingMode = DRIVENDRAWING_MODE
+        self.DrawingMode = FREEDRAWING_MODE
         
         self.RefreshFileMenu()
         self.RefreshEditMenu()
@@ -2078,14 +2078,10 @@
         self.RefreshUpDownButtons()
 
         self.OptionList = "Yes,No"
-        self.TypeList = ""
-        for value, parent in TypeHierarchy_list:
-            if not value.startswith("ANY"):
-                self.TypeList += "%s,"%value
-        self.TypeList = self.TypeList[:-1]
+        self.TypeList = ",".join([value for value, parent in TypeHierarchy_list if not value.startswith("ANY")])
         
         if pou_type == "function":
-            for value in TypeHierarchy.keys():
+            for value, parent in TypeHierarchy_list:
                 if not value.startswith("ANY"):
                     self.ReturnType.Append(value)
             self.ReturnType.Enable(True)
@@ -2220,8 +2216,10 @@
         new_index = max(0, min(value_index + move, len(self.Values) - 1))
         if new_index != value_index:
             self.Values.insert(new_index, self.Values.pop(value_index))
+            self.RefreshValues()
             self.VariablesGrid.SetGridCursor(new_index, self.VariablesGrid.GetGridCursorCol())
-        self.RefreshValues()
+        else:
+            self.RefreshValues()
     
     def RefreshValues(self):
         self.VariablesGrid.SetGridCursor(0, 0)
--- a/SFCViewer.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/SFCViewer.py	Tue Jul 10 09:52:53 2007 +0200
@@ -767,78 +767,230 @@
 #-------------------------------------------------------------------------------
 
     def DeleteStep(self, step):
-        step_connectors = step.GetConnectors()
-        if not step.GetInitial() or not step_connectors["output"]:
-            previous = step.GetPreviousConnector()
-            if previous:
-                previous_block = previous.GetParentBlock()
-            else:
-                previous_block = None
-            next = step.GetNextConnector()
-            if next:
-                next_block = next.GetParentBlock()
-            else:
-                next_block = None
-            if isinstance(next_block, SFC_Transition):
-                self.RemoveTransition(next_block)
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            Viewer.DeleteStep(self, step)
+        else:
+            step_connectors = step.GetConnectors()
+            if not step.GetInitial() or not step_connectors["output"]:
+                previous = step.GetPreviousConnector()
+                if previous:
+                    previous_block = previous.GetParentBlock()
+                else:
+                    previous_block = None
                 next = step.GetNextConnector()
                 if next:
                     next_block = next.GetParentBlock()
                 else:
                     next_block = None
-            elif isinstance(previous_block, SFC_Transition):
-                self.RemoveTransition(previous_block)
-                previous = step.GetPreviousConnector()
-                if previous:
-                    previous_block = previous.GetParentBlock()
-                else:
-                    previous_block = None
-            wire = self.RemoveStep(step)
-            self.SelectedElement = None
-            if next_block:
-                if isinstance(next_block, SFC_Divergence) and next_block.GetType() == SIMULTANEOUS_CONVERGENCE and isinstance(previous_block, SFC_Divergence) and previous_block.GetType() == SIMULTANEOUS_DIVERGENCE:
-                    wire.Clean()
-                    self.Wires.remove(wire)
-                    self.Elements.remove(wire)
-                    next_block.RemoveBranch(next)
-                    if next_block.GetBranchNumber() < 2:
-                        self.DeleteDivergence(next_block)
+                if isinstance(next_block, SFC_Transition):
+                    self.RemoveTransition(next_block)
+                    next = step.GetNextConnector()
+                    if next:
+                        next_block = next.GetParentBlock()
                     else:
-                        next_block.RefreshModel()
-                    previous_block.RemoveBranch(previous)
-                    if previous_block.GetBranchNumber() < 2:
-                        self.DeleteDivergence(previous_block)
+                        next_block = None
+                elif isinstance(previous_block, SFC_Transition):
+                    self.RemoveTransition(previous_block)
+                    previous = step.GetPreviousConnector()
+                    if previous:
+                        previous_block = previous.GetParentBlock()
                     else:
-                        previous_block.RefreshModel()
-                else:
-                    pos = previous.GetPosition(False)
-                    next_pos = next.GetPosition(False)
-                    wire_size = GetWireSize(previous_block)
-                    previous_block.RefreshOutputPosition((0, pos.y + wire_size - next_pos.y))
-                    wire.SetPoints([wxPoint(pos.x, pos.y + wire_size), wxPoint(pos.x, pos.y)])
-                    if isinstance(next_block, SFC_Divergence):
-                        next_block.RefreshPosition()
-                    previous_block.RefreshOutputModel(True)
-            else:
-                if isinstance(previous_block, SFC_Step):
-                    previous_block.RemoveOutput()
-                    self.RefreshStepModel(previous_block)
-                elif isinstance(previous_block, SFC_Divergence):
-                    if previous_block.GetType() in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
-                        self.DeleteDivergence(previous_block)
-                    else:
+                        previous_block = None
+                wire = self.RemoveStep(step)
+                self.SelectedElement = None
+                if next_block:
+                    if isinstance(next_block, SFC_Divergence) and next_block.GetType() == SIMULTANEOUS_CONVERGENCE and isinstance(previous_block, SFC_Divergence) and previous_block.GetType() == SIMULTANEOUS_DIVERGENCE:
+                        wire.Clean()
+                        self.Wires.remove(wire)
+                        self.Elements.remove(wire)
+                        next_block.RemoveBranch(next)
+                        if next_block.GetBranchNumber() < 2:
+                            self.DeleteDivergence(next_block)
+                        else:
+                            next_block.RefreshModel()
                         previous_block.RemoveBranch(previous)
                         if previous_block.GetBranchNumber() < 2:
                             self.DeleteDivergence(previous_block)
                         else:
-                            self.RefreshDivergenceModel(previous_block)
+                            previous_block.RefreshModel()
+                    else:
+                        pos = previous.GetPosition(False)
+                        next_pos = next.GetPosition(False)
+                        wire_size = GetWireSize(previous_block)
+                        previous_block.RefreshOutputPosition((0, pos.y + wire_size - next_pos.y))
+                        wire.SetPoints([wxPoint(pos.x, pos.y + wire_size), wxPoint(pos.x, pos.y)])
+                        if isinstance(next_block, SFC_Divergence):
+                            next_block.RefreshPosition()
+                        previous_block.RefreshOutputModel(True)
+                else:
+                    if isinstance(previous_block, SFC_Step):
+                        previous_block.RemoveOutput()
+                        self.RefreshStepModel(previous_block)
+                    elif isinstance(previous_block, SFC_Divergence):
+                        if previous_block.GetType() in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
+                            self.DeleteDivergence(previous_block)
+                        else:
+                            previous_block.RemoveBranch(previous)
+                            if previous_block.GetBranchNumber() < 2:
+                                self.DeleteDivergence(previous_block)
+                            else:
+                                self.RefreshDivergenceModel(previous_block)
         
     def DeleteTransition(self, transition):
-        previous = transition.GetPreviousConnector()
-        previous_block = previous.GetParentBlock()
-        next = transition.GetNextConnector()
-        next_block = next.GetParentBlock()
-        if isinstance(previous_block, SFC_Divergence) and previous_block.GetType() == SELECTION_DIVERGENCE and isinstance(next_block, SFC_Divergence) and next_block.GetType() == SELECTION_CONVERGENCE:
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            Viewer.DeleteTransition(self, transition)
+        else:
+            previous = transition.GetPreviousConnector()
+            previous_block = previous.GetParentBlock()
+            next = transition.GetNextConnector()
+            next_block = next.GetParentBlock()
+            if isinstance(previous_block, SFC_Divergence) and previous_block.GetType() == SELECTION_DIVERGENCE and isinstance(next_block, SFC_Divergence) and next_block.GetType() == SELECTION_CONVERGENCE:
+                wires = previous.GetWires()
+                if len(wires) != 1:
+                    return
+                wire = wires[0][0]
+                wire.Clean()
+                self.Wires.remove(wire)
+                self.Elements.remove(wire)
+                wires = next.GetWires()
+                if len(wires) != 1:
+                    return
+                wire = wires[0][0]
+                wire.Clean()
+                self.Wires.remove(wire)
+                self.Elements.remove(wire)
+                transition.Clean()
+                self.Blocks.remove(transition)
+                self.Elements.remove(transition)
+                self.Controler.RemoveCurrentElementEditingInstance(transition.GetId())
+                previous_block.RemoveBranch(previous)
+                if previous_block.GetBranchNumber() < 2:
+                    self.DeleteDivergence(previous_block)
+                else:
+                    self.RefreshDivergenceModel(previous_block)
+                next_block.RemoveBranch(next)
+                if next_block.GetBranchNumber() < 2:
+                    self.DeleteDivergence(next_block)
+                else:
+                    self.RefreshDivergenceModel(next_block)
+            self.Parent.RefreshProjectTree()
+
+    def DeleteDivergence(self, divergence):
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            Viewer.DeleteDivergence(self, divergence)
+        else:
+            connectors = divergence.GetConnectors()
+            type = divergence.GetType()
+            if type in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
+                wires = connectors["outputs"][0].GetWires()
+                if len(wires) > 1:
+                    return
+                elif len(wires) == 1:
+                    next = wires[0][0].StartConnected
+                    next_block = next.GetParentBlock()
+                    wire = wires[0][0]
+                    wire.Clean()
+                    self.Wires.remove(wire)
+                    self.Elements.remove(wire)
+                else:
+                    next = None
+                    next_block = None
+                for index, connector in enumerate(connectors["inputs"]):
+                    if next and index == 0:
+                        wires = connector.GetWires()
+                        wire = wires[0][0]
+                        previous = wires[0][0].EndConnected
+                        wire.Clean()
+                        self.Wires.remove(wire)
+                        self.Elements.remove(wire)
+                    else:
+                        if type == SELECTION_CONVERGENCE:
+                            wires = connector.GetWires()
+                            previous_block = wires[0][0].EndConnected.GetParentBlock()
+                            self.RemoveTransition(previous_block)
+                        wires = connector.GetWires()
+                        wire = wires[0][0]
+                        previous_connector = wire.EndConnected
+                        previous_block = previous_connector.GetParentBlock()
+                        wire.Clean()
+                        self.Wires.remove(wire)
+                        self.Elements.remove(wire)
+                        if isinstance(previous_block, SFC_Step):
+                            previous_block.RemoveOutput()
+                            self.RefreshStepModel(previous_block)
+                        elif isinstance(previous_block, SFC_Divergence):
+                            if previous_block.GetType() in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
+                                previous_block.RemoveBranch(previous_connector)
+                                if previous_block.GetBranchNumber() < 2:
+                                    self.DeleteDivergence(previous_block)
+                                else:
+                                    self.RefreshDivergenceModel(previous_block)
+                            else:
+                                self.DeleteDivergence(previous_block)
+                divergence.Clean()
+                self.Blocks.remove(divergence)
+                self.Elements.remove(divergence)
+                self.Controler.RemoveCurrentElementEditingInstance(divergence.GetId())
+                if next:
+                    wire = self.ConnectConnectors(next, previous)
+                    previous_block = previous.GetParentBlock()
+                    pos = previous.GetPosition(False)
+                    next_pos = next.GetPosition(False)
+                    wire_size = GetWireSize(previous_block)
+                    previous_block.RefreshOutputPosition((0, previous_pos.y + wire_size - next_pos.y))
+                    wire.SetPoints([wxPoint(previous_pos.x, previous_pos.y + wire_size), 
+                        wxPoint(previous_pos.x, previous_pos.y)])
+                    if isinstance(next_block, SFC_Divergence):
+                        next_block.RefreshPosition()
+                    previous_block.RefreshOutputModel(True)
+            elif divergence.GetBranchNumber() == 1:
+                wires = connectors["inputs"][0].GetWires()
+                if len(wires) != 1:
+                    return
+                wire = wires[0][0]
+                previous = wire.EndConnected
+                previous_block = previous.GetParentBlock()
+                wire.Clean()
+                self.Wires.remove(wire)
+                self.Elements.remove(wire)
+                wires = connectors["outputs"][0].GetWires()
+                if len(wires) != 1:
+                    return
+                wire = wires[0][0]
+                next = wire.StartConnected
+                next_block = next.GetParentBlock()
+                wire.Clean()
+                self.Wires.remove(wire)
+                self.Elements.remove(wire)
+                divergence.Clean()
+                self.Blocks.remove(divergence)
+                self.Elements.remove(divergence)
+                self.Controler.RemoveCurrentElementEditingInstance(divergence.GetId())
+                wire = self.ConnectConnectors(next, previous)
+                previous_pos = previous.GetPosition(False)
+                next_pos = next.GetPosition(False)
+                wire_size = GetWireSize(previous_block)
+                previous_block.RefreshOutputPosition((previous_pos.x - next_pos.x, previous_pos.y + wire_size - next_pos.y))
+                wire.SetPoints([wxPoint(previous_pos.x, previous_pos.y + wire_size), 
+                    wxPoint(previous_pos.x, previous_pos.y)])
+                if isinstance(next_block, SFC_Divergence):
+                    next_block.RefreshPosition()
+                previous_block.RefreshOutputModel(True)
+            self.Parent.RefreshProjectTree()
+
+    def DeleteJump(self, jump):
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            Viewer.DeleteJump(self, jump)
+        else:
+            previous = jump.GetPreviousConnector()
+            previous_block = previous.GetParentBlock()
+            if isinstance(previous_block, SFC_Transition):
+                self.RemoveTransition(previous_block)
+                previous = jump.GetPreviousConnector()
+                if previous:
+                    previous_block = previous.GetParentBlock()
+                else:
+                    previous_block = None
             wires = previous.GetWires()
             if len(wires) != 1:
                 return
@@ -846,188 +998,48 @@
             wire.Clean()
             self.Wires.remove(wire)
             self.Elements.remove(wire)
-            wires = next.GetWires()
+            jump.Clean()
+            self.Blocks.remove(jump)
+            self.Elements.remove(jump)
+            self.Controler.RemoveCurrentElementEditingInstance(jump.GetId())
+            if isinstance(previous_block, SFC_Step):
+                previous_block.RemoveOutput()
+                self.RefreshStepModel(previous_block)
+            elif isinstance(previous_block, SFC_Divergence):
+                if previous_block.GetType() in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
+                    self.DeleteDivergence(previous_block)
+                else:
+                    previous_block.RemoveBranch(previous)
+                    if previous_block.GetBranchNumber() < 2:
+                        self.DeleteDivergence(previous_block)
+                    else:
+                        previous_block.RefreshModel()
+            self.Parent.RefreshProjectTree()
+
+    def DeleteActionBlock(self, actionblock):
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            Viewer.DeleteActionBlock(self, actionblock)
+        else:
+            connector = actionblock.GetConnector()
+            wires = connector.GetWires()
             if len(wires) != 1:
                 return
             wire = wires[0][0]
+            step = wire.EndConnected.GetParentBlock()
             wire.Clean()
             self.Wires.remove(wire)
             self.Elements.remove(wire)
-            transition.Clean()
-            self.Blocks.remove(transition)
-            self.Elements.remove(transition)
-            self.Controler.RemoveCurrentElementEditingInstance(transition.GetId())
-            previous_block.RemoveBranch(previous)
-            if previous_block.GetBranchNumber() < 2:
-                self.DeleteDivergence(previous_block)
-            else:
-                self.RefreshDivergenceModel(previous_block)
-            next_block.RemoveBranch(next)
-            if next_block.GetBranchNumber() < 2:
-                self.DeleteDivergence(next_block)
-            else:
-                self.RefreshDivergenceModel(next_block)
-        self.Parent.RefreshProjectTree()
-
-    def DeleteDivergence(self, divergence):
-        connectors = divergence.GetConnectors()
-        type = divergence.GetType()
-        if type in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
-            wires = connectors["outputs"][0].GetWires()
-            if len(wires) > 1:
-                return
-            elif len(wires) == 1:
-                next = wires[0][0].StartConnected
-                next_block = next.GetParentBlock()
-                wire = wires[0][0]
-                wire.Clean()
-                self.Wires.remove(wire)
-                self.Elements.remove(wire)
-            else:
-                next = None
-                next_block = None
-            for index, connector in enumerate(connectors["inputs"]):
-                if next and index == 0:
-                    wires = connector.GetWires()
-                    wire = wires[0][0]
-                    previous = wires[0][0].EndConnected
-                    wire.Clean()
-                    self.Wires.remove(wire)
-                    self.Elements.remove(wire)
-                else:
-                    if type == SELECTION_CONVERGENCE:
-                        wires = connector.GetWires()
-                        previous_block = wires[0][0].EndConnected.GetParentBlock()
-                        self.RemoveTransition(previous_block)
-                    wires = connector.GetWires()
-                    wire = wires[0][0]
-                    previous_connector = wire.EndConnected
-                    previous_block = previous_connector.GetParentBlock()
-                    wire.Clean()
-                    self.Wires.remove(wire)
-                    self.Elements.remove(wire)
-                    if isinstance(previous_block, SFC_Step):
-                        previous_block.RemoveOutput()
-                        self.RefreshStepModel(previous_block)
-                    elif isinstance(previous_block, SFC_Divergence):
-                        if previous_block.GetType() in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
-                            previous_block.RemoveBranch(previous_connector)
-                            if previous_block.GetBranchNumber() < 2:
-                                self.DeleteDivergence(previous_block)
-                            else:
-                                self.RefreshDivergenceModel(previous_block)
-                        else:
-                            self.DeleteDivergence(previous_block)
-            divergence.Clean()
-            self.Blocks.remove(divergence)
-            self.Elements.remove(divergence)
-            self.Controler.RemoveCurrentElementEditingInstance(divergence.GetId())
-            if next:
-                wire = self.ConnectConnectors(next, previous)
-                previous_block = previous.GetParentBlock()
-                pos = previous.GetPosition(False)
-                next_pos = next.GetPosition(False)
-                wire_size = GetWireSize(previous_block)
-                previous_block.RefreshOutputPosition((0, previous_pos.y + wire_size - next_pos.y))
-                wire.SetPoints([wxPoint(previous_pos.x, previous_pos.y + wire_size), 
-                    wxPoint(previous_pos.x, previous_pos.y)])
-                if isinstance(next_block, SFC_Divergence):
-                    next_block.RefreshPosition()
-                previous_block.RefreshOutputModel(True)
-        elif divergence.GetBranchNumber() == 1:
-            wires = connectors["inputs"][0].GetWires()
-            if len(wires) != 1:
-                return
-            wire = wires[0][0]
-            previous = wire.EndConnected
-            previous_block = previous.GetParentBlock()
-            wire.Clean()
-            self.Wires.remove(wire)
-            self.Elements.remove(wire)
-            wires = connectors["outputs"][0].GetWires()
-            if len(wires) != 1:
-                return
-            wire = wires[0][0]
-            next = wire.StartConnected
-            next_block = next.GetParentBlock()
-            wire.Clean()
-            self.Wires.remove(wire)
-            self.Elements.remove(wire)
-            divergence.Clean()
-            self.Blocks.remove(divergence)
-            self.Elements.remove(divergence)
-            self.Controler.RemoveCurrentElementEditingInstance(divergence.GetId())
-            wire = self.ConnectConnectors(next, previous)
-            previous_pos = previous.GetPosition(False)
-            next_pos = next.GetPosition(False)
-            wire_size = GetWireSize(previous_block)
-            previous_block.RefreshOutputPosition((previous_pos.x - next_pos.x, previous_pos.y + wire_size - next_pos.y))
-            wire.SetPoints([wxPoint(previous_pos.x, previous_pos.y + wire_size), 
-                wxPoint(previous_pos.x, previous_pos.y)])
-            if isinstance(next_block, SFC_Divergence):
-                next_block.RefreshPosition()
-            previous_block.RefreshOutputModel(True)
-        self.Parent.RefreshProjectTree()
-
-    def DeleteJump(self, jump):
-        previous = jump.GetPreviousConnector()
-        previous_block = previous.GetParentBlock()
-        if isinstance(previous_block, SFC_Transition):
-            self.RemoveTransition(previous_block)
-            previous = jump.GetPreviousConnector()
-            if previous:
-                previous_block = previous.GetParentBlock()
-            else:
-                previous_block = None
-        wires = previous.GetWires()
-        if len(wires) != 1:
-            return
-        wire = wires[0][0]
-        wire.Clean()
-        self.Wires.remove(wire)
-        self.Elements.remove(wire)
-        jump.Clean()
-        self.Blocks.remove(jump)
-        self.Elements.remove(jump)
-        self.Controler.RemoveCurrentElementEditingInstance(jump.GetId())
-        if isinstance(previous_block, SFC_Step):
-            previous_block.RemoveOutput()
-            self.RefreshStepModel(previous_block)
-        elif isinstance(previous_block, SFC_Divergence):
-            if previous_block.GetType() in [SELECTION_CONVERGENCE, SIMULTANEOUS_CONVERGENCE]:
-                self.DeleteDivergence(previous_block)
-            else:
-                previous_block.RemoveBranch(previous)
-                if previous_block.GetBranchNumber() < 2:
-                    self.DeleteDivergence(previous_block)
-                else:
-                    previous_block.RefreshModel()
-        self.Parent.RefreshProjectTree()
-
-    def DeleteActionBlock(self, actionblock):
-        connector = actionblock.GetConnector()
-        wires = connector.GetWires()
-        if len(wires) != 1:
-            return
-        wire = wires[0][0]
-        step = wire.EndConnected.GetParentBlock()
-        wire.Clean()
-        self.Wires.remove(wire)
-        self.Elements.remove(wire)
-        actionblock.Clean()
-        self.Blocks.remove(actionblock)
-        self.Elements.remove(actionblock)
-        self.Controler.RemoveCurrentElementEditingInstance(actionblock.GetId())
-        step.RemoveAction()
-        self.RefreshStepModel(step)
-        step.RefreshOutputPosition()
-        step.RefreshOutputModel(True)
-        self.Parent.RefreshProjectTree()
-
-    def DeleteComment(self, comment):
-        self.Elements.remove(self.SelectedElement)
-        self.Controler.RemoveCurrentElementEditingInstance(comment.GetId())
-        
+            actionblock.Clean()
+            self.Blocks.remove(actionblock)
+            self.Elements.remove(actionblock)
+            self.Controler.RemoveCurrentElementEditingInstance(actionblock.GetId())
+            step.RemoveAction()
+            self.RefreshStepModel(step)
+            step.RefreshOutputPosition()
+            step.RefreshOutputModel(True)
+            self.Parent.RefreshProjectTree()
+
     def DeleteWire(self, wire):
-        pass
-
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            Viewer.DeleteWire(self, wire)
+    
--- a/Viewer.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/Viewer.py	Tue Jul 10 09:52:53 2007 +0200
@@ -274,7 +274,7 @@
             connector = connection.GetConnector()
             connector.SetPosition(wxPoint(*instance["connector"]["position"]))
         elif instance["type"] == "connection":
-            connection = FBD_Connection(self, CONNECTOR, instance["name"], instance["id"])
+            connection = FBD_Connector(self, CONNECTOR, instance["name"], instance["id"])
             connection.SetPosition(instance["x"], instance["y"])
             connection.SetSize(instance["width"], instance["height"])
             self.Blocks.append(connection)
@@ -874,9 +874,9 @@
             id = self.GetNewId()
             values = dialog.GetValues()
             if "name" in values:
-                block = FBD_Block(self, values["type"], values["name"], id, values["extension"])
+                block = FBD_Block(self, values["type"], values["name"], id, values["extension"], values["inputs"])
             else:
-                block = FBD_Block(self, values["type"], "", id, values["extension"])
+                block = FBD_Block(self, values["type"], "", id, values["extension"], values["inputs"])
             block.SetPosition(bbox.x, bbox.y)
             block.SetSize(values["width"], values["height"])
             self.Blocks.append(block)
@@ -952,7 +952,7 @@
                     varlist.append(var["Name"])
         dialog.SetVariables(varlist)
         dialog.SetValues({"name":"","type":CONTACT_NORMAL})
-        dialog.SetElementSize(bbox.width, bbox.height)
+        dialog.SetElementSize((bbox.width, bbox.height))
         if dialog.ShowModal() == wxID_OK:
             id = self.GetNewId()
             values = dialog.GetValues()
@@ -979,7 +979,7 @@
             varlist.append(self.Controler.GetCurrentElementEditingName())
         dialog.SetVariables(varlist)
         dialog.SetValues({"name":"","type":COIL_NORMAL})
-        dialog.SetElementSize(bbox.width, bbox.height)
+        dialog.SetElementSize((bbox.width, bbox.height))
         if dialog.ShowModal() == wxID_OK:
             id = self.GetNewId()
             values = dialog.GetValues()
@@ -1043,209 +1043,6 @@
             self.Refresh()
         dialog.Destroy()
 
-#-------------------------------------------------------------------------------
-#                          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.SetCurrentElementEditingBlockInfos(blockid, infos)
-    
-    def RefreshVariableModel(self, variable):
-        variableid = variable.GetId()
-        infos = {}
-        infos["name"] = variable.GetName()
-        infos["x"], infos["y"] = variable.GetPosition()
-        infos["width"], infos["height"] = variable.GetSize()
-        infos["connectors"] = variable.GetConnectors()
-        self.Controler.SetCurrentElementEditingVariableInfos(variableid, infos)
-
-    def RefreshConnectionModel(self, connection):
-        connectionid = connection.GetId()
-        infos = {}
-        infos["name"] = connection.GetName()
-        infos["x"], infos["y"] = connection.GetPosition()
-        infos["width"], infos["height"] = connection.GetSize()
-        infos["connector"] = connection.GetConnector()
-        self.Controler.SetCurrentElementEditingConnectionInfos(connectionid, infos)
-
-    def RefreshCommentModel(self, comment):
-        commentid = comment.GetId()
-        infos = {}
-        infos["content"] = comment.GetContent()
-        infos["x"], infos["y"] = comment.GetPosition()
-        infos["width"], infos["height"] = comment.GetSize()
-        self.Controler.SetCurrentElementEditingCommentInfos(commentid, infos)
-
-    def RefreshPowerRailModel(self, powerrail):
-        powerrailid = powerrail.GetId()
-        infos = {}
-        infos["x"], infos["y"] = powerrail.GetPosition()
-        infos["width"], infos["height"] = powerrail.GetSize()
-        infos["connectors"] = powerrail.GetConnectors()
-        self.Controler.SetCurrentElementEditingPowerRailInfos(powerrailid, infos)
-
-    def RefreshContactModel(self, contact):
-        contactid = contact.GetId()
-        infos = {}
-        infos["name"] = contact.GetName()
-        infos["type"] = contact.GetType()
-        infos["x"], infos["y"] = contact.GetPosition()
-        infos["width"], infos["height"] = contact.GetSize()
-        infos["connectors"] = contact.GetConnectors()
-        self.Controler.SetCurrentElementEditingContactInfos(contactid, infos)
-
-    def RefreshCoilModel(self, coil):
-        coilid = coil.GetId()
-        infos = {}
-        infos["name"] = coil.GetName()
-        infos["type"] = coil.GetType()
-        infos["x"], infos["y"] = coil.GetPosition()
-        infos["width"], infos["height"] = coil.GetSize()
-        infos["connectors"] = coil.GetConnectors()
-        self.Controler.SetCurrentElementEditingCoilInfos(coilid, infos)
-
-    def RefreshStepModel(self, step):
-        stepid = step.GetId()
-        infos = {}
-        infos["name"] = step.GetName()
-        infos["initial"] = step.GetInitial()
-        infos["x"], infos["y"] = step.GetPosition()
-        infos["width"], infos["height"] = step.GetSize()
-        infos["connectors"] = step.GetConnectors()
-        self.Controler.SetCurrentElementEditingStepInfos(stepid, infos)
-
-    def RefreshTransitionModel(self, transition):
-        transitionid = transition.GetId()
-        infos = {}
-        infos["type"] = transition.GetType()
-        infos["condition"] = transition.GetCondition()
-        infos["x"], infos["y"] = transition.GetPosition()
-        infos["width"], infos["height"] = transition.GetSize()
-        infos["connectors"] = transition.GetConnectors()
-        self.Controler.SetCurrentElementEditingTransitionInfos(transitionid, infos)
-
-    def RefreshDivergenceModel(self, divergence):
-        divergenceid = divergence.GetId()
-        infos = {}
-        infos["x"], infos["y"] = divergence.GetPosition()
-        infos["width"], infos["height"] = divergence.GetSize()
-        infos["connectors"] = divergence.GetConnectors()
-        self.Controler.SetCurrentElementEditingDivergenceInfos(divergenceid, infos)
-
-    def RefreshJumpModel(self, jump):
-        jumpid = jump.GetId()
-        infos = {}
-        infos["target"] = jump.GetTarget()
-        infos["x"], infos["y"] = jump.GetPosition()
-        infos["width"], infos["height"] = jump.GetSize()
-        infos["connector"] = jump.GetConnector()
-        self.Controler.SetCurrentElementEditingJumpInfos(jumpid, infos)
-
-    def RefreshActionBlockModel(self, actionblock):
-        actionblockid = actionblock.GetId()
-        infos = {}
-        infos["actions"] = actionblock.GetActions()
-        infos["x"], infos["y"] = actionblock.GetPosition()
-        infos["width"], infos["height"] = actionblock.GetSize()
-        infos["connector"] = actionblock.GetConnector()
-        self.Controler.SetCurrentElementEditingActionBlockInfos(actionblockid, infos)
-
-
-#-------------------------------------------------------------------------------
-#                          Model delete functions
-#-------------------------------------------------------------------------------
-
-
-    def DeleteBlock(self, block):
-        elements = []
-        for output in block.GetConnectors()["outputs"]:
-            for element in output.GetConnectedBlocks():
-                if element not in elements:
-                    elements.append(element)
-        block.Clean()
-        self.Blocks.remove(block)
-        self.Elements.remove(block)
-        self.Controler.RemoveCurrentElementEditingInstance(block.GetId())
-        for element in elements:
-            element.RefreshModel()
-
-    def DeleteVariable(self, variable):
-        connectors = variable.GetConnectors()
-        if connectors["output"]:
-            elements = connectors["output"].GetConnectedBlocks()
-        else:
-            elements = []
-        variable.Clean()
-        self.Blocks.remove(variable)
-        self.Elements.remove(variable)
-        self.Controler.RemoveCurrentElementEditingInstance(variable.GetId())
-        for element in elements:
-            element.RefreshModel()
-
-    def DeleteConnection(self, connection):
-        if connection.GetType() == CONTINUATION:
-            elements = connection.GetConnector().GetConnectedBlocks()
-        else:
-            elements = []
-        connection.Clean()
-        self.Blocks.remove(connection)
-        self.Elements.remove(connection)
-        self.Controler.RemoveCurrentElementEditingInstance(connection.GetId())
-        for element in elements:
-            element.RefreshModel()
-
-    def DeleteComment(self, comment):
-        self.Elements.remove(comment)
-        self.Controler.RemoveCurrentElementEditingInstance(comment.GetId())
-
-    def DeleteWire(self, wire):
-        connected = wire.GetConnected()
-        wire.Clean()
-        self.Wires.remove(wire)
-        self.Elements.remove(wire)
-        for connector in connected:
-            connector.RefreshParentBlock()
-
-    def DeleteContact(self, contact):
-        connectors = contact.GetConnectors()
-        elements = connectors["output"].GetConnectedBlocks()
-        contact.Clean()
-        self.Blocks.remove(contact)
-        self.Elements.remove(contact)
-        self.Controler.RemoveCurrentElementEditingInstance(contact.GetId())
-        for element in elements:
-            element.RefreshModel()
-
-    def DeleteCoil(self, coil):
-        connectors = coil.GetConnectors()
-        elements = connectors["output"].GetConnectedBlocks()
-        coil.Clean()
-        self.Blocks.remove(coil)
-        self.Elements.remove(coil)
-        self.Controler.RemoveCurrentElementEditingInstance(coil.GetId())
-        for element in elements:
-            element.RefreshModel()
-
-    def DeletePowerRail(self, powerrail):
-        elements = []
-        if powerrail.GetType() == LEFTRAIL:
-            for connector in powerrail.GetConnectors():
-                for element in connector.GetConnectedBlocks():
-                    if element not in elements:
-                        elements.append(element)
-        powerrrail.Clean()
-        self.Blocks.remove(powerrrail)
-        self.Elements.remove(powerrrail)
-        self.Controler.RemoveCurrentElementEditingInstance(powerrrail.GetId())
-        for element in elements:
-            element.RefreshModel()
 
 #-------------------------------------------------------------------------------
 #                          Edit element content functions
@@ -1255,7 +1052,7 @@
         dialog = BlockPropertiesDialog(self.Parent)
         dialog.SetBlockList(self.Controler.GetBlockTypes())
         dialog.SetMinBlockSize(block.GetSize())
-        values = {"name" : block.GetName(), "type" : block.GetType()}
+        values = {"name" : block.GetName(), "type" : block.GetType(), "inputs" : block.GetInputTypes()}
         values["extension"] = block.GetExtension()
         dialog.SetValues(values)
         if dialog.ShowModal() == wxID_OK:
@@ -1296,6 +1093,384 @@
             self.Refresh()
         dialog.Destroy()
 
+    def EditConnectionContent(self, connection):
+        dialog = ConnectionPropertiesDialog(self.Parent)
+        dialog.SetMinConnectionSize(connection.GetSize())
+        values = {"name" : connection.GetName(), "type" : connection.GetType()}
+        dialog.SetValues(values)
+        if dialog.ShowModal() == wxID_OK:
+            old_type = connection.GetType()
+            values = dialog.GetValues()
+            connection.SetName(values["name"])
+            connection.SetType(values["type"])
+            connection.SetSize(values["width"], values["height"])
+            if old_type != values["type"]:
+                id = connection.GetId()
+                self.Controler.RemoveCurrentElementEditingInstance(id)
+                self.Controler.AddCurrentElementEditingConnection(id, values["type"])
+            self.RefreshConnectionModel(connection)
+            self.Refresh()
+        dialog.Destroy()
+
+    def EditContactContent(self, contact):
+        dialog = LDElementDialog(self.Parent, "contact")
+        varlist = []
+        vars = self.Controler.GetCurrentElementEditingInterfaceVars()
+        if vars:
+            for var in vars:
+                if var["Class"] != "Output" and var["Type"] == "BOOL":
+                    varlist.append(var["Name"])
+        dialog.SetVariables(varlist)
+        values = {"name" : contact.GetName(), "type" : contact.GetType()}
+        dialog.SetValues(values)
+        dialog.SetElementSize(contact.GetSize())
+        if dialog.ShowModal() == wxID_OK:
+            values = dialog.GetValues()
+            contact.SetName(values["name"])
+            contact.SetType(values["type"])
+            contact.SetSize(values["width"], values["height"])
+            self.RefreshContactModel(contact)
+            self.Refresh()
+        dialog.Destroy()
+
+    def EditCoilContent(self, coil):
+        dialog = LDElementDialog(self.Parent, "coil")
+        varlist = []
+        vars = self.Controler.GetCurrentElementEditingInterfaceVars()
+        if vars:
+            for var in vars:
+                if var["Class"] != "Input" and var["Type"] == "BOOL":
+                    varlist.append(var["Name"])
+        returntype = self.Controler.GetCurrentElementEditingInterfaceReturnType()
+        if returntype == "BOOL":
+            varlist.append(self.Controler.GetCurrentElementEditingName())
+        dialog.SetVariables(varlist)
+        values = {"name" : coil.GetName(), "type" : coil.GetType()}
+        dialog.SetValues(values)
+        dialog.SetElementSize(contact.GetSize())
+        if dialog.ShowModal() == wxID_OK:
+            values = dialog.GetValues()
+            coil.SetName(values["name"])
+            coil.SetType(values["type"])
+            coil.SetSize(values["width"], values["height"])
+            self.RefreshContactModel(coil)
+            self.Refresh()
+        dialog.Destroy()
+
+    def EditPowerRailContent(self, powerrail):
+        dialog = LDPowerRailDialog(self.Parent, powerrail.GetType(), len(powerrail.GetConnectors()))
+        dialog.SetMinSize(powerrail.GetSize())
+        if dialog.ShowModal() == wxID_OK:
+            old_type = powerrail.GetType()
+            values = dialog.GetValues()
+            powerrail.SetType(values["type"])
+            powerrail.SetSize(values["width"], values["height"])
+            if old_type != values["type"]:
+                id = powerrail.GetId()
+                self.Controler.RemoveCurrentElementEditingInstance(id)
+                self.Controler.AddCurrentElementEditingPowerRail(id, values["type"])
+            self.RefreshPowerRailModel(powerrail)
+            self.Refresh()
+        dialog.Destroy()
+
+
+    def AddNewTransition(self, bbox):
+        dialog = TransitionContentDialog(self.Parent)
+        dialog.SetTransitions(self.Controler.GetCurrentElementEditingTransitions())
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            transition = SFC_Transition(self, values["type"], values["value"], id)
+            transition.SetPosition(bbox.x, bbox.y)
+            min_width, min_height = transition.GetMinSize()
+            transition.SetSize(max(bbox.width, min_width), max(bbox.height, min_height))
+            self.Blocks.append(transition)
+            self.Elements.append(transition)
+            self.Controler.AddCurrentElementEditingTransition(id)
+            self.RefreshTransitionModel(transition)
+            self.Refresh()
+        dialog.Destroy()
+
+    def AddNewDivergence(self, bbox):
+        dialog = DivergenceCreateDialog(self.Parent)
+        dialog.SetMinSize((bbox.width, bbox.height))
+        if dialog.ShowModal() == wxID_OK:
+            id = self.GetNewId()
+            values = dialog.GetValues()
+            divergence = SFC_Divergence(self, values["type"], values["number"], id)
+            divergence.SetPosition(bbox.x, bbox.y)
+            min_width, min_height = divergence.GetMinSize()
+            divergence.SetSize(max(bbox.width, min_width), max(bbox.height, min_height))
+            self.Blocks.append(divergence)
+            self.Elements.append(divergence)
+            self.Controler.AddCurrentElementEditingDivergence(id, values["type"])
+            self.RefreshDivergenceModel(divergence)
+            self.Refresh()
+        dialog.Destroy()
+
+#-------------------------------------------------------------------------------
+#                          Model update functions
+#-------------------------------------------------------------------------------
+
+    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.SetCurrentElementEditingBlockInfos(blockid, infos)
+    
+    def RefreshVariableModel(self, variable):
+        variableid = variable.GetId()
+        infos = {}
+        infos["name"] = variable.GetName()
+        infos["x"], infos["y"] = variable.GetPosition()
+        infos["width"], infos["height"] = variable.GetSize()
+        infos["connectors"] = variable.GetConnectors()
+        self.Controler.SetCurrentElementEditingVariableInfos(variableid, infos)
+
+    def RefreshConnectionModel(self, connection):
+        connectionid = connection.GetId()
+        infos = {}
+        infos["name"] = connection.GetName()
+        infos["x"], infos["y"] = connection.GetPosition()
+        infos["width"], infos["height"] = connection.GetSize()
+        infos["connector"] = connection.GetConnector()
+        self.Controler.SetCurrentElementEditingConnectionInfos(connectionid, infos)
+
+    def RefreshCommentModel(self, comment):
+        commentid = comment.GetId()
+        infos = {}
+        infos["content"] = comment.GetContent()
+        infos["x"], infos["y"] = comment.GetPosition()
+        infos["width"], infos["height"] = comment.GetSize()
+        self.Controler.SetCurrentElementEditingCommentInfos(commentid, infos)
+
+    def RefreshPowerRailModel(self, powerrail):
+        powerrailid = powerrail.GetId()
+        infos = {}
+        infos["x"], infos["y"] = powerrail.GetPosition()
+        infos["width"], infos["height"] = powerrail.GetSize()
+        infos["connectors"] = powerrail.GetConnectors()
+        self.Controler.SetCurrentElementEditingPowerRailInfos(powerrailid, infos)
+
+    def RefreshContactModel(self, contact):
+        contactid = contact.GetId()
+        infos = {}
+        infos["name"] = contact.GetName()
+        infos["type"] = contact.GetType()
+        infos["x"], infos["y"] = contact.GetPosition()
+        infos["width"], infos["height"] = contact.GetSize()
+        infos["connectors"] = contact.GetConnectors()
+        self.Controler.SetCurrentElementEditingContactInfos(contactid, infos)
+
+    def RefreshCoilModel(self, coil):
+        coilid = coil.GetId()
+        infos = {}
+        infos["name"] = coil.GetName()
+        infos["type"] = coil.GetType()
+        infos["x"], infos["y"] = coil.GetPosition()
+        infos["width"], infos["height"] = coil.GetSize()
+        infos["connectors"] = coil.GetConnectors()
+        self.Controler.SetCurrentElementEditingCoilInfos(coilid, infos)
+
+    def RefreshStepModel(self, step):
+        stepid = step.GetId()
+        infos = {}
+        infos["name"] = step.GetName()
+        infos["initial"] = step.GetInitial()
+        infos["x"], infos["y"] = step.GetPosition()
+        infos["width"], infos["height"] = step.GetSize()
+        infos["connectors"] = step.GetConnectors()
+        self.Controler.SetCurrentElementEditingStepInfos(stepid, infos)
+
+    def RefreshTransitionModel(self, transition):
+        transitionid = transition.GetId()
+        infos = {}
+        infos["type"] = transition.GetType()
+        infos["condition"] = transition.GetCondition()
+        infos["x"], infos["y"] = transition.GetPosition()
+        infos["width"], infos["height"] = transition.GetSize()
+        infos["connectors"] = transition.GetConnectors()
+        self.Controler.SetCurrentElementEditingTransitionInfos(transitionid, infos)
+
+    def RefreshDivergenceModel(self, divergence):
+        divergenceid = divergence.GetId()
+        infos = {}
+        infos["x"], infos["y"] = divergence.GetPosition()
+        infos["width"], infos["height"] = divergence.GetSize()
+        infos["connectors"] = divergence.GetConnectors()
+        self.Controler.SetCurrentElementEditingDivergenceInfos(divergenceid, infos)
+
+    def RefreshJumpModel(self, jump):
+        jumpid = jump.GetId()
+        infos = {}
+        infos["target"] = jump.GetTarget()
+        infos["x"], infos["y"] = jump.GetPosition()
+        infos["width"], infos["height"] = jump.GetSize()
+        infos["connector"] = jump.GetConnector()
+        self.Controler.SetCurrentElementEditingJumpInfos(jumpid, infos)
+
+    def RefreshActionBlockModel(self, actionblock):
+        actionblockid = actionblock.GetId()
+        infos = {}
+        infos["actions"] = actionblock.GetActions()
+        infos["x"], infos["y"] = actionblock.GetPosition()
+        infos["width"], infos["height"] = actionblock.GetSize()
+        infos["connector"] = actionblock.GetConnector()
+        self.Controler.SetCurrentElementEditingActionBlockInfos(actionblockid, infos)
+
+
+#-------------------------------------------------------------------------------
+#                          Model delete functions
+#-------------------------------------------------------------------------------
+
+
+    def DeleteBlock(self, block):
+        elements = []
+        for output in block.GetConnectors()["outputs"]:
+            for element in output.GetConnectedBlocks():
+                if element not in elements:
+                    elements.append(element)
+        block.Clean()
+        self.Blocks.remove(block)
+        self.Elements.remove(block)
+        self.Controler.RemoveCurrentElementEditingInstance(block.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteVariable(self, variable):
+        connectors = variable.GetConnectors()
+        if connectors["output"]:
+            elements = connectors["output"].GetConnectedBlocks()
+        else:
+            elements = []
+        variable.Clean()
+        self.Blocks.remove(variable)
+        self.Elements.remove(variable)
+        self.Controler.RemoveCurrentElementEditingInstance(variable.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteConnection(self, connection):
+        if connection.GetType() == CONTINUATION:
+            elements = connection.GetConnector().GetConnectedBlocks()
+        else:
+            elements = []
+        connection.Clean()
+        self.Blocks.remove(connection)
+        self.Elements.remove(connection)
+        self.Controler.RemoveCurrentElementEditingInstance(connection.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteComment(self, comment):
+        self.Elements.remove(comment)
+        self.Controler.RemoveCurrentElementEditingInstance(comment.GetId())
+
+    def DeleteWire(self, wire):
+        if wire in self.Wires:
+            connected = wire.GetConnected()
+            wire.Clean()
+            self.Wires.remove(wire)
+            self.Elements.remove(wire)
+            for connector in connected:
+                connector.RefreshParentBlock()
+
+    def DeleteContact(self, contact):
+        connectors = contact.GetConnectors()
+        elements = connectors["output"].GetConnectedBlocks()
+        contact.Clean()
+        self.Blocks.remove(contact)
+        self.Elements.remove(contact)
+        self.Controler.RemoveCurrentElementEditingInstance(contact.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteCoil(self, coil):
+        connectors = coil.GetConnectors()
+        elements = connectors["output"].GetConnectedBlocks()
+        coil.Clean()
+        self.Blocks.remove(coil)
+        self.Elements.remove(coil)
+        self.Controler.RemoveCurrentElementEditingInstance(coil.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeletePowerRail(self, powerrail):
+        elements = []
+        if powerrail.GetType() == LEFTRAIL:
+            for connector in powerrail.GetConnectors():
+                for element in connector.GetConnectedBlocks():
+                    if element not in elements:
+                        elements.append(element)
+        powerrrail.Clean()
+        self.Blocks.remove(powerrrail)
+        self.Elements.remove(powerrrail)
+        self.Controler.RemoveCurrentElementEditingInstance(powerrrail.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteStep(self, step):
+        elements = []
+        connectors = step.GetConnectors()
+        if connectors["output"]:
+            for element in connectors["output"].GetConnectedBlocks():
+                if element not in elements:
+                    elements.append(element)
+        if connectors["action"]:
+            for element in connectors["action"].GetConnectedBlocks():
+                if element not in elements:
+                    elements.append(element)
+        step.Clean()
+        self.Blocks.remove(step)
+        self.Elements.remove(step)
+        self.Controler.RemoveCurrentElementEditingInstance(step.GetId())
+        for element in elements:
+            element.RefreshModel()
+            
+    def DeleteTransition(self, transition):
+        elements = []
+        connectors = transition.GetConnectors()
+        if connectors["output"]:
+            for element in connectors["output"].GetConnectedBlocks():
+                if element not in elements:
+                    elements.append(element)
+        transition.Clean()
+        self.Blocks.remove(transition)
+        self.Elements.remove(transition)
+        self.Controler.RemoveCurrentElementEditingInstance(transition.GetId())
+        for element in elements:
+            element.RefreshModel()
+
+    def DeleteDivergence(self, divergence):
+        elements = []
+        connectors = divergence.GetConnectors()
+        for output in connectors["outputs"]:
+            for element in output.GetConnectedBlocks():
+                if element not in elements:
+                    elements.append(element)
+        divergence.Clean()
+        self.Blocks.remove(divergence)
+        self.Elements.remove(divergence)
+        self.Controler.RemoveCurrentElementEditingInstance(divergence.GetId())
+        for element in elements:
+            element.RefreshModel()
+    
+    def DeleteJump(self, jump):
+        jump.Clean()
+        self.Blocks.remove(jump)
+        self.Elements.remove(jump)
+        self.Controler.RemoveCurrentElementEditingInstance(jump.GetId())
+    
+    def DeleteActionBlock(self, actionblock):
+        actionblock.Clean()
+        self.Blocks.remove(actionblock)
+        self.Elements.remove(actionblock)
+        self.Controler.RemoveCurrentElementEditingInstance(actionblock.GetId())
+
 
 #-------------------------------------------------------------------------------
 #                            Editing functions
--- a/graphics/FBD_Objects.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/graphics/FBD_Objects.py	Tue Jul 10 09:52:53 2007 +0200
@@ -40,7 +40,7 @@
 class FBD_Block(Graphic_Element):
     
     # Create a new block
-    def __init__(self, parent, type, name, id = None, extension = 0):
+    def __init__(self, parent, type, name, id = None, extension = 0, inputs = None):
         Graphic_Element.__init__(self, parent)
         self.Type = None
         self.Extension = None
@@ -48,7 +48,7 @@
         self.Id = id
         self.Inputs = []
         self.Outputs = []
-        self.SetType(type, extension)
+        self.SetType(type, extension, inputs)
     
     # Destructor
     def __del__(self):
@@ -129,6 +129,9 @@
                 return output
         return None
     
+    def GetInputTypes(self):
+        return tuple([input.GetType() for input in self.Inputs])
+    
     # Returns all the block connectors 
     def GetConnectors(self):
         return {"inputs" : self.Inputs, "outputs" : self.Outputs}
@@ -146,13 +149,13 @@
         return None
     
     # Changes the block type
-    def SetType(self, type, extension):
+    def SetType(self, type, extension, inputs = None):
         if type != self.Type or self.Extension != extension: 
             self.Type = type
             self.Extension = extension
             # Find the block definition from type given and create the corresponding
             # inputs and outputs
-            blocktype = GetBlockType(type)
+            blocktype = GetBlockType(type, inputs)
             if blocktype:
                 inputs = [input for input in blocktype["inputs"]]
                 outputs = [output for output in blocktype["outputs"]]
@@ -338,7 +341,7 @@
             self.Input.SetPosition(wxPoint(0, self.Size[1] / 2))
         if self.Output:
             self.Output.SetPosition(wxPoint(self.Size[0], self.Size[1] / 2))
-        self.RefreshConnected(self)
+        self.RefreshConnected()
     
     # Refresh the position of wires connected to connector
     def RefreshConnected(self, exclude = []):
@@ -495,7 +498,7 @@
     # Unconnect connector
     def Clean(self):
         if self.Connector:
-            self.Connector.UnConnect()
+            self.Connector.UnConnect(delete = True)
     
     # Delete this connection by calling the appropriate method
     def Delete(self):
@@ -517,7 +520,7 @@
             self.Connector.SetPosition(wxPoint(0, self.Size[1] / 2))
         else:
             self.Connector.SetPosition(wxPoint(self.Size[0], self.Size[1] / 2))
-        self.RefreshConnected(self)
+        self.RefreshConnected()
     
     # Refresh the position of wires connected to connector
     def RefreshConnected(self, exclude = []):
@@ -534,6 +537,18 @@
     def GetConnector(self, position = None, name = None):
         return self.Connector
     
+    # Changes the variable type
+    def SetType(self, type):
+        if type != self.Type:
+            self.Type = type
+            self.Clean()
+            # Create an input or output connector according to connection type
+            if self.Type == CONNECTOR:
+                self.Connector = Connector(self, "", "ANY", wxPoint(0, 0), WEST, onlyone = True)
+            else:
+                self.Connector = Connector(self, "", "ANY", wxPoint(0, 0), EAST)
+            self.RefreshConnectors()
+    
     # Returns the connection type
     def GetType(self):
         return self.Type
@@ -554,6 +569,11 @@
             text_height += 1
         return text_width + text_height + 20, text_height + 10
     
+    # Method called when a LeftDClick event have been generated
+    def OnLeftDClick(self, event, dc, scaling):
+        # Edit the connection properties
+        self.Parent.EditConnectionContent(self)
+    
     # Method called when a RightUp event have been generated
     def OnRightUp(self, event, dc, scaling):
         # Popup the default menu
--- a/graphics/GraphicCommons.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/graphics/GraphicCommons.py	Tue Jul 10 09:52:53 2007 +0200
@@ -36,30 +36,30 @@
 """
 
 # FBD and SFC constants
-MIN_MOVE = 5            # Minimum move before starting a element dragging
-CONNECTOR_SIZE = 8      # Size of connectors
-BLOCK_LINE_SIZE = 20    # Minimum size of each line in a block
-HANDLE_SIZE = 6         # Size of the squares for handles
-ANCHOR_DISTANCE = 5     # Distance where wire is automativally attached to a connector
-POINT_RADIUS = 2        # Radius of the point of wire ends
-MIN_SEGMENT_SIZE = 2    # Minimum size of the endling segments of a wire
+MIN_MOVE = 5                            # Minimum move before starting a element dragging
+CONNECTOR_SIZE = 8                      # Size of connectors
+BLOCK_LINE_SIZE = 20                    # Minimum size of each line in a block
+HANDLE_SIZE = 6                         # Size of the squares for handles
+ANCHOR_DISTANCE = 5                     # Distance where wire is automativally attached to a connector
+POINT_RADIUS = 2                        # Radius of the point of wire ends
+MIN_SEGMENT_SIZE = 2                    # Minimum size of the endling segments of a wire
 
 # LD constants
-LD_LINE_SIZE = 40                   # Distance between two lines in a ladder rung
-LD_ELEMENT_SIZE = (21, 15)          # Size (width, height) of a ladder element (contact or coil)
-LD_WIRE_SIZE = 30                   # Size of a wire between two contact
-LD_WIRECOIL_SIZE = 70               # Size of a wire between a coil and a contact
-LD_OFFSET = (10, 10)                # Distance (x, y) between each comment and rung of the ladder
-LD_COMMENT_DEFAULTSIZE = (600, 40)  # Size (width, height) of a comment box
+LD_LINE_SIZE = 40                       # Distance between two lines in a ladder rung
+LD_ELEMENT_SIZE = (21, 15)              # Size (width, height) of a ladder element (contact or coil)
+LD_WIRE_SIZE = 30                       # Size of a wire between two contact
+LD_WIRECOIL_SIZE = 70                   # Size of a wire between a coil and a contact
+LD_OFFSET = (10, 10)                    # Distance (x, y) between each comment and rung of the ladder
+LD_COMMENT_DEFAULTSIZE = (600, 40)      # Size (width, height) of a comment box
 
 # SFC constants
-SFC_STEP_DEFAULT_SIZE = (40, 30)      # Default size of a SFC step
-SFC_TRANSITION_SIZE = (20, 2)         # Size of a SFC transition
-SFC_DEFAULT_SEQUENCE_INTERVAL = 40    # Default size of the interval between two divergence branches
-SFC_SIMULTANEOUS_SEQUENCE_EXTRA = 20  # Size of extra lines for simultaneous divergence and convergence
-SFC_JUMP_SIZE = (12, 13)              # Size of a SFC jump to step
-SFC_WIRE_MIN_SIZE = 25                # Size of a wire between two elements
-SFC_ACTION_MIN_SIZE = (100, 30)       # Minimum size of an action block line
+SFC_STEP_DEFAULT_SIZE = (40, 30)        # Default size of a SFC step
+SFC_TRANSITION_SIZE = (20, 2)           # Size of a SFC transition
+SFC_DEFAULT_SEQUENCE_INTERVAL = 40      # Default size of the interval between two divergence branches
+SFC_SIMULTANEOUS_SEQUENCE_EXTRA = 20    # Size of extra lines for simultaneous divergence and convergence
+SFC_JUMP_SIZE = (12, 13)                # Size of a SFC jump to step
+SFC_WIRE_MIN_SIZE = 25                  # Size of a wire between two elements
+SFC_ACTION_MIN_SIZE = (100, 30)         # Minimum size of an action block line
 
 # Type definition constants for graphic elements
 [INPUT, OUTPUT, INOUT] = range(3)
--- a/graphics/LD_Objects.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/graphics/LD_Objects.py	Tue Jul 10 09:52:53 2007 +0200
@@ -208,13 +208,13 @@
             # Initializes the last position
             self.oldPos = GetScaledEventPosition(event, dc, scaling)
         else:
-            self.RealConnectors = {"Inputs":[],"Outputs":[]}
-            for input in self.Inputs:
-                position = input.GetRelPosition()
-                self.RealConnectors["Inputs"].append(float(position.x)/float(self.Size[0]))
-            for output in self.Outputs:
-                position = output.GetRelPosition()
-                self.RealConnectors["Outputs"].append(float(position.x)/float(self.Size[0]))
+##            self.RealConnectors = {"Inputs":[],"Outputs":[]}
+##            for input in self.Inputs:
+##                position = input.GetRelPosition()
+##                self.RealConnectors["Inputs"].append(float(position.x)/float(self.Size[0]))
+##            for output in self.Outputs:
+##                position = output.GetRelPosition()
+##                self.RealConnectors["Outputs"].append(float(position.x)/float(self.Size[0]))
             Graphic_Element.OnLeftDown(self, event, dc, scaling)
     
     # Method called when a LeftUp event have been generated
@@ -232,6 +232,11 @@
             block.RefreshModel(False)
         Graphic_Element.OnLeftUp(self, event, dc, scaling)
     
+    # Method called when a LeftDClick event have been generated
+    def OnLeftDClick(self, event, dc, scaling):
+        # Edit the powerrail properties
+        self.Parent.EditPowerRailContent(self)
+    
     # Method called when a RightUp event have been generated
     def OnRightUp(self, event, dc, scaling):
         pos = GetScaledEventPosition(event, dc, scaling)
--- a/plcopen/structures.py	Mon Jul 09 11:10:14 2007 +0200
+++ b/plcopen/structures.py	Tue Jul 10 09:52:53 2007 +0200
@@ -128,10 +128,15 @@
 Function that returns the block definition associated to the block type given
 """
 
-def GetBlockType(type):
+def GetBlockType(type, inputs = None):
     for category in BlockTypes:
         for blocktype in category["list"]:
-            if blocktype["name"] == type:
+            if inputs:
+                block_inputs = tuple([var_type for name, var_type, modifier in blocktype["inputs"]])
+                same_inputs = inputs == block_inputs
+            else:
+                same_inputs = True
+            if blocktype["name"] == type and same_inputs:
                 return blocktype
     return None
 
--- a/test.xml	Mon Jul 09 11:10:14 2007 +0200
+++ b/test.xml	Tue Jul 10 09:52:53 2007 +0200
@@ -3,14 +3,11 @@
          xmlns="http://www.plcopen.org/xml/tc6.xsd"
          xmlns:xhtml="http://www.w3.org/1999/xhtml"
          xsi:schemaLocation="http://www.plcopen.org/xml/tc6.xsd http://www.plcopen.org/xml/tc6.xsd">
-  <fileHeader contentDescription=""
-              companyName="test"
-              companyURL=""
-              productName="test"
-              productRelease=""
-              productVersion="test"
-              creationDateTime="2007-07-09 08:54:39"/>
-  <contentHeader name="test">
+  <fileHeader companyName="Lolitech"
+              productName="PLCOpenEditorExample"
+              productVersion="1.0"
+              creationDateTime="2006-09-07 18:52:43"/>
+  <contentHeader name="Test">
     <coordinateInfo>
       <fbd>
         <scaling y="0" x="0"/>
@@ -25,9 +22,875 @@
   </contentHeader>
   <types>
     <dataTypes/>
-    <pous/>
+    <pous>
+      <pou name="FBDTest" pouType="functionBlock">
+        <interface>
+          <inputVars>
+            <variable name="IN1">
+              <type>
+                <BOOL/>
+              </type>
+              <initialValue>
+                <simpleValue value="false"/>
+              </initialValue>
+            </variable>
+            <variable name="IN2">
+              <type>
+                <BOOL/>
+              </type>
+              <initialValue>
+                <simpleValue value="true"/>
+              </initialValue>
+            </variable>
+            <variable name="IN3">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+          </inputVars>
+          <outputVars>
+            <variable name="OUT">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+          </outputVars>
+        </interface>
+        <body>
+          <FBD>
+            <inVariable localId="2" width="89" height="27">
+              <position y="84" x="64"/>
+              <connectionPointOut>
+                <relPosition y="13" x="89"/>
+              </connectionPointOut>
+              <expression>IN1</expression>
+            </inVariable>
+            <inVariable localId="3" width="90" height="27">
+              <position y="204" x="63"/>
+              <connectionPointOut>
+                <relPosition y="13" x="90"/>
+              </connectionPointOut>
+              <expression>IN2</expression>
+            </inVariable>
+            <outVariable localId="4" width="95" height="33">
+              <position y="182" x="587"/>
+              <connectionPointIn>
+                <relPosition y="16" x="0"/>
+                <connection refLocalId="11" formalParameter="Q1">
+                  <position y="198" x="587"/>
+                  <position y="198" x="517"/>
+                </connection>
+              </connectionPointIn>
+              <expression>OUT</expression>
+            </outVariable>
+            <block localId="6" height="84" width="99" typeName="AND">
+              <position y="105" x="235"/>
+              <inputVariables>
+                <variable formalParameter="" edge="rising">
+                  <connectionPointIn>
+                    <relPosition y="36" x="0"/>
+                    <connection refLocalId="2">
+                      <position y="141" x="235"/>
+                      <position y="141" x="190"/>
+                      <position y="97" x="190"/>
+                      <position y="97" x="153"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+                <variable formalParameter="">
+                  <connectionPointIn>
+                    <relPosition y="68" x="0"/>
+                    <connection refLocalId="3">
+                      <position y="173" x="235"/>
+                      <position y="173" x="190"/>
+                      <position y="217" x="190"/>
+                      <position y="217" x="153"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="" negated="true">
+                  <connectionPointOut>
+                    <relPosition y="36" x="99"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+            <inVariable localId="7" width="90" height="28">
+              <position y="336" x="63"/>
+              <connectionPointOut>
+                <relPosition y="14" x="90"/>
+              </connectionPointOut>
+              <expression>IN3</expression>
+            </inVariable>
+            <block localId="8" height="87" width="99" typeName="OR">
+              <position y="246" x="235"/>
+              <inputVariables>
+                <variable formalParameter="IN1" negated="true">
+                  <connectionPointIn>
+                    <relPosition y="36" x="0"/>
+                    <connection refLocalId="3">
+                      <position y="282" x="235"/>
+                      <position y="282" x="190"/>
+                      <position y="217" x="190"/>
+                      <position y="217" x="153"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+                <variable formalParameter="IN2">
+                  <connectionPointIn>
+                    <relPosition y="69" x="0"/>
+                    <connection refLocalId="7">
+                      <position y="315" x="235"/>
+                      <position y="315" x="191"/>
+                      <position y="350" x="191"/>
+                      <position y="350" x="153"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="OUT">
+                  <connectionPointOut>
+                    <relPosition y="36" x="99"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+            <comment localId="10" height="37" width="261">
+              <position y="32" x="243"/>
+              <content>POU qui sert a tester PLCOpenEditor.</content>
+            </comment>
+            <block localId="11" height="91" width="97" instanceName="SR1" typeName="SR">
+              <position y="161" x="420"/>
+              <inputVariables>
+                <variable formalParameter="S1">
+                  <connectionPointIn>
+                    <relPosition y="37" x="0"/>
+                    <connection refLocalId="6" formalParameter="OUT">
+                      <position y="198" x="420"/>
+                      <position y="198" x="369"/>
+                      <position y="141" x="369"/>
+                      <position y="141" x="334"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+                <variable formalParameter="R">
+                  <connectionPointIn>
+                    <relPosition y="72" x="0"/>
+                    <connection refLocalId="8" formalParameter="OUT">
+                      <position y="233" x="420"/>
+                      <position y="233" x="369"/>
+                      <position y="282" x="369"/>
+                      <position y="282" x="334"/>
+                    </connection>
+                  </connectionPointIn>
+                </variable>
+              </inputVariables>
+              <inOutVariables/>
+              <outputVariables>
+                <variable formalParameter="Q1">
+                  <connectionPointOut>
+                    <relPosition y="37" x="97"/>
+                  </connectionPointOut>
+                </variable>
+              </outputVariables>
+            </block>
+          </FBD>
+        </body>
+      </pou>
+      <pou name="LDTest" pouType="function">
+        <interface>
+          <returnType>
+            <BOOL/>
+          </returnType>
+          <inputVars>
+            <variable name="IN1">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="IN2">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="IN3">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="IN4">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+          </inputVars>
+        </interface>
+        <body>
+          <LD>
+            <comment localId="1" height="40" width="600">
+              <position y="10" x="10"/>
+              <content>Commentaire</content>
+            </comment>
+            <leftPowerRail localId="2" height="80" width="2">
+              <position y="60" x="10"/>
+              <connectionPointOut formalParameter="">
+                <relPosition y="20" x="2"/>
+              </connectionPointOut>
+              <connectionPointOut formalParameter="">
+                <relPosition y="60" x="2"/>
+              </connectionPointOut>
+            </leftPowerRail>
+            <coil localId="3" width="21" storage="none" height="15" negated="false">
+              <position y="72" x="265"/>
+              <connectionPointIn>
+                <relPosition y="8" x="0"/>
+                <connection refLocalId="7">
+                  <position y="80" x="265"/>
+                  <position y="80" x="195"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="8" x="21"/>
+              </connectionPointOut>
+              <variable>LDTest</variable>
+            </coil>
+            <rightPowerRail localId="4" height="40" width="2">
+              <position y="60" x="316"/>
+              <connectionPointIn>
+                <relPosition y="20" x="0"/>
+                <connection refLocalId="3">
+                  <position y="80" x="316"/>
+                  <position y="80" x="286"/>
+                </connection>
+              </connectionPointIn>
+            </rightPowerRail>
+            <contact localId="5" width="21" height="15" edge="none" negated="true">
+              <position y="72" x="42"/>
+              <connectionPointIn>
+                <relPosition y="8" x="0"/>
+                <connection refLocalId="2">
+                  <position y="80" x="42"/>
+                  <position y="80" x="12"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="8" x="21"/>
+              </connectionPointOut>
+              <variable>IN1</variable>
+            </contact>
+            <contact localId="7" width="21" height="15" edge="none" negated="false">
+              <position y="72" x="174"/>
+              <connectionPointIn>
+                <relPosition y="8" x="0"/>
+                <connection refLocalId="5">
+                  <position y="80" x="174"/>
+                  <position y="80" x="63"/>
+                </connection>
+                <connection refLocalId="9">
+                  <position y="80" x="174"/>
+                  <position y="80" x="144"/>
+                  <position y="120" x="144"/>
+                  <position y="120" x="114"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="8" x="21"/>
+              </connectionPointOut>
+              <variable>IN2</variable>
+            </contact>
+            <contact localId="8" width="21" height="15" edge="none" negated="false">
+              <position y="112" x="42"/>
+              <connectionPointIn>
+                <relPosition y="8" x="0"/>
+                <connection refLocalId="2">
+                  <position y="120" x="42"/>
+                  <position y="120" x="12"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="8" x="21"/>
+              </connectionPointOut>
+              <variable>IN3</variable>
+            </contact>
+            <contact localId="9" width="21" height="15" edge="none" negated="true">
+              <position y="112" x="93"/>
+              <connectionPointIn>
+                <relPosition y="8" x="0"/>
+                <connection refLocalId="8">
+                  <position y="120" x="93"/>
+                  <position y="120" x="63"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="8" x="21"/>
+              </connectionPointOut>
+              <variable>IN4</variable>
+            </contact>
+          </LD>
+        </body>
+      </pou>
+      <pou name="ILTest" pouType="function">
+        <interface>
+          <returnType>
+            <REAL/>
+          </returnType>
+          <inputVars>
+            <variable name="X1">
+              <type>
+                <REAL/>
+              </type>
+              <initialValue>
+                <simpleValue value="1.0"/>
+              </initialValue>
+            </variable>
+          </inputVars>
+          <localVars>
+            <variable name="Temp">
+              <type>
+                <REAL/>
+              </type>
+            </variable>
+          </localVars>
+          <inputVars>
+            <variable name="X2">
+              <type>
+                <REAL/>
+              </type>
+              <initialValue>
+                <simpleValue value="0.0"/>
+              </initialValue>
+            </variable>
+            <variable name="Y1">
+              <type>
+                <REAL/>
+              </type>
+              <initialValue>
+                <simpleValue value="1.0"/>
+              </initialValue>
+            </variable>
+            <variable name="Y2">
+              <type>
+                <REAL/>
+              </type>
+              <initialValue>
+                <simpleValue value="0.0"/>
+              </initialValue>
+            </variable>
+            <variable name="TMax">
+              <type>
+                <REAL/>
+              </type>
+            </variable>
+          </inputVars>
+          <outputVars>
+            <variable name="ERROR">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+          </outputVars>
+        </interface>
+        <body>
+          <IL>
+     LD   Y1
+     SUB  Y2     (* Substract Y2 from Y1 *)
+     ST   Temp   (* Store Y1-Y2 in Temp *)
+     MUL  Temp   (* Multiply by Temp to square *)
+     ADD( X1     (* Defer ADD *)
+     SUB  X2     (* Substract X1 from X2 *)
+     ST   Temp   (* Store X1-X2 in Temp *)
+     MUL  Temp   (* Multiply by Temp to square *)
+     )
+     SQRT        (* Call Square root fun *)
+     ST   ILTest (* Setup function result *)
+     GT   TMax   (* Greater than TMax ? *)
+     JMPC ERR    (* Yes, Jump to Error *)
+     S    ERROR  (* Set ERROR *)
+     RET         (* Normal return *)
+ERR: RET         (* Error return, ENO not set *)
+          </IL>
+        </body>
+      </pou>
+      <pou name="SFCTest" pouType="program">
+        <interface>
+          <inputVars>
+            <variable name="IN1">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="IN2">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="IN3">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="IN4">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="IN5">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+          </inputVars>
+        </interface>
+        <actions>
+          <action name="ACT1">
+            <body>
+              <ST>
+IF IN1 THEN
+  IN2 := 1;
+ELSE
+  IN3 := 1;
+END_IF;
+              </ST>
+            </body>
+          </action>
+        </actions>
+        <transitions>
+          <transition name="TR1">
+            <body>
+              <ST>:= AND(IN1, IN2, IN3);</ST>
+            </body>
+          </transition>
+        </transitions>
+        <body>
+          <SFC>
+            <step localId="1" height="31" width="46" initialStep="true" name="Start">
+              <position y="46" x="82"/>
+              <connectionPointOut formalParameter="">
+                <relPosition y="31" x="23"/>
+              </connectionPointOut>
+            </step>
+            <transition localId="2" height="2" width="20">
+              <position y="102" x="95"/>
+              <connectionPointIn>
+                <relPosition y="0" x="10"/>
+                <connection refLocalId="1">
+                  <position y="102" x="105"/>
+                  <position y="77" x="105"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="2" x="10"/>
+              </connectionPointOut>
+              <condition>
+                <reference name="TR1"/>
+              </condition>
+            </transition>
+            <step localId="3" height="27" width="29" initialStep="false" name="Init">
+              <position y="129" x="91"/>
+              <connectionPointIn>
+                <relPosition y="0" x="14"/>
+                <connection refLocalId="2">
+                  <position y="129" x="105"/>
+                  <position y="104" x="105"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut formalParameter="">
+                <relPosition y="27" x="14"/>
+              </connectionPointOut>
+              <connectionPointOutAction formalParameter="">
+                <relPosition y="13" x="29"/>
+              </connectionPointOutAction>
+            </step>
+            <selectionDivergence localId="4" height="1" width="391">
+              <position y="181" x="105"/>
+              <connectionPointIn>
+                <relPosition y="0" x="0"/>
+                <connection refLocalId="3">
+                  <position y="181" x="105"/>
+                  <position y="156" x="105"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut formalParameter="">
+                <relPosition y="1" x="0"/>
+              </connectionPointOut>
+              <connectionPointOut formalParameter="">
+                <relPosition y="1" x="228"/>
+              </connectionPointOut>
+              <connectionPointOut formalParameter="">
+                <relPosition y="1" x="391"/>
+              </connectionPointOut>
+            </selectionDivergence>
+            <transition localId="5" height="2" width="20">
+              <position y="207" x="95"/>
+              <connectionPointIn>
+                <relPosition y="0" x="10"/>
+                <connection refLocalId="4">
+                  <position y="207" x="105"/>
+                  <position y="182" x="105"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="2" x="10"/>
+              </connectionPointOut>
+              <condition>
+                <inline name="">
+                  <ST>IN2 AND IN3</ST>
+                </inline>
+              </condition>
+            </transition>
+            <step localId="6" height="27" width="48" initialStep="false" name="Step1">
+              <position y="262" x="81"/>
+              <connectionPointIn>
+                <relPosition y="0" x="24"/>
+                <connection refLocalId="21">
+                  <position y="262" x="105"/>
+                  <position y="237" x="105"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut formalParameter="">
+                <relPosition y="27" x="24"/>
+              </connectionPointOut>
+            </step>
+            <transition localId="7" height="2" width="20">
+              <position y="207" x="323"/>
+              <connectionPointIn>
+                <relPosition y="0" x="10"/>
+                <connection refLocalId="4">
+                  <position y="207" x="333"/>
+                  <position y="182" x="333"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="2" x="10"/>
+              </connectionPointOut>
+              <condition>
+                <inline name="">
+                  <ST>IN3</ST>
+                </inline>
+              </condition>
+            </transition>
+            <step localId="8" height="27" width="48" initialStep="false" name="Step2">
+              <position y="234" x="309"/>
+              <connectionPointIn>
+                <relPosition y="0" x="24"/>
+                <connection refLocalId="7">
+                  <position y="234" x="333"/>
+                  <position y="209" x="333"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut formalParameter="">
+                <relPosition y="27" x="24"/>
+              </connectionPointOut>
+            </step>
+            <transition localId="9" height="2" width="20">
+              <position y="207" x="486"/>
+              <connectionPointIn>
+                <relPosition y="0" x="10"/>
+                <connection refLocalId="4">
+                  <position y="207" x="496"/>
+                  <position y="182" x="496"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="2" x="10"/>
+              </connectionPointOut>
+              <condition>
+                <inline name="">
+                  <ST>IN4</ST>
+                </inline>
+              </condition>
+            </transition>
+            <step localId="10" height="27" width="48" initialStep="false" name="Step3">
+              <position y="234" x="472"/>
+              <connectionPointIn>
+                <relPosition y="0" x="24"/>
+                <connection refLocalId="9">
+                  <position y="234" x="496"/>
+                  <position y="209" x="496"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut formalParameter="">
+                <relPosition y="27" x="24"/>
+              </connectionPointOut>
+              <connectionPointOutAction formalParameter="">
+                <relPosition y="13" x="48"/>
+              </connectionPointOutAction>
+            </step>
+            <transition localId="11" height="2" width="20">
+              <position y="342" x="95"/>
+              <connectionPointIn>
+                <relPosition y="0" x="10"/>
+                <connection refLocalId="23">
+                  <position y="342" x="105"/>
+                  <position y="317" x="105"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="2" x="10"/>
+              </connectionPointOut>
+              <condition>
+                <inline name="">
+                  <ST>IN5</ST>
+                </inline>
+              </condition>
+            </transition>
+            <jumpStep localId="12" height="13" width="12" targetName="Start">
+              <position y="369" x="99"/>
+              <connectionPointIn>
+                <relPosition y="0" x="6"/>
+                <connection refLocalId="11">
+                  <position y="369" x="105"/>
+                  <position y="344" x="105"/>
+                </connection>
+              </connectionPointIn>
+            </jumpStep>
+            <actionBlock localId="13" height="30" width="100">
+              <position y="127" x="145"/>
+              <connectionPointIn>
+                <relPosition y="15" x="0"/>
+                <connection refLocalId="3">
+                  <position y="142" x="145"/>
+                  <position y="142" x="120"/>
+                </connection>
+              </connectionPointIn>
+              <action qualifier="N">
+                <reference name="ACT1"/>
+              </action>
+            </actionBlock>
+            <transition localId="14" height="2" width="20">
+              <position y="286" x="323"/>
+              <connectionPointIn>
+                <relPosition y="0" x="10"/>
+                <connection refLocalId="8">
+                  <position y="286" x="333"/>
+                  <position y="261" x="333"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="2" x="10"/>
+              </connectionPointOut>
+              <condition>
+                <inline name="">
+                  <ST>IN5</ST>
+                </inline>
+              </condition>
+            </transition>
+            <transition localId="15" height="2" width="20">
+              <position y="316" x="486"/>
+              <connectionPointIn>
+                <relPosition y="0" x="10"/>
+                <connection refLocalId="10">
+                  <position y="316" x="496"/>
+                  <position y="261" x="496"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="2" x="10"/>
+              </connectionPointOut>
+              <condition>
+                <inline name="">
+                  <ST>IN5</ST>
+                </inline>
+              </condition>
+            </transition>
+            <selectionConvergence localId="16" height="1" width="163">
+              <position y="343" x="333"/>
+              <connectionPointIn>
+                <relPosition y="0" x="0"/>
+                <connection refLocalId="14">
+                  <position y="343" x="333"/>
+                  <position y="288" x="333"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointIn>
+                <relPosition y="0" x="163"/>
+                <connection refLocalId="15">
+                  <position y="343" x="496"/>
+                  <position y="318" x="496"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="1" x="80"/>
+              </connectionPointOut>
+            </selectionConvergence>
+            <jumpStep localId="19" height="13" width="12" targetName="Init">
+              <position y="369" x="407"/>
+              <connectionPointIn>
+                <relPosition y="0" x="6"/>
+                <connection refLocalId="16">
+                  <position y="369" x="413"/>
+                  <position y="344" x="413"/>
+                </connection>
+              </connectionPointIn>
+            </jumpStep>
+            <actionBlock localId="20" height="60" width="181">
+              <position y="232" x="545"/>
+              <connectionPointIn>
+                <relPosition y="15" x="0"/>
+                <connection refLocalId="10">
+                  <position y="247" x="545"/>
+                  <position y="247" x="520"/>
+                </connection>
+              </connectionPointIn>
+              <action indicator="IN5" qualifier="N">
+                <reference name="ACT1"/>
+              </action>
+              <action qualifier="D" duration="T#10s">
+                <reference name="IN1"/>
+              </action>
+            </actionBlock>
+            <simultaneousDivergence localId="21" height="3" width="118">
+              <position y="234" x="105"/>
+              <connectionPointIn>
+                <relPosition y="0" x="0"/>
+                <connection refLocalId="5">
+                  <position y="234" x="105"/>
+                  <position y="209" x="105"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut formalParameter="">
+                <relPosition y="3" x="0"/>
+              </connectionPointOut>
+              <connectionPointOut formalParameter="">
+                <relPosition y="3" x="118"/>
+              </connectionPointOut>
+            </simultaneousDivergence>
+            <step localId="22" height="27" width="48" initialStep="false" name="Step4">
+              <position y="262" x="199"/>
+              <connectionPointIn>
+                <relPosition y="0" x="24"/>
+                <connection refLocalId="21">
+                  <position y="262" x="223"/>
+                  <position y="237" x="223"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut formalParameter="">
+                <relPosition y="27" x="24"/>
+              </connectionPointOut>
+            </step>
+            <simultaneousConvergence localId="23" height="3" width="118">
+              <position y="314" x="105"/>
+              <connectionPointIn>
+                <relPosition y="0" x="0"/>
+                <connection refLocalId="6">
+                  <position y="314" x="105"/>
+                  <position y="289" x="105"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointIn>
+                <relPosition y="0" x="118"/>
+                <connection refLocalId="22">
+                  <position y="314" x="223"/>
+                  <position y="289" x="223"/>
+                </connection>
+              </connectionPointIn>
+              <connectionPointOut>
+                <relPosition y="3" x="0"/>
+              </connectionPointOut>
+            </simultaneousConvergence>
+          </SFC>
+        </body>
+      </pou>
+      <pou name="STTest" pouType="functionBlock">
+        <interface>
+          <inputVars>
+            <variable name="Collision">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="Gate">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="Pump">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="Temp">
+              <type>
+                <REAL/>
+              </type>
+            </variable>
+          </inputVars>
+          <outputVars>
+            <variable name="Speed">
+              <type>
+                <INT/>
+              </type>
+            </variable>
+            <variable name="PumpSpeed">
+              <type>
+                <INT/>
+              </type>
+            </variable>
+            <variable name="Brakes">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+            <variable name="Control_State">
+              <type>
+                <BOOL/>
+              </type>
+            </variable>
+          </outputVars>
+        </interface>
+        <body>
+          <ST>
+IF Collision THEN
+  Speed := 0;
+  Brakes := TRUE;
+END_IF;
+
+IF (Gate = TRUE) AND
+    (Pump = TRUE) AND (Temp > 200.0) THEN
+  Control_State := TRUE;
+ELSE
+  Control_State := FALSE;
+  PumpSpeed := 10.0;
+END_IF;
+          </ST>
+        </body>
+      </pou>
+    </pous>
   </types>
   <instances>
-    <configurations/>
+    <configurations>
+      <configuration name="ConfigTest">
+        <resource name="ResourceTest">
+          <task interval="01:00:00.100000" name="Toto" priority="6">
+            <pouInstance type="SFCTest" name="Program1"/>
+          </task>
+          <globalVars>
+            <variable name="Titi" address="M30">
+              <type>
+                <INT/>
+              </type>
+            </variable>
+          </globalVars>
+        </resource>
+        <globalVars>
+          <variable name="Toto" address="M10">
+            <type>
+              <INT/>
+            </type>
+          </variable>
+          <variable name="Tutu" address="M20">
+            <type>
+              <BOOL/>
+            </type>
+          </variable>
+        </globalVars>
+      </configuration>
+      <configuration name="ConfigTest2"/>
+    </configurations>
   </instances>
 </project>