Adding test on step names in SFC Editor
authorlbessard
Thu, 12 Apr 2007 17:26:07 +0200
changeset 9 b29105e29081
parent 8 7ceec5c40d77
child 10 112985848e1d
Adding test on step names in SFC Editor
Adding language icons into project tree
FBDViewer.py
Images/FBD.png
Images/IL.png
Images/LD.png
Images/SFC.png
Images/ST.png
Images/icons.svg
LDViewer.py
PLCOpenEditor.py
SFCViewer.py
plcopen/structures.py
--- a/FBDViewer.py	Wed Apr 11 17:26:07 2007 +0200
+++ b/FBDViewer.py	Thu Apr 12 17:26:07 2007 +0200
@@ -471,7 +471,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
         self.Name.SetValue("")
         self.Name.Enable(False)
@@ -670,7 +670,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
         self.Variable = None
         self.VarList = []
@@ -845,7 +845,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
         self.Connection = None
         self.MinConnectionSize = None
@@ -892,3 +892,4 @@
 
     def OnPaint(self, event):
         self.RefreshPreview()
+
Binary file Images/FBD.png has changed
Binary file Images/IL.png has changed
Binary file Images/LD.png has changed
Binary file Images/SFC.png has changed
Binary file Images/ST.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Images/icons.svg	Thu Apr 12 17:26:07 2007 +0200
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://web.resource.org/cc/"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="16"
+   height="16"
+   id="svg2"
+   sodipodi:version="0.32"
+   inkscape:version="0.45"
+   sodipodi:modified="TRUE"
+   version="1.0"
+   inkscape:export-filename="/taf/Pim/workspace_laurent/plcopeneditor/Images/SFC.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="31.678384"
+     inkscape:cx="7.9374999"
+     inkscape:cy="7.4758732"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer6"
+     width="16px"
+     height="16px"
+     showgrid="true"
+     inkscape:grid-points="true"
+     gridtolerance="50"
+     showguides="true"
+     inkscape:guide-bbox="true"
+     inkscape:window-width="1272"
+     inkscape:window-height="937"
+     inkscape:window-x="0"
+     inkscape:window-y="0" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1">
+    <path
+       style="opacity:1;color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 0,0 L 0,16 L 16,16 L 16,0 L 0,0 z M 1,1 L 15,1 L 15,15 L 1,15 L 1,1 z "
+       id="rect2160"
+       sodipodi:nodetypes="cccccccccc" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="ST"
+     style="display:none">
+    <text
+       xml:space="preserve"
+       style="font-size:10.35983276px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;font-family:Bitstream Vera Sans"
+       x="1.3590535"
+       y="11.606757"
+       id="text3137"
+       transform="scale(0.9794545,1.0209765)"><tspan
+         sodipodi:role="line"
+         id="tspan3139"
+         x="1.3590535"
+         y="11.606757">ST</tspan></text>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer4"
+     inkscape:label="FBD"
+     style="display:none">
+    <path
+       style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 3,3 L 3,4 L 2,4 L 2,5 L 3,5 L 3,7 L 7,7 L 7,5 L 8,5 L 8,10 L 7,10 L 7,9 L 3,9 L 3,10 L 2,10 L 2,11 L 3,11 L 3,13 L 7,13 L 7,11 L 9,11 L 9,8 L 10,8 L 10,10 L 14,10 L 14,6 L 10,6 L 10,7 L 9,7 L 9,4 L 7,4 L 7,3 L 3,3 z M 4,4 L 6,4 L 6,6 L 4,6 L 4,4 z M 11,7 L 13,7 L 13,9 L 11,9 L 11,7 z M 4,10 L 6,10 L 6,12 L 4,12 L 4,10 z "
+       id="rect4119" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer5"
+     inkscape:label="LD"
+     style="display:none">
+    <path
+       style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 5,4 L 5,7 L 4,7 L 4,6 L 3,6 L 3,10 L 4,10 L 4,9 L 5,9 L 5,12 L 4,12 L 4,11 L 3,11 L 3,13 L 2,13 L 2,3 L 3,3 L 3,5 L 4,5 L 4,4 L 5,4 z "
+       id="path4154"
+       sodipodi:nodetypes="ccccccccccccccccccccc" />
+    <path
+       style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 6,4 L 6,7 L 7,7 L 7,6 L 8,6 L 8,10 L 7,10 L 7,9 L 6,9 L 6,12 L 7,12 L 7,11 L 9,11 L 9,6 L 9.5625,6 C 9.6339067,6.3274464 9.7824133,6.649006 10,7 L 11,7 C 10.189404,5.9684327 10.157836,5.0315673 11,4 L 10.125,4 C 9.8543812,4.3520909 9.6845473,4.6715671 9.59375,5 L 7,5 L 7,4 L 6,4 z "
+       id="path4156" />
+    <path
+       style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 14,3 L 14,8 L 13,8 L 13,6 L 12.4375,6 C 12.366093,6.3274464 12.217587,6.649006 12,7 L 11,7 C 11.810596,5.9684327 11.842164,5.0315673 11,4 L 11.875,4 C 12.145619,4.3520909 12.315453,4.6715671 12.40625,5 L 13,5 L 13,3 L 14,3 z "
+       id="path4167"
+       sodipodi:nodetypes="ccccccccccccc" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer6"
+     inkscape:label="SFC"
+     style="display:inline">
+    <path
+       style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;marker:none;stroke-miterlimit:4;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible"
+       d="M 2,14 L 7,14 L 7,11 L 5,11 L 5,10 L 6,10 L 6,9 L 5,9 L 5,8 L 11,8 L 11,9 L 10,9 L 10,10 L 11,10 L 11,11 L 9,11 L 9,14 L 14,14 L 14,11 L 12,11 L 12,10 L 13,10 L 13,9 L 12,9 L 12,7 L 8,7 L 8,5 L 10,5 L 10,2 L 5,2 L 5,5 L 7,5 L 7,7 L 4,7 L 4,9 L 3,9 L 3,10 L 4,10 L 4,11 L 2,11 L 2,14 z M 3,13 L 3,12 L 6,12 L 6,13 L 3,13 z M 6,4 L 6,3 L 9,3 L 9,4 L 6,4 z M 10,13 L 10,12 L 13,12 L 13,13 L 10,13 z "
+       id="path4188"
+       sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer3"
+     inkscape:label="IL"
+     style="display:none">
+    <text
+       xml:space="preserve"
+       style="font-size:10.82976246px;font-style:normal;font-weight:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;font-family:Bitstream Vera Sans"
+       x="2.9903469"
+       y="11.842409"
+       id="text4114"
+       transform="scale(0.9868675,1.0133073)"><tspan
+         sodipodi:role="line"
+         id="tspan4116"
+         x="2.9903469"
+         y="11.842409">IL</tspan></text>
+  </g>
+</svg>
--- a/LDViewer.py	Wed Apr 11 17:26:07 2007 +0200
+++ b/LDViewer.py	Thu Apr 12 17:26:07 2007 +0200
@@ -1241,7 +1241,7 @@
             self.Element = LD_Coil(self.Preview, COIL_NORMAL, "")
         self.Element.SetPosition((150 - LD_ELEMENT_SIZE[0]) / 2, (150 - LD_ELEMENT_SIZE[1]) / 2)
 
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
 
         EVT_PAINT(self, self.OnPaint)
--- a/PLCOpenEditor.py	Wed Apr 11 17:26:07 2007 +0200
+++ b/PLCOpenEditor.py	Thu Apr 12 17:26:07 2007 +0200
@@ -68,19 +68,6 @@
     fileOpen = args[0]
 CWD = sys.path[0]
 
-
-# Test if identifier is valid
-def TestIdentifier(identifier):
-     if identifier[0].isdigit():
-        return False
-     words = identifier.split('_')
-     for i, word in enumerate(words):
-         if len(word) == 0 and i != 0:
-             return False
-         if len(word) != 0 and not word.isalnum():
-             return False
-     return True
-
 [wxID_PLCOPENEDITOR, wxID_PLCOPENEDITORPROJECTTREE, 
  wxID_PLCOPENEDITORSPLITTERWINDOW1, wxID_PLCOPENEDITOREDITORPANEL,
  wxID_PLCOPENEDITORTABSOPENED, wxID_PLCOPENEDITORTOOLBAR,
@@ -393,6 +380,11 @@
     def __init__(self, parent):
         self._init_ctrls(parent)
         
+        self.TreeImageList = wxImageList(16, 16)
+        for language in LANGUAGES:
+            self.TreeImageList.Add(wxBitmap(os.path.join(CWD, 'Images/%s.png'%language)))
+        self.ProjectTree.SetImageList(self.TreeImageList)
+        
         self.Controler = PLCControler()
         
         if fileOpen:
@@ -406,46 +398,48 @@
         self.RefreshToolBar()
 
     def RefreshFileMenu(self):
-        if self.Controler.HasOpenedProject():
-            if self.TabsOpened.GetPageCount() > 0:
-                self.FileMenu.FindItemByPosition(2).Enable(True)
+        if self.FileMenu:
+            if self.Controler.HasOpenedProject():
+                if self.TabsOpened.GetPageCount() > 0:
+                    self.FileMenu.FindItemByPosition(2).Enable(True)
+                else:
+                    self.FileMenu.FindItemByPosition(2).Enable(False)
+                self.FileMenu.FindItemByPosition(3).Enable(True)
+                self.FileMenu.FindItemByPosition(5).Enable(True)
+                self.FileMenu.FindItemByPosition(6).Enable(True)
+                self.FileMenu.FindItemByPosition(7).Enable(True)
+                self.FileMenu.FindItemByPosition(9).Enable(True)
             else:
                 self.FileMenu.FindItemByPosition(2).Enable(False)
-            self.FileMenu.FindItemByPosition(3).Enable(True)
-            self.FileMenu.FindItemByPosition(5).Enable(True)
-            self.FileMenu.FindItemByPosition(6).Enable(True)
-            self.FileMenu.FindItemByPosition(7).Enable(True)
-            self.FileMenu.FindItemByPosition(9).Enable(True)
-        else:
-            self.FileMenu.FindItemByPosition(2).Enable(False)
-            self.FileMenu.FindItemByPosition(3).Enable(False)
-            self.FileMenu.FindItemByPosition(5).Enable(False)
-            self.FileMenu.FindItemByPosition(6).Enable(False)
-            self.FileMenu.FindItemByPosition(7).Enable(False)
-            self.FileMenu.FindItemByPosition(9).Enable(False)
+                self.FileMenu.FindItemByPosition(3).Enable(False)
+                self.FileMenu.FindItemByPosition(5).Enable(False)
+                self.FileMenu.FindItemByPosition(6).Enable(False)
+                self.FileMenu.FindItemByPosition(7).Enable(False)
+                self.FileMenu.FindItemByPosition(9).Enable(False)
 
     def RefreshEditMenu(self):
-        self.EditMenu.FindItemByPosition(1).Enable(False)
-        self.EditMenu.FindItemByPosition(2).Enable(False)
-        if self.Controler.HasOpenedProject():
-            if self.TabsOpened.GetPageCount() > 0:
-                self.EditMenu.FindItemByPosition(0).Enable(True)
+        if self.EditMenu:
+            self.EditMenu.FindItemByPosition(1).Enable(False)
+            self.EditMenu.FindItemByPosition(2).Enable(False)
+            if self.Controler.HasOpenedProject():
+                if self.TabsOpened.GetPageCount() > 0:
+                    self.EditMenu.FindItemByPosition(0).Enable(True)
+                else:
+                    self.EditMenu.FindItemByPosition(0).Enable(False)
+                self.EditMenu.FindItemByPosition(8).Enable(True)
+                self.EditMenu.FindItemByPosition(9).Enable(True)
             else:
                 self.EditMenu.FindItemByPosition(0).Enable(False)
-            self.EditMenu.FindItemByPosition(8).Enable(True)
-            self.EditMenu.FindItemByPosition(9).Enable(True)
-        else:
-            self.EditMenu.FindItemByPosition(0).Enable(False)
-            self.EditMenu.FindItemByPosition(8).Enable(False)
-            self.EditMenu.FindItemByPosition(9).Enable(False)
-        bodytype = self.Controler.GetCurrentElementEditingBodyType()
-        if bodytype in ["IL","ST"]:
-            self.EditMenu.FindItemByPosition(4).Enable(True)
-            self.EditMenu.FindItemByPosition(5).Enable(True)
-            self.EditMenu.FindItemByPosition(6).Enable(True)
-        else:
-            self.EditMenu.FindItemByPosition(4).Enable(False)
-            self.EditMenu.FindItemByPosition(5).Enable(False)
+                self.EditMenu.FindItemByPosition(8).Enable(False)
+                self.EditMenu.FindItemByPosition(9).Enable(False)
+            bodytype = self.Controler.GetCurrentElementEditingBodyType()
+            if bodytype in ["IL","ST"]:
+                self.EditMenu.FindItemByPosition(4).Enable(True)
+                self.EditMenu.FindItemByPosition(5).Enable(True)
+                self.EditMenu.FindItemByPosition(6).Enable(True)
+            else:
+                self.EditMenu.FindItemByPosition(4).Enable(False)
+                self.EditMenu.FindItemByPosition(5).Enable(False)
             self.EditMenu.FindItemByPosition(6).Enable(False)
 
     def OnNewProjectMenu(self, event):
@@ -1005,6 +999,8 @@
         else:
             root = self.ProjectTree.AddRoot(infos["name"])
         self.ProjectTree.SetPyData(root, infos["type"])
+        if infos["type"] == ITEM_POU:
+            self.ProjectTree.SetItemImage(root, LANGUAGES.index(self.Controler.GetPouBodyType(infos["name"])))
         item, root_cookie = self.ProjectTree.GetFirstChild(root)
         if len(infos["values"]) > 0:
             for values in infos["values"]:
@@ -1348,7 +1344,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
         
         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
@@ -1474,7 +1470,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
         
         for option in ["function","functionBlock","program"]:
@@ -1619,7 +1615,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
 
         for option in ["IL","ST","LD","FBD"]:
@@ -1735,7 +1731,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
 
         for option in ["IL","ST","LD","FBD"]:
@@ -2028,7 +2024,7 @@
 
     def __init__(self, parent, name, pou_type, filter = "All"):
         self._init_ctrls(parent, name)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
         self.Filter = filter
         self.FilterChoices = []
--- a/SFCViewer.py	Wed Apr 11 17:26:07 2007 +0200
+++ b/SFCViewer.py	Thu Apr 12 17:26:07 2007 +0200
@@ -329,7 +329,10 @@
 #-------------------------------------------------------------------------------
 
     def AddInitialStep(self, pos):
-        dialog = wxTextEntryDialog(self.Parent, "Add a new initial step", "Please enter step name", "", wxOK|wxCANCEL)
+        dialog = StepNameDialog(self.Parent, "Add a new initial step", "Please enter step name", "", wxOK|wxCANCEL)
+        dialog.SetPouNames(self.Controler.GetProjectPouNames())
+        dialog.SetVariables(self.Controler.GetCurrentElementEditingInterfaceVars())
+        dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)])
         if dialog.ShowModal() == wxID_OK:
             id = self.GetNewId()
             name = dialog.GetValue()
@@ -348,7 +351,10 @@
 
     def AddStep(self):
         if self.SelectedElement in self.Wires or isinstance(self.SelectedElement, SFC_Step):
-            dialog = wxTextEntryDialog(self.Parent, "Add a new step", "Please enter step name", "", wxOK|wxCANCEL)
+            dialog = StepNameDialog(self.Parent, "Add a new step", "Please enter step name", "", wxOK|wxCANCEL)
+            dialog.SetPouNames(self.Controler.GetProjectPouNames())
+            dialog.SetVariables(self.Controler.GetCurrentElementEditingInterfaceVars())
+            dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step)])
             if dialog.ShowModal() == wxID_OK:
                 name = dialog.GetValue()
                 if self.SelectedElement in self.Wires:
@@ -688,7 +694,10 @@
         dialog.Destroy()
 
     def EditStepContent(self, step):
-        dialog = wxTextEntryDialog(self.Parent, "Edit step name", "Please enter step name", step.GetName(), wxOK|wxCANCEL)
+        dialog = StepNameDialog(self.Parent, "Edit step name", "Please enter step name", step.GetName(), wxOK|wxCANCEL)
+        dialog.SetPouNames(self.Controler.GetProjectPouNames())
+        dialog.SetVariables(self.Controler.GetCurrentElementEditingInterfaceVars())
+        dialog.SetStepNames([block.GetName() for block in self.Blocks if isinstance(block, SFC_Step) and block.GetName() != step.GetName()])
         if dialog.ShowModal() == wxID_OK:
             value = dialog.GetValue()
             step.SetName(value)
@@ -1069,7 +1078,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
         
         EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
@@ -1221,7 +1230,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
         
         self.Divergence = None
@@ -1508,7 +1517,7 @@
 
     def __init__(self, parent):
         self._init_ctrls(parent)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL)
+        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
         self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
         
         self.DefaultValue = {"Qualifier" : "N", "Duration" : "", "Type" : "Action", "Value" : "", "Indicator" : ""}
@@ -1609,3 +1618,58 @@
                 action["indicator"] = data["Indicator"]
             values.append(action)
         return values
+
+
+#-------------------------------------------------------------------------------
+#                          Edit Step Name Dialog
+#-------------------------------------------------------------------------------
+
+class StepNameDialog(wxTextEntryDialog):
+
+    def __init__(self, parent, message, caption = "Please enter text", defaultValue = "", 
+                       style = wxOK|wxCANCEL|wxCENTRE, pos = wxDefaultPosition):
+        wx.TextEntryDialog.__init__(self, parent, message, caption, defaultValue, style, pos)
+        
+        self.PouNames = []
+        self.Variables = []
+        self.StepNames = []
+        
+        EVT_BUTTON(self, self.GetSizer().GetItem(3).GetSizer().GetAffirmativeButton().GetId(), self.OnOK)
+        
+    def OnOK(self, event):
+        step_name = self.GetSizer().GetItem(1).GetWindow().GetValue()
+        if step_name == "":
+            message = wxMessageDialog(self, "You must type a name!", "Error", wxOK|wxICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif not TestIdentifier(step_name):
+            message = wxMessageDialog(self, "\"%s\" is not a valid identifier!"%step_name, "Error", wxOK|wxICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif step_name.upper() in IEC_KEYWORDS:
+            message = wxMessageDialog(self, "\"%s\" is a keyword. It can't be used!"%step_name, "Error", wxOK|wxICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif step_name.upper() in self.PouNames:
+            message = wxMessageDialog(self, "A pou with \"%s\" as name exists!"%step_name, "Error", wxOK|wxICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif step_name.upper() in self.Variables:
+            message = wxMessageDialog(self, "A variable with \"%s\" as name exists!"%step_name, "Error", wxOK|wxICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        elif step_name.upper() in self.StepNames:
+            message = wxMessageDialog(self, "\"%s\" step already exists!"%step_name, "Error", wxOK|wxICON_ERROR)
+            message.ShowModal()
+            message.Destroy()
+        else:
+            self.EndModal(wxID_OK)
+
+    def SetPouNames(self, pou_names):
+        self.PouNames = [pou_name.upper() for pou_name in pou_names]
+
+    def SetVariables(self, variables):
+        self.Variables = [var["Name"].upper() for var in variables]
+
+    def SetStepNames(self, step_names):
+        self.StepNames = [step_name.upper() for step_name in step_names]
--- a/plcopen/structures.py	Wed Apr 11 17:26:07 2007 +0200
+++ b/plcopen/structures.py	Thu Apr 12 17:26:07 2007 +0200
@@ -23,6 +23,8 @@
 #Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 
 
+LANGUAGES = ["IL","ST","FBD","LD","SFC"]
+
 #-------------------------------------------------------------------------------
 #                        Function Block Types definitions
 #-------------------------------------------------------------------------------
@@ -377,6 +379,24 @@
 
 
 #-------------------------------------------------------------------------------
+#                             Test identifier
+#-------------------------------------------------------------------------------
+
+
+
+# Test if identifier is valid
+def TestIdentifier(identifier):
+     if identifier[0].isdigit():
+        return False
+     words = identifier.split('_')
+     for i, word in enumerate(words):
+         if len(word) == 0 and i != 0:
+             return False
+         if len(word) != 0 and not word.isalnum():
+             return False
+     return True
+
+#-------------------------------------------------------------------------------
 #                            Languages Keywords
 #-------------------------------------------------------------------------------