PLCOpenEditor.py
changeset 68 66308e07402c
parent 67 3a1b0afdaf84
child 70 0e48629c1e6d
--- a/PLCOpenEditor.py	Thu Aug 09 18:07:44 2007 +0200
+++ b/PLCOpenEditor.py	Fri Aug 10 16:14:33 2007 +0200
@@ -301,13 +301,9 @@
             self.FileMenu = wx.Menu(title=u'')
         else:
             self.FileMenu = None
-
         self.EditMenu = wx.Menu(title=u'')
-
         self.HelpMenu = wx.Menu(title='')
-
         self.SFCMenu = wx.Menu(title='')
-
         self.ConfigMenu = wx.Menu(title='')
 
         self._init_coll_menuBar1_Menus(self.menuBar1)
@@ -912,156 +908,6 @@
         data = self.ProjectTree.GetPyData(selected)
         if name == "Properties":
             self.ShowProperties()
-##        elif data == ITEM_CLASS:
-##            item = self.ProjectTree.GetItemParent(selected)
-##            item_type = self.ProjectTree.GetPyData(item)
-##            while item_type not in [ITEM_POU, ITEM_RESOURCE, ITEM_CONFIGURATION] and item.IsOk():
-##                item = self.ProjectTree.GetItemParent(item)
-##                item_type = self.ProjectTree.GetPyData(item)
-##            item_name = self.ProjectTree.GetItemText(item)
-##            if item_type == ITEM_POU:
-##                dialog = EditVariableDialog(self, item_name, self.Controler.GetPouType(item_name), self.Controler.PouIsUsed(item_name), name)
-##                dialog.SetPouNames(self.Controler.GetProjectPouNames())
-##                values = {}
-##                values["returnType"] = self.Controler.GetPouInterfaceReturnTypeByName(item_name)
-##                values["data"] = self.Controler.GetPouInterfaceVarsByName(item_name)
-##                dialog.SetValues(values)
-##                if dialog.ShowModal() == wx.ID_OK:
-##                    new_values = dialog.GetValues()
-##                    if "returnType" in new_values:
-##                        self.Controler.SetPouInterfaceReturnType(item_name, new_values["returnType"])
-##                    self.Controler.SetPouInterfaceVars(item_name, new_values["data"])
-##                    pou_names = self.Controler.GetElementsOpenedNames()
-##                    if item_name in pou_names:
-##                        window = self.TabsOpened.GetPage(pou_names.index(item_name))
-##                        if isinstance(window, TextViewer):
-##                            varlist = []
-##                            if "returnType" in new_values:
-##                                varlist.append(name)
-##                            for var in new_values["data"]:
-##                                varlist.append(var["Name"])
-##                            window.SetVariables(varlist)
-##                dialog.Destroy()
-##                self.RefreshProjectTree()
-##            elif item_type == ITEM_CONFIGURATION:
-##                dialog = EditVariableDialog(self, item_name, None, False, name)
-##                dialog.SetPouNames(self.Controler.GetProjectPouNames())
-##                values = {"data" : self.Controler.GetConfigurationGlobalVars(item_name)}
-##                dialog.SetValues(values)
-##                if dialog.ShowModal() == wx.ID_OK:
-##                    new_values = dialog.GetValues()
-##                    self.Controler.SetConfigurationGlobalVars(item_name, new_values["data"])
-##                dialog.Destroy()
-##                self.RefreshProjectTree()
-##            elif item_type == ITEM_RESOURCE:
-##                config = self.ProjectTree.GetItemParent(item)
-##                config_type = self.ProjectTree.GetPyData(config)
-##                while config_type != ITEM_CONFIGURATION and config.IsOk():
-##                    config = self.ProjectTree.GetItemParent(config)
-##                    config_type = self.ProjectTree.GetPyData(config)
-##                if config.IsOk():
-##                    config_name = self.ProjectTree.GetItemText(config)
-##                    dialog = EditVariableDialog(self, item_name, None, False, name)
-##                    values = {"data" : self.Controler.GetConfigurationResourceGlobalVars(config_name, item_name)}
-##                    dialog.SetValues(values)
-##                    if dialog.ShowModal() == wx.ID_OK:
-##                        new_values = dialog.GetValues()
-##                        self.Controler.SetConfigurationResourceGlobalVars(config_name, item_name, new_values["data"])
-##                    dialog.Destroy()
-##                    self.RefreshProjectTree()
-##        elif data in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION]:
-##            if data == ITEM_POU:
-##                idx = self.Controler.OpenElementEditing(name)
-##                language = self.Controler.GetPouBodyType(name)
-##                varlist = []
-##                returnType = self.Controler.GetPouInterfaceReturnTypeByName(name)
-##                if returnType:
-##                    varlist.append(name)
-##                vars = self.Controler.GetPouInterfaceVarsByName(name)
-##                if vars:
-##                    for var in vars:
-##                        varlist.append(var["Name"])
-##                self.EditVariable.SetPou(self.Controler.GetPouType(name), self.Controler.PouIsUsed(name))
-##                self.EditVariable.SetValues({"returnType":returnType,"data":vars})
-##            else:
-##                parent = self.ProjectTree.GetItemParent(selected)
-##                parent_name = self.ProjectTree.GetItemText(parent)
-##                grandparent = self.ProjectTree.GetItemParent(parent)
-##                grandparent_name = self.ProjectTree.GetItemText(grandparent)
-##                if data == ITEM_TRANSITION:
-##                    idx = self.Controler.OpenPouTransitionEditing(grandparent_name, name)
-##                    language = self.Controler.GetTransitionBodyType(grandparent_name, name)
-##                elif data == ITEM_ACTION:
-##                    idx = self.Controler.OpenPouActionEditing(grandparent_name, name)
-##                    language = self.Controler.GetActionBodyType(grandparent_name, name)
-##                varlist = [name]
-##                vars = self.Controler.GetPouInterfaceVarsByName(grandparent_name)
-##                if vars:
-##                    for var in vars:
-##                        varlist.append(var["Name"])
-##                self.EditVariable.SetPou(self.Controler.GetPouType(grandparent_name), self.Controler.PouIsUsed(grandparent_name))
-##                self.EditVariable.SetValues({"returnType":returnType,"data":vars})
-##            if idx != None:
-##                if language == "FBD":
-##                    new_window = Viewer(self.TabsOpened, self, self.Controler)
-##                elif language == "LD":
-##                    new_window = LD_Viewer(self.TabsOpened, self, self.Controler)
-##                elif language == "SFC":
-##                    new_window = SFC_Viewer(self.TabsOpened, self, self.Controler)
-##                elif language in ["IL", "ST"]:
-##                    new_window = TextViewer(self.TabsOpened, self, self.Controler)
-##                    new_window.SetTextSyntax(language)
-##                    if language == "IL":
-##                        new_window.SetKeywords(IL_KEYWORDS)
-##                    else:
-##                        new_window.SetKeywords(ST_KEYWORDS)
-##                    new_window.SetVariables(varlist)
-##                    new_window.SetFunctions(self.Controler.GetBlockTypes())
-##                else:
-##                    return
-##                new_window.RefreshView()
-##                self.TabsOpened.AddPage(new_window, "")
-##                self.TabsOpened.SetSelection(idx)
-##                self.RefreshTabsOpenedTitles()
-##                self.RefreshFileMenu()
-##                self.RefreshEditMenu()
-##                self.RefreshToolBar()
-##            else:
-##                if data == ITEM_POU:
-##                    idx = self.Controler.ChangeElementEditing(name)
-##                elif data == ITEM_TRANSITION:
-##                    idx = self.Controler.ChangePouTransitionEditing(grandparent_name, name)
-##                elif data == ITEM_ACTION:
-##                    idx = self.Controler.ChangePouActionEditing(grandparent_name, name)
-##                if idx != None:
-##                    self.TabsOpened.SetSelection(idx)
-##                    self.RefreshFileMenu()
-##                    self.RefreshEditMenu()
-##                    self.RefreshToolBar()
-##        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)
-##            idx = self.Controler.OpenConfigurationResourceEditing(config_name, name)
-##            if idx != None:
-##                new_window = ResourceEditor(self.TabsOpened, self, self.Controler)
-##                new_window.RefreshView()
-##                self.TabsOpened.AddPage(new_window, "")
-##                self.TabsOpened.SetSelection(idx)
-##                self.RefreshTabsOpenedTitles()
-##                self.RefreshFileMenu()
-##                self.RefreshEditMenu()
-##                self.RefreshToolBar()
-##            else:
-##                idx = self.Controler.ChangeConfigurationResourceEditing(parent_name, name)
-##                if idx != None:
-##                    self.TabsOpened.SetSelection(idx)
-##                    self.RefreshFileMenu()
-##                    self.RefreshEditMenu()
-##                    self.RefreshToolBar()
         elif data in [ITEM_POU, ITEM_TRANSITION, ITEM_ACTION, ITEM_RESOURCE, ITEM_CONFIGURATION]:
             if data == ITEM_CONFIGURATION:
                 idx = self.Controler.OpenConfigurationEditing(name)
@@ -1968,7 +1814,7 @@
         return values
 
 #-------------------------------------------------------------------------------
-#                            Pou Interface Dialog
+#                            Pou Editor Panel
 #-------------------------------------------------------------------------------
 
 class VariableTable(wx.grid.PyGridTableBase):
@@ -2009,9 +1855,6 @@
             name = str(self.data[row].get(self.GetColLabelValue(col), ""))
             return name
     
-    def GetValueByName(self, row, colname):
-        return self.data[row].get(colname)
-
     def SetValue(self, row, col, value):
         if col < len(self.colnames):
             colname = self.GetColLabelValue(col)
@@ -2019,6 +1862,14 @@
                 self.old_value = self.data[row][colname]
             self.data[row][colname] = value
     
+    def GetValueByName(self, row, colname):
+        if row < self.GetNumberRows():
+            return self.data[row].get(colname)
+
+    def SetValueByName(self, row, colname, value):
+        if row < self.GetNumberRows():
+            self.data[row][colname] = value
+
     def GetOldValue(self):
         return self.old_value
     
@@ -2077,37 +1928,34 @@
                 editor = None
                 renderer = None
                 colname = self.GetColLabelValue(col)
-                grid.SetReadOnly(row, col, False)
-                if col == 0:
-                    grid.SetReadOnly(row, col, True)
-                elif colname == "Name":
-                    if self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
-                        grid.SetReadOnly(row, col, True)
-                    else:
+                if col != 0 and self.GetValueByName(row, "Edit"):
+                    grid.SetReadOnly(row, col, False)
+                    if colname == "Name":
+                        if self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
+                            grid.SetReadOnly(row, col, True)
+                        else:
+                            editor = wx.grid.GridCellTextEditor()
+                            renderer = wx.grid.GridCellStringRenderer()
+                    elif colname in ["Initial Value","Location"]:
                         editor = wx.grid.GridCellTextEditor()
                         renderer = wx.grid.GridCellStringRenderer()
-                elif colname in ["Initial Value","Location"]:
-                    editor = wx.grid.GridCellTextEditor()
-                    renderer = wx.grid.GridCellStringRenderer()
-                elif colname == "Class":
-                    if len(self.Parent.ClassList) == 1 or self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
-                        grid.SetReadOnly(row, col, True)
-                    else:
+                    elif colname == "Class":
+                        if len(self.Parent.ClassList) == 1 or self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
+                            grid.SetReadOnly(row, col, True)
+                        else:
+                            editor = wx.grid.GridCellChoiceEditor()
+                            excluded = []
+                            if self.Parent.PouIsUsed:
+                                excluded.extend(["Input","Output","InOut"])    
+                            editor.SetParameters(",".join([choice for choice in self.Parent.ClassList if choice not in excluded]))
+                    elif colname in ["Retain", "Constant"]:
                         editor = wx.grid.GridCellChoiceEditor()
-                        excluded = []
-                        if self.Parent.PouIsUsed:
-                            excluded.extend(["Input","Output","InOut"])    
-                        editor.SetParameters(",".join([choice for choice in self.Parent.ClassList if choice not in excluded]))
-                elif colname == "Type":
-                    if self.Parent.PouIsUsed and self.GetValueByName(row, "Class") in ["Input", "Output", "InOut"]:
-                        grid.SetReadOnly(row, col, True)
-                    else:
-                        editor = wx.grid.GridCellChoiceEditor()
-                        editor.SetParameters(self.Parent.TypeList)
-                elif colname in ["Retain", "Constant"]:
-                    editor = wx.grid.GridCellChoiceEditor()
-                    editor.SetParameters(self.Parent.OptionList)
-                    
+                        editor.SetParameters(self.Parent.OptionList)
+                    elif colname == "Type":
+                        editor = wx.grid.GridCellTextEditor()
+                else:
+                    grid.SetReadOnly(row, col, True)
+                
                 grid.SetCellEditor(row, col, editor)
                 grid.SetCellRenderer(row, col, renderer)
                 
@@ -2177,15 +2025,7 @@
  ID_POUEDITORPANELSTATICTEXT2, ID_POUEDITORPANELSTATICTEXT3,
 ] = [wx.NewId() for _init_ctrls in range(12)]
 
-class PouEditorPanel(wx.Panel):
-    def _init_coll_MainPanelSizer_Items(self, parent):
-        parent.AddWindow(self.Viewer, 0, border=0, flag=wx.GROW)
-        parent.AddSizer(self.VariablePanelSizer, 0, border=0, flag=wx.GROW)
-
-    def _init_coll_MainPanelSizer_Growables(self, parent):
-        parent.AddGrowableCol(0)
-        parent.AddGrowableRow(0)
-    
+class PouEditorPanel(wx.SplitterWindow):
     def _init_coll_VariablePanelSizer_Items(self, parent):
         parent.AddWindow(self.VariablesGrid, 0, border=0, flag=wx.GROW)
         parent.AddSizer(self.ControlPanelSizer, 0, border=0, flag=wx.GROW)
@@ -2223,14 +2063,11 @@
         parent.AddGrowableRow(0)
 
     def _init_sizers(self):
-        self.MainPanelSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
         self.VariablePanelSizer = wx.FlexGridSizer(cols=2, hgap=10, rows=1, vgap=0)
         self.ControlPanelSizer = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=10)
         self.ChoicePanelSizer = wx.GridSizer(cols=1, hgap=5, rows=4, vgap=5)
         self.ButtonPanelSizer = wx.FlexGridSizer(cols=2, hgap=5, rows=2, vgap=0)
         
-        self._init_coll_MainPanelSizer_Items(self.MainPanelSizer)
-        self._init_coll_MainPanelSizer_Growables(self.MainPanelSizer)
         self._init_coll_VariablePanelSizer_Items(self.VariablePanelSizer)
         self._init_coll_VariablePanelSizer_Growables(self.VariablePanelSizer)
         self._init_coll_ControlPanelSizer_Items(self.ControlPanelSizer)
@@ -2239,16 +2076,18 @@
         self._init_coll_ButtonPanelSizer_Items(self.ButtonPanelSizer)
         self._init_coll_ButtonPanelSizer_Growables(self.ButtonPanelSizer)
         
-        self.SetSizer(self.MainPanelSizer)
+        self.VariablePanel.SetSizer(self.VariablePanelSizer)
 
     def _init_ctrls(self, prnt, element_type):
-        wx.Panel.__init__(self, id=ID_POUEDITORPANEL,
+        wx.SplitterWindow.__init__(self, id=ID_POUEDITORPANEL,
               name='EditVariablePanel', parent=prnt, pos=wx.Point(0, 0),
-              size=wx.Size(-1, -1), style=0)
+              size=wx.Size(-1, -1), 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),
+              name='ConfigPanel', parent=self.splitterWindow1, pos=wx.Point(0, 0),
               size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL)
             self.Viewer.ResetBuffer = lambda: None
             self.Viewer.RefreshView = lambda: None
@@ -2268,25 +2107,29 @@
             else:
                 self.Viewer.SetKeywords(ST_KEYWORDS)
         
+        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)
+        
         self.staticText1 = wx.StaticText(id=ID_POUEDITORPANELSTATICTEXT1,
-              label='Return Type:', name='staticText1', parent=self,
+              label='Return Type:', name='staticText1', parent=self.VariablePanel,
               pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0)
 
         self.ReturnType = wx.Choice(id=ID_POUEDITORPANELRETURNTYPE,
-              name='ReturnType', parent=self, pos=wx.Point(0, 0),
+              name='ReturnType', parent=self.VariablePanel, pos=wx.Point(0, 0),
               size=wx.Size(145, 24), style=0)
 
         self.staticText2 = wx.StaticText(id=ID_POUEDITORPANELSTATICTEXT2,
-              label='Class Filter:', name='staticText2', parent=self,
+              label='Class Filter:', name='staticText2', parent=self.VariablePanel,
               pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0)
 
         self.ClassFilter = wx.Choice(id=ID_POUEDITORPANELCLASSFILTER,
-              name='ClassFilter', parent=self, pos=wx.Point(0, 0),
+              name='ClassFilter', parent=self.VariablePanel, pos=wx.Point(0, 0),
               size=wx.Size(145, 24), style=0)
         self.Bind(wx.EVT_CHOICE, self.OnClassFilter, id=ID_POUEDITORPANELCLASSFILTER)
 
         self.VariablesGrid = wx.grid.Grid(id=ID_POUEDITORPANELVARIABLESGRID,
-              name='VariablesGrid', parent=self, pos=wx.Point(0, 0), 
+              name='VariablesGrid', parent=self.VariablePanel, pos=wx.Point(0, 0), 
               size=wx.Size(0, 150), style=wx.VSCROLL)
         self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
               'Sans'))
@@ -2295,29 +2138,31 @@
         self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
         self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridSelectCell)
         self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick)
-        
+        self.VariablesGrid.Bind(wx.grid.EVT_GRID_EDITOR_SHOWN, self.OnVariablesGridEditorShown)
         self.VariablesGrid.SetDropTarget(VariableDropTarget(self))
         
         self.AddButton = wx.Button(id=ID_POUEDITORPANELADDBUTTON, label='Add',
-              name='AddButton', parent=self, pos=wx.Point(345, 340),
+              name='AddButton', parent=self.VariablePanel, pos=wx.Point(345, 340),
               size=wx.Size(72, 32), style=0)
         self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_POUEDITORPANELADDBUTTON)
 
         self.DeleteButton = wx.Button(id=ID_POUEDITORPANELDELETEBUTTON, label='Delete',
-              name='DeleteButton', parent=self, pos=wx.Point(425, 340),
+              name='DeleteButton', parent=self.VariablePanel, pos=wx.Point(425, 340),
               size=wx.Size(72, 32), style=0)
         self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_POUEDITORPANELDELETEBUTTON)
 
         self.UpButton = wx.Button(id=ID_POUEDITORPANELUPBUTTON, label='^',
-              name='UpButton', parent=self, pos=wx.Point(505, 340),
+              name='UpButton', parent=self.VariablePanel, pos=wx.Point(505, 340),
               size=wx.Size(32, 32), style=0)
         self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_POUEDITORPANELUPBUTTON)
 
         self.DownButton = wx.Button(id=ID_POUEDITORPANELDOWNBUTTON, label='v',
-              name='DownButton', parent=self, pos=wx.Point(545, 340),
+              name='DownButton', parent=self.VariablePanel, pos=wx.Point(545, 340),
               size=wx.Size(32, 32), style=0)
         self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_POUEDITORPANELDOWNBUTTON)
 
+        self.SplitHorizontally(self.Viewer, self.VariablePanel, -200)
+
         self._init_sizers()
 
     def __init__(self, parent, window, controler, element_type, pou_name = None, transition_name = None, action_name = None, config_name = None, resource_name = None):
@@ -2354,23 +2199,23 @@
         
         if pou_type in ["config", "resource"]:
             self.DefaultTypes = {"All" : "Global"}
-            self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
+            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"}
+            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"])
+            self.Table = VariableTable(self, [], ["#", "Name", "Class", "Type", "Location", "Initial Value", "Retain", "Constant", "Edit"])
             if pou_type not in ["config", "resource"]:
                 self.FilterChoices = ["All","Interface","   Input","   Output","   InOut","   External","Variables","   Local","   Temp","Global","Access"]
             else:
                 self.FilterChoices = ["All","Global","Access"]
-            self.ColSizes = [40, 80, 70, 80, 80, 80, 60, 70]
-            self.ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER]
-        else:
-            self.Table = VariableTable(self, [], ["#", "Name", "Class", "Type", "Initial Value", "Retain", "Constant"])
+            self.ColSizes = [40, 80, 70, 80, 80, 80, 60, 70, 50]
+            self.ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER, wx.ALIGN_LEFT]
+        else:
+            self.Table = VariableTable(self, [], ["#", "Name", "Class", "Type", "Initial Value", "Retain", "Constant", "Edit"])
             self.FilterChoices = ["All","Interface","   Input","   Output","   InOut","   External","Variables","   Local","   Temp"]
-            self.ColSizes = [40, 120, 70, 80, 120, 60, 70]
-            self.ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER]
+            self.ColSizes = [40, 120, 70, 80, 120, 60, 70, 50]
+            self.ColAlignements = [wx.ALIGN_CENTER, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER, wx.ALIGN_LEFT]
         for choice in self.FilterChoices:
             self.ClassFilter.Append(choice)
         reverse_transfer = {}
@@ -2380,7 +2225,7 @@
         self.RefreshTypeList()
 
         self.OptionList = "Yes,No"
-        self.TypeList = ",".join([value for value, parent in TypeHierarchy_list if not value.startswith("ANY")])
+        self.TypeList = [value for value, parent in TypeHierarchy_list if not value.startswith("ANY")]
         
         if pou_type == "function":
             for value, parent in TypeHierarchy_list:
@@ -2424,10 +2269,21 @@
             self.PouIsUsed = self.Controler.PouIsUsed(self.PouName)
             returnType = self.Controler.GetCurrentElementEditingInterfaceReturnType()
             self.Values = self.Controler.GetCurrentElementEditingInterfaceVars()
+        
+        if returnType and self.ReturnType.IsEnabled():
+            self.ReturnType.SetStringSelection(returnType)
+        
+        self.RefreshValues()
+        self.RefreshViewerVarList()
+        self.RefreshButtons()
+        self.Viewer.RefreshView()
+    
+    def RefreshViewerVarList(self):
+        if self.ElementType not in ["config", "ressource"]:
             varlist = [var["Name"] for var in self.Values]
-            if self.ElementType == "transtion":
+            if self.ElementType == "transition":
                 language = self.Controler.GetTransitionBodyType(self.PouName, self.TransitionName)
-                varlist.append(self.ActionName)
+                varlist.append(self.TransitionName)
             elif self.ElementType == "action":
                 language = self.Controler.GetActionBodyType(self.PouName, self.ActionName)
                 varlist.append(self.ActionName)
@@ -2437,12 +2293,6 @@
             if language in ["IL", "ST"]:
                 self.Viewer.SetVariables(varlist)
                 self.Viewer.SetFunctions(self.Controler.GetBlockTypes())
-        
-        if returnType and self.ReturnType.IsEnabled():
-            self.ReturnType.SetStringSelection(returnType)
-        self.RefreshValues()
-        self.RefreshButtons()
-        self.Viewer.RefreshView()
     
     def OnClassFilter(self, event):
         self.Filter = self.FilterChoiceTransfer[self.ClassFilter.GetStringSelection()]
@@ -2480,6 +2330,7 @@
         else:
             new_row["Class"] = self.Filter
         self.Values.append(new_row)
+        self.SaveValues()
         self.RefreshValues()
         self.RefreshButtons()
         event.Skip()
@@ -2487,6 +2338,7 @@
     def OnDeleteButton(self, event):
         row = self.Table.GetRow(self.VariablesGrid.GetGridCursorRow())
         self.Values.remove(row)
+        self.SaveValues()
         self.RefreshValues()
         self.RefreshButtons()
         event.Skip()
@@ -2534,6 +2386,7 @@
                 self.Controler.BufferProject()
                 self.Parent.RefreshTitle()
                 self.Parent.RefreshEditMenu()
+                self.RefreshViewerVarList()
                 self.Viewer.RefreshView()
                 event.Skip()
         else:
@@ -2541,6 +2394,49 @@
             event.Skip()
 
     def OnVariablesGridCellLeftClick(self, event):
+        if event.GetCol() == "#":
+            row = event.GetRow()
+            var_name = self.Table.GetValueByName(row, "Name")
+            var_class = self.Table.GetValueByName(row, "Class")
+            var_type = self.Table.GetValueByName(row, "Type")
+            data = wx.TextDataObject(str((var_name, var_class, var_type)))
+            dragSource = wx.DropSource(self.VariablesGrid)
+            dragSource.SetData(data)
+            dragSource.DoDragDrop()
+        event.Skip()
+    
+    def OnVariablesGridEditorShown(self, event):
+        row, col = event.GetRow(), event.GetCol() 
+        if self.Table.GetColLabelValue(col) == "Type":
+            type_menu = wx.Menu(title='')
+            base_menu = wx.Menu(title='')
+            for base_type in self.TypeList:
+                new_id = wx.NewId()
+                base_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=base_type)
+                self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(base_type), id=new_id)
+            type_menu.AppendMenu(-1, "Base Types", base_menu, '')
+            functionblock_menu = wx.Menu(title='')
+            for functionblock_type in self.Controler.GetFunctionBlockTypes():
+                new_id = wx.NewId()
+                functionblock_menu.Append(help='', id=new_id, kind=wx.ITEM_NORMAL, text=functionblock_type)
+                self.Bind(wx.EVT_MENU, self.GetVariableTypeFunction(functionblock_type), id=new_id)
+            type_menu.AppendMenu(-1, "Function Block Types", functionblock_menu, '')
+            rect = self.VariablesGrid.BlockToDeviceRect((row, col), (row, col))
+            self.VariablesGrid.PopupMenuXY(type_menu, rect.x + rect.width, rect.y + self.VariablesGrid.GetColLabelSize())
+            event.Veto()
+        else:
+            event.Skip()
+    
+    def GetVariableTypeFunction(self, base_type):
+        def VariableTypeFunction(event):
+            row = self.VariablesGrid.GetGridCursorRow()
+            self.Table.SetValueByName(row, "Type", base_type)
+            self.SaveValues()
+            self.Table.ResetView(self.VariablesGrid)
+            event.Skip()
+        return VariableTypeFunction
+    
+    def OnVariablesGridCellLeftClick(self, event):
         if event.GetCol() == 0:
             row = event.GetRow()
             var_name = self.Table.GetValueByName(row, "Name")
@@ -2590,310 +2486,6 @@
             self.Parent.RefreshTitle()
             self.Parent.RefreshEditMenu()
 
-##[ID_EDITVARIABLEDIALOG, ID_EDITVARIABLEDIALOGMAINPANEL, 
-## ID_EDITVARIABLEDIALOGVARIABLESGRID, ID_EDITVARIABLEDIALOGRETURNTYPE, 
-## ID_EDITVARIABLEDIALOGCLASSFILTER, ID_EDITVARIABLEDIALOGADDBUTTON,
-## ID_EDITVARIABLEDIALOGDELETEBUTTON, ID_EDITVARIABLEDIALOGUPBUTTON, 
-## ID_EDITVARIABLEDIALOGDOWNBUTTON, ID_EDITVARIABLEDIALOGSTATICTEXT1, 
-## ID_EDITVARIABLEDIALOGSTATICTEXT2, ID_EDITVARIABLEDIALOGSTATICTEXT3,
-##] = [wx.NewId() for _init_ctrls in range(12)]
-##
-##class EditVariableDialog(wx.Dialog):
-##    def _init_coll_flexGridSizer1_Items(self, parent):
-##        parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
-##        parent.AddWindow(self.ButtonSizer, 0, border=0, flag=wx.ALIGN_RIGHT)
-##
-##    def _init_sizers(self):
-##        self.flexGridSizer1 = wx.FlexGridSizer(cols=1, hgap=0, rows=2, vgap=0)
-##
-##        self._init_coll_flexGridSizer1_Items(self.flexGridSizer1)
-##
-##        self.SetSizer(self.flexGridSizer1)
-##
-##    def _init_ctrls(self, prnt, name):
-##        wx.Dialog.__init__(self, id=ID_EDITVARIABLEDIALOG,
-##              name='EditVariableDialog', parent=prnt, pos=wx.Point(376, 223),
-##              size=wx.Size(600, 440), style=wx.DEFAULT_DIALOG_STYLE,
-##              title='Edit variables of %s'%name)
-##        self.SetClientSize(wx.Size(600, 440))
-##
-##        self.MainPanel = wx.Panel(id=ID_EDITVARIABLEDIALOGMAINPANEL,
-##              name='MainPanel', parent=self, pos=wx.Point(0, 0),
-##              size=wx.Size(600, 440), style=wx.TAB_TRAVERSAL)
-##        self.MainPanel.SetAutoLayout(True)
-##
-##        self.staticText1 = wx.StaticText(id=ID_EDITVARIABLEDIALOGSTATICTEXT1,
-##              label='Return Type:', name='staticText1', parent=self.MainPanel,
-##              pos=wx.Point(24, 29), size=wx.Size(95, 17), style=0)
-##
-##        self.ReturnType = wx.Choice(id=ID_EDITVARIABLEDIALOGRETURNTYPE,
-##              name='ReturnType', parent=self.MainPanel, pos=wx.Point(124, 24),
-##              size=wx.Size(145, 24), style=0)
-##
-##        self.staticText2 = wx.StaticText(id=ID_EDITVARIABLEDIALOGSTATICTEXT2,
-##              label='Class Filter:', name='staticText2', parent=self.MainPanel,
-##              pos=wx.Point(324, 29), size=wx.Size(95, 17), style=0)
-##
-##        self.ClassFilter = wx.Choice(id=ID_EDITVARIABLEDIALOGCLASSFILTER,
-##              name='ClassFilter', parent=self.MainPanel, pos=wx.Point(424, 24),
-##              size=wx.Size(145, 24), style=0)
-##        self.Bind(wx.EVT_CHOICE, self.OnClassFilter, id=ID_EDITVARIABLEDIALOGCLASSFILTER)
-##
-##        self.staticText3 = wx.StaticText(id=ID_EDITVARIABLEDIALOGSTATICTEXT3,
-##              label='Variables:', name='staticText3', parent=self.MainPanel,
-##              pos=wx.Point(24, 60), size=wx.Size(95, 17), style=0)
-##
-##        self.VariablesGrid = wx.grid.Grid(id=ID_EDITVARIABLEDIALOGVARIABLESGRID,
-##              name='VariablesGrid', parent=self.MainPanel, pos=wx.Point(24, 80), 
-##              size=wx.Size(550, 250), style=wx.VSCROLL)
-##        self.VariablesGrid.SetFont(wx.Font(12, 77, wx.NORMAL, wx.NORMAL, False,
-##              'Sans'))
-##        self.VariablesGrid.SetLabelFont(wx.Font(10, 77, wx.NORMAL, wx.NORMAL,
-##              False, 'Sans'))
-##        self.VariablesGrid.DisableDragGridSize()
-##        self.VariablesGrid.EnableScrolling(False, True)
-##        self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_CHANGE, self.OnVariablesGridCellChange)
-##        self.VariablesGrid.Bind(wx.grid.EVT_GRID_SELECT_CELL, self.OnVariablesGridSelectCell)
-##
-##        self.AddButton = wx.Button(id=ID_EDITVARIABLEDIALOGADDBUTTON, label='Add',
-##              name='AddButton', parent=self.MainPanel, pos=wx.Point(345, 340),
-##              size=wx.Size(72, 32), style=0)
-##        self.Bind(wx.EVT_BUTTON, self.OnAddButton, id=ID_EDITVARIABLEDIALOGADDBUTTON)
-##
-##        self.DeleteButton = wx.Button(id=ID_EDITVARIABLEDIALOGDELETEBUTTON, label='Delete',
-##              name='DeleteButton', parent=self.MainPanel, pos=wx.Point(425, 340),
-##              size=wx.Size(72, 32), style=0)
-##        self.Bind(wx.EVT_BUTTON, self.OnDeleteButton, id=ID_EDITVARIABLEDIALOGDELETEBUTTON)
-##
-##        self.UpButton = wx.Button(id=ID_EDITVARIABLEDIALOGUPBUTTON, label='^',
-##              name='UpButton', parent=self.MainPanel, pos=wx.Point(505, 340),
-##              size=wx.Size(32, 32), style=0)
-##        self.Bind(wx.EVT_BUTTON, self.OnUpButton, id=ID_EDITVARIABLEDIALOGUPBUTTON)
-##
-##        self.DownButton = wx.Button(id=ID_EDITVARIABLEDIALOGDOWNBUTTON, label='v',
-##              name='DownButton', parent=self.MainPanel, pos=wx.Point(545, 340),
-##              size=wx.Size(32, 32), style=0)
-##        self.Bind(wx.EVT_BUTTON, self.OnDownButton, id=ID_EDITVARIABLEDIALOGDOWNBUTTON)
-##
-##        self.ButtonSizer = self.CreateButtonSizer(wx.OK|wx.CANCEL|wx.CENTRE)
-##        self.Bind(wx.EVT_BUTTON, self.OnOK, id=self.ButtonSizer.GetAffirmativeButton().GetId())       
-##
-##        self._init_sizers()
-##
-##    def __init__(self, parent, name, pou_type, pou_is_used, filter = "All"):
-##        self._init_ctrls(parent, name)
-##
-##        self.Filter = filter
-##        self.PouIsUsed = pou_is_used
-##        self.FilterChoices = []
-##        self.FilterChoiceTransfer = {"All" : "All", "Interface" : "Interface", 
-##            "   Input" : "Input", "   Output" : "Output", "   InOut" : "InOut", 
-##            "   External" : "External", "Variables" : "Variables", "   Local" : "Local",
-##            "   Temp" : "Temp", "Global" : "Global", "Access" : "Access"}
-##        
-##        if pou_type:
-##            self.DefaultTypes = {"All" : "Local", "Interface" : "Input", "Variables" : "Local"}
-##            self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
-##        else:
-##            self.DefaultTypes = {"All" : "Global"}
-##            self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
-##        if not pou_type or pou_type == "program":
-##            self.Table = VariableTable(self, [], ["Name", "Class", "Type", "Location", "Initial Value", "Retain", "Constant"])
-##            if pou_type:
-##                self.FilterChoices = ["All","Interface","   Input","   Output","   InOut","   External","Variables","   Local","   Temp","Global","Access"]
-##            else:
-##                self.FilterChoices = ["All","Global","Access"]
-##            self.ColSizes = [80, 70, 80, 80, 80, 60, 70]
-##            self.ColAlignements = [wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER]
-##        else:
-##            self.Table = VariableTable(self, [], ["Name", "Class", "Type", "Initial Value", "Retain", "Constant"])
-##            self.FilterChoices = ["All","Interface","   Input","   Output","   InOut","   External","Variables","   Local","   Temp"]
-##            self.ColSizes = [120, 70, 80, 120, 60, 70]
-##            self.ColAlignements = [wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_LEFT, wx.ALIGN_CENTER, wx.ALIGN_CENTER]
-##        for choice in self.FilterChoices:
-##            self.ClassFilter.Append(choice)
-##        reverse_transfer = {}
-##        for filter, choice in self.FilterChoiceTransfer.items():
-##            reverse_transfer[choice] = filter
-##        self.ClassFilter.SetStringSelection(reverse_transfer[self.Filter])
-##        self.RefreshTypeList()
-##        self.RefreshButtons()
-##
-##        self.OptionList = "Yes,No"
-##        self.TypeList = ",".join([value for value, parent in TypeHierarchy_list if not value.startswith("ANY")])
-##        
-##        if pou_type == "function":
-##            for value, parent in TypeHierarchy_list:
-##                if not value.startswith("ANY"):
-##                    self.ReturnType.Append(value)
-##            self.ReturnType.Enable(True)
-##        else:
-##            self.ReturnType.Enable(False)
-##            self.staticText2.Hide()
-##            self.ReturnType.Hide()
-##        
-##        self.VariablesGrid.SetTable(self.Table)
-##        self.VariablesGrid.SetRowLabelSize(0)
-##        
-##        self.Table.ResetView(self.VariablesGrid)
-##
-##        self.PouNames = []
-##
-##        if self.PouIsUsed:
-##            wx.CallAfter(self.WarningMessage, name)
-##    
-##    def WarningMessage(self, name):
-##        message = wx.MessageDialog(self, "\"%s\" is used by one or more POUs. Its interface can't be changed!"%name, "WARNING", wx.OK|wx.ICON_EXCLAMATION)
-##        message.ShowModal()
-##        message.Destroy()
-##    
-##    def OnOK(self, event):
-##        self.VariablesGrid.SetGridCursor(0, 0)
-##        error = []
-##        if self.ReturnType.IsEnabled() and self.ReturnType.GetStringSelection() == "":
-##            error.append("Return Type")
-##        if len(error) > 0:
-##            text = ""
-##            for i, item in enumerate(error):
-##                if i == 0:
-##                    text += item
-##                elif i == len(error) - 1:
-##                    text += " and %s"%item
-##                else:
-##                    text += ", %s"%item 
-##            message = wx.MessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wx.OK|wx.ICON_ERROR)
-##            message.ShowModal()
-##            message.Destroy()
-##        else:
-##            self.EndModal(wx.ID_OK)
-##
-##    def OnClassFilter(self, event):
-##        self.Filter = self.FilterChoiceTransfer[self.ClassFilter.GetStringSelection()]
-##        self.RefreshTypeList()
-##        self.RefreshValues()
-##        self.RefreshButtons()
-##        event.Skip()
-##
-##    def RefreshTypeList(self):
-##        if self.Filter == "All":
-##            self.ClassList = [self.FilterChoiceTransfer[choice] for choice in self.FilterChoices if self.FilterChoiceTransfer[choice] not in ["All","Interface","Variables"]]
-##        elif self.Filter == "Interface":
-##            self.ClassList = ["Input","Output","InOut","External"]
-##        elif self.Filter == "Variables":
-##            self.ClassList = ["Local","Temp"]
-##        else:
-##            self.ClassList = [self.Filter]
-##
-##    def RefreshButtons(self):
-##        table_length = len(self.Table.data)
-##        row_class = None
-##        if table_length and self.PouIsUsed:
-##            row = self.VariablesGrid.GetGridCursorRow()
-##            row_class = self.Table.GetValueByName(row, "Class")
-##        self.AddButton.Enable(not self.PouIsUsed or self.Filter not in ["Interface", "Input", "Output", "InOut"])
-##        self.DeleteButton.Enable(table_length > 0 and row_class not in ["Input", "Output", "InOut"])
-##        self.UpButton.Enable(table_length > 0 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"])
-##        self.DownButton.Enable(table_length > 0 and self.Filter == "All" and row_class not in ["Input", "Output", "InOut"])
-##    
-##    def OnAddButton(self, event):
-##        new_row = self.DefaultValue.copy()
-##        if self.Filter in self.DefaultTypes:
-##            new_row["Class"] = self.DefaultTypes[self.Filter]
-##        else:
-##            new_row["Class"] = self.Filter
-##        self.Values.append(new_row)
-##        self.RefreshValues()
-##        self.RefreshButtons()
-##        event.Skip()
-##
-##    def OnDeleteButton(self, event):
-##        row = self.Table.GetRow(self.VariablesGrid.GetGridCursorRow())
-##        self.Values.remove(row)
-##        self.RefreshValues()
-##        self.RefreshButtons()
-##        event.Skip()
-##
-##    def OnUpButton(self, event):
-##        self.MoveValue(self.VariablesGrid.GetGridCursorRow(), -1)
-##        self.RefreshButtons()
-##        event.Skip()
-##
-##    def OnDownButton(self, event):
-##        self.MoveValue(self.VariablesGrid.GetGridCursorRow(), 1)
-##        self.RefreshButtons()
-##        event.Skip()
-##
-##    def OnVariablesGridCellChange(self, event):
-##        row, col = event.GetRow(), event.GetCol()
-##        colname = self.Table.GetColLabelValue(col)
-##        value = self.Table.GetValue(row, col)
-##        if colname == "Name":
-##            if not TestIdentifier(value):
-##                message = wx.MessageDialog(self, "\"%s\" is not a valid identifier!"%value, "Error", wx.OK|wx.ICON_ERROR)
-##                message.ShowModal()
-##                message.Destroy()
-##                event.Veto()
-##            elif value.upper() in IEC_KEYWORDS:
-##                message = wx.MessageDialog(self, "\"%s\" is a keyword. It can't be used!"%value, "Error", wx.OK|wx.ICON_ERROR)
-##                message.ShowModal()
-##                message.Destroy()
-##                event.Veto()
-##            elif value.upper() in self.PouNames:
-##                message = wx.MessageDialog(self, "A pou with \"%s\" as name exists!"%value, "Error", wx.OK|wx.ICON_ERROR)
-##                message.ShowModal()
-##                message.Destroy()
-##                event.Veto()
-##            elif value.upper() in [var["Name"].upper() for var in self.Values if var != self.Table.data[row]]:
-##                message = wx.MessageDialog(self, "A variable with \"%s\" as name exists in this pou!"%value, "Error", wx.OK|wx.ICON_ERROR)
-##                message.ShowModal()
-##                message.Destroy()
-##                event.Veto()
-##            else:
-##                event.Skip()
-##        else:
-##            event.Skip()
-##
-##    def OnVariablesGridSelectCell(self, event):
-##        wx.CallAfter(self.RefreshButtons)
-##        event.Skip()
-##
-##    def SetPouNames(self, pou_names):
-##        self.PouNames = [pou_name.upper() for pou_name in pou_names]
-##
-##    def SetValues(self, values):
-##        for item, value in values.items():
-##            if item == "returnType" and value and self.ReturnType.IsEnabled():
-##                self.ReturnType.SetStringSelection(value)
-##            if item == "data":
-##                self.Values = value
-##        self.RefreshValues()
-##
-##    def MoveValue(self, value_index, move):
-##        new_index = max(0, min(value_index + move, len(self.Values) - 1))
-##        if new_index != value_index:
-##            self.Values.insert(new_index, self.Values.pop(value_index))
-##            self.RefreshValues()
-##            self.VariablesGrid.SetGridCursor(new_index, self.VariablesGrid.GetGridCursorCol())
-##        else:
-##            self.RefreshValues()
-##    
-##    def RefreshValues(self):
-##        if len(self.Table.data) > 0:
-##            self.VariablesGrid.SetGridCursor(0, 0)
-##        data = []
-##        for variable in self.Values:
-##            if variable["Class"] in self.ClassList:
-##                data.append(variable)
-##        self.Table.SetData(data)
-##        self.Table.ResetView(self.VariablesGrid)
-##                
-##    def GetValues(self):
-##        values = {}
-##        if self.ReturnType.IsEnabled():
-##            values["returnType"] = self.ReturnType.GetStringSelection()
-##        values["data"] = self.Values
-##        return values
-
 #-------------------------------------------------------------------------------
 #                               Exception Handler
 #-------------------------------------------------------------------------------