Lots of bugs fixed
authorlbessard
Mon, 27 Aug 2007 17:37:50 +0200
changeset 80 c798a68c5560
parent 79 b22f661cbcfb
child 81 11ca9ad9e3c3
Lots of bugs fixed
Support for prioritized transition added into SFC
Dialogs.py
LDViewer.py
PLCControler.py
PLCGenerator.py
PLCOpenEditor.py
RessourceEditor.py
SFCViewer.py
TextViewer.py
Viewer.py
examples/example.xml
graphics/GraphicCommons.py
graphics/LD_Objects.py
graphics/SFC_Objects.py
--- a/Dialogs.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/Dialogs.py	Mon Aug 27 17:37:50 2007 +0200
@@ -296,24 +296,25 @@
         dc = wx.ClientDC(self.Preview)
         dc.Clear()
         item = self.TypeTree.GetSelection()
-        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(), inputs = pydata["inputs"])
-                width, height = self.MinBlockSize
-                min_width, min_height = self.Block.GetMinSize()
-                width, height = max(min_width, width), max(min_height, height)
-                self.Block.SetSize(width, height)
-                clientsize = self.Preview.GetClientSize()
-                x = (clientsize.width - width) / 2
-                y = (clientsize.height - height) / 2
-                self.Block.SetPosition(x, y)
-                self.Block.Draw(dc)
+        if item.IsOk():
+            pydata = self.TypeTree.GetPyData(item)
+            if pydata["type"] == CATEGORY:
+                self.Block = None
             else:
-                self.Block = None
+                blocktype = self.TypeTree.GetItemText(item)
+                if blocktype:
+                    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)
+                    self.Block.SetSize(width, height)
+                    clientsize = self.Preview.GetClientSize()
+                    x = (clientsize.width - width) / 2
+                    y = (clientsize.height - height) / 2
+                    self.Block.SetPosition(x, y)
+                    self.Block.Draw(dc)
+                else:
+                    self.Block = None
 
     def OnPaint(self, event):
         if self.Block:
@@ -1363,10 +1364,11 @@
 
 [ID_TRANSITIONCONTENTDIALOG, ID_TRANSITIONCONTENTDIALOGSPACER, 
  ID_TRANSITIONCONTENTDIALOGREFERENCE, ID_TRANSITIONCONTENTDIALOGINLINE, 
- ID_TRANSITIONCONTENTDIALOGPREVIEW, ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1, 
- ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2, ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3, 
- ID_TRANSITIONCONTENTDIALOGSTATICTEXT1, ID_TRANSITIONCONTENTDIALOGSTATICTEXT2, 
-] = [wx.NewId() for _init_ctrls in range(10)]
+ ID_TRANSITIONCONTENTDIALOGPRIORITY, ID_TRANSITIONCONTENTDIALOGPREVIEW, 
+ ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1, ID_TRANSITIONCONTENTDIALOGRADIOBUTTON2, 
+ ID_TRANSITIONCONTENTDIALOGRADIOBUTTON3, ID_TRANSITIONCONTENTDIALOGSTATICTEXT1, 
+ ID_TRANSITIONCONTENTDIALOGSTATICTEXT2, ID_TRANSITIONCONTENTDIALOGSTATICTEXT3, 
+] = [wx.NewId() for _init_ctrls in range(12)]
 
 class TransitionContentDialog(wx.Dialog):
     def _init_coll_flexGridSizer1_Items(self, parent):
@@ -1388,6 +1390,8 @@
         parent.AddWindow(self.radioButton2, 0, border=0, flag=wx.GROW)
         parent.AddWindow(self.Inline, 0, border=0, flag=wx.GROW)
         parent.AddWindow(self.radioButton3, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.staticText3, 0, border=0, flag=wx.GROW)
+        parent.AddWindow(self.Priority, 0, border=0, flag=wx.GROW)
         parent.AddWindow(self.Spacer, 0, border=0, flag=wx.GROW)
     
     def _init_coll_LeftGridSizer_Growables(self, parent):
@@ -1405,7 +1409,7 @@
     def _init_sizers(self):
         self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
         self.MainSizer = wx.BoxSizer(wx.HORIZONTAL)
-        self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=7, vgap=5)
+        self.LeftGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=9, vgap=5)
         self.RightGridSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=5)
 
         self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
@@ -1421,9 +1425,9 @@
     def _init_ctrls(self, prnt):
         wx.Dialog.__init__(self, id=ID_TRANSITIONCONTENTDIALOG,
               name='ProjectDialog', parent=prnt, pos=wx.Point(376, 223),
-              size=wx.Size(350, 260), style=wx.DEFAULT_DIALOG_STYLE,
+              size=wx.Size(350, 300), style=wx.DEFAULT_DIALOG_STYLE,
               title='Edit transition')
-        self.SetClientSize(wx.Size(350, 260))
+        self.SetClientSize(wx.Size(350, 300))
 
         self.staticText1 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT1,
               label='Type:', name='staticText1', parent=self,
@@ -1433,6 +1437,10 @@
               label='Preview:', name='staticText2', parent=self,
               pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
 
+        self.staticText3 = wx.StaticText(id=ID_TRANSITIONCONTENTDIALOGSTATICTEXT3,
+              label='Priority:', name='staticText3', parent=self,
+              pos=wx.Point(0, 0), size=wx.Size(0, 17), style=0)
+        
         self.radioButton1 = wx.RadioButton(id=ID_TRANSITIONCONTENTDIALOGRADIOBUTTON1,
               label='Reference', name='radioButton1', parent=self,
               pos=wx.Point(0, 0), size=wx.Size(0, 24), style=0)
@@ -1463,6 +1471,11 @@
         if not self.Connection:
             self.radioButton3.Hide()
 
+        self.Priority = wx.SpinCtrl(id=ID_TRANSITIONCONTENTDIALOGPRIORITY,
+              name='Priority', parent=self, pos=wx.Point(0, 0),
+              size=wx.Size(0, 24), style=wx.SP_ARROW_KEYS, min=0)
+        self.Bind(wx.EVT_TEXT, self.OnPriorityChanged, id=ID_TRANSITIONCONTENTDIALOGPRIORITY)
+
         self.Preview = wx.Panel(id=ID_TRANSITIONCONTENTDIALOGPREVIEW,
               name='Preview', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL|wx.SIMPLE_BORDER)
@@ -1541,6 +1554,11 @@
         self.RefreshPreview()
         event.Skip()
 
+    def OnPriorityChanged(self, event):
+        self.Element.SetPriority(int(self.Priority.GetValue()))
+        self.RefreshPreview()
+        event.Skip()
+
     def SetTransitions(self, transitions):
         self.Reference.Append("")
         for transition in transitions:
@@ -1570,10 +1588,11 @@
             self.Reference.Enable(False)
             self.Inline.Enable(False)
             self.Element.SetType("connection")
+        self.Element.SetPriority(values["priority"])
         self.RefreshPreview()
         
     def GetValues(self):
-        values = {}
+        values = {"priority" : int(self.Priority.GetValue())}
         if self.radioButton1.GetValue():
             values["type"] = "reference"
             values["value"] = self.Reference.GetStringSelection()
--- a/LDViewer.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/LDViewer.py	Mon Aug 27 17:37:50 2007 +0200
@@ -188,56 +188,55 @@
     
     def loadInstance(self, instance, ids):
         Viewer.loadInstance(self, instance, ids)
-        if instance["type"] == "leftPowerRail":
-            element = self.FindElementById(instance["id"])
-            rung = Graphic_Group(self)
-            rung.SelectElement(element)
-            self.Rungs.append(rung)
-        elif instance["type"] == "rightPowerRail":
-            rungs = []
-            for connector in instance["connectors"]:
-                for link in connector["links"]:
+        if self.GetDrawingMode() != FREEDRAWING_MODE:
+            if instance["type"] == "leftPowerRail":
+                element = self.FindElementById(instance["id"])
+                rung = Graphic_Group(self)
+                rung.SelectElement(element)
+                self.Rungs.append(rung)
+            elif instance["type"] == "rightPowerRail":
+                rungs = []
+                for connector in instance["connectors"]:
+                    for link in connector["links"]:
+                        connected = self.FindElementById(link["refLocalId"])
+                        rung = self.FindRung(connected)
+                        if rung not in rungs:
+                            rungs.append(rung)
+                if len(rungs) > 1:
+                    raise "ValueError", "Ladder element with id %d is on more than one rung."%instance["id"]
+                element = self.FindElementById(instance["id"])
+                self.Rungs[rungs[0]].SelectElement(element)
+                for connector in element.GetConnectors():
+                    for wire, num in connector.GetWires():
+                        self.Rungs[rungs[0]].SelectElement(wire)
+                self.RefreshPosition(element)
+            elif instance["type"] in ["contact", "coil"]:
+                rungs = []
+                for link in instance["connectors"]["input"]["links"]:
                     connected = self.FindElementById(link["refLocalId"])
                     rung = self.FindRung(connected)
                     if rung not in rungs:
                         rungs.append(rung)
-            if len(rungs) > 1:
-                raise "ValueError", "Ladder element with id %d is on more than one rung."%instance["id"]
-            element = self.FindElementById(instance["id"])
-            self.Rungs[rungs[0]].SelectElement(element)
-            for connector in element.GetConnectors():
-                for wire, num in connector.GetWires():
+                if len(rungs) > 1:
+                    raise "ValueError", "Ladder element with id %d is on more than one rung."%instance["id"]
+                element = self.FindElementById(instance["id"])
+                self.Rungs[rungs[0]].SelectElement(element)
+                for wire, num in element.GetConnectors()["input"].GetWires():
                     self.Rungs[rungs[0]].SelectElement(wire)
-            if self.GetDrawingMode() != FREEDRAWING_MODE:
                 self.RefreshPosition(element)
-        elif instance["type"] in ["contact", "coil"]:
-            rungs = []
-            for link in instance["connectors"]["input"]["links"]:
-                connected = self.FindElementById(link["refLocalId"])
-                rung = self.FindRung(connected)
-                if rung not in rungs:
-                    rungs.append(rung)
-            if len(rungs) > 1:
-                raise "ValueError", "Ladder element with id %d is on more than one rung."%instance["id"]
-            element = self.FindElementById(instance["id"])
-            self.Rungs[rungs[0]].SelectElement(element)
-            for wire, num in element.GetConnectors()["input"].GetWires():
-                self.Rungs[rungs[0]].SelectElement(wire)
-            if self.GetDrawingMode() != FREEDRAWING_MODE:
-                self.RefreshPosition(element)
-        elif instance["type"] == "comment":
-            element = self.FindElementById(instance["id"])
-            pos = element.GetPosition()
-            i = 0
-            inserted = False
-            while i < len(self.RungComments) and not inserted: 
-                ipos = self.RungComments[i].GetPosition()
-                if pos[1] < ipos[1]:
-                    self.RungComments.insert(i, element)
-                    inserted = True
-                i += 1
-            if not inserted:
-                self.RungComments.append(element)
+            elif instance["type"] == "comment":
+                element = self.FindElementById(instance["id"])
+                pos = element.GetPosition()
+                i = 0
+                inserted = False
+                while i < len(self.RungComments) and not inserted: 
+                    ipos = self.RungComments[i].GetPosition()
+                    if pos[1] < ipos[1]:
+                        self.RungComments.insert(i, element)
+                        inserted = True
+                    i += 1
+                if not inserted:
+                    self.RungComments.append(element)
 
 #-------------------------------------------------------------------------------
 #                          Search Element functions
@@ -249,10 +248,13 @@
                 return i
         return None
 
-    def FindElement(self, pos):
-        if self.GetDrawingMode() == FREEDRAWING_MODE:
-            return Viewer.FindElement(self, pos)
+    def FindElement(self, pos, exclude_group = False):
+        if self.GetDrawingMode() == FREEDRAWING_MODE:
+            return Viewer.FindElement(self, pos, exclude_group)
         
+        if self.SelectedElement and not (exclude_group and isinstance(self.SelectedElement, Graphic_Group)):
+            if self.SelectedElement.HitTest(pos) or self.SelectedElement.TestHandle(pos) != (0, 0):
+                return self.SelectedElement
         elements = []
         for element in self.GetElements(sort_wires=True):
             if element.HitTest(pos) or element.TestHandle(pos) != (0, 0):
--- a/PLCControler.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/PLCControler.py	Mon Aug 27 17:37:50 2007 +0200
@@ -196,11 +196,15 @@
     
     # Return project pou names
     def GetProjectPouNames(self):
-        return [pou.getName() for pou in self.Project.getPous()]
+        if self.Project:
+            return [pou.getName() for pou in self.Project.getPous()]
+        return []
     
     # Return project pou names
     def GetProjectConfigNames(self):
-        return [config.getName() for config in self.Project.getConfigurations()]
+        if self.Project:
+            return [config.getName() for config in self.Project.getConfigurations()]
+        return []
     
     # Return project pou variables
     def GetProjectPouVariables(self, pou_name=None):
@@ -383,6 +387,7 @@
     def ProjectAddPou(self, name, pou_type, body_type):
         # Add the pou to project
         self.Project.appendPou(name, pou_type, body_type)
+        self.SetPouInterfaceReturnType(name, "BOOL")
         self.RefreshPouUsingTree()
         self.RefreshBlockTypes()
         self.BufferProject()
@@ -455,9 +460,15 @@
         pou = self.Project.getPou(old_name)
         pou.setName(new_name)
         # If pou is currently opened, change its name in the list of opened pous
-        if old_name in self.ElementsOpened:
-            idx = self.ElementsOpened.index(old_name)
-            self.ElementsOpened[idx] = new_name
+        for idx, element in enumerate(self.ElementsOpened):
+            words = element.split("::")
+            if words[0] in ["P","T","A"] and words[1] == old_name:
+                if words[0] == "P":
+                    self.ElementsOpened[idx] = self.ComputePouName(new_name)
+                elif words[0] == "T":
+                    self.ElementsOpened[idx] = self.ComputePouTransitionName(new_name, words[2])
+                else:
+                    self.ElementsOpened[idx] = self.ComputePouActionName(new_name, words[2])
         self.Project.updateElementName(old_name, new_name)
         self.RefreshPouUsingTree()
         self.RefreshBlockTypes()
@@ -491,7 +502,7 @@
             self.ElementsOpened[idx] = new_computedname
         self.BufferProject()
     
-    # Change the name of a pou action
+    # Change the name of a pou variable
     def ChangePouVariableName(self, pou_name, old_name, new_name):
         # Found the pou action corresponding to old name and change its name to new name
         pou = self.Project.getPou(pou_name)
@@ -509,7 +520,12 @@
         configuration.setName(new_name)
         # If configuration is currently opened, change its name in the list of opened elements
         for idx, element in enumerate(self.ElementsOpened):
-            self.ElementsOpened[idx] = element.replace(old_name, new_name)
+            words = element.split("::")
+            if words[0] in ["C","R"] and words[1] == old_name:
+                if words[0] == "C":
+                    self.ElementsOpened[idx] = self.ComputeConfigurationName(new_name)
+                else:
+                    self.ElementsOpened[idx] = self.ComputeConfigurationResourceName(new_name, words[2])
         self.BufferProject()
     
     # Change the name of a configuration resource
@@ -865,15 +881,14 @@
             if type == "function":
                 blocktypes = []
                 for category in BlockTypes[:-1]:
-                    if category["name"] != "SVGUI function blocks":
-                        cat = {"name" : category["name"], "list" : []}
-                        for block in category["list"]:
-                            if block["type"] == "function":
-                                cat["list"].append(block)
-                        if len(cat["list"]) > 0:
-                            blocktypes.append(cat)
+                    cat = {"name" : category["name"], "list" : []}
+                    for block in category["list"]:
+                        if block["type"] == "function":
+                            cat["list"].append(block)
+                    if len(cat["list"]) > 0:
+                        blocktypes.append(cat)
             else:
-                blocktypes = [category for category in BlockTypes[:-1] if category["name"] != "SVGUI function blocks"]
+                blocktypes = [category for category in BlockTypes[:-1]]
             if self.Project:
                 blocktypes.append({"name" : "User-defined POUs", "list": []})
                 for blocktype in BlockTypes[-1]["list"]:
@@ -887,6 +902,7 @@
         if self.CurrentElementEditing != None:
             if self.Project:
                 current_name = self.ElementsOpened[self.CurrentElementEditing]
+                print current_name
                 words = current_name.split("::")
                 if len(words) == 1:
                     name = current_name
@@ -898,10 +914,9 @@
                 type = None
             blocktypes = []
             for category in BlockTypes[:-1]:
-                if category["name"] != "SVGUI function blocks":
-                    for block in category["list"]:
-                        if block["type"] != "function":
-                            blocktypes.append(block["name"])
+                for block in category["list"]:
+                    if block["type"] != "function":
+                        blocktypes.append(block["name"])
             if self.Project:
                 for blocktype in BlockTypes[-1]["list"]:
                     if blocktype["name"] != name and not self.PouIsUsedBy(name, blocktype["name"]) and not (type == "function" and blocktype["type"] != "function"):
@@ -932,15 +947,17 @@
         names = []
         for pou_name in self.ElementsOpened:
             words = pou_name.split("::")
-            if len(words) == 1:
-                names.append(pou_name)
-            elif len(words) == 2:
+            if words[0] in ["P","C"]:
                 names.append(words[1])
             else:
                 names.append("%s-%s"%(words[1],words[2]))
         return names
     
     # Compute a pou transition name
+    def ComputePouName(self, pou):
+        return "P::%s" % pou
+    
+    # Compute a pou transition name
     def ComputePouTransitionName(self, pou, transition):
         return "T::%s::%s" % (pou, transition)
     
@@ -967,6 +984,10 @@
         return None
 
     # Open a pou transition by giving pou and transition names
+    def OpenPouEditing(self, pou):
+        return self.OpenElementEditing(self.ComputePouName(pou))
+
+    # Open a pou transition by giving pou and transition names
     def OpenPouTransitionEditing(self, pou, transition):
         return self.OpenElementEditing(self.ComputePouTransitionName(pou, transition))
 
@@ -983,8 +1004,8 @@
         return self.OpenElementEditing(self.ComputeConfigurationResourceName(config, resource))
 
     # Return if pou given by name is opened
-    def IsElementEditing(self, name):
-        return name in self.ElementsOpened
+    def IsPouEditing(self, pou):
+        return self.ComputePouName(pou) in self.ElementsOpened
 
     # Return if pou transition given by pou and transition names is opened
     def IsPouTransitionEditing(self, pou, transition):
@@ -995,45 +1016,49 @@
         return self.ComputePouActionName(pou, action) in self.ElementsOpened
 
     # Return if pou action given by configuration name is opened
-    def IsConfigurationEditing(self, pou):
+    def IsConfigurationEditing(self, config):
         return self.ComputeConfigurationName(config) in self.ElementsOpened
 
     # Return if pou action given by configuration and resource names is opened
-    def IsConfigurationResourceEditing(self, pou, resource):
+    def IsConfigurationResourceEditing(self, config, resource):
         return self.ComputeConfigurationResourceName(config, resource) in self.ElementsOpened
 
-    # Close current pou editing
+    # Close current element editing
     def CloseElementEditing(self):
         # Remove pou from list of pou opened
         self.ElementsOpened.pop(self.CurrentElementEditing)
-        # Update index of current pou editing
+        # Update index of current element editing
         if len(self.ElementsOpened) > 0:
             self.CurrentElementEditing = min(self.CurrentElementEditing, len(self.ElementsOpened) - 1)
         else:
             self.CurrentElementEditing = None
 
-    # Change current pou editing for pou given by name
+    # Change current element editing for pou given by name
     def ChangeElementEditing(self, name):
-        # Verify that pou is opened
+        # Verify that element is opened
         if name in self.ElementsOpened:
-            # Change current pou editing
+            # Change current element editing
             self.CurrentElementEditing = self.ElementsOpened.index(name)
             return self.CurrentElementEditing
         return None
-
-    # Change current pou editing for transition given by pou and transition names
+    
+    # Change current element editing for pou given by pou name
+    def ChangePouEditing(self, pou):
+        return self.ChangeElementEditing(self.ComputePouName(pou))
+
+    # Change current element editing for transition given by pou and transition names
     def ChangePouTransitionEditing(self, pou, transition):
         return self.ChangeElementEditing(self.ComputePouTransitionName(pou, transition))
 
-    # Change current pou editing for action given by pou and action names
+    # Change current element editing for action given by pou and action names
     def ChangePouActionEditing(self, pou, action):
         return self.ChangeElementEditing(self.ComputePouActionName(pou, action))
 
-    # Change current pou editing for action given by configuration name
+    # Change current element editing for configuration given by configuration name
     def ChangeConfigurationEditing(self, config):
         return self.ChangeElementEditing(self.ComputeConfigurationName(config))
 
-    # Change current pou editing for action given by configuration and resource names
+    # Change current element editing for resource given by configuration and resource names
     def ChangeConfigurationResourceEditing(self, config, resource):
         return self.ChangeElementEditing(self.ComputeConfigurationResourceName(config, resource))
 
@@ -1047,21 +1072,18 @@
         if self.CurrentElementEditing != None:
             name = self.ElementsOpened[self.CurrentElementEditing]
             words = name.split("::")
-            if len(words) == 1:
-                return self.Project.getPou(name)
-            else:
-                if words[0] in ['T', 'A']:
-                    pou = self.Project.getPou(words[1])
-                    if words[0] == 'T':
-                        return pou.getTransition(words[2])
-                    elif words[0] == 'A':
-                        return pou.getAction(words[2])
-                elif words[0] == 'C':
-                    result = self.Project.getConfiguration(words[1])
-                    return result
-                elif words[0] == 'R':
-                    result = self.Project.getConfigurationResource(words[1], words[2])
-                    return result
+            if words[0] == "P":
+                return self.Project.getPou(words[1])
+            if words[0] in ['T', 'A']:
+                pou = self.Project.getPou(words[1])
+                if words[0] == 'T':
+                    return pou.getTransition(words[2])
+                elif words[0] == 'A':
+                    return pou.getAction(words[2])
+            elif words[0] == 'C':
+                return self.Project.getConfiguration(words[1])
+            elif words[0] == 'R':
+                return self.Project.getConfigurationResource(words[1], words[2])
         return None
     
     # Return current pou editing name
@@ -1070,9 +1092,7 @@
         if self.CurrentElementEditing != None:
             name = self.ElementsOpened[self.CurrentElementEditing]
             words = name.split("::")
-            if len(words) == 1:
-                return name
-            elif len(words) == 2:
+            if words[0] in ["P","C"]:
                 return words[1]
             else:
                 return words[2]
@@ -1087,11 +1107,7 @@
         if self.CurrentElementEditing != None:
             name = self.ElementsOpened[self.CurrentElementEditing]
             words = name.split("::")
-            if len(words) == 1:
-                return self.GetPouType(name)
-            elif len(words) == 2:
-                return None
-            elif words[0] != "R":
+            if words[0] == "P":
                 return self.GetPouType(words[1])
         return None
 
@@ -1100,13 +1116,12 @@
         if self.CurrentElementEditing != None:
             name = self.ElementsOpened[self.CurrentElementEditing]
             words = name.split("::")
-            if len(words) == 1:
-                return self.GetPouBodyType(name)
-            else:
-                if words[0] == 'T':
-                    return self.GetTransitionBodyType(words[1], words[2])
-                elif words[0] == 'A':
-                    return self.GetActionBodyType(words[1], words[2])
+            if words[0] == "P":
+                return self.GetPouBodyType(words[1])
+            elif words[0] == 'T':
+                return self.GetTransitionBodyType(words[1], words[2])
+            elif words[0] == 'A':
+                return self.GetActionBodyType(words[1], words[2])
         return None
 
     # Return the variables of the current pou editing
@@ -1114,10 +1129,7 @@
         if self.CurrentElementEditing != None:
             current_name = self.ElementsOpened[self.CurrentElementEditing]
             words = current_name.split("::")
-            if len(words) == 1:
-                pou = self.Project.getPou(current_name)
-                return self.GetPouInterfaceVars(pou)
-            else:
+            if words[0] in ["P","T","A"]:
                 pou = self.Project.getPou(words[1])
                 return self.GetPouInterfaceVars(pou)
         return []
@@ -1127,8 +1139,8 @@
         if self.CurrentElementEditing != None:
             current_name = self.ElementsOpened[self.CurrentElementEditing]
             words = current_name.split("::")
-            if len(words) == 1:
-                pou = self.Project.getPou(current_name)
+            if words[0] == "P":
+                pou = self.Project.getPou(words[1])
                 return self.GetPouInterfaceReturnType(pou)
             elif words[0] == 'T':
                 return "BOOL"
@@ -1173,9 +1185,7 @@
         if self.CurrentElementEditing != None:
             current_name = self.ElementsOpened[self.CurrentElementEditing]
             words = current_name.split("::")
-            if len(words) == 1:
-                return self.GetProjectPouVariables(current_name)
-            else:
+            if words[0] in ["P","T","A"]:
                 return self.GetProjectPouVariables(words[1])
         return []
 
@@ -1345,6 +1355,11 @@
             elif isinstance(instance, plcopen.transition):
                 infos["type"] = "transition"
                 condition = instance.getConditionContent()
+                priority = instance.getPriority()
+                if priority == None:
+                    infos["priority"] = 0
+                else:
+                    infos["priority"] = priority
                 infos["condition_type"] = condition["type"]
                 infos["connectors"] = {"input":{},"output":{}}
                 infos["connectors"]["input"]["position"] = instance.connectionPointIn.getRelPosition()
@@ -1433,14 +1448,12 @@
     def GetCurrentPouVarValueType(self, varname):
         current_name = self.ElementsOpened[self.CurrentElementEditing]
         words = current_name.split("::")
-        if len(words) == 1:
-            pou = self.Project.getPou(current_name)
-        else:
+        if words[0] in ["P","T","A"]:
             pou = self.Project.getPou(words[1])
-        for type, varlist in pou.getVars():
-            for var in varlist.getVariable():
-                if var.getName() == varname:
-                    return var.getType()
+            for type, varlist in pou.getVars():
+                for var in varlist.getVariable():
+                    if var.getName() == varname:
+                        return var.getType()
         return ""
     
     def SetConnectionWires(self, connection, connector):
@@ -1475,9 +1488,7 @@
             if self.CurrentElementEditing != None:
                 name = self.ElementsOpened[self.CurrentElementEditing]
                 words = name.split("::")
-                if len(words) == 1:
-                    element.addPouVar(blocktype, blockname)
-                elif words[0] in ['T', 'A']:
+                if words[0] in ["P","T","A"]:
                     pou = self.Project.getPou(words[1])
                     pou.addPouVar(blocktype, blockname)    
         element.addInstance("block", block)
@@ -1823,6 +1834,11 @@
                 transition.setX(value)
             elif param == "y":
                 transition.setY(value)
+            elif param == "priority":
+                if value != 0:
+                    transition.setPriority(value)
+                else:
+                    transition.setPriority(None)
             elif param == "connectors":
                 input_connector = value["input"]
                 position = input_connector.GetRelPosition()
--- a/PLCGenerator.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/PLCGenerator.py	Mon Aug 27 17:37:50 2007 +0200
@@ -53,7 +53,6 @@
                 compute += "\n"
     return compute
 
-
 def GeneratePouProgram(pou_name):
     if not pouComputed.get(pou_name, True):
         pouComputed[pou_name] = True
@@ -468,7 +467,7 @@
                             steps.extend(self.ExtractConvergenceInputs(step, pou))
                 elif isinstance(instance, plcopen.simultaneousConvergence):
                     steps.extend(self.ExtractConvergenceInputs(instance, pou))
-            transition_infos = {"from": [], "to" : []}
+            transition_infos = {"priority": transition.getPriority(), "from": [], "to" : []}
             transitionValues = transition.getConditionContent()
             if transitionValues["type"] == "inline":
                 transition_infos["content"] = "\n    := %s;\n"%transitionValues["value"]
@@ -552,7 +551,10 @@
     def ComputeSFCTransition(self, transition):
         if transition in self.SFCNetworks["Transitions"].keys():
             transition_infos = self.SFCNetworks["Transitions"].pop(transition)
-            self.Program += "  TRANSITION FROM "
+            self.Program += "  TRANSITION"
+            if transition_infos["priority"] != None:
+                self.Program += " (PRIORITY := %d)"%transition_infos["priority"]
+            self.Program += " FROM "
             if len(transition_infos["from"]) > 1:
                 self.Program += "(%s)"%", ".join(transition_infos["from"])
             else:
--- a/PLCOpenEditor.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/PLCOpenEditor.py	Mon Aug 27 17:37:50 2007 +0200
@@ -64,10 +64,7 @@
     sys.exit()
 elif len(args) == 1:
     fileOpen = args[0]
-CWD = ""
-for path in sys.path:
-    if os.path.isfile(os.path.join(path, "PLCOpenEditor.py")):
-        CWD = path
+CWD = os.path.split(__file__)[0]
 
 [ID_PLCOPENEDITOR, ID_PLCOPENEDITORPROJECTTREE, 
  ID_PLCOPENEDITORSPLITTERWINDOW1, ID_PLCOPENEDITOREDITORPANEL,
@@ -352,17 +349,17 @@
         
         self.splitterWindow1 = wx.SplitterWindow(id=ID_PLCOPENEDITORSPLITTERWINDOW1,
               name='splitterWindow1', parent=self, point=wx.Point(0, 0),
-              size=wx.Size(-1, -1), style=wx.SP_3D)
+              size=wx.Size(0, 0), style=wx.SP_3D)
         self.splitterWindow1.SetNeedUpdating(True)
         self.splitterWindow1.SetMinimumPaneSize(1)
 
         self.EditorPanel = wx.Panel(id=ID_PLCOPENEDITOREDITORPANEL, 
               name='TabPanel', parent=self.splitterWindow1, pos=wx.Point(0, 0),
-              size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL)
+              size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
         
         self.TabsOpened = wx.Notebook(id=ID_PLCOPENEDITORTABSOPENED,
               name='TabsOpened', parent=self.EditorPanel, pos=wx.Point(0,
-              0), size=wx.Size(-1, -1), style=0)
+              0), size=wx.Size(0, 0), style=0)
         self.TabsOpened.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED,
               self.OnPouSelectedChanged, id=ID_PLCOPENEDITORTABSOPENED)
 
@@ -500,14 +497,18 @@
 
     def OnCloseFrame(self, event):
         if not self.Controler.ProjectIsSaved():
-            dialog = wx.MessageDialog(self, "There are changes, do you want to save?",  "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
+            dialog = wx.MessageDialog(self, "There are changes, do you want to save?", "Close Application", wx.YES_NO|wx.CANCEL|wx.ICON_QUESTION)
             answer = dialog.ShowModal()
             dialog.Destroy()
             if answer == wx.ID_YES:
                 self.SaveProject()
                 event.Skip()
             elif answer == wx.ID_NO:
+                self.Controler.Reset()
+                wx.CallAfter(self.Close)
                 event.Skip()
+            else:
+                event.Veto()
         else:
             event.Skip()
 
@@ -631,8 +632,6 @@
         event.Skip()
 
     def OnQuitMenu(self, event):
-        self.ToolBar.Reparent(self)
-        self.Controler.Reset()
         self.Close()
         event.Skip()
 
@@ -895,6 +894,7 @@
         if name == "Properties":
             self.ShowProperties()
         elif data in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE, ITEM_CONFIGURATION]:
+            idx = None
             if data == ITEM_CONFIGURATION:
                 idx = self.Controler.OpenConfigurationEditing(name)
                 if idx != None:
@@ -916,31 +916,33 @@
                 else:
                     idx = self.Controler.ChangeConfigurationResourceEditing(config_name, name)
             elif data == ITEM_POU:
-                idx = self.Controler.OpenElementEditing(name)
+                idx = self.Controler.OpenPouEditing(name)
                 if idx != None:
                     new_window = PouEditorPanel(self.TabsOpened, self, self.Controler, self.Controler.GetPouType(name), pou_name = name)
                     self.TabsOpened.AddPage(new_window, "")
                 else:
-                    idx = self.Controler.ChangeElementEditing(name)
+                    idx = self.Controler.ChangePouEditing(name)
             else:
-                parent = self.ProjectTree.GetItemParent(selected)
-                parent_name = self.ProjectTree.GetItemText(parent)
-                grandparent = self.ProjectTree.GetItemParent(parent)
-                grandparent_name = self.ProjectTree.GetItemText(grandparent)
+                item = self.ProjectTree.GetItemParent(selected)
+                item_type = self.ProjectTree.GetPyData(item)
+                while item_type != ITEM_POU:
+                    item = self.ProjectTree.GetItemParent(item)
+                    item_type = self.ProjectTree.GetPyData(item)
+                pou_name = self.ProjectTree.GetItemText(item)
                 if data == ITEM_TRANSITION:
-                    idx = self.Controler.OpenPouTransitionEditing(grandparent_name, name)
+                    idx = self.Controler.OpenPouTransitionEditing(pou_name, name)
                     if idx != None:
-                        new_window = PouEditorPanel(self.TabsOpened, self, self.Controler, "transition", pou_name = grandparent_name, transition_name = name)
+                        new_window = PouEditorPanel(self.TabsOpened, self, self.Controler, "transition", pou_name = pou_name, transition_name = name)
                         self.TabsOpened.AddPage(new_window, "")
                     else:
-                        idx = self.Controler.ChangePouTransitionEditing(grandparent_name, name)
+                        idx = self.Controler.ChangePouTransitionEditing(pou_name, name)
                 elif data == ITEM_ACTION:
-                    idx = self.Controler.OpenPouActionEditing(grandparent_name, name)
+                    idx = self.Controler.OpenPouActionEditing(pou_name, name)
                     if idx != None:
-                        new_window = PouEditorPanel(self.TabsOpened, self, self.Controler, "action", pou_name = grandparent_name, action_name = name)
+                        new_window = PouEditorPanel(self.TabsOpened, self, self.Controler, "action", pou_name = pou_name, action_name = name)
                         self.TabsOpened.AddPage(new_window, "")
                     else:
-                        idx = self.Controler.ChangePouActionEditing(grandparent_name, name)
+                        idx = self.Controler.ChangePouActionEditing(pou_name, name)
             if idx != None:
                 old_selected = self.TabsOpened.GetSelection()
                 if old_selected >= 0:
@@ -966,34 +968,48 @@
     def OnProjectTreeItemSelected(self, event):
         selected = event.GetItem()
         name = self.ProjectTree.GetItemText(selected)
-        if self.ProjectTree.GetItemParent(selected) == self.ProjectTree.GetRootItem() and name != "Properties":
-            if self.Controler.IsElementEditing(name):
-                idx = self.Controler.ChangeElementEditing(name)
-                if idx != None:
-                    self.TabsOpened.SetSelection(idx)
-                    self.RefreshFileMenu()
-                    self.RefreshEditMenu()
-                    self.RefreshToolBar()
-        else:
-            name = self.ProjectTree.GetItemText(selected)
-            parent = self.ProjectTree.GetItemParent(selected)
-            parent_name = self.ProjectTree.GetItemText(parent)
-            grandparent = self.ProjectTree.GetItemParent(parent)
-            grandparent_name = self.ProjectTree.GetItemText(grandparent)
-            if parent_name == "Transitions":
-                idx = self.Controler.ChangePouTransitionEditing(grandparent_name, name)
-                if idx != None:
-                    self.TabsOpened.SetSelection(idx)
-                    self.RefreshFileMenu()
-                    self.RefreshEditMenu()
-                    self.RefreshToolBar()
-            elif parent_name == "Action":
-                idx = self.Controler.ChangePouActionEditing(grandparent_name, name)
-                if idx != None:
-                    self.TabsOpened.SetSelection(idx)
-                    self.RefreshFileMenu()
-                    self.RefreshEditMenu()
-                    self.RefreshToolBar()
+        data = self.ProjectTree.GetPyData(selected)
+        if data in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE, ITEM_CONFIGURATION]:
+            idx = None
+            if data == ITEM_CONFIGURATION:
+                if self.Controler.IsConfigurationEditing(name):
+                    idx = self.Controler.ChangeConfigurationEditing(name)
+            elif data == ITEM_RESOURCE:
+                item = self.ProjectTree.GetItemParent(selected)
+                item_type = self.ProjectTree.GetPyData(item)
+                while item_type != ITEM_CONFIGURATION:
+                    item = self.ProjectTree.GetItemParent(item)
+                    item_type = self.ProjectTree.GetPyData(item)
+                config_name = self.ProjectTree.GetItemText(item)
+                if self.Controler.IsConfigurationResourceEditing(config_name, name):
+                    idx = self.Controler.ChangeConfigurationResourceEditing(config_name, name)
+            elif data == ITEM_POU:
+                if self.Controler.IsPouEditing(name):
+                    idx = self.Controler.ChangePouEditing(name)
+            else:
+                item = self.ProjectTree.GetItemParent(selected)
+                item_type = self.ProjectTree.GetPyData(item)
+                while item_type != ITEM_POU:
+                    item = self.ProjectTree.GetItemParent(item)
+                    item_type = self.ProjectTree.GetPyData(item)
+                pou_name = self.ProjectTree.GetItemText(item)
+                if data == ITEM_TRANSITION:
+                    if self.Controler.IsPouTransitionEditing(pou_name, name):
+                        idx = self.Controler.ChangePouTransitionEditing(pou_name, name)
+                elif data == ITEM_ACTION:
+                    if self.Controler.IsPouActionEditing(pou_name, name):
+                        idx = self.Controler.ChangePouActionEditing(pou_name, name)
+            if idx != None:
+                old_selected = self.TabsOpened.GetSelection()
+                if old_selected >= 0:
+                    self.TabsOpened.GetPage(old_selected).ResetBuffer()
+                self.TabsOpened.SetSelection(idx)
+                window = self.TabsOpened.GetPage(idx)
+                window.RefreshView()
+                self.RefreshTabsOpenedTitles()
+                self.RefreshFileMenu()
+                self.RefreshEditMenu()
+                self.RefreshToolBar()
         event.Skip()
 
     def RefreshProjectTree(self):
@@ -1066,6 +1082,7 @@
             self.TabsOpened.GetPage(selected).Refresh()
         self.RefreshTitle()
         self.RefreshEditMenu()
+        self.RefreshProjectTree()
         event.Skip()
     
     def OnRedoMenu(self, event):
@@ -1076,6 +1093,7 @@
             self.TabsOpened.GetPage(selected).Refresh()
         self.RefreshTitle()
         self.RefreshEditMenu()
+        self.RefreshProjectTree()
         event.Skip()
 
     def OnCutMenu(self, event):
@@ -1112,6 +1130,8 @@
         if dialog.ShowModal() == wx.ID_OK:
             values = dialog.GetValues()
             self.Controler.ProjectAddPou(values["pouName"], values["pouType"], values["language"])
+            self.RefreshTitle()
+            self.RefreshEditMenu()
             self.RefreshProjectTree()
         dialog.Destroy()
         event.Skip()
@@ -1129,6 +1149,8 @@
                         deleted = i
                 if deleted != None:
                     self.TabsOpened.DeletePage(i)
+                self.RefreshTitle()
+                self.RefreshEditMenu()
                 self.RefreshProjectTree()
                 self.RefreshToolBar()
             else:
@@ -1138,20 +1160,26 @@
         event.Skip()
 
     def OnAddConfigurationMenu(self, event):
-        dialog = wx.TextEntryDialog(self, "Enter configuration name:", "Create new configuration", "", wx.OK|wx.CANCEL)
+        dialog = ConfigurationNameDialog(self, "Please enter configuration name", "Add new configuration")
+        dialog.SetPouNames(self.Controler.GetProjectPouNames())
+        dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
         if dialog.ShowModal() == wx.ID_OK:
             value = dialog.GetValue()
             self.Controler.ProjectAddConfiguration(value)
+            self.RefreshTitle()
+            self.RefreshEditMenu()
             self.RefreshProjectTree()
         dialog.Destroy()
         event.Skip()
 
     def OnRemoveConfigurationMenu(self, event):
         configs = self.Controler.GetProjectConfigNames()
-        dialog = wx.SingleChoiceDialog(self, "Select Configuration to remove:", "Remove configuration", configs, wx.OK|wx.CANCEL)
+        dialog = wx.SingleChoiceDialog(self, "Please select a configuration", "Remove configuration", configs, wx.OK|wx.CANCEL)
         if dialog.ShowModal() == wx.ID_OK:
             selected = dialog.GetStringSelection()
             self.Controler.ProjectRemoveConfiguration(selected)
+            self.RefreshTitle()
+            self.RefreshEditMenu()
             self.RefreshProjectTree()
         event.Skip()
 
@@ -1166,6 +1194,8 @@
                 if dialog.ShowModal() == wx.ID_OK: 
                     values = dialog.GetValues()
                     self.Controler.ProjectAddPouTransition(pouname, values["transitionName"], values["language"])
+                    self.RefreshTitle()
+                    self.RefreshEditMenu()
                     self.RefreshProjectTree()
                 dialog.Destroy()
         event.Skip()
@@ -1180,6 +1210,8 @@
                 if dialog.ShowModal() == wx.ID_OK: 
                     selected = dialog.GetStringSelection()
                     self.Controler.ProjectRemovePouTransition(pouname, selected)
+                    self.RefreshTitle()
+                    self.RefreshEditMenu()
                     self.RefreshProjectTree()
                 dialog.Destroy()
         event.Skip()
@@ -1195,6 +1227,8 @@
                 if dialog.ShowModal() == wx.ID_OK:
                     values = dialog.GetValues()
                     self.Controler.ProjectAddPouAction(pouname, values["actionName"], values["language"])
+                    self.RefreshTitle()
+                    self.RefreshEditMenu()
                     self.RefreshProjectTree()
                 dialog.Destroy()
         event.Skip()
@@ -1209,6 +1243,8 @@
                 if dialog.ShowModal() == wx.ID_OK: 
                     selected = dialog.GetStringSelection()
                     self.Controler.ProjectRemovePouAction(pouname, selected)
+                    self.RefreshTitle()
+                    self.RefreshEditMenu()
                     self.RefreshProjectTree()
                 dialog.Destroy()
         event.Skip()
@@ -1217,10 +1253,14 @@
         selected = self.ProjectTree.GetSelection()
         if self.ProjectTree.GetPyData(selected) == ITEM_CONFIGURATION:
             config_name = self.ProjectTree.GetItemText(selected)
-            dialog = wx.TextEntryDialog(self, "Enter Resource name:", "Create new Resource", "", wx.OK|wx.CANCEL)
+            dialog = ResourceNameDialog(self, "Please enter resource name", "Add new resource")
+            dialog.SetPouNames(self.Controler.GetProjectPouNames())
+            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
             if dialog.ShowModal() == wx.ID_OK:
                 value = dialog.GetValue()
                 self.Controler.ProjectAddConfigurationResource(config_name, value)
+                self.RefreshTitle()
+                self.RefreshEditMenu()
                 self.RefreshProjectTree()
             dialog.Destroy()
         event.Skip()
@@ -1238,6 +1278,8 @@
             if dialog.ShowModal() == wx.ID_OK:
                 resource = dialog.GetStringSelection()
                 self.Controler.ProjectRemoveConfigurationResource(config_name, resource)
+                self.RefreshTitle()
+                self.RefreshEditMenu()
                 self.RefreshProjectTree()
             dialog.Destroy()
         event.Skip()
@@ -1867,6 +1909,108 @@
         return values
 
 #-------------------------------------------------------------------------------
+#                          Configuration Name Dialog
+#-------------------------------------------------------------------------------
+
+class ConfigurationNameDialog(wx.TextEntryDialog):
+
+    def __init__(self, parent, message, caption = "Please enter configuration name", defaultValue = "", 
+                       style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
+        wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
+        
+        self.PouNames = []
+        self.PouElementNames = []
+        
+        self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
+        
+    def OnOK(self, event):
+        config_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
+        if config_name == "":
+            message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif not TestIdentifier(config_name):
+            message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%config_name, "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif config_name.upper() in IEC_KEYWORDS:
+            message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%config_name, "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif config_name.upper() in self.PouNames:
+            message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%config_name, "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif config_name.upper() in self.PouElementNames:
+            message = wx.MessageDialog(self, "A pou has an element with \"%s\" for name. It can generate a conflict. Do you wish to continue?"%config_name, "Warning", wx.YES_NO|wx.ICON_EXCLAMATION)
+            result = message.ShowModal()
+            message.Destroy()
+            if result == wx.ID_YES:
+                self.EndModal(wx.ID_OK)
+        else:
+            self.EndModal(wx.ID_OK)
+
+    def SetPouNames(self, pou_names):
+        self.PouNames = [pou_name.upper() for pou_name in pou_names]
+    
+    def SetPouElementNames(self, pou_names):
+        self.PouElementNames = [pou_name.upper() for pou_name in pou_names]
+    
+    def GetValue(self):
+        return self.GetSizer().GetItem(1).GetWindow().GetValue()
+
+#-------------------------------------------------------------------------------
+#                          Resource Name Dialog
+#-------------------------------------------------------------------------------
+
+class ResourceNameDialog(wx.TextEntryDialog):
+
+    def __init__(self, parent, message, caption = "Please enter resource name", defaultValue = "", 
+                       style = wx.OK|wx.CANCEL|wx.CENTRE, pos = wx.DefaultPosition):
+        wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
+        
+        self.PouNames = []
+        self.PouElementNames = []
+        
+        self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId())
+        
+    def OnOK(self, event):
+        resource_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
+        if resource_name == "":
+            message = wx.MessageDialog(self, "You must type a name!", "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif not TestIdentifier(resource_name):
+            message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%resource_name, "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif resource_name.upper() in IEC_KEYWORDS:
+            message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%resource_name, "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif resource_name.upper() in self.PouNames:
+            message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%resource_name, "Error", wx.OK|wx.ICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif resource_name.upper() in self.PouElementNames:
+            message = wx.MessageDialog(self, "A pou has an element with \"%s\" for name. It can generate a conflict. Do you wish to continue?"%resource_name, "Warning", wx.YES_NO|wx.ICON_EXCLAMATION)
+            result = message.ShowModal()
+            message.Destroy()
+            if result == wx.ID_YES:
+                self.EndModal(wx.ID_OK)
+        else:
+            self.EndModal(wx.ID_OK)
+
+    def SetPouNames(self, pou_names):
+        self.PouNames = [pou_name.upper() for pou_name in pou_names]
+    
+    def SetPouElementNames(self, pou_names):
+        self.PouElementNames = [pou_name.upper() for pou_name in pou_names]
+    
+    def GetValue(self):
+        return self.GetSizer().GetItem(1).GetWindow().GetValue()
+
+#-------------------------------------------------------------------------------
 #                            Pou Editor Panel
 #-------------------------------------------------------------------------------
 
@@ -1904,7 +2048,7 @@
     def GetValue(self, row, col):
         if row < self.GetNumberRows():
             if col == 0:
-                return self.Parent.Values.index(self.data[row]) + 1
+                return self.data[row]["Number"]
             name = str(self.data[row].get(self.GetColLabelValue(col), ""))
             return name
     
@@ -2134,14 +2278,15 @@
     def _init_ctrls(self, prnt, element_type):
         wx.SplitterWindow.__init__(self, id=ID_POUEDITORPANEL,
               name='EditVariablePanel', parent=prnt, pos=wx.Point(0, 0),
-              size=wx.Size(-1, -1), style=wx.SP_3D)
+              size=wx.Size(0, 0), style=wx.SP_3D)
         self.SetNeedUpdating(True)
         self.SetMinimumPaneSize(1)
         
         if element_type == "config":
             self.Viewer = wx.Panel(id=ID_POUEDITORPANELVIEWER,
               name='ConfigPanel', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL)
+              size=wx.Size(0, 0), style=0)
+            self.Viewer.SetSizer(wx.BoxSizer(wx.VERTICAL))
             self.Viewer.ResetBuffer = lambda: None
             self.Viewer.RefreshView = lambda: None
         elif element_type == "resource":
@@ -2162,7 +2307,7 @@
         
         self.VariablePanel = wx.Panel(id=ID_POUEDITORPANELVIEWER,
               name='VariablePanel', parent=self, pos=wx.Point(0, 0),
-              size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL)
+              size=wx.Size(0, 0), style=wx.TAB_TRAVERSAL)
         
         self.staticText1 = wx.StaticText(id=ID_POUEDITORPANELSTATICTEXT1,
               label='Return Type:', name='staticText1', parent=self.VariablePanel,
@@ -2171,6 +2316,7 @@
         self.ReturnType = wx.Choice(id=ID_POUEDITORPANELRETURNTYPE,
               name='ReturnType', parent=self.VariablePanel, pos=wx.Point(0, 0),
               size=wx.Size(145, 24), style=0)
+        self.Bind(wx.EVT_CHOICE, self.OnReturnTypeChanged, id=ID_POUEDITORPANELRETURNTYPE)
 
         self.staticText2 = wx.StaticText(id=ID_POUEDITORPANELSTATICTEXT2,
               label='Class Filter:', name='staticText2', parent=self.VariablePanel,
@@ -2252,10 +2398,10 @@
         
         if pou_type in ["config", "resource"]:
             self.DefaultTypes = {"All" : "Global"}
-            self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No", "Edit" : "True"}
+            self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No", "Edit" : True}
         else:
             self.DefaultTypes = {"All" : "Local", "Interface" : "Input", "Variables" : "Local"}
-            self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No", "Edit" : "True"}
+            self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No", "Edit" : True}
         if pou_type in ["config", "resource"] or pou_type == "program":
             self.Table = VariableTable(self, [], ["#", "Name", "Class", "Type", "Location", "Initial Value", "Retain", "Constant"])
             if pou_type not in ["config", "resource"]:
@@ -2347,6 +2493,13 @@
                 self.Viewer.SetVariables(varlist)
                 self.Viewer.SetFunctions(self.Controler.GetBlockTypes())
     
+    def OnReturnTypeChanged(self, event):
+        self.Controler.SetPouInterfaceReturnType(self.PouName, self.ReturnType.GetStringSelection())
+        self.Controler.BufferProject()
+        self.Parent.RefreshTitle()
+        self.Parent.RefreshEditMenu()
+        event.Skip()
+    
     def OnClassFilter(self, event):
         self.Filter = self.FilterChoiceTransfer[self.ClassFilter.GetStringSelection()]
         self.RefreshTypeList()
@@ -2519,8 +2672,9 @@
         if len(self.Table.data) > 0:
             self.VariablesGrid.SetGridCursor(0, 1)
         data = []
-        for variable in self.Values:
+        for num, variable in enumerate(self.Values):
             if variable["Class"] in self.ClassList:
+                variable["Number"] = num + 1
                 data.append(variable)
         self.Table.SetData(data)
         self.Table.ResetView(self.VariablesGrid)
--- a/RessourceEditor.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/RessourceEditor.py	Mon Aug 27 17:37:50 2007 +0200
@@ -278,8 +278,7 @@
 
     def _init_ctrls(self, prnt):
         wx.Panel.__init__(self, id=ID_RESOURCEEDITOR, name='', parent=prnt,
-              pos=wx.Point(0, 0), size=wx.Size(-1, -1),
-              style=wx.SUNKEN_BORDER)
+              size=wx.Size(0, 0), style=wx.SUNKEN_BORDER)
         
         self.staticText1 = wx.StaticText(id=ID_RESOURCEEDITORSTATICTEXT1,
               label=u'Tasks:', name='staticText2', parent=self, pos=wx.Point(0,
--- a/SFCViewer.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/SFCViewer.py	Mon Aug 27 17:37:50 2007 +0200
@@ -46,7 +46,7 @@
     def CreateTransition(self, connector, next = None):
         previous = connector.GetParentBlock()
         id = self.GetNewId()
-        transition = SFC_Transition(self, "reference", "", id)
+        transition = SFC_Transition(self, "reference", "", 0, id)
         pos = connector.GetPosition(False)
         transition.SetPosition(pos.x, pos.y + SFC_WIRE_MIN_SIZE)
         transition_connectors = transition.GetConnectors()
@@ -384,7 +384,6 @@
             self.AddBlock(step)
             self.Controler.AddCurrentElementEditingStep(id)
             self.RefreshStepModel(step)
-            self.Parent.RefreshProjectTree()
             self.RefreshBuffer()
             self.RefreshScrollBars()
             self.Refresh()
@@ -439,7 +438,6 @@
                     self.SelectedElement.SetSelected(False)
                     self.SelectedElement = step
                     self.SelectedElement.SetSelected(True)
-                self.Parent.RefreshProjectTree()
                 self.RefreshBuffer()
                 self.RefreshScrollBars()
                 self.Refresh()
@@ -672,17 +670,28 @@
     
     def AddDivergenceBranch(self, divergence):
         if isinstance(divergence, SFC_Divergence):
-            type = divergence.GetType()
-            if type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
+            if self.GetDrawingMode() == FREEDRAWING_MODE:
                 divergence.AddBranch()
-                divergence_connectors = divergence.GetConnectors()
-                if type == SELECTION_DIVERGENCE:
-                    transition = self.CreateTransition(divergence_connectors["outputs"][-1])
-                    transition_connectors = transition.GetConnectors()
-                    previous = transition_connectors["output"]
-                else:
-                    previous = divergence_connectors["outputs"][-1]
-                step = self.CreateStep("Step", previous)
+            else:
+                type = divergence.GetType()
+                if type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]:
+                    divergence.AddBranch()
+                    divergence_connectors = divergence.GetConnectors()
+                    if type == SELECTION_DIVERGENCE:
+                        transition = self.CreateTransition(divergence_connectors["outputs"][-1])
+                        transition_connectors = transition.GetConnectors()
+                        previous = transition_connectors["output"]
+                    else:
+                        previous = divergence_connectors["outputs"][-1]
+                    step = self.CreateStep("Step", previous)
+            self.RefreshBuffer()
+            self.RefreshScrollBars()
+            self.Refresh()
+    
+    def RemoveDivergenceBranch(self, divergence):
+        if isinstance(divergence, SFC_Divergence):
+            if self.GetDrawingMode() == FREEDRAWING_MODE:
+                divergence.RemoveHandledBranch()
                 self.RefreshBuffer()
                 self.RefreshScrollBars()
                 self.Refresh()
@@ -844,8 +853,7 @@
                     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)
@@ -940,8 +948,7 @@
                 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)
@@ -976,8 +983,7 @@
                         self.DeleteDivergence(previous_block)
                     else:
                         previous_block.RefreshModel()
-            self.Parent.RefreshProjectTree()
-
+            
     def DeleteActionBlock(self, actionblock):
         if self.GetDrawingMode() == FREEDRAWING_MODE:
             Viewer.DeleteActionBlock(self, actionblock)
@@ -997,8 +1003,7 @@
             self.RefreshStepModel(step)
             step.RefreshOutputPosition()
             step.RefreshOutputModel(True)
-            self.Parent.RefreshProjectTree()
-
+            
     def DeleteWire(self, wire):
         if self.GetDrawingMode() == FREEDRAWING_MODE:
             Viewer.DeleteWire(self, wire)
--- a/TextViewer.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/TextViewer.py	Mon Aug 27 17:37:50 2007 +0200
@@ -92,7 +92,7 @@
 class TextViewer(wx.stc.StyledTextCtrl):
     
     def __init__(self, parent, window, controler):
-        wx.stc.StyledTextCtrl.__init__(self, parent, ID_TEXTVIEWER, style=0)
+        wx.stc.StyledTextCtrl.__init__(self, parent, ID_TEXTVIEWER, size=wx.Size(0, 0), style=0)
         
         self.CmdKeyAssign(ord('+'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMIN)
         self.CmdKeyAssign(ord('-'), wx.stc.STC_SCMOD_CTRL, wx.stc.STC_CMD_ZOOMOUT)
@@ -143,7 +143,6 @@
         self.SetModEventMask(wx.stc.STC_MOD_BEFOREINSERT|wx.stc.STC_MOD_BEFOREDELETE)
 
         self.Bind(wx.stc.EVT_STC_STYLENEEDED, self.OnStyleNeeded, id=ID_TEXTVIEWER)
-        
         if window and controler :
             self.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
             self.Bind(wx.stc.EVT_STC_DO_DROP, self.OnDoDrop, id=ID_TEXTVIEWER)
@@ -230,10 +229,10 @@
         self.SetText(new_text)
         new_cursor_pos = GetCursorPos(old_text, new_text)
         if new_cursor_pos != None:
-            self.SetSelection(new_cursor_pos, new_cursor_pos)
-            self.EnsureCaretVisible()
-        else:
-            self.SetSelection(old_cursor_pos, old_cursor_pos)
+            self.GotoPos(new_cursor_pos)
+        else:
+            self.GotoPos(old_cursor_pos)
+        self.ScrollToColumn(0)
         self.RefreshJumpList()
         self.EmptyUndoBuffer()
         self.DisableEvents = False
--- a/Viewer.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/Viewer.py	Mon Aug 27 17:37:50 2007 +0200
@@ -142,7 +142,8 @@
     
     # Create a new Viewer
     def __init__(self, parent, window, controler):
-        wx.ScrolledWindow.__init__(self, parent, style=wx.SUNKEN_BORDER | wx.HSCROLL | wx.VSCROLL)
+        wx.ScrolledWindow.__init__(self, parent, pos=wx.Point(0, 0), size=wx.Size(0, 0), 
+            style=wx.SUNKEN_BORDER | wx.HSCROLL | wx.VSCROLL)
         self._init_menus()
         # Adding a rubberband to Viewer
         self.rubberBand = RubberBand(drawingSurface=self)
@@ -384,6 +385,7 @@
         elif instance["type"] == "leftPowerRail":
             leftpowerrail = LD_PowerRail(self, LEFTRAIL, instance["id"], [True for i in range(len(instance["connectors"]))])
             leftpowerrail.SetPosition(instance["x"], instance["y"])
+            leftpowerrail.SetSize(instance["width"], instance["height"])
             self.AddBlock(leftpowerrail)
             connectors = leftpowerrail.GetConnectors()
             for i, connector in enumerate(instance["connectors"]):
@@ -391,6 +393,7 @@
         elif instance["type"] == "rightPowerRail":
             rightpowerrail = LD_PowerRail(self, RIGHTRAIL, instance["id"], [True for i in range(len(instance["connectors"]))])
             rightpowerrail.SetPosition(instance["x"], instance["y"])
+            rightpowerrail.SetSize(instance["width"], instance["height"])
             self.AddBlock(rightpowerrail)
             connectors = rightpowerrail.GetConnectors()
             for i, connector in enumerate(instance["connectors"]):
@@ -466,7 +469,7 @@
             if connectors["action"]:
                 connectors["action"].SetPosition(wx.Point(*instance["connectors"]["action"]["position"]))
         elif instance["type"] == "transition":
-            transition = SFC_Transition(self, instance["condition_type"], instance["condition"], instance["id"])
+            transition = SFC_Transition(self, instance["condition_type"], instance["condition"], instance["priority"], instance["id"])
             transition.SetPosition(instance["x"], instance["y"])
             self.AddBlock(transition)
             connectors = transition.GetConnectors()
@@ -700,47 +703,54 @@
     def OnNoModifierMenu(self, event):
         if self.SelectedElement and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorNegated(False)
+            self.RefreshBuffer()
         event.Skip()
     
     def OnNegatedMenu(self, event):
         if self.SelectedElement and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorNegated(True)
+            self.RefreshBuffer()
         event.Skip()
 
     def OnRisingEdgeMenu(self, event):
         if self.SelectedElement and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorEdge("rising")
+            self.RefreshBuffer()
         event.Skip()
 
     def OnFallingEdgeMenu(self, event):
         if self.SelectedElement and self.IsBlock(self.SelectedElement):
             self.SelectedElement.SetConnectorEdge("falling")
+            self.RefreshBuffer()
         event.Skip()
 
     def OnAddSegmentMenu(self, event):
-        if self.SelectedElement and self.IsBlock(self.SelectedElement):
+        if self.SelectedElement and self.IsWire(self.SelectedElement):
             self.SelectedElement.AddSegment()
         event.Skip()
 
     def OnDeleteSegmentMenu(self, event):
-        if self.SelectedElement and self.IsBlock(self.SelectedElement):
+        if self.SelectedElement and self.IsWire(self.SelectedElement):
             self.SelectedElement.DeleteSegment()
         event.Skip()
 
     def OnAddBranchMenu(self, event):
         if self.SelectedElement and self.IsBlock(self.SelectedElement):
             self.AddDivergenceBranch(self.SelectedElement)
+            self.RefreshBuffer()
         event.Skip()
 
     def OnDeleteBranchMenu(self, event):
         if self.SelectedElement and self.IsBlock(self.SelectedElement):
             self.RemoveDivergenceBranch(self.SelectedElement)
+            self.RefreshBuffer()
         event.Skip()
 
     def OnDeleteMenu(self, event):
         if self.SelectedElement:
             self.SelectedElement.Delete()
             self.SelectedElement = None
+            self.RefreshBuffer()
         event.Skip()
 
 #-------------------------------------------------------------------------------
@@ -813,7 +823,11 @@
             if self.Mode == MODE_SELECTION:
                 elements = self.SearchElements(self.rubberBand.GetCurrentExtent())
                 self.rubberBand.OnLeftUp(event, self.GetLogicalDC(), self.Scaling)
-                if len(elements) > 0:
+                if len(elements) == 1:
+                    self.SelectedElement = elements[0]
+                    self.SelectedElement.SetSelected(True)
+                    self.Refresh()
+                elif len(elements) > 1:
                     self.SelectedElement = Graphic_Group(self)
                     self.SelectedElement.SetElements(elements)
                     self.SelectedElement.SetSelected(True)
@@ -869,7 +883,8 @@
         event.Skip()
     
     def OnViewerRightUp(self, event):
-        pos = event.GetPosition()
+        dc = self.GetLogicalDC()
+        pos = event.GetLogicalPosition(dc)
         element = self.FindElement(pos)
         if element:
             if self.SelectedElement and self.SelectedElement != element:
@@ -1186,7 +1201,7 @@
         if dialog.ShowModal() == wx.ID_OK:
             id = self.GetNewId()
             values = dialog.GetValues()
-            transition = SFC_Transition(self, values["type"], values["value"], id)
+            transition = SFC_Transition(self, values["type"], values["value"], values["priority"], 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))
@@ -1397,11 +1412,12 @@
     def EditTransitionContent(self, transition):
         dialog = TransitionContentDialog(self.Parent, self.GetDrawingMode() == FREEDRAWING_MODE)
         dialog.SetTransitions(self.Controler.GetCurrentElementEditingTransitions())
-        dialog.SetValues({"type":transition.GetType(),"value":transition.GetCondition()})
+        dialog.SetValues({"type":transition.GetType(),"value":transition.GetCondition(), "priority":transition.GetPriority()})
         dialog.SetElementSize(transition.GetSize())
         if dialog.ShowModal() == wx.ID_OK:
             values = dialog.GetValues()
             transition.SetType(values["type"],values["value"])
+            transition.SetPriority(values["priority"])
             transition.RefreshModel()
             self.RefreshBuffer()
             self.RefreshScrollBars()
@@ -1521,6 +1537,7 @@
         transitionid = transition.GetId()
         infos = {}
         infos["type"] = transition.GetType()
+        infos["priority"] = transition.GetPriority()
         infos["condition"] = transition.GetCondition()
         infos["x"], infos["y"] = transition.GetPosition()
         infos["width"], infos["height"] = transition.GetSize()
@@ -1710,6 +1727,7 @@
 #-------------------------------------------------------------------------------
 
     def OnMoveWindow(self, event):
+        self.GetBestSize()
         self.RefreshScrollBars()
         event.Skip()
 
--- a/examples/example.xml	Thu Aug 23 09:50:35 2007 +0200
+++ b/examples/example.xml	Mon Aug 27 17:37:50 2007 +0200
@@ -118,7 +118,7 @@
               </inputVariables>
               <inOutVariables/>
               <outputVariables>
-                <variable formalParameter="OUT" negated="true">
+                <variable formalParameter="OUT">
                   <connectionPointOut>
                     <relPosition y="36" x="99"/>
                   </connectionPointOut>
@@ -174,7 +174,7 @@
             <block localId="11" height="97" width="105" instanceName="SR1" typeName="SR">
               <position y="159" x="418"/>
               <inputVariables>
-                <variable formalParameter="S1">
+                <variable formalParameter="S1" negated="true">
                   <connectionPointIn>
                     <relPosition y="39" x="0"/>
                     <connection refLocalId="6" formalParameter="OUT">
@@ -245,10 +245,10 @@
             </comment>
             <leftPowerRail localId="2" height="80" width="2">
               <position y="60" x="10"/>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="20" x="2"/>
               </connectionPointOut>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="60" x="2"/>
               </connectionPointOut>
             </leftPowerRail>
@@ -542,10 +542,10 @@
               <LD>
                 <leftPowerRail localId="1" height="98" width="2">
                   <position y="20" x="31"/>
-                  <connectionPointOut formalParameter="">
+                  <connectionPointOut formalParameter="None">
                     <relPosition y="20" x="2"/>
                   </connectionPointOut>
-                  <connectionPointOut formalParameter="">
+                  <connectionPointOut formalParameter="None">
                     <relPosition y="64" x="2"/>
                   </connectionPointOut>
                 </leftPowerRail>
@@ -625,7 +625,7 @@
           <SFC>
             <step localId="1" height="31" width="46" initialStep="true" name="Start">
               <position y="46" x="82"/>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="31" x="23"/>
               </connectionPointOut>
             </step>
@@ -654,10 +654,10 @@
                   <position y="104" x="105"/>
                 </connection>
               </connectionPointIn>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="27" x="14"/>
               </connectionPointOut>
-              <connectionPointOutAction formalParameter="">
+              <connectionPointOutAction formalParameter="None">
                 <relPosition y="13" x="29"/>
               </connectionPointOutAction>
             </step>
@@ -670,13 +670,13 @@
                   <position y="156" x="105"/>
                 </connection>
               </connectionPointIn>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="1" x="0"/>
               </connectionPointOut>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="1" x="228"/>
               </connectionPointOut>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="1" x="391"/>
               </connectionPointOut>
             </selectionDivergence>
@@ -693,7 +693,7 @@
                 <relPosition y="2" x="10"/>
               </connectionPointOut>
               <condition>
-                <inline name="">
+                <inline name="None">
                   <ST><![CDATA[IN2 AND IN3]]></ST>
                 </inline>
               </condition>
@@ -707,11 +707,11 @@
                   <position y="237" x="105"/>
                 </connection>
               </connectionPointIn>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="27" x="24"/>
               </connectionPointOut>
             </step>
-            <transition localId="7" height="2" width="20">
+            <transition localId="7" height="2" priority="1" width="20">
               <position y="207" x="323"/>
               <connectionPointIn>
                 <relPosition y="0" x="10"/>
@@ -736,7 +736,7 @@
                   <position y="209" x="333"/>
                 </connection>
               </connectionPointIn>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="27" x="24"/>
               </connectionPointOut>
             </step>
@@ -765,10 +765,10 @@
                   <position y="209" x="496"/>
                 </connection>
               </connectionPointIn>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="27" x="24"/>
               </connectionPointOut>
-              <connectionPointOutAction formalParameter="">
+              <connectionPointOutAction formalParameter="None">
                 <relPosition y="13" x="48"/>
               </connectionPointOutAction>
             </step>
@@ -824,7 +824,7 @@
                 <relPosition y="2" x="10"/>
               </connectionPointOut>
               <condition>
-                <inline name="">
+                <inline name="None">
                   <ST><![CDATA[IN5]]></ST>
                 </inline>
               </condition>
@@ -842,7 +842,7 @@
                 <relPosition y="2" x="10"/>
               </connectionPointOut>
               <condition>
-                <inline name="">
+                <inline name="None">
                   <ST><![CDATA[IN5]]></ST>
                 </inline>
               </condition>
@@ -907,10 +907,10 @@
                   <position y="209" x="105"/>
                 </connection>
               </connectionPointIn>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="3" x="0"/>
               </connectionPointOut>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="3" x="118"/>
               </connectionPointOut>
             </simultaneousDivergence>
@@ -923,7 +923,7 @@
                   <position y="237" x="223"/>
                 </connection>
               </connectionPointIn>
-              <connectionPointOut formalParameter="">
+              <connectionPointOut formalParameter="None">
                 <relPosition y="27" x="24"/>
               </connectionPointOut>
             </step>
--- a/graphics/GraphicCommons.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/graphics/GraphicCommons.py	Mon Aug 27 17:37:50 2007 +0200
@@ -1543,7 +1543,7 @@
             Graphic_Element.OnLeftDown(self, event, dc, scaling)
         self.oldPos = pos
     
-    # Method called when a RightUp event have been generated
+    # Method called when a RightUp event has been generated
     def OnRightUp(self, event, dc, scaling):
         pos = GetScaledEventPosition(event, dc, scaling)
         # Test if a segment has been handled
@@ -1556,14 +1556,14 @@
             # Execute the default method for a graphic element
             Graphic_Element.OnRightUp(self, event, dc, scaling)
     
-    # Method called when a LeftDClick event have been generated
+    # Method called when a LeftDClick event has been generated
     def OnLeftDClick(self, event, dc, scaling):
         self.ResetPoints()
         self.GeneratePoints()
         self.RefreshModel()
         self.Parent.RefreshBuffer()
         
-    # Method called when a Motion event have been generated
+    # Method called when a Motion event has been generated
     def OnMotion(self, event, dc, scaling):
         pos = GetScaledEventPosition(event, dc, scaling)
         if not event.Dragging():
--- a/graphics/LD_Objects.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/graphics/LD_Objects.py	Mon Aug 27 17:37:50 2007 +0200
@@ -103,7 +103,7 @@
     def InsertConnector(self, idx, connector = True):
         if connector:
             if self.Type == LEFTRAIL:
-                connector = Connector(self, "", "BOOL", wx.Point(2, 0), EAST)
+                connector = Connector(self, "", "BOOL", wx.Point(self.Size[0], 0), EAST)
             elif self.Type == RIGHTRAIL:
                 connector = Connector(self, "", "BOOL", wx.Point(0, 0), WEST)
             self.Connectors.insert(idx, connector)
@@ -120,15 +120,19 @@
         maxy = 0
         for connect in self.Connectors:
             connect_pos = connect.GetRelPosition()
-            miny = min(miny, connect_pos.y)
-            maxy = max(maxy, connect_pos.y)
-        min_pos = self.Pos.y + miny - self.Extensions[0]
+            miny = min(miny, connect_pos.y - self.Extensions[0])
+            maxy = max(maxy, connect_pos.y - self.Extensions[0])
+        min_pos = self.Pos.y + miny
         self.Pos.y = min(min_pos, self.Pos.y)
         if min_pos == self.Pos.y:
             for connect in self.Connectors:
                 connect_pos = connect.GetRelPosition()
-                connect.SetPosition(wx.Point(connect_pos.x, connect_pos.y - miny + self.Extensions[0]))
-        self.Size[1] = max(maxy - miny + self.Extensions[0] + self.Extensions[1], self.Size[1])
+                connect.SetPosition(wx.Point(connect_pos.x, connect_pos.y - miny))
+        maxy = 0
+        for connect in self.Connectors:
+            connect_pos = connect.GetRelPosition()
+            maxy = max(maxy, connect_pos.y)
+        self.Size[1] = max(maxy + self.Extensions[1], self.Size[1])
         connector.MoveConnected()
         self.RefreshBoundingBox()
     
@@ -154,13 +158,19 @@
     def RefreshConnectors(self):
         if self.Parent.GetDrawingMode() == FREEDRAWING_MODE:
             height = self.Size[1] - self.Extensions[0] - self.Extensions[1]
+            interval = float(height) / float(max(len(self.Connectors) - 1, 1))
             for i, connector in enumerate(self.Connectors):
                 position = connector.GetRelPosition()
-                if self.RealConnectors:
-                    if self.Type == LEFTRAIL:
+                if self.Type == LEFTRAIL:
+                    if self.RealConnectors:
                         connector.SetPosition(wx.Point(self.Size[0], self.Extensions[0] + int(round(self.RealConnectors[i] * height))))
-                    elif self.Type == RIGHTRAIL:
+                    else:
+                        connector.SetPosition(wx.Point(self.Size[0], self.Extensions[0] + int(round(i * height))))
+                elif self.Type == RIGHTRAIL:
+                    if self.RealConnectors:
                         connector.SetPosition(wx.Point(0, self.Extensions[0] + int(round(self.RealConnectors[i] * height))))
+                    else:
+                        connector.SetPosition(wx.Point(0, self.Extensions[0] + int(round(i * height))))
         else:
             position = self.Extensions[0]
             for connector in self.Connectors:
@@ -237,7 +247,6 @@
             for connector in self.Connectors:
                 position = connector.GetRelPosition()
                 self.RealConnectors.append(float(position.y - self.Extensions[0])/float(max(1, height)))
-            print self.RealConnectors
             Graphic_Element.OnLeftDown(self, event, dc, scaling)
     
     # Method called when a LeftUp event have been generated
@@ -246,13 +255,12 @@
         handle_type, handle = self.Handle
         if handle_type == HANDLE_CONNECTOR:
             wires = handle.GetWires()
-            if len(wires) != 1:
-                return
-            if handle == wires[0][0].StartConnected:
-                block = wires[0][0].EndConnected.GetParentBlock()
-            else:
-                block = wires[0][0].StartConnected.GetParentBlock()
-            block.RefreshModel(False)
+            if len(wires) == 1:
+                if handle == wires[0][0].StartConnected:
+                    block = wires[0][0].EndConnected.GetParentBlock()
+                else:
+                    block = wires[0][0].StartConnected.GetParentBlock()
+                block.RefreshModel(False)
         Graphic_Element.OnLeftUp(self, event, dc, scaling)
     
     # Method called when a LeftDClick event have been generated
--- a/graphics/SFC_Objects.py	Thu Aug 23 09:50:35 2007 +0200
+++ b/graphics/SFC_Objects.py	Mon Aug 27 17:37:50 2007 +0200
@@ -436,15 +436,17 @@
 class SFC_Transition(Graphic_Element):
     
     # Create a new transition
-    def __init__(self, parent, type = "reference", condition = None, id = None):
+    def __init__(self, parent, type = "reference", condition = None, priority = 0, id = None):
         Graphic_Element.__init__(self, parent)
         self.Type = None
         self.Id = id
+        self.Priority = 0
         self.Size = wx.Size(SFC_TRANSITION_SIZE[0], SFC_TRANSITION_SIZE[1])
         # Create an input and output connector
         self.Input = Connector(self, "", "ANY", wx.Point(self.Size[0] / 2, 0), NORTH)
         self.Output = Connector(self, "", "ANY", wx.Point(self.Size[0] / 2, self.Size[1]), SOUTH)
         self.SetType(type, condition)
+        self.SetPriority(priority)
     
     # Destructor
     def __del__(self):
@@ -472,6 +474,14 @@
             else:
                 self.ConditionSize = dc.GetTextExtent("Transition")
     
+    # Refresh the size of text for name
+    def RefreshPrioritySize(self):
+        if self.Priority != "":
+            dc = wx.ClientDC(self.Parent)
+            self.PrioritySize = dc.GetTextExtent(str(self.Priority))
+        else:
+            self.PrioritySize = None
+
     # Delete this transition by calling the appropriate method
     def Delete(self):
         self.Parent.DeleteTransition(self)
@@ -486,18 +496,20 @@
     # Refresh the transition bounding box
     def RefreshBoundingBox(self):
         dc = wx.ClientDC(self.Parent)
+        bbx_x, bbx_y, bbx_width, bbx_height = self.Pos.x, self.Pos.y, self.Size[0], self.Size[1]
+        if self.Priority != 0:
+            bbx_y = self.Pos.y - self.PrioritySize[1] - 2
+            bbx_width = max(self.Size[0], self.PrioritySize[0])
+            bbx_height = self.Size[1] + self.PrioritySize[1] + 2
         if self.Type == "connection":
             bbx_x = self.Pos.x - CONNECTOR_SIZE
-            bbx_width = self.Size[0] + CONNECTOR_SIZE
-            bbx_y = self.Pos.y
-            bbx_height = self.Size[1]
+            bbx_width = bbx_width + CONNECTOR_SIZE
         else:
             text_width, text_height = self.ConditionSize
             # Calculate the bounding box size
-            bbx_x = self.Pos.x
-            bbx_width = self.Size[0] + 5 + text_width
-            bbx_y = self.Pos.y - max(0, (text_height - 5 - self.Size[1]) / 2)
-            bbx_height = max(self.Size[1], text_height) - 5
+            bbx_width = max(bbx_width, self.Size[0] + 5 + text_width)
+            bbx_y = min(bbx_y, self.Pos.y - max(0, (text_height - self.Size[1]) / 2))
+            bbx_height = max(bbx_height, self.Pos.y - bbx_y + (self.Size[1] + text_height) / 2)
         self.BoundingBox = wx.Rect(bbx_x, bbx_y, bbx_width + 1, bbx_height + 1)
         
     # Returns the connector connected to input
@@ -601,6 +613,16 @@
     def GetType(self):
         return self.Type
 
+    # Changes the transition priority
+    def SetPriority(self, priority):
+        self.Priority = priority
+        self.RefreshPrioritySize()
+        self.RefreshBoundingBox()
+        
+    # Returns the transition type
+    def GetPriority(self):
+        return self.Priority
+
     # Returns the transition condition
     def GetCondition(self):
         if self.Type != "connection":
@@ -719,6 +741,10 @@
                 condition = "Transition"
             dc.DrawText(condition, self.Pos.x + self.Size[0] + 5,
                         self.Pos.y + (self.Size[1] - text_height) / 2)
+        # Draw priority number
+        if self.Priority != 0:
+            priority_width, priority_height = self.PrioritySize
+            dc.DrawText(str(self.Priority), self.Pos.x, self.Pos.y - self.PrioritySize[1] - 2)
         # Draw input and output connectors
         self.Input.Draw(dc)
         self.Output.Draw(dc)
@@ -815,6 +841,13 @@
                 self.Inputs.remove(connector)
                 self.MoveConnector(self.Inputs[0], 0)
     
+    # Remove the handled branch from the divergence
+    def RemoveHandledBranch(self):
+        handle_type, handle = self.Handle
+        if handle_type == HANDLE_CONNECTOR:
+            handle.UnConnect(delete=True)
+            self.RemoveBranch(handle)
+            
     # Return the number of branches for the divergence
     def GetBranchNumber(self):
         if self.Type in [SELECTION_DIVERGENCE, SIMULTANEOUS_DIVERGENCE]: