PLCOpenEditor.py
changeset 80 c798a68c5560
parent 71 0578bc212c20
child 82 119b62c73085
--- 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)