Lots of bugs fixed
authorlbessard
Mon, 27 Aug 2007 17:37:50 +0200 (2007-08-27)
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]: