Add support for defining execution order in FBD networks (related ST code not generated yet)
authorlbessard
Tue, 30 Oct 2007 16:53:08 +0100
changeset 118 0c53d6a36013
parent 117 bbe0697cf1ea
child 119 564564136c79
Add support for defining execution order in FBD networks (related ST code not generated yet)
Dialogs.py
PLCControler.py
PLCOpenEditor.py
Viewer.py
graphics/FBD_Objects.py
plcopen/plcopen.py
--- a/Dialogs.py	Fri Oct 26 17:04:18 2007 +0200
+++ b/Dialogs.py	Tue Oct 30 16:53:08 2007 +0100
@@ -34,9 +34,10 @@
 [ID_BLOCKPROPERTIESDIALOG, ID_BLOCKPROPERTIESDIALOGNAME, 
  ID_BLOCKPROPERTIESDIALOGTYPETREE, ID_BLOCKPROPERTIESDIALOGTYPEDESC, 
  ID_BLOCKPROPERTIESDIALOGINPUTS, ID_BLOCKPROPERTIESDIALOGPREVIEW, 
- ID_BLOCKPROPERTIESDIALOGSTATICTEXT1, ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, 
- ID_BLOCKPROPERTIESDIALOGSTATICTEXT3, ID_BLOCKPROPERTIESDIALOGSTATICTEXT4, 
-] = [wx.NewId() for _init_ctrls in range(10)]
+ ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER, ID_BLOCKPROPERTIESDIALOGSTATICTEXT1, 
+ ID_BLOCKPROPERTIESDIALOGSTATICTEXT2, ID_BLOCKPROPERTIESDIALOGSTATICTEXT3, 
+ ID_BLOCKPROPERTIESDIALOGSTATICTEXT4, ID_BLOCKPROPERTIESDIALOGSTATICTEXT5, 
+] = [wx.NewId() for _init_ctrls in range(12)]
 
 [CATEGORY, BLOCK] = range(2)
 
@@ -67,7 +68,7 @@
 
     def _init_coll_RightGridSizer_Items(self, parent):
         parent.AddSizer(self.RightUpGridSizer, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText4, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText5, 0, border=0, flag=wx.GROW)
         parent.AddWindow(self.Preview, 0, border=0, flag=wx.GROW)
 
     def _init_coll_RightGridSizer_Growables(self, parent):
@@ -75,17 +76,19 @@
         parent.AddGrowableRow(2)
 
     def _init_coll_RightUpGridSizer_Items(self, parent):
-        parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW|wx.ALIGN_BOTTOM)
-        parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW|wx.ALIGN_BOTTOM)
+        parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.BlockName, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText3, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.Inputs, 0, border=0, flag=wx.GROW)
-
+        parent.AddWindow(self.staticText4, 0, border=4, flag=wx.GROW|wx.TOP)
+        parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW)
+        
     def _init_sizers(self):
         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
         self.LeftBoxSizer = wx.StaticBoxSizer(self.staticbox1, wx.VERTICAL)
         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5)
-        self.RightUpGridSizer = wx.GridSizer(cols=2, hgap=5, rows=2, vgap=5)
+        self.RightUpGridSizer = wx.GridSizer(cols=2, hgap=5, rows=3, vgap=5)
         
         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
         self._init_coll_flexGridSizer1_Growables(self.flexGridSizer1)
@@ -100,9 +103,9 @@
     def _init_ctrls(self, prnt):
         wx.Dialog.__init__(self, id=ID_BLOCKPROPERTIESDIALOG,
               name='BlockPropertiesDialog', parent=prnt, pos=wx.Point(376, 223),
-              size=wx.Size(600, 360), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
+              size=wx.Size(600, 380), style=wx.DEFAULT_DIALOG_STYLE|wx.RESIZE_BORDER,
               title='Block Properties')
-        self.SetClientSize(wx.Size(600, 360))
+        self.SetClientSize(wx.Size(600, 380))
 
         self.staticbox1 = wx.StaticBox(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT1,
               label='Type:', name='staticBox1', parent=self,
@@ -117,7 +120,11 @@
               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
 
         self.staticText4 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT4,
-              label='Preview:', name='staticText4', parent=self,
+              label='Execution Order:', name='staticText4', parent=self,
+              pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
+
+        self.staticText5 = wx.StaticText(id=ID_BLOCKPROPERTIESDIALOGSTATICTEXT5,
+              label='Preview:', name='staticText5', parent=self,
               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
 
         if wx.Platform == '__WXMSW__':
@@ -144,6 +151,11 @@
               size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=2, max=20)
         self.Bind(wx.EVT_SPINCTRL, self.OnInputsChanged, id=ID_BLOCKPROPERTIESDIALOGINPUTS)
 
+        self.ExecutionOrder = wx.SpinCtrl(id=ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER,
+              name='ExecutionOrder', parent=self, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0)
+        self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, id=ID_BLOCKPROPERTIESDIALOGEXECUTIONORDER)
+
         self.Preview = wx.Panel(id=ID_BLOCKPROPERTIESDIALOGPREVIEW,
               name='Preview', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
@@ -262,6 +274,8 @@
                 self.BlockName.SetValue(value)
             elif name == "extension":
                 self.Inputs.SetValue(value)
+            elif name == "executionOrder":
+                self.ExecutionOrder.SetValue(value)
         self.RefreshPreview()
 
     def GetValues(self):
@@ -273,6 +287,7 @@
             values["name"] = self.BlockName.GetValue()
         values["width"], values["height"] = self.Block.GetSize()
         values["extension"] = self.Inputs.GetValue()
+        values["executionOrder"] = self.ExecutionOrder.GetValue()
         return values
 
     def OnTypeTreeItemSelected(self, event):
@@ -311,6 +326,10 @@
             self.RefreshPreview()
         event.Skip()
     
+    def OnExecutionOrderChanged(self, event):
+        self.RefreshPreview()
+        event.Skip()
+    
     def ErasePreview(self):
         dc = wx.ClientDC(self.Preview)
         dc.Clear()
@@ -327,7 +346,7 @@
             else:
                 blocktype = self.TypeTree.GetItemText(item)
                 if blocktype:
-                    self.Block = FBD_Block(self.Preview, blocktype, self.BlockName.GetValue(), extension = self.Inputs.GetValue(), inputs = pydata["inputs"])
+                    self.Block = FBD_Block(self.Preview, blocktype, self.BlockName.GetValue(), extension = self.Inputs.GetValue(), inputs = pydata["inputs"], executionOrder = self.ExecutionOrder.GetValue())
                     width, height = self.MinBlockSize
                     min_width, min_height = self.Block.GetMinSize()
                     width, height = max(min_width, width), max(min_height, height)
@@ -352,9 +371,10 @@
 [ID_VARIABLEPROPERTIESDIALOG, ID_VARIABLEPROPERTIESDIALOGSPACER, 
  ID_VARIABLEPROPERTIESDIALOGNAME, ID_VARIABLEPROPERTIESDIALOGCLASS, 
  ID_VARIABLEPROPERTIESDIALOGPREVIEW, ID_VARIABLEPROPERTIESDIALOGEXPRESSION,
- ID_VARIABLEPROPERTIESDIALOGSTATICTEXT1, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT2,
- ID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT4,
-] = [wx.NewId() for _init_ctrls in range(10)]
+ ID_VARIABLEPROPERTIESDIALOGEXECUTIONORDER, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT1, 
+ ID_VARIABLEPROPERTIESDIALOGSTATICTEXT2, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT3, 
+ ID_VARIABLEPROPERTIESDIALOGSTATICTEXT4, ID_VARIABLEPROPERTIESDIALOGSTATICTEXT5
+] = [wx.NewId() for _init_ctrls in range(12)]
 
 class VariablePropertiesDialog(wx.Dialog):
     
@@ -389,16 +409,18 @@
     def _init_coll_LeftGridSizer_Items(self, parent):
         parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
         parent.AddWindow(self.Class, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
         parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
         parent.AddWindow(self.Expression, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.ExecutionOrder, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
     
     def _init_coll_LeftGridSizer_Growables(self, parent):
         parent.AddGrowableCol(0)
         parent.AddGrowableRow(2)
             
     def _init_coll_RightGridSizer_Items(self, parent):
-        parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText5, 0, border=0, flag=wx.GROW)
         parent.AddWindow(self.VariableName, 0, border=0, flag=wx.GROW)
         
     def _init_coll_RightGridSizer_Growables(self, parent):
@@ -409,7 +431,7 @@
         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
         self.MainSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=3, vgap=5)
         self.TopSizer = wx.BoxSizer(wx.HORIZONTAL)
-        self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=5, vgap=5)
+        self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=5)
         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
 
         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
@@ -440,11 +462,15 @@
               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
 
         self.staticText3 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT3,
-              label='Name:', name='staticText3', parent=self,
+              label='Execution Order:', name='staticText3', parent=self,
               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
 
         self.staticText4 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT4,
-              label='Preview:', name='staticText4', parent=self,
+              label='Name:', name='staticText4', parent=self,
+              pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
+
+        self.staticText5 = wx.StaticText(id=ID_VARIABLEPROPERTIESDIALOGSTATICTEXT5,
+              label='Preview:', name='staticText5', parent=self,
               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
 
         self.Class = wx.Choice(id=ID_VARIABLEPROPERTIESDIALOGCLASS,
@@ -462,6 +488,11 @@
               size=wx.Size(0, 24), style=0)
         self.Bind(wx.EVT_TEXT, self.OnExpressionChanged, id=ID_VARIABLEPROPERTIESDIALOGEXPRESSION)
 
+        self.ExecutionOrder = wx.SpinCtrl(id=ID_VARIABLEPROPERTIESDIALOGEXECUTIONORDER,
+              name='ExecutionOrder', parent=self, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0)
+        self.Bind(wx.EVT_SPINCTRL, self.OnExecutionOrderChanged, id=ID_VARIABLEPROPERTIESDIALOGEXECUTIONORDER)
+
         self.Spacer = wx.Panel(id=ID_VARIABLEPROPERTIESDIALOGSPACER,
               name='Spacer', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
@@ -536,6 +567,8 @@
             else:
                 self.Expression.SetValue(value_name)
                 self.VariableName.Enable(False)
+        if "executionOrder" in values:
+            self.ExecutionOrder.SetValue(values["executionOrder"])
         self.RefreshPreview()
         
     def GetValues(self):
@@ -557,6 +590,7 @@
             if var_name == values["name"]:
                 values["value_type"] = value_type
         values["width"], values["height"] = self.Variable.GetSize()
+        values["executionOrder"] = self.ExecutionOrder.GetValue()
         return values
 
     def OnClassChanged(self, event):
@@ -584,6 +618,10 @@
         self.RefreshPreview()
         event.Skip()
     
+    def OnExecutionOrderChanged(self, event):
+        self.RefreshPreview()
+        event.Skip()
+    
     def RefreshPreview(self):
         dc = wx.ClientDC(self.Preview)
         dc.Clear()
@@ -598,11 +636,11 @@
                 type = value_type
         classtype = self.Class.GetStringSelection()
         if classtype == "Input":
-            self.Variable = FBD_Variable(self.Preview, INPUT, name, type)
+            self.Variable = FBD_Variable(self.Preview, INPUT, name, type, executionOrder = self.ExecutionOrder.GetValue())
         elif classtype == "Output":
-            self.Variable = FBD_Variable(self.Preview, OUTPUT, name, type)
+            self.Variable = FBD_Variable(self.Preview, OUTPUT, name, type, executionOrder = self.ExecutionOrder.GetValue())
         elif classtype == "InOut":
-            self.Variable = FBD_Variable(self.Preview, INOUT, name, type)
+            self.Variable = FBD_Variable(self.Preview, INOUT, name, type, executionOrder = self.ExecutionOrder.GetValue())
         width, height = self.MinVariableSize
         min_width, min_height = self.Variable.GetMinSize()
         width, height = max(min_width, width), max(min_height, height)
--- a/PLCControler.py	Fri Oct 26 17:04:18 2007 +0200
+++ b/PLCControler.py	Tue Oct 30 16:53:08 2007 +0100
@@ -1233,6 +1233,11 @@
             if isinstance(instance, plcopen.block):
                 infos["name"] = instance.getInstanceName()
                 infos["type"] = instance.getTypeName()
+                executionOrder = instance.getExecutionOrderId()
+                if executionOrder is not None:
+                    infos["executionOrder"] = executionOrder
+                else:
+                    infos["executionOrder"] = 0
                 infos["connectors"] = {"inputs":[],"outputs":[]}
                 for variable in instance.inputVariables.getVariable():
                     connector = {}
@@ -1258,6 +1263,11 @@
                 infos["name"] = instance.getExpression()
                 infos["value_type"] = self.GetCurrentPouVarValueType(infos["name"])
                 infos["type"] = "input"
+                executionOrder = instance.getExecutionOrderId()
+                if executionOrder is not None:
+                    infos["executionOrder"] = executionOrder
+                else:
+                    infos["executionOrder"] = 0
                 infos["connector"] = {}
                 infos["connector"]["position"] = instance.connectionPointOut.getRelPosition()
                 infos["connector"]["negated"] = instance.getNegated()
@@ -1266,6 +1276,11 @@
                 infos["name"] = instance.getExpression()
                 infos["value_type"] = self.GetCurrentPouVarValueType(infos["name"])
                 infos["type"] = "output"
+                executionOrder = instance.getExecutionOrderId()
+                if executionOrder is not None:
+                    infos["executionOrder"] = executionOrder
+                else:
+                    infos["executionOrder"] = 0
                 infos["connector"] = {}
                 infos["connector"]["position"] = instance.connectionPointIn.getRelPosition()
                 infos["connector"]["negated"] = instance.getNegated()
@@ -1280,6 +1295,11 @@
                 infos["name"] = instance.getExpression()
                 infos["value_type"] = self.GetCurrentPouVarValueType(infos["name"])
                 infos["type"] = "inout"
+                executionOrder = instance.getExecutionOrderId()
+                if executionOrder is not None:
+                    infos["executionOrder"] = executionOrder
+                else:
+                    infos["executionOrder"] = 0
                 infos["connectors"] = {"input":{},"output":{}}
                 infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition()
                 infos["connectors"]["output"]["negated"] = instance.getNegatedOut()
@@ -1297,12 +1317,22 @@
                 infos["name"] = instance.getName()
                 infos["value_type"] = self.GetCurrentPouVarValueType(infos["name"])
                 infos["type"] = "continuation"
+                executionOrder = instance.getExecutionOrderId()
+                if executionOrder is not None:
+                    infos["executionOrder"] = executionOrder
+                else:
+                    infos["executionOrder"] = 0
                 infos["connector"] = {}
                 infos["connector"]["position"] = instance.connectionPointOut.getRelPosition()
             elif isinstance(instance, plcopen.connector):
                 infos["name"] = instance.getName()
                 infos["value_type"] = self.GetCurrentPouVarValueType(infos["name"])
                 infos["type"] = "connection"
+                executionOrder = instance.getExecutionOrderId()
+                if executionOrder is not None:
+                    infos["executionOrder"] = executionOrder
+                else:
+                    infos["executionOrder"] = 0
                 infos["connector"] = {}
                 infos["connector"]["position"] = instance.connectionPointIn.getRelPosition()
                 infos["connector"]["links"] = []
@@ -1333,8 +1363,13 @@
                         connector["links"].append(dic)
                     infos["connectors"].append(connector)
             elif isinstance(instance, plcopen.contact):
+                infos["name"] = instance.getVariable()
                 infos["type"] = "contact"
-                infos["name"] = instance.getVariable()
+                executionOrder = instance.getExecutionOrderId()
+                if executionOrder is not None:
+                    infos["executionOrder"] = executionOrder
+                else:
+                    infos["executionOrder"] = 0
                 infos["negated"] = instance.getNegated()
                 infos["edge"] = instance.getContactEdge()
                 infos["connectors"] = {"input":{},"output":{}}
@@ -1347,8 +1382,13 @@
                         infos["connectors"]["input"]["links"].append(dic)
                 infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition()
             elif isinstance(instance, plcopen.coil):
+                infos["name"] = instance.getVariable()
                 infos["type"] = "coil"
-                infos["name"] = instance.getVariable()
+                executionOrder = instance.getExecutionOrderId()
+                if executionOrder is not None:
+                    infos["executionOrder"] = executionOrder
+                else:
+                    infos["executionOrder"] = 0
                 infos["negated"] = instance.getNegated()
                 infos["storage"] = instance.getCoilStorage()
                 infos["connectors"] = {"input":{},"output":{}}
@@ -1361,8 +1401,8 @@
                         infos["connectors"]["input"]["links"].append(dic)
                 infos["connectors"]["output"]["position"] = instance.connectionPointOut.getRelPosition()
             elif isinstance(instance, plcopen.step):
+                infos["name"] = instance.getName()
                 infos["type"] = "step"
-                infos["name"] = instance.getName()
                 infos["initial"] = instance.getInitialStep()
                 infos["connectors"] = {}
                 if instance.connectionPointIn:
@@ -1470,6 +1510,12 @@
             return infos
         return False
     
+    def ClearCurrentExecutionOrder(self):
+        self.GetCurrentElementEditing().resetExecutionOrder()
+    
+    def ResetCurrentExecutionOrder(self):
+        self.GetCurrentElementEditing().compileExecutionOrder()
+    
     # Return the variable type of the given pou
     def GetCurrentPouVarValueType(self, varname):
         current_name = self.ElementsOpened[self.CurrentElementEditing]
@@ -1533,6 +1579,8 @@
                 block.setInstanceName(value)
             elif param == "type":
                 block.setTypeName(value)
+            elif param == "executionOrder" and block.getExecutionOrderId() != value:
+                self.GetCurrentElementEditing().setElementExecutionOrder(block, value)
             elif param == "height":
                 block.setHeight(value)
             elif param == "width":
@@ -1586,6 +1634,8 @@
         for param, value in infos.items():
             if param == "name":
                 variable.setExpression(value)    
+            elif param == "executionOrder" and variable.getExecutionOrderId() != value:
+                self.GetCurrentElementEditing().setElementExecutionOrder(variable, value)
             elif param == "height":
                 variable.setHeight(value)
             elif param == "width":
--- a/PLCOpenEditor.py	Fri Oct 26 17:04:18 2007 +0200
+++ b/PLCOpenEditor.py	Tue Oct 30 16:53:08 2007 +0100
@@ -365,7 +365,7 @@
         if wx.Platform != '__WXMSW__':
             self.TreeImageList = wx.ImageList(16, 16)
             for language in LANGUAGES:
-                self.TreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images','%s.png'%language)))
+                self.TreeImageList.Add(wx.Bitmap(os.path.join(CWD, 'Images', '%s.png'%language)))
             self.ProjectTree.AssignImageList(self.TreeImageList)
         
         if self.ModeSolo:
@@ -814,11 +814,12 @@
                 message = "\"%s\" is a keyword. It can't be used!"%new_name
             else:
                 item = event.GetItem()
+                old_name = self.ProjectTree.GetItemText(item)
                 itemtype = self.ProjectTree.GetPyData(item)
                 if itemtype == ITEM_PROJECT:
                     self.Controler.SetProjectProperties(name = new_name)
                 elif itemtype == ITEM_POU:
-                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]:
                         message = "\"%s\" pou already exists!"%new_name
                         abort = True
                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
@@ -827,7 +828,6 @@
                             abort = True
                         messageDialog.Destroy()
                     if not abort:
-                        old_name = self.ProjectTree.GetItemText(item)
                         self.Controler.ChangePouName(old_name, new_name)
                         self.RefreshEditorNames(itemtype, old_name, new_name)
                         self.RefreshTabsOpenedTitles()
@@ -840,10 +840,9 @@
                     pou_name = self.ProjectTree.GetItemText(parent)
                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
                         message = "A pou with \"%s\" as name exists!"%new_name
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
                         message = "A variable with \"%s\" as name already exists in this pou!"%new_name
                     else:
-                        old_name = self.ProjectTree.GetItemText(item)
                         self.Controler.ChangePouTransitionName(pou_name, old_name, new_name)
                         self.RefreshEditorNames(itemtype, old_name, new_name)
                         self.RefreshTabsOpenedTitles()
@@ -856,15 +855,14 @@
                     pou_name = self.ProjectTree.GetItemText(parent)
                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
                         message = "A pou with \"%s\" as name exists!"%new_name
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name)]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
                         message = "A variable with \"%s\" as name already exists in this pou!"%new_name
                     else:
-                        old_name = self.ProjectTree.GetItemText(item)
                         self.Controler.ChangePouActionName(pou_name, old_name, new_name)
                         self.RefreshEditorNames(itemtype, old_name, new_name)
                         self.RefreshTabsOpenedTitles()
                 elif itemtype == ITEM_CONFIGURATION:
-                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames()]:
+                    if new_name.upper() in [name.upper() for name in self.Controler.GetProjectConfigNames() if name != old_name]:
                         message = "\"%s\" config already exists!"%new_name
                         abort = True
                     elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
@@ -878,7 +876,6 @@
                             abort = True
                         messageDialog.Destroy()
                     if not abort:
-                        old_name = self.ProjectTree.GetItemText(item)
                         self.Controler.ChangeConfigurationName(old_name, new_name)
                         self.RefreshEditorNames(itemtype, old_name, new_name)
                         self.RefreshTabsOpenedTitles()
@@ -903,7 +900,6 @@
                             abort = True
                         messageDialog.Destroy()
                     if not abort:
-                        old_name = self.ProjectTree.GetItemText(item)
                         self.Controler.ChangeConfigurationResourceName(config_name, old_name, new_name)
                         self.RefreshEditorNames(itemtype, old_name, new_name)
                         self.RefreshTabsOpenedTitles()
@@ -918,7 +914,8 @@
             else:
                 wx.CallAfter(self.RefreshProjectTree)
                 window = self.TabsOpened.GetCurrentPage()
-                window.RefreshView()
+                if window:
+                    window.RefreshView()
                 event.Skip()
 
     def OnProjectTreeItemBeginEdit(self, event):
@@ -1381,19 +1378,19 @@
         parent.AddGrowableRow(0)
     
     def _init_coll_MainSizer_Items(self, parent):
-        parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.ProjectName, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.CompanyName, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText3, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.CompanyURL, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText4, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText4, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.ProductName, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText5, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText5, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.ProductVersion, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText6, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText6, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.ProductRelease, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText7, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText7, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.ContentDescription, 0, border=0, flag=wx.GROW)
         
     def _init_coll_MainSizer_Growables(self, parent):
@@ -1564,11 +1561,11 @@
         parent.AddGrowableRow(0)
     
     def _init_coll_MainSizer_Items(self, parent):
-        parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.PouName, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.PouType, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText3, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW)
         
     def _init_coll_MainSizer_Growables(self, parent):
@@ -1736,9 +1733,9 @@
         parent.AddGrowableRow(0)
     
     def _init_coll_MainSizer_Items(self, parent):
-        parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.TransitionName, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW)
         
     def _init_coll_MainSizer_Growables(self, parent):
@@ -1875,9 +1872,9 @@
         parent.AddGrowableRow(0)
     
     def _init_coll_MainSizer_Items(self, parent):
-        parent.AddWindow(self.staticText1, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText1, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.ActionName, 0, border=0, flag=wx.GROW)
-        parent.AddWindow(self.staticText2, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText2, 0, border=4, flag=wx.GROW|wx.TOP)
         parent.AddWindow(self.Language, 0, border=0, flag=wx.GROW)
         
     def _init_coll_MainSizer_Growables(self, parent):
--- a/Viewer.py	Fri Oct 26 17:04:18 2007 +0200
+++ b/Viewer.py	Tue Oct 30 16:53:08 2007 +0100
@@ -49,7 +49,8 @@
  ID_FBDVIEWERCONTEXTUALMENUITEMS5, ID_FBDVIEWERCONTEXTUALMENUITEMS6,
  ID_FBDVIEWERCONTEXTUALMENUITEMS8, ID_FBDVIEWERCONTEXTUALMENUITEMS9,
  ID_FBDVIEWERCONTEXTUALMENUITEMS11, ID_FBDVIEWERCONTEXTUALMENUITEMS12,
-] = [wx.NewId() for _init_coll_ContextualMenu_Items in range(10)]
+ ID_FBDVIEWERCONTEXTUALMENUITEMS14, ID_FBDVIEWERCONTEXTUALMENUITEMS15,
+] = [wx.NewId() for _init_coll_ContextualMenu_Items in range(12)]
 
 
 class ViewerDropTarget(wx.TextDropTarget):
@@ -155,8 +156,13 @@
               kind=wx.ITEM_NORMAL, text=u'Delete Divergence Branch')
         parent.AppendSeparator()
         AppendMenu(parent, help='', id=ID_FBDVIEWERCONTEXTUALMENUITEMS11,
+              kind=wx.ITEM_NORMAL, text=u'Clear Execution Order')
+        AppendMenu(parent, help='', id=ID_FBDVIEWERCONTEXTUALMENUITEMS12,
+              kind=wx.ITEM_NORMAL, text=u'Reset Execution Order')
+        parent.AppendSeparator()
+        AppendMenu(parent, help='', id=ID_FBDVIEWERCONTEXTUALMENUITEMS14,
               kind=wx.ITEM_NORMAL, text=u'Edit Block')
-        AppendMenu(parent, help='', id=ID_FBDVIEWERCONTEXTUALMENUITEMS12,
+        AppendMenu(parent, help='', id=ID_FBDVIEWERCONTEXTUALMENUITEMS15,
               kind=wx.ITEM_NORMAL, text=u'Delete')
         # Link menu event to corresponding called functions
         self.Bind(wx.EVT_MENU, self.OnNoModifierMenu,
@@ -175,10 +181,14 @@
               id=ID_FBDVIEWERCONTEXTUALMENUITEMS8)
         self.Bind(wx.EVT_MENU, self.OnDeleteBranchMenu,
               id=ID_FBDVIEWERCONTEXTUALMENUITEMS9)
+        self.Bind(wx.EVT_MENU, self.OnClearExecutionOrderMenu,
+              id=ID_FBDVIEWERCONTEXTUALMENUITEMS11)
+        self.Bind(wx.EVT_MENU, self.OnResetExecutionOrderMenu,
+              id=ID_FBDVIEWERCONTEXTUALMENUITEMS12)
         self.Bind(wx.EVT_MENU, self.OnEditBlockMenu,
-              id=ID_FBDVIEWERCONTEXTUALMENUITEMS11)
+              id=ID_FBDVIEWERCONTEXTUALMENUITEMS14)
         self.Bind(wx.EVT_MENU, self.OnDeleteMenu,
-              id=ID_FBDVIEWERCONTEXTUALMENUITEMS12)
+              id=ID_FBDVIEWERCONTEXTUALMENUITEMS15)
     
     # Create and initialize Contextual Menu
     def _init_menus(self):
@@ -388,7 +398,7 @@
         ids.append(instance["id"])
         self.current_id = max(self.current_id, instance["id"]) 
         if instance["type"] == "input":
-            variable = FBD_Variable(self, INPUT, instance["name"], instance["value_type"], instance["id"])
+            variable = FBD_Variable(self, INPUT, instance["name"], instance["value_type"], instance["id"], instance["executionOrder"])
             variable.SetPosition(instance["x"], instance["y"])
             variable.SetSize(instance["width"], instance["height"])
             self.AddBlock(variable)
@@ -399,7 +409,7 @@
             if instance["connector"]["edge"]:
                 connectors["output"].SetEdge(instance["connector"]["edge"])
         elif instance["type"] == "output":
-            variable = FBD_Variable(self, OUTPUT, instance["name"], instance["value_type"], instance["id"])
+            variable = FBD_Variable(self, OUTPUT, instance["name"], instance["value_type"], instance["id"], instance["executionOrder"])
             variable.SetPosition(instance["x"], instance["y"])
             variable.SetSize(instance["width"], instance["height"])
             self.AddBlock(variable)
@@ -411,7 +421,7 @@
                 connectors["input"].SetEdge(instance["connector"]["edge"])
             self.CreateWires(connectors["input"], instance["connector"]["links"], ids)
         elif instance["type"] == "inout":
-            variable = FBD_Variable(self, INOUT, instance["name"], instance["value_type"], instance["id"])
+            variable = FBD_Variable(self, INOUT, instance["name"], instance["value_type"], instance["id"], instance["executionOrder"])
             variable.SetPosition(instance["x"], instance["y"])
             variable.SetSize(instance["width"], instance["height"])
             self.AddBlock(variable)
@@ -599,9 +609,9 @@
                 else:
                     connectors["outputs"].append((output["name"], None, "none"))
             if instance["name"] != None:
-                block = FBD_Block(self, instance["type"], instance["name"], instance["id"], len(instance["connectors"]["inputs"]), connectors=connectors)
-            else:
-                block = FBD_Block(self, instance["type"], "", instance["id"], len(instance["connectors"]["inputs"]), connectors=connectors)
+                block = FBD_Block(self, instance["type"], instance["name"], instance["id"], len(instance["connectors"]["inputs"]), connectors=connectors, executionOrder=instance["executionOrder"])
+            else:
+                block = FBD_Block(self, instance["type"], "", instance["id"], len(instance["connectors"]["inputs"]), connectors=connectors, executionOrder=instance["executionOrder"])
             block.SetPosition(instance["x"], instance["y"])
             block.SetSize(instance["width"], instance["height"])
             self.AddBlock(block)
@@ -698,65 +708,69 @@
     def PopupBlockMenu(self, connector = None):
         if connector is not None and connector.IsCompatible("BOOL"):
             type = self.Controler.GetCurrentElementEditingType()
-            self.ContextualMenu.FindItemByPosition(0).Enable(True)
-            self.ContextualMenu.FindItemByPosition(1).Enable(True)
-            self.ContextualMenu.FindItemByPosition(2).Enable(type != "function")
-            self.ContextualMenu.FindItemByPosition(3).Enable(type != "function")
+            self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS0, True)
+            self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS1, True)
+            self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS2, type != "function")
+            self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS3, type != "function")
         else:
-            self.ContextualMenu.FindItemByPosition(0).Enable(False)
-            self.ContextualMenu.FindItemByPosition(1).Enable(False)
-            self.ContextualMenu.FindItemByPosition(2).Enable(False)
-            self.ContextualMenu.FindItemByPosition(3).Enable(False)
-        self.ContextualMenu.FindItemByPosition(5).Enable(False)
-        self.ContextualMenu.FindItemByPosition(6).Enable(False)
-        self.ContextualMenu.FindItemByPosition(8).Enable(False)
-        self.ContextualMenu.FindItemByPosition(9).Enable(False)
-        self.ContextualMenu.FindItemByPosition(11).Enable(self.SelectedElement.GetType() in self.Controler.GetProjectPouNames())
+            self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS0, False)
+            self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS1, False)
+            self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS2, False)
+            self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS3, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS5, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS6, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS8, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS9, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS14, self.SelectedElement.GetType() in self.Controler.GetProjectPouNames())
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS15, True)
         if connector:
             if connector.IsNegated():
-                self.ContextualMenu.FindItemByPosition(1).Check(True)
+                self.ContextualMenu.Check(ID_FBDVIEWERCONTEXTUALMENUITEMS1, True)
             elif connector.GetEdge() == "rising":
-                self.ContextualMenu.FindItemByPosition(2).Check(True)
+                self.ContextualMenu.Check(ID_FBDVIEWERCONTEXTUALMENUITEMS2, True)
             elif connector.GetEdge() == "falling":
-                self.ContextualMenu.FindItemByPosition(3).Check(True)
-            else:
-                self.ContextualMenu.FindItemByPosition(0).Check(True)
+                self.ContextualMenu.Check(ID_FBDVIEWERCONTEXTUALMENUITEMS3, True)
+            else:
+                self.ContextualMenu.Check(ID_FBDVIEWERCONTEXTUALMENUITEMS0, True)
         self.PopupMenu(self.ContextualMenu)
     
     def PopupWireMenu(self):
-        self.ContextualMenu.FindItemByPosition(0).Enable(False)
-        self.ContextualMenu.FindItemByPosition(1).Enable(False)
-        self.ContextualMenu.FindItemByPosition(2).Enable(False)
-        self.ContextualMenu.FindItemByPosition(3).Enable(False)
-        self.ContextualMenu.FindItemByPosition(5).Enable(True)
-        self.ContextualMenu.FindItemByPosition(6).Enable(True)
-        self.ContextualMenu.FindItemByPosition(8).Enable(False)
-        self.ContextualMenu.FindItemByPosition(9).Enable(False)
-        self.ContextualMenu.FindItemByPosition(11).Enable(False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS0, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS1, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS2, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS3, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS5, True)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS6, True)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS8, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS9, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS14, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS15, True)
         self.PopupMenu(self.ContextualMenu)
     
     def PopupDivergenceMenu(self, connector):
-        self.ContextualMenu.FindItemByPosition(0).Enable(False)
-        self.ContextualMenu.FindItemByPosition(1).Enable(False)
-        self.ContextualMenu.FindItemByPosition(2).Enable(False)
-        self.ContextualMenu.FindItemByPosition(3).Enable(False)
-        self.ContextualMenu.FindItemByPosition(5).Enable(False)
-        self.ContextualMenu.FindItemByPosition(6).Enable(False)
-        self.ContextualMenu.FindItemByPosition(8).Enable(True)
-        self.ContextualMenu.FindItemByPosition(9).Enable(connector)
-        self.ContextualMenu.FindItemByPosition(11).Enable(False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS0, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS1, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS2, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS3, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS5, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS6, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS8, True)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS9, connector)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS14, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS15, True)
         self.PopupMenu(self.ContextualMenu)
     
-    def PopupDefaultMenu(self):
-        self.ContextualMenu.FindItemByPosition(0).Enable(False)
-        self.ContextualMenu.FindItemByPosition(1).Enable(False)
-        self.ContextualMenu.FindItemByPosition(2).Enable(False)
-        self.ContextualMenu.FindItemByPosition(3).Enable(False)
-        self.ContextualMenu.FindItemByPosition(5).Enable(False)
-        self.ContextualMenu.FindItemByPosition(6).Enable(False)
-        self.ContextualMenu.FindItemByPosition(8).Enable(False)
-        self.ContextualMenu.FindItemByPosition(9).Enable(False)
-        self.ContextualMenu.FindItemByPosition(11).Enable(False)
+    def PopupDefaultMenu(self, block = True):
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS0, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS1, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS2, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS3, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS5, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS6, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS8, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS9, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS14, False)
+        self.ContextualMenu.Enable(ID_FBDVIEWERCONTEXTUALMENUITEMS15, block)
         self.PopupMenu(self.ContextualMenu)
 
 #-------------------------------------------------------------------------------
@@ -821,6 +835,16 @@
             self.RefreshBuffer()
         event.Skip()
 
+    def OnClearExecutionOrderMenu(self, event):
+        self.Controler.ClearCurrentExecutionOrder()
+        self.RefreshBuffer()
+        self.RefreshView()
+        
+    def OnResetExecutionOrderMenu(self, event):
+        self.Controler.ResetCurrentExecutionOrder()
+        self.RefreshBuffer()
+        self.RefreshView()
+
 #-------------------------------------------------------------------------------
 #                          Mouse event functions
 #-------------------------------------------------------------------------------
@@ -962,6 +986,8 @@
             wx.CallAfter(self.SetCursor, wx.NullCursor)
             self.ReleaseMouse()
             self.Refresh(False)
+        else:
+            self.PopupDefaultMenu(False)
         event.Skip()
     
     def OnViewerLeftDClick(self, event):
@@ -1361,18 +1387,24 @@
         dialog = BlockPropertiesDialog(self.ParentWindow)
         dialog.SetBlockList(self.Controler.GetBlockTypes())
         dialog.SetPouNames(self.Controler.GetProjectPouNames())
-        dialog.SetPouElementNames(self.Controler.GetCurrentElementEditingVariables())
+        variable_names = self.Controler.GetCurrentElementEditingVariables()
+        if block.GetName() != "":
+            variable_names.remove(block.GetName())
+        dialog.SetPouElementNames(variable_names)
         dialog.SetMinBlockSize(block.GetSize())
-        values = {"name" : block.GetName(), "type" : block.GetType(), "inputs" : block.GetInputTypes()}
-        values["extension"] = block.GetExtension()
-        dialog.SetValues(values)
-        if dialog.ShowModal() == wx.ID_OK:
-            values = dialog.GetValues()
-            if "name" in values:
-                block.SetName(values["name"])
-            block.SetSize(values["width"], values["height"])
-            block.SetType(values["type"], values["extension"])
+        old_values = {"name" : block.GetName(), "type" : block.GetType(), "inputs" : block.GetInputTypes(), 
+            "executionOrder" : block.GetExecutionOrder(), "extension" : block.GetExtension()}
+        dialog.SetValues(old_values)
+        if dialog.ShowModal() == wx.ID_OK:
+            new_values = dialog.GetValues()
+            if "name" in new_values:
+                block.SetName(new_values["name"])
+            block.SetSize(new_values["width"], new_values["height"])
+            block.SetType(new_values["type"], new_values["extension"])
+            block.SetExecutionOrder(new_values["executionOrder"])
             self.RefreshBlockModel(block)
+            if old_values["executionOrder"] != new_values["executionOrder"]:
+                self.RefreshView()
             self.RefreshBuffer()
             self.RefreshScrollBars()
             self.ParentWindow.RefreshEditor()
@@ -1392,19 +1424,22 @@
         if returntype:
             varlist.append((self.Controler.GetCurrentElementEditingName(), "Output", returntype))
         dialog.SetVariables(varlist)
-        values = {"name" : variable.GetName(), "type" : variable.GetType()}
-        dialog.SetValues(values)
-        if dialog.ShowModal() == wx.ID_OK:
-            old_type = variable.GetType()
-            values = dialog.GetValues()
-            variable.SetName(values["name"])
-            variable.SetType(values["type"], values["value_type"])
-            variable.SetSize(values["width"], values["height"])
-            if old_type != values["type"]:
+        old_values = {"name" : variable.GetName(), "type" : variable.GetType(), 
+            "executionOrder" : variable.GetExecutionOrder()}
+        dialog.SetValues(old_values)
+        if dialog.ShowModal() == wx.ID_OK:
+            new_values = dialog.GetValues()
+            variable.SetName(new_values["name"])
+            variable.SetType(new_values["type"], new_values["value_type"])
+            variable.SetSize(new_values["width"], new_values["height"])
+            variable.SetExecutionOrder(new_values["executionOrder"])
+            if old_values["type"] != new_values["type"]:
                 id = variable.GetId()
                 self.Controler.RemoveCurrentElementEditingInstance(id)
-                self.Controler.AddCurrentElementEditingVariable(id, values["type"])
+                self.Controler.AddCurrentElementEditingVariable(id, new_values["type"])
             self.RefreshVariableModel(variable)
+            if old_values["executionOrder"] != new_values["executionOrder"]:
+                self.RefreshView()
             self.RefreshBuffer()
             self.RefreshScrollBars()
             self.Refresh(False)
@@ -1600,6 +1635,7 @@
         infos = {}
         infos["type"] = block.GetType()
         infos["name"] = block.GetName()
+        infos["executionOrder"] = block.GetExecutionOrder()
         infos["x"], infos["y"] = block.GetPosition()
         infos["width"], infos["height"] = block.GetSize()
         infos["connectors"] = block.GetConnectors()
@@ -1609,6 +1645,7 @@
         variableid = variable.GetId()
         infos = {}
         infos["name"] = variable.GetName()
+        infos["executionOrder"] = variable.GetExecutionOrder()
         infos["x"], infos["y"] = variable.GetPosition()
         infos["width"], infos["height"] = variable.GetSize()
         infos["connectors"] = variable.GetConnectors()
@@ -1618,6 +1655,7 @@
         connectionid = connection.GetId()
         infos = {}
         infos["name"] = connection.GetName()
+        infos["executionOrder"] = connection.GetExecutionOrder()
         infos["x"], infos["y"] = connection.GetPosition()
         infos["width"], infos["height"] = connection.GetSize()
         infos["connector"] = connection.GetConnector()
--- a/graphics/FBD_Objects.py	Fri Oct 26 17:04:18 2007 +0200
+++ b/graphics/FBD_Objects.py	Tue Oct 30 16:53:08 2007 +0100
@@ -39,15 +39,15 @@
 class FBD_Block(Graphic_Element):
     
     # Create a new block
-    def __init__(self, parent, type, name, id = None, extension = 0, inputs = None, connectors = {}):
+    def __init__(self, parent, type, name, id = None, extension = 0, inputs = None, connectors = {}, executionOrder = 0):
         Graphic_Element.__init__(self, parent)
         self.Type = None
         self.Extension = None
-        self.Name = name
         self.Id = id
+        self.SetName(name)
+        self.SetExecutionOrder(executionOrder)
         self.Inputs = []
         self.Outputs = []
-        self.RefreshNameSize()
         self.Colour = wx.BLACK
         self.Pen = wx.BLACK_PEN
         self.SetType(type, extension, inputs, connectors)
@@ -83,6 +83,11 @@
         dc = wx.ClientDC(self.Parent)
         self.NameSize = dc.GetTextExtent(self.Name)
     
+    # Refresh the size of text for execution order
+    def RefreshExecutionOrderSize(self):
+        dc = wx.ClientDC(self.Parent)
+        self.ExecutionOrderSize = dc.GetTextExtent(str(self.ExecutionOrder))
+    
     # Refresh the block bounding box
     def RefreshBoundingBox(self):
         # Calculate the size of the name outside the block
@@ -96,6 +101,10 @@
         else:
             bbx_y = self.Pos.y
             bbx_height = self.Size[1]
+        if self.ExecutionOrder != 0:
+            bbx_x = min(bbx_x, self.Pos.x + self.Size[0] - self.ExecutionOrderSize[0])
+            bbx_width = max(bbx_width, bbx_width + self.Pos.x + self.ExecutionOrderSize[0] - bbx_x - self.Size[0])
+            bbx_height = bbx_height + (self.ExecutionOrderSize[1] + 2)
         self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1)
     
     # Refresh the positions of the block connectors
@@ -260,6 +269,15 @@
     def GetExtension(self):
         return self.Extension
     
+    # Changes the execution order
+    def SetExecutionOrder(self, executionOrder):
+        self.ExecutionOrder = executionOrder
+        self.RefreshExecutionOrderSize()
+    
+    # Returs the execution order
+    def GetExecutionOrder(self):
+        return self.ExecutionOrder
+    
     # Refresh the block minimum size
     def RefreshMinSize(self):
         # Calculate the inputs maximum width
@@ -335,6 +353,10 @@
             input.Draw(dc)
         for output in self.Outputs:
             output.Draw(dc)
+        if self.ExecutionOrder != 0:
+            # Draw block execution order
+            dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - self.ExecutionOrderSize[0],
+                    self.Pos.y + self.Size[1] + 2)
         Graphic_Element.Draw(self, dc)
         dc.SetTextForeground(wx.BLACK)
 
@@ -350,15 +372,15 @@
 class FBD_Variable(Graphic_Element):
 
     # Create a new variable
-    def __init__(self, parent, type, name, value_type, id = None):
+    def __init__(self, parent, type, name, value_type, id = None, executionOrder = 0):
         Graphic_Element.__init__(self, parent)
         self.Type = None
         self.ValueType = None
-        self.Name = name
         self.Id = id
+        self.SetName(name)
+        self.SetExecutionOrder(executionOrder)
         self.Input = None
         self.Output = None
-        self.RefreshNameSize()
         self.SetType(type, value_type)
     
     # Make a clone of this FBD_Variable
@@ -392,6 +414,11 @@
         dc = wx.ClientDC(self.Parent)
         self.NameSize = dc.GetTextExtent(self.Name)
     
+    # Refresh the size of text for execution order
+    def RefreshExecutionOrderSize(self):
+        dc = wx.ClientDC(self.Parent)
+        self.ExecutionOrderSize = dc.GetTextExtent(str(self.ExecutionOrder))
+    
     # Refresh the variable bounding box
     def RefreshBoundingBox(self):
         if self.Type in (OUTPUT, INOUT):
@@ -402,7 +429,12 @@
             bbx_width = self.Size[0] + 2 * CONNECTOR_SIZE
         else:
             bbx_width = self.Size[0] + CONNECTOR_SIZE
-        self.BoundingBox = wx.Rect(bbx_x, self.Pos.y, bbx_width + 1, self.Size[1] + 1)
+        bbx_height = self.Size[1]
+        if self.ExecutionOrder != 0:
+            bbx_x = min(bbx_x, self.Pos.x + self.Size[0] - self.ExecutionOrderSize[0])
+            bbx_width = max(bbx_width, bbx_width + self.Pos.x + self.ExecutionOrderSize[0] - bbx_x - self.Size[0])
+            bbx_height = bbx_height + (self.ExecutionOrderSize[1] + 2)
+        self.BoundingBox = wx.Rect(bbx_x, self.Pos.y, bbx_width + 1, bbx_height + 1)
     
     # Refresh the position of the variable connector
     def RefreshConnectors(self):
@@ -492,6 +524,15 @@
     def GetName(self):
         return self.Name
     
+    # Changes the execution order
+    def SetExecutionOrder(self, executionOrder):
+        self.ExecutionOrder = executionOrder
+        self.RefreshExecutionOrderSize()
+    
+    # Returs the execution order
+    def GetExecutionOrder(self):
+        return self.ExecutionOrder
+    
     # Returns the variable minimum size
     def GetMinSize(self):
         return self.NameSize[0] + 10, self.NameSize[1] + 10
@@ -528,6 +569,10 @@
             self.Input.Draw(dc)
         if self.Output:    
             self.Output.Draw(dc)
+        if self.ExecutionOrder != 0:
+            # Draw variable execution order
+            dc.DrawText(str(self.ExecutionOrder), self.Pos.x + self.Size[0] - self.ExecutionOrderSize[0],
+                    self.Pos.y + self.Size[1] + 2)
         Graphic_Element.Draw(self, dc)
 
 
@@ -545,8 +590,8 @@
     def __init__(self, parent, type, name, id = None):
         Graphic_Element.__init__(self, parent)
         self.Type = type
-        self.Name = name
         self.Id = id
+        self.SetName(name)
         self.Pos = wx.Point(0, 0)
         self.Size = wx.Size(0, 0)
         # Create an input or output connector according to connection type
@@ -682,7 +727,7 @@
                 self.Pos.x + self.Size[0], self.Pos.y + self.Size[1] / 2)
         dc.DrawLine(self.Pos.x + self.Size[0], self.Pos.y + self.Size[1] / 2, 
                 self.Pos.x + self.Size[0] - arrowsize, self.Pos.y + self.Size[1])
-        # Draw variable name
+        # Draw connection name
         dc.DrawText(self.Name, self.Pos.x + (self.Size[0] - self.NameSize[0]) / 2,
                 self.Pos.y + (self.Size[1] - self.NameSize[1]) / 2)
         # Draw connector
--- a/plcopen/plcopen.py	Fri Oct 26 17:04:18 2007 +0200
+++ b/plcopen/plcopen.py	Tue Oct 30 16:53:08 2007 +0100
@@ -349,6 +349,15 @@
 def getBodyType(self):
     return self.body.getContent()["name"]
 
+def resetExecutionOrder(self):
+    self.body.resetExecutionOrder()
+
+def compileExecutionOrder(self):
+    self.body.compileExecutionOrder()
+
+def setElementExecutionOrder(self, instance, new_executionOrder):
+    self.body.setElementExecutionOrder(instance, new_executionOrder)
+
 def addInstance(self, name, instance):
     self.body.appendContentInstance(name, instance)
 
@@ -378,6 +387,9 @@
 if cls:
     setattr(cls, "setBodyType", setBodyType)
     setattr(cls, "getBodyType", getBodyType)
+    setattr(cls, "resetExecutionOrder", resetExecutionOrder)
+    setattr(cls, "compileExecutionOrder", compileExecutionOrder)
+    setattr(cls, "setElementExecutionOrder", setElementExecutionOrder)
     setattr(cls, "addInstance", addInstance)
     setattr(cls, "getInstances", getInstances)
     setattr(cls, "getInstance", getInstance)
@@ -556,6 +568,9 @@
 if cls:
     setattr(cls, "setBodyType", setBodyType)
     setattr(cls, "getBodyType", getBodyType)
+    setattr(cls, "resetExecutionOrder", resetExecutionOrder)
+    setattr(cls, "compileExecutionOrder", compileExecutionOrder)
+    setattr(cls, "setElementExecutionOrder", setElementExecutionOrder)
     setattr(cls, "addInstance", addInstance)
     setattr(cls, "getInstances", getInstances)
     setattr(cls, "getInstance", getInstance)
@@ -581,6 +596,9 @@
 if cls:
     setattr(cls, "setBodyType", setBodyType)
     setattr(cls, "getBodyType", getBodyType)
+    setattr(cls, "resetExecutionOrder", resetExecutionOrder)
+    setattr(cls, "compileExecutionOrder", compileExecutionOrder)
+    setattr(cls, "setElementExecutionOrder", setElementExecutionOrder)
     setattr(cls, "addInstance", addInstance)
     setattr(cls, "getInstances", getInstances)
     setattr(cls, "getInstance", getInstance)
@@ -604,6 +622,77 @@
 
 cls = PLCOpenClasses.get("body", None)
 if cls:
+    cls.currentExecutionOrderId = 0
+    
+    def resetCurrentExecutionOrderId(self):
+        self.currentExecutionOrderId = 0
+    setattr(cls, "resetCurrentExecutionOrderId", resetCurrentExecutionOrderId)
+    
+    def getNewExecutionOrderId(self):
+        self.currentExecutionOrderId += 1
+        return self.currentExecutionOrderId
+    setattr(cls, "getNewExecutionOrderId", getNewExecutionOrderId)
+    
+    def resetExecutionOrder(self):
+        if self.content["name"] == "FBD":
+            for element in self.content["value"].getContent():
+                if not isinstance(element["value"], (PLCOpenClasses.get("comment", None), PLCOpenClasses.get("connector", None), PLCOpenClasses.get("continuation", None))):
+                    element["value"].setExecutionOrderId(0)
+        else:
+            raise TypeError, "Can only generate execution order on FBD networks!"
+    setattr(cls, "resetExecutionOrder", resetExecutionOrder)
+    
+    def compileExecutionOrder(self):
+        if self.content["name"] == "FBD":
+            self.resetExecutionOrder()
+            self.resetCurrentExecutionOrderId()
+            for element in self.content["value"].getContent():
+                if isinstance(element["value"], PLCOpenClasses.get("outVariable", None)) and element["value"].getExecutionOrderId() == 0:
+                    connections = element["value"].connectionPointIn.getConnections()
+                    if connections and len(connections) == 1:
+                        self.compileElementExecutionOrder(connections[0])
+                    element["value"].setExecutionOrderId(self.getNewExecutionOrderId())
+        else:
+            raise TypeError, "Can only generate execution order on FBD networks!"
+    setattr(cls, "compileExecutionOrder", compileExecutionOrder)
+    
+    def compileElementExecutionOrder(self, link):
+        if self.content["name"] == "FBD":
+            localid = link.getRefLocalId()
+            instance = self.getContentInstance(localid)
+            if isinstance(instance, PLCOpenClasses.get("block", None)) and instance.getExecutionOrderId() == 0:
+                for variable in instance.inputVariables.getVariable():
+                    connections = variable.connectionPointIn.getConnections()
+                    if connections and len(connections) == 1:
+                        self.compileElementExecutionOrder(connections[0])
+                instance.setExecutionOrderId(self.getNewExecutionOrderId())
+            elif isinstance(instance, PLCOpenClasses.get("continuation", None)) and instance.getExecutionOrderId() == 0:
+                name = instance.getName()
+                for tmp_instance in self.getContentInstances():
+                    if isinstance(tmp_instance, PLCOpenClasses.get("connector", None)) and tmp_instance.getName() == name and tmp_instance.getExecutionOrderId() == 0:
+                        connections = tmp_instance.connectionPointIn.getConnections()
+                        if connections and len(connections) == 1:
+                            self.compileElementExecutionOrder(connections[0])
+        else:
+            raise TypeError, "Can only generate execution order on FBD networks!"
+    setattr(cls, "compileElementExecutionOrder", compileElementExecutionOrder)
+    
+    def setElementExecutionOrder(self, instance, new_executionOrder):
+        if self.content["name"] == "FBD":
+            old_executionOrder = instance.getExecutionOrderId()
+            if old_executionOrder is not None and old_executionOrder != 0 and new_executionOrder != 0:
+                for element in self.content["value"].getContent():
+                    if element["value"] != instance and not isinstance(element["value"], PLCOpenClasses.get("comment", None)):
+                        element_executionOrder = element["value"].getExecutionOrderId()
+                        if old_executionOrder <= element_executionOrder <= new_executionOrder:
+                            element["value"].setExecutionOrderId(element_executionOrder - 1)
+                        if new_executionOrder <= element_executionOrder <= old_executionOrder:
+                            element["value"].setExecutionOrderId(element_executionOrder + 1)
+            instance.setExecutionOrderId(new_executionOrder)
+        else:
+            raise TypeError, "Can only generate execution order on FBD networks!"
+    setattr(cls, "setElementExecutionOrder", setElementExecutionOrder)
+    
     def appendContentInstance(self, name, instance):
         if self.content["name"] in ["LD","FBD","SFC"]:
             self.content["value"].appendContent(name, instance)