Interface changed to show pou interface at the bottom of the window
authorlbessard
Fri, 20 Jul 2007 18:28:03 +0200
changeset 47 2b2f8d88e6d3
parent 46 4379e98a30aa
child 48 2675bf9b0a01
Interface changed to show pou interface at the bottom of the window
Adding Drag&Drop between ProjectTree and VariableGrid for adding block and variables into graphical Viewer
PLCControler.py
PLCGenerator.py
PLCOpenEditor.py
TextViewer.py
Viewer.py
__init__.py
examples/example.xml
plcopen/plcopen.py
plcopen/structures.py
--- a/PLCControler.py	Thu Jul 19 15:04:41 2007 +0200
+++ b/PLCControler.py	Fri Jul 20 18:28:03 2007 +0200
@@ -261,24 +261,24 @@
             for pou in self.Project.getPous():
                 pou_type = pou.getPouType().getValue()
                 pou_infos = {"name": pou.getName(), "type": ITEM_POU}
-                var_types = {"Input": {"name": "Input", "type": ITEM_CLASS, "values": []},
-                         "Output": {"name": "Output", "type": ITEM_CLASS, "values": []},
-                         "InOut": {"name": "InOut", "type": ITEM_CLASS, "values": []},
-                         "External": {"name": "External", "type": ITEM_CLASS, "values": []},
-                         "Local": {"name": "Local", "type": ITEM_CLASS, "values": []},
-                         "Temp": {"name": "Temp", "type": ITEM_CLASS, "values": []},
-                         "Global": {"name": "Global", "type": ITEM_CLASS, "values": []}}
-                for var in self.GetPouInterfaceVars(pou):
-                    var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []}
-                    if var["Class"] in var_types.keys():
-                        var_types[var["Class"]]["values"].append(var_values)
                 pou_values = []
-                pou_values.append({"name": "Interface", "type": ITEM_CLASS, 
-                    "values": [var_types["Input"], var_types["Output"], var_types["InOut"], var_types["External"]]})
-                pou_values.append({"name": "Variables", "type": ITEM_CLASS, 
-                    "values": [var_types["Local"], var_types["Temp"]]})
-                if pou_type == "program":
-                    pou_values.append(var_types["Global"])
+##                var_types = {"Input": {"name": "Input", "type": ITEM_CLASS, "values": []},
+##                         "Output": {"name": "Output", "type": ITEM_CLASS, "values": []},
+##                         "InOut": {"name": "InOut", "type": ITEM_CLASS, "values": []},
+##                         "External": {"name": "External", "type": ITEM_CLASS, "values": []},
+##                         "Local": {"name": "Local", "type": ITEM_CLASS, "values": []},
+##                         "Temp": {"name": "Temp", "type": ITEM_CLASS, "values": []},
+##                         "Global": {"name": "Global", "type": ITEM_CLASS, "values": []}}
+##                for var in self.GetPouInterfaceVars(pou):
+##                    var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []}
+##                    if var["Class"] in var_types.keys():
+##                        var_types[var["Class"]]["values"].append(var_values)
+##                pou_values.append({"name": "Interface", "type": ITEM_CLASS, 
+##                    "values": [var_types["Input"], var_types["Output"], var_types["InOut"], var_types["External"]]})
+##                pou_values.append({"name": "Variables", "type": ITEM_CLASS, 
+##                    "values": [var_types["Local"], var_types["Temp"]]})
+##                if pou_type == "program":
+##                    pou_values.append(var_types["Global"])
                 if pou.getBodyType() == "SFC":
                     transitions = []
                     for transition in pou.getTransitionList():
@@ -295,21 +295,22 @@
             for config in self.Project.getConfigurations():
                 config_name = config.getName()
                 config_infos = {"name": config_name, "type": ITEM_CONFIGURATION, "values": []}
-                config_vars = {"name": "Global", "type": ITEM_CLASS, "values": []}
-                for var in self.GetConfigurationGlobalVars(config_name):
-                    var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []}
-                    config_vars["values"].append(var_values)
+##                config_vars = {"name": "Global", "type": ITEM_CLASS, "values": []}
+##                for var in self.GetConfigurationGlobalVars(config_name):
+##                    var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []}
+##                    config_vars["values"].append(var_values)
                 resources = {"name": "Resources", "type": ITEM_UNEDITABLE, "values": []}
                 for resource in config.getResource():
                     resource_name = resource.getName()
                     resource_infos = {"name": resource_name, "type": ITEM_RESOURCE, "values": []}
-                    resource_vars = {"name": "Global", "type": ITEM_CLASS, "values": []}
-                    for var in self.GetConfigurationResourceGlobalVars(config_name, resource_name):
-                        var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []}
-                        resource_vars["values"].append(var_values)
-                    resource_infos["values"].append(resource_vars)
+##                    resource_vars = {"name": "Global", "type": ITEM_CLASS, "values": []}
+##                    for var in self.GetConfigurationResourceGlobalVars(config_name, resource_name):
+##                        var_values = {"name": var["Name"], "type": ITEM_VARIABLE, "values": []}
+##                        resource_vars["values"].append(var_values)
+##                    resource_infos["values"].append(resource_vars)
                     resources["values"].append(resource_infos)
-                config_infos["values"] = [config_vars, resources]
+##                config_infos["values"] = [config_vars, resources]
+                config_infos["values"] = [resources]
                 configurations["values"].append(config_infos)
             infos["values"] = [{"name": "Properties", "type": ITEM_UNEDITABLE, "values": []},
                                pou_types["function"], pou_types["functionBlock"], 
@@ -851,6 +852,8 @@
             words = pou_name.split("::")
             if len(words) == 1:
                 names.append(pou_name)
+            elif len(words) == 2:
+                names.append(words[1])
             else:
                 names.append("%s-%s"%(words[1],words[2]))
         return names
@@ -864,6 +867,10 @@
         return "A::%s::%s" % (pou, action)
 
     # Compute a pou  name
+    def ComputeConfigurationName(self, config):
+        return "C::%s" % config
+
+    # Compute a pou  name
     def ComputeConfigurationResourceName(self, config, resource):
         return "R::%s::%s" % (config, resource)
     
@@ -885,6 +892,10 @@
     def OpenPouActionEditing(self, pou, action):
         return self.OpenElementEditing(self.ComputePouActionName(pou, action))
 
+    # Open a configuration resource by giving configuration name
+    def OpenConfigurationEditing(self, config):
+        return self.OpenElementEditing(self.ComputeConfigurationName(config))
+
     # Open a configuration resource by giving configuration and resource names
     def OpenConfigurationResourceEditing(self, config, resource):
         return self.OpenElementEditing(self.ComputeConfigurationResourceName(config, resource))
@@ -901,8 +912,12 @@
     def IsPouActionEditing(self, pou, action):
         return self.ComputePouActionName(pou, action) in self.ElementsOpened
 
-    # Return if pou action given by pou and action names is opened
-    def IsConfigurationResourceEditing(self, pou, action):
+    # Return if pou action given by configuration name is opened
+    def IsConfigurationEditing(self, pou):
+        return self.ComputeConfigurationName(config) in self.ElementsOpened
+
+    # Return if pou action given by configuration and resource names is opened
+    def IsConfigurationResourceEditing(self, pou, resource):
         return self.ComputeConfigurationResourceName(config, resource) in self.ElementsOpened
 
     # Close current pou editing
@@ -932,6 +947,10 @@
     def ChangePouActionEditing(self, pou, action):
         return self.ChangeElementEditing(self.ComputePouActionName(pou, action))
 
+    # Change current pou editing for action given by configuration name
+    def ChangeConfigurationEditing(self, config):
+        return self.ChangeElementEditing(self.ComputeConfigurationName(config))
+
     # Change current pou editing for action given by configuration and resource names
     def ChangeConfigurationResourceEditing(self, config, resource):
         return self.ChangeElementEditing(self.ComputeConfigurationResourceName(config, resource))
@@ -955,6 +974,9 @@
                         return pou.getTransition(words[2])
                     elif words[0] == 'A':
                         return pou.getAction(words[2])
+                elif words[0] == 'C':
+                    result = self.Project.getConfiguration(words[1])
+                    return result
                 elif words[0] == 'R':
                     result = self.Project.getConfigurationResource(words[1], words[2])
                     return result
@@ -968,6 +990,8 @@
             words = name.split("::")
             if len(words) == 1:
                 return name
+            elif len(words) == 2:
+                return words[1]
             else:
                 return words[2]
         return None
@@ -983,7 +1007,9 @@
             words = name.split("::")
             if len(words) == 1:
                 return self.GetPouType(name)
-            else:
+            elif len(words) == 2:
+                return None
+            elif words[0] != "R":
                 return self.GetPouType(words[1])
         return None
 
--- a/PLCGenerator.py	Thu Jul 19 15:04:41 2007 +0200
+++ b/PLCGenerator.py	Fri Jul 20 18:28:03 2007 +0200
@@ -277,7 +277,6 @@
             if step_name in self.SFCNetworks["Steps"].keys():
                 actions = actionBlock.getActions()
                 for action in actions:
-                    print action
                     action_infos = {"qualifier" : action["qualifier"], "content" : action["value"]}
                     if "duration" in action:
                         action_infos["duration"] = action["duration"]
--- a/PLCOpenEditor.py	Thu Jul 19 15:04:41 2007 +0200
+++ b/PLCOpenEditor.py	Fri Jul 20 18:28:03 2007 +0200
@@ -65,7 +65,10 @@
     sys.exit()
 elif len(args) == 1:
     fileOpen = args[0]
-CWD = sys.path[0]
+CWD = ""
+for path in sys.path:
+    if os.path.isfile(os.path.join(path, "PLCOpenEditor.py")):
+        CWD = path
 
 [wxID_PLCOPENEDITOR, wxID_PLCOPENEDITORPROJECTTREE, 
  wxID_PLCOPENEDITORSPLITTERWINDOW1, wxID_PLCOPENEDITOREDITORPANEL,
@@ -204,8 +207,9 @@
 
     def _init_coll_menuBar1_Menus(self, parent):
         # generated method, don't edit
-
-        parent.Append(menu=self.FileMenu, title=u'File')
+        
+        if self.ModeSolo:
+            parent.Append(menu=self.FileMenu, title=u'File')
         parent.Append(menu=self.EditMenu, title=u'Edit')
         parent.Append(menu=self.HelpMenu, title=u'Help')
 
@@ -230,8 +234,9 @@
               kind=wx.ITEM_NORMAL, text=u'PLCOpen\tF2')
         parent.Append(help='', id=wxID_PLCOPENEDITORHELPMENUITEMS2,
               kind=wx.ITEM_NORMAL, text=u'IEC 61131-3\tF3')
-        parent.Append(help='', id=wxID_PLCOPENEDITORHELPMENUITEMS3,
-              kind=wx.ITEM_NORMAL, text=u'About')
+        if self.ModeSolo:
+            parent.Append(help='', id=wxID_PLCOPENEDITORHELPMENUITEMS3,
+                  kind=wx.ITEM_NORMAL, text=u'About')
         self.Bind(wx.EVT_MENU, self.OnPLCOpenMenu,
               id=wxID_PLCOPENEDITORHELPMENUITEMS1)
 
@@ -302,7 +307,10 @@
         # generated method, don't edit
         self.menuBar1 = wx.MenuBar()
 
-        self.FileMenu = wx.Menu(title=u'')
+        if self.ModeSolo:
+            self.FileMenu = wx.Menu(title=u'')
+        else:
+            self.FileMenu = None
 
         self.EditMenu = wx.Menu(title=u'')
 
@@ -313,7 +321,8 @@
         self.ConfigMenu = wx.Menu(title='')
 
         self._init_coll_menuBar1_Menus(self.menuBar1)
-        self._init_coll_FileMenu_Items(self.FileMenu)
+        if self.ModeSolo:
+            self._init_coll_FileMenu_Items(self.FileMenu)
         self._init_coll_EditMenu_Items(self.EditMenu)
         self._init_coll_HelpMenu_Items(self.HelpMenu)
         self._init_coll_SFCMenu_Items(self.SFCMenu)
@@ -406,10 +415,11 @@
               id=wxID_PLCOPENEDITORPROJECTTREE)
         self.splitterWindow1.SplitVertically(self.ProjectTree, self.EditorPanel,
               200)
-              
+        
         self._init_sizers()
 
-    def __init__(self, parent):
+    def __init__(self, parent, controler = None):
+        self.ModeSolo = controler == None
         self._init_ctrls(parent)
         
         self.TreeImageList = wxImageList(16, 16)
@@ -417,7 +427,10 @@
             self.TreeImageList.Add(wxBitmap(os.path.join(CWD, 'Images/%s.png'%language)))
         self.ProjectTree.SetImageList(self.TreeImageList)
         
-        self.Controler = PLCControler()
+        if self.ModeSolo:
+            self.Controler = PLCControler()
+        else:
+            self.Controler = controler
         
         if fileOpen:
             self.Controler.OpenXMLFile(fileOpen)
@@ -612,8 +625,7 @@
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
             window = self.TabsOpened.GetPage(selected)
-            if not isinstance(window, TextViewer):
-                window.SetMode(MODE_SELECTION)
+            window.SetMode(MODE_SELECTION)
         self.ToolBar.ToggleTool(wxID_PLCOPENEDITORTOOLBARSELECTION, True)
 
     def ResetToolToggle(self, id):
@@ -670,7 +682,7 @@
     def OnRungTool(self, event):
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
-            self.TabsOpened.GetPage(selected).AddLadderRung()
+            self.TabsOpened.GetPage(selected).Viewer.AddLadderRung()
         event.Skip()
     
     def OnCoilTool(self, event):
@@ -688,13 +700,13 @@
             if self.DrawingMode == FREEDRAWING_MODE:
                 self.TabsOpened.GetPage(selected).SetMode(MODE_CONTACT)
             else:
-                self.TabsOpened.GetPage(selected).AddLadderContact()
+                self.TabsOpened.GetPage(selected).Viewer.AddLadderContact()
         event.Skip()
     
     def OnBranchTool(self, event): 
         selected = self.TabsOpened.GetSelection()
         if selected != -1:
-            self.TabsOpened.GetPage(selected).AddLadderBranch()
+            self.TabsOpened.GetPage(selected).Viewer.AddLadderBranch()
         event.Skip()    
     
     def OnInitialStepTool(self, event):
@@ -712,7 +724,7 @@
             if self.GetDrawingMode() == FREEDRAWING_MODE:
                 self.TabsOpened.GetPage(selected).SetMode(MODE_STEP)
             else:
-                self.TabsOpened.GetPage(selected).AddStep()
+                self.TabsOpened.GetPage(selected).Viewer.AddStep()
         event.Skip()
 
     def OnActionBlockTool(self, event):
@@ -723,7 +735,7 @@
             if self.GetDrawingMode() == FREEDRAWING_MODE:
                 self.TabsOpened.GetPage(selected).SetMode(MODE_ACTION)
             else:
-                self.TabsOpened.GetPage(selected).AddStepAction()
+                self.TabsOpened.GetPage(selected).Viewer.AddStepAction()
         event.Skip()
 
     def OnTransitionTool(self, event):
@@ -741,7 +753,7 @@
             if self.GetDrawingMode() == FREEDRAWING_MODE:
                 self.TabsOpened.GetPage(selected).SetMode(MODE_DIVERGENCE)
             else:
-                self.TabsOpened.GetPage(selected).AddDivergence()
+                self.TabsOpened.GetPage(selected).Viewer.AddDivergence()
         event.Skip()
     
     def OnJumpTool(self, event):
@@ -752,7 +764,7 @@
             if self.GetDrawingMode() == FREEDRAWING_MODE:
                 self.TabsOpened.GetPage(selected).SetMode(MODE_JUMP)
             else:
-                self.TabsOpened.GetPage(selected).AddJump()
+                self.TabsOpened.GetPage(selected).Viewer.AddJump()
         event.Skip()
         
     def OnPouSelectedChanged(self, event):
@@ -767,6 +779,7 @@
                 if self.ProjectTree.GetItemText(item) == name:
                     self.ProjectTree.SelectItem(item)
                 item, root_cookie = self.ProjectTree.GetNextChild(root, root_cookie)
+            self.TabsOpened.GetPage(selected).RefreshView()
             self.RefreshFileMenu()
             self.RefreshEditMenu()
             self.RefreshToolBar()
@@ -774,12 +787,13 @@
 
     def OnProjectTreeBeginDrag(self, event):
         item = event.GetItem()
-        if self.ProjectTree.GetPyData(item) == ITEM_VARIABLE:
-            data = wxTextDataObject(self.ProjectTree.GetItemText(item))
+        if self.ProjectTree.GetPyData(item) == ITEM_POU:
+            block_name = self.ProjectTree.GetItemText(item)
+            block_type = self.Controler.GetPouType(block_name)
+            data = wxTextDataObject(str((block_name, block_type)))
             dragSource = wxDropSource(self.ProjectTree)
             dragSource.SetData(data)
             dragSource.DoDragDrop()
-        event.Skip()
 
     def OnProjectTreeItemEndEdit(self, event):
         message = None
@@ -875,75 +889,184 @@
         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)
+##        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() == wxID_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() == wxID_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() == wxID_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)
+                if idx != None:
+                    new_window = PouEditorPanel(self.TabsOpened, self, self.Controler, "config", config_name = name)
+                    self.TabsOpened.AddPage(new_window, "")
+                else:
+                    idx = self.Controler.ChangeConfigurationEditing(name)
+            elif data == ITEM_RESOURCE:
+                item = self.ProjectTree.GetItemParent(selected)
                 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() == wxID_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() == wxID_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() == wxID_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:
+                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 = PouEditorPanel(self.TabsOpened, self, self.Controler, "resource", config_name = config_name, resource_name = name)
+                    self.TabsOpened.AddPage(new_window, "")
+                else:
+                    idx = self.Controler.ChangeConfigurationResourceEditing(config_name, name)
+            elif 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"])
+                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)
             else:
                 parent = self.ProjectTree.GetItemParent(selected)
                 parent_name = self.ProjectTree.GetItemText(parent)
@@ -951,76 +1074,26 @@
                 grandparent_name = self.ProjectTree.GetItemText(grandparent)
                 if data == ITEM_TRANSITION:
                     idx = self.Controler.OpenPouTransitionEditing(grandparent_name, name)
-                    language = self.Controler.GetTransitionBodyType(grandparent_name, name)
+                    if idx != None:
+                        new_window = PouEditorPanel(self.TabsOpened, self, self.Controler, "transition", pou_name = grandparent_name, transition_name = name)
+                        self.TabsOpened.AddPage(new_window, "")
+                    else:
+                        idx = self.Controler.ChangePouTransitionEditing(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"])
+                    if idx != None:
+                        new_window = PouEditorPanel(self.TabsOpened, self, self.Controler, "action", pou_name = grandparent_name, action_name = name)
+                        self.TabsOpened.AddPage(new_window, "")
+                    else:
+                        idx = self.Controler.ChangePouActionEditing(grandparent_name, name)
             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)
+                window = self.TabsOpened.GetPage(idx)
+                window.RefreshView()
                 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()
     
     def OnProjectTreeRightUp(self, event):
         selected = self.ProjectTree.GetSelection()
@@ -1826,6 +1899,8 @@
 
     def GetValue(self, row, col):
         if row < self.GetNumberRows():
+            if col == 0:
+                return "d"
             name = str(self.data[row].get(self.GetColLabelValue(col), ""))
             return name
     
@@ -1892,13 +1967,15 @@
                 renderer = None
                 colname = self.GetColLabelValue(col)
                 grid.SetReadOnly(row, col, False)
-                if colname == "Name":
+                if colname == "Drag":
+                    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:
                         editor = wxGridCellTextEditor()
                         renderer = wxGridCellStringRenderer()
-                if colname in ["Initial Value","Location"]:
+                elif colname in ["Initial Value","Location"]:
                     editor = wxGridCellTextEditor()
                     renderer = wxGridCellStringRenderer()
                 elif colname == "Class":
@@ -1950,127 +2027,228 @@
         self.data = []
         self.editors = []
 
-[wxID_EDITVARIABLEDIALOG, wxID_EDITVARIABLEDIALOGMAINPANEL, 
- wxID_EDITVARIABLEDIALOGVARIABLESGRID, wxID_EDITVARIABLEDIALOGRETURNTYPE, 
- wxID_EDITVARIABLEDIALOGCLASSFILTER, wxID_EDITVARIABLEDIALOGADDBUTTON,
- wxID_EDITVARIABLEDIALOGDELETEBUTTON, wxID_EDITVARIABLEDIALOGUPBUTTON, 
- wxID_EDITVARIABLEDIALOGDOWNBUTTON, wxID_EDITVARIABLEDIALOGSTATICTEXT1, 
- wxID_EDITVARIABLEDIALOGSTATICTEXT2, wxID_EDITVARIABLEDIALOGSTATICTEXT3,
+[wxID_POUEDITORPANEL, wxID_POUEDITORPANELVIEWER, 
+ wxID_POUEDITORPANELVARIABLESGRID, wxID_POUEDITORPANELRETURNTYPE, 
+ wxID_POUEDITORPANELCLASSFILTER, wxID_POUEDITORPANELADDBUTTON,
+ wxID_POUEDITORPANELDELETEBUTTON, wxID_POUEDITORPANELUPBUTTON, 
+ wxID_POUEDITORPANELDOWNBUTTON, wxID_POUEDITORPANELSTATICTEXT1, 
+ wxID_POUEDITORPANELSTATICTEXT2, wxID_POUEDITORPANELSTATICTEXT3,
 ] = [wx.NewId() for _init_ctrls in range(12)]
 
-class EditVariableDialog(wx.Dialog):
-    def _init_coll_flexGridSizer1_Items(self, parent):
-        # generated method, don't edit
-
-        parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
+class PouEditorPanel(wx.Panel):
+    def _init_coll_MainPanelSizer_Items(self, parent):
+        # generated method, don't edit
+
+        parent.AddWindow(self.Viewer, 0, border=0, flag=wxGROW)
+        parent.AddSizer(self.VariablePanelSizer, 0, border=0, flag=wxGROW)
+
+    def _init_coll_MainPanelSizer_Growables(self, parent):
+        # generated method, don't edit
+
+        parent.AddGrowableCol(0)
+        parent.AddGrowableRow(0)
+    
+    def _init_coll_VariablePanelSizer_Items(self, parent):
+        # generated method, don't edit
+
+        parent.AddWindow(self.VariablesGrid, 0, border=0, flag=wxGROW)
+        parent.AddSizer(self.ControlPanelSizer, 0, border=0, flag=wxGROW)
+    
+    def _init_coll_VariablePanelSizer_Growables(self, parent):
+        # generated method, don't edit
+
+        parent.AddGrowableCol(0)
+        parent.AddGrowableRow(0)
+    
+    def _init_coll_ControlPanelSizer_Items(self, parent):
+        # generated method, don't edit
+
+        parent.AddSizer(self.ChoicePanelSizer, 0, border=0, flag=wxGROW)
+        parent.AddSizer(self.ButtonPanelSizer, 0, border=0, flag=wxALIGN_CENTER)
+
+    def _init_coll_ControlPanelSizer_Growables(self, parent):
+        # generated method, don't edit
+
+        parent.AddGrowableCol(0)
+        parent.AddGrowableRow(0)
+        parent.AddGrowableRow(1)
+
+    def _init_coll_ChoicePanelSizer_Items(self, parent):
+        # generated method, don't edit
+
+        parent.AddWindow(self.staticText1, 0, border=0, flag=wxALIGN_BOTTOM)
+        parent.AddWindow(self.staticText2, 0, border=0, flag=wxALIGN_BOTTOM)
+        parent.AddWindow(self.ReturnType, 0, border=0, flag=0)
+        parent.AddWindow(self.ClassFilter, 0, border=0, flag=0)
+
+    def _init_coll_ButtonPanelSizer_Items(self, parent):
+        # generated method, don't edit
+
+        parent.AddWindow(self.AddButton, 0, border=0, flag=0)
+        parent.AddWindow(self.DeleteButton, 0, border=0, flag=0)
+        parent.AddWindow(self.UpButton, 0, border=0, flag=0)
+        parent.AddWindow(self.DownButton, 0, border=0, flag=0)
+
+    def _init_coll_ButtonPanelSizer_Growables(self, parent):
+        # generated method, don't edit
+
+        parent.AddGrowableCol(0)
+        parent.AddGrowableCol(1)
+        parent.AddGrowableCol(2)
+        parent.AddGrowableCol(3)
+        parent.AddGrowableRow(0)
 
     def _init_sizers(self):
         # generated method, don't edit
-        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):
-        # generated method, don't edit
-        wx.Dialog.__init__(self, id=wxID_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=wxID_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=wxID_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=wxID_EDITVARIABLEDIALOGRETURNTYPE,
-              name='ReturnType', parent=self.MainPanel, pos=wx.Point(124, 24),
+        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=0)
+        
+        self.ChoicePanelSizer = wx.GridSizer(cols=2, hgap=5, rows=2, vgap=5)
+        
+        self.ButtonPanelSizer = wx.FlexGridSizer(cols=4, hgap=5, rows=1, 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)
+        self._init_coll_ControlPanelSizer_Growables(self.ControlPanelSizer)
+        self._init_coll_ChoicePanelSizer_Items(self.ChoicePanelSizer)
+        self._init_coll_ButtonPanelSizer_Items(self.ButtonPanelSizer)
+        self._init_coll_ButtonPanelSizer_Growables(self.ButtonPanelSizer)
+        
+        self.SetSizer(self.MainPanelSizer)
+
+    def _init_ctrls(self, prnt, element_type):
+        # generated method, don't edit
+        wx.Panel.__init__(self, id=wxID_POUEDITORPANEL,
+              name='EditVariablePanel', parent=prnt, pos=wx.Point(0, 0),
+              size=wx.Size(-1, -1), style=0)
+        
+        if element_type == "config":
+            self.Viewer = wx.Panel(id=wxID_POUEDITORPANELVIEWER,
+              name='ConfigPanel', parent=self, pos=wx.Point(0, 0),
+              size=wx.Size(-1, -1), style=wx.TAB_TRAVERSAL)
+        elif element_type == "resource":
+            self.Viewer = ResourceEditor(self, self.Parent, self.Controler)
+        elif element_type == "FBD":
+            self.Viewer = Viewer(self, self.Parent, self.Controler)
+        elif element_type == "LD":
+            self.Viewer = LD_Viewer(self, self.Parent, self.Controler)
+        elif element_type == "SFC":
+            self.Viewer = SFC_Viewer(self, self.Parent, self.Controler)
+        else:
+            self.Viewer = TextViewer(self, self.Parent, self.Controler)
+            self.Viewer.SetTextSyntax(element_type)
+            if element_type == "IL":
+                self.Viewer.SetKeywords(IL_KEYWORDS)
+            else:
+                self.Viewer.SetKeywords(ST_KEYWORDS)
+        
+        self.staticText1 = wx.StaticText(id=wxID_POUEDITORPANELSTATICTEXT1,
+              label='Return Type:', name='staticText1', parent=self,
+              pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0)
+
+        self.ReturnType = wx.Choice(id=wxID_POUEDITORPANELRETURNTYPE,
+              name='ReturnType', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(145, 24), style=0)
 
-        self.staticText2 = wx.StaticText(id=wxID_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=wxID_EDITVARIABLEDIALOGCLASSFILTER,
-              name='ClassFilter', parent=self.MainPanel, pos=wx.Point(424, 24),
+        self.staticText2 = wx.StaticText(id=wxID_POUEDITORPANELSTATICTEXT2,
+              label='Class Filter:', name='staticText2', parent=self,
+              pos=wx.Point(0, 0), size=wx.Size(95, 17), style=0)
+
+        self.ClassFilter = wx.Choice(id=wxID_POUEDITORPANELCLASSFILTER,
+              name='ClassFilter', parent=self, pos=wx.Point(0, 0),
               size=wx.Size(145, 24), style=0)
-        EVT_CHOICE(self, wxID_EDITVARIABLEDIALOGCLASSFILTER, self.OnClassFilter)
-
-        self.staticText3 = wx.StaticText(id=wxID_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=wxID_EDITVARIABLEDIALOGVARIABLESGRID,
-              name='VariablesGrid', parent=self.MainPanel, pos=wx.Point(24, 80), 
-              size=wx.Size(550, 250), style=wxVSCROLL)
+        EVT_CHOICE(self, wxID_POUEDITORPANELCLASSFILTER, self.OnClassFilter)
+
+        self.VariablesGrid = wx.grid.Grid(id=wxID_POUEDITORPANELVARIABLESGRID,
+              name='VariablesGrid', parent=self, pos=wx.Point(0, 0), 
+              size=wx.Size(-1, 150), style=wxVSCROLL)
         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=wxID_EDITVARIABLEDIALOGADDBUTTON, label='Add',
-              name='AddButton', parent=self.MainPanel, pos=wx.Point(345, 340),
+        self.VariablesGrid.Bind(wx.grid.EVT_GRID_CELL_LEFT_CLICK, self.OnVariablesGridCellLeftClick)
+        
+        self.AddButton = wx.Button(id=wxID_POUEDITORPANELADDBUTTON, label='Add',
+              name='AddButton', parent=self, pos=wx.Point(345, 340),
               size=wx.Size(72, 32), style=0)
-        EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGADDBUTTON, self.OnAddButton)
-
-        self.DeleteButton = wx.Button(id=wxID_EDITVARIABLEDIALOGDELETEBUTTON, label='Delete',
-              name='DeleteButton', parent=self.MainPanel, pos=wx.Point(425, 340),
+        EVT_BUTTON(self, wxID_POUEDITORPANELADDBUTTON, self.OnAddButton)
+
+        self.DeleteButton = wx.Button(id=wxID_POUEDITORPANELDELETEBUTTON, label='Delete',
+              name='DeleteButton', parent=self, pos=wx.Point(425, 340),
               size=wx.Size(72, 32), style=0)
-        EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGDELETEBUTTON, self.OnDeleteButton)
-
-        self.UpButton = wx.Button(id=wxID_EDITVARIABLEDIALOGUPBUTTON, label='^',
-              name='UpButton', parent=self.MainPanel, pos=wx.Point(505, 340),
+        EVT_BUTTON(self, wxID_POUEDITORPANELDELETEBUTTON, self.OnDeleteButton)
+
+        self.UpButton = wx.Button(id=wxID_POUEDITORPANELUPBUTTON, label='^',
+              name='UpButton', parent=self, pos=wx.Point(505, 340),
               size=wx.Size(32, 32), style=0)
-        EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGUPBUTTON, self.OnUpButton)
-
-        self.DownButton = wx.Button(id=wxID_EDITVARIABLEDIALOGDOWNBUTTON, label='v',
-              name='DownButton', parent=self.MainPanel, pos=wx.Point(545, 340),
+        EVT_BUTTON(self, wxID_POUEDITORPANELUPBUTTON, self.OnUpButton)
+
+        self.DownButton = wx.Button(id=wxID_POUEDITORPANELDOWNBUTTON, label='v',
+              name='DownButton', parent=self, pos=wx.Point(545, 340),
               size=wx.Size(32, 32), style=0)
-        EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGDOWNBUTTON, self.OnDownButton)
+        EVT_BUTTON(self, wxID_POUEDITORPANELDOWNBUTTON, self.OnDownButton)
 
         self._init_sizers()
 
-    def __init__(self, parent, name, pou_type, pou_is_used, filter = "All"):
-        self._init_ctrls(parent, name)
-        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
-        self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
-        self.Filter = filter
-        self.PouIsUsed = pou_is_used
+    def __init__(self, parent, window, controler, element_type, pou_name = None, transition_name = None, action_name = None, config_name = None, resource_name = None):
+        self.Parent = window
+        self.Controler = controler
+        self.ElementType = element_type
+        self.PouName = pou_name
+        self.TransitionName = transition_name
+        self.ActionName = action_name
+        self.ConfigName = config_name
+        self.ResourceName = resource_name
+        
+        if element_type == "config":
+            self._init_ctrls(parent, "config")
+            pou_type = "config"
+        elif element_type == "resource":
+            self._init_ctrls(parent, "resource")
+            pou_type = "resource"
+        else:
+            if element_type == "transition":
+                self._init_ctrls(parent, self.Controler.GetTransitionBodyType(pou_name, transition_name))
+            elif element_type == "action":
+                self._init_ctrls(parent, self.Controler.GetActionBodyType(pou_name, action_name))
+            else:
+                self._init_ctrls(parent, self.Controler.GetPouBodyType(pou_name))
+            pou_type = self.Controler.GetPouType(pou_name)
+        
+        self.Filter = "All"
         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:
+        if pou_type in ["config", "resource"]:
+            self.DefaultTypes = {"All" : "Global"}
+            self.DefaultValue = {"Name" : "", "Class" : "", "Type" : "INT", "Location" : "", "Initial Value" : "", "Retain" : "No", "Constant" : "No"}
+        else:
             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:
+        if pou_type in ["config", "resource"] or pou_type == "program":
+            self.Table = VariableTable(self, [], ["Drag", "Name", "Class", "Type", "Location", "Initial Value", "Retain", "Constant"])
+            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 = [80, 70, 80, 80, 80, 60, 70]
-            self.ColAlignements = [wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_CENTER]
+            self.ColSizes = [40, 80, 70, 80, 80, 80, 60, 70]
+            self.ColAlignements = [wxALIGN_CENTER, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_CENTER]
         else:
-            self.Table = VariableTable(self, [], ["Name", "Class", "Type", "Initial Value", "Retain", "Constant"])
+            self.Table = VariableTable(self, [], ["Drag", "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 = [wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_CENTER]
+            self.ColSizes = [40, 120, 70, 80, 120, 60, 70]
+            self.ColAlignements = [wxALIGN_CENTER, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_CENTER]
         for choice in self.FilterChoices:
             self.ClassFilter.Append(choice)
         reverse_transfer = {}
@@ -2078,7 +2256,6 @@
             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")])
@@ -2090,46 +2267,62 @@
             self.ReturnType.Enable(True)
         else:
             self.ReturnType.Enable(False)
-            self.staticText2.Hide()
+            self.staticText1.Hide()
             self.ReturnType.Hide()
         
         self.VariablesGrid.SetTable(self.Table)
         self.VariablesGrid.SetRowLabelSize(0)
-        
-        self.Table.ResetView(self.VariablesGrid)
-
-        self.PouNames = []
-
+    
+    def SetMode(self, mode):
+        if self.ElementType not in ["resource", "config"]:
+            if self.ElementType == "transition":
+                language = self.Controler.GetTransitionBodyType(self.PouName, self.TransitionName)
+            elif self.ElementType == "action":
+                language = self.Controler.GetActionBodyType(self.PouName, self.ActionName)
+            else:
+                language = self.Controler.GetPouBodyType(self.PouName)
+            if language not in ["IL", "ST"]:
+                self.Viewer.SetMode(mode)
+
+    def RefreshView(self):
+        self.PouNames = self.Controler.GetProjectPouNames()
+        
+        if self.ElementType == "config":
+            self.PouIsUsed = False
+            returnType = None
+            self.Values = self.Controler.GetConfigurationGlobalVars(self.ConfigName)
+        elif self.ElementType == "resource":
+            self.PouIsUsed = False
+            returnType = None
+            self.Values = self.Controler.GetConfigurationResourceGlobalVars(self.ConfigName, self.ResourceName)
+        else:
+            self.PouIsUsed = self.Controler.PouIsUsed(self.PouName)
+            returnType = self.Controler.GetCurrentElementEditingInterfaceReturnType()
+            self.Values = self.Controler.GetCurrentElementEditingInterfaceVars()
+            varlist = [var["Name"] for var in self.Values]
+            if self.ElementType == "transtion":
+                language = self.Controler.GetTransitionBodyType(self.PouName, self.TransitionName)
+                varlist.append(self.ActionName)
+            elif self.ElementType == "action":
+                language = self.Controler.GetActionBodyType(self.PouName, self.ActionName)
+                varlist.append(self.ActionName)
+            else:
+                language = self.Controler.GetPouBodyType(self.PouName)
+                varlist.append(self.PouName)
+            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()
+        if self.ElementType != "config":
+            self.Viewer.RefreshView()
+        
         if self.PouIsUsed:
             wxCallAfter(self.WarningMessage, name)
-
-        EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
-    
-    def WarningMessage(self, name):
-        message = wxMessageDialog(self, "\"%s\" is used by one or more POUs. Its interface can't be changed!"%name, "WARNING", wxOK|wxICON_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 = wxMessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wxOK|wxICON_ERROR)
-            message.ShowModal()
-            message.Destroy()
-        else:
-            self.EndModal(wxID_OK)
-
+        
     def OnClassFilter(self, event):
         self.Filter = self.FilterChoiceTransfer[self.ClassFilter.GetStringSelection()]
         self.RefreshTypeList()
@@ -2157,7 +2350,7 @@
         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:
@@ -2212,25 +2405,28 @@
                 message.Destroy()
                 event.Veto()
             else:
+                self.SaveValues()
                 event.Skip()
         else:
+            self.SaveValues()
             event.Skip()
 
+    def OnVariablesGridCellLeftClick(self, event):
+        if event.GetCol() == 0:
+            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 = wxTextDataObject(str((var_name, var_class, var_type)))
+            dragSource = wxDropSource(self.VariablesGrid)
+            dragSource.SetData(data)
+            dragSource.DoDragDrop()
+        event.Skip()
+    
     def OnVariablesGridSelectCell(self, event):
         wxCallAfter(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:
@@ -2239,23 +2435,334 @@
             self.VariablesGrid.SetGridCursor(new_index, self.VariablesGrid.GetGridCursorCol())
         else:
             self.RefreshValues()
-    
+        self.SaveValues()
+
     def RefreshValues(self):
         if len(self.Table.data) > 0:
-            self.VariablesGrid.SetGridCursor(0, 0)
+            self.VariablesGrid.SetGridCursor(0, 1)
         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
+
+    def SaveValues(self):
+        if self.ElementType == "config":
+            self.Controler.SetConfigurationGlobalVars(self.ConfigName, self.Values)
+        elif self.ElementType == "resource":
+            self.Controler.SetConfigurationResourceGlobalVars(self.ConfigName, self.ResourceName, self.Values)
+        else:
+            if self.ReturnType.IsEnabled():
+                self.Controler.SetPouInterfaceReturnType(self.PouName, self.ReturnType.GetStringSelection())
+            self.Controler.SetPouInterfaceVars(self.PouName, self.Values)
+
+##[wxID_EDITVARIABLEDIALOG, wxID_EDITVARIABLEDIALOGMAINPANEL, 
+## wxID_EDITVARIABLEDIALOGVARIABLESGRID, wxID_EDITVARIABLEDIALOGRETURNTYPE, 
+## wxID_EDITVARIABLEDIALOGCLASSFILTER, wxID_EDITVARIABLEDIALOGADDBUTTON,
+## wxID_EDITVARIABLEDIALOGDELETEBUTTON, wxID_EDITVARIABLEDIALOGUPBUTTON, 
+## wxID_EDITVARIABLEDIALOGDOWNBUTTON, wxID_EDITVARIABLEDIALOGSTATICTEXT1, 
+## wxID_EDITVARIABLEDIALOGSTATICTEXT2, wxID_EDITVARIABLEDIALOGSTATICTEXT3,
+##] = [wx.NewId() for _init_ctrls in range(12)]
+##
+##class EditVariableDialog(wx.Dialog):
+##    def _init_coll_flexGridSizer1_Items(self, parent):
+##        # generated method, don't edit
+##
+##        parent.AddWindow(self.MainPanel, 0, border=0, flag=0)
+##
+##    def _init_sizers(self):
+##        # generated method, don't edit
+##        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):
+##        # generated method, don't edit
+##        wx.Dialog.__init__(self, id=wxID_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=wxID_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=wxID_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=wxID_EDITVARIABLEDIALOGRETURNTYPE,
+##              name='ReturnType', parent=self.MainPanel, pos=wx.Point(124, 24),
+##              size=wx.Size(145, 24), style=0)
+##
+##        self.staticText2 = wx.StaticText(id=wxID_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=wxID_EDITVARIABLEDIALOGCLASSFILTER,
+##              name='ClassFilter', parent=self.MainPanel, pos=wx.Point(424, 24),
+##              size=wx.Size(145, 24), style=0)
+##        EVT_CHOICE(self, wxID_EDITVARIABLEDIALOGCLASSFILTER, self.OnClassFilter)
+##
+##        self.staticText3 = wx.StaticText(id=wxID_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=wxID_EDITVARIABLEDIALOGVARIABLESGRID,
+##              name='VariablesGrid', parent=self.MainPanel, pos=wx.Point(24, 80), 
+##              size=wx.Size(550, 250), style=wxVSCROLL)
+##        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=wxID_EDITVARIABLEDIALOGADDBUTTON, label='Add',
+##              name='AddButton', parent=self.MainPanel, pos=wx.Point(345, 340),
+##              size=wx.Size(72, 32), style=0)
+##        EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGADDBUTTON, self.OnAddButton)
+##
+##        self.DeleteButton = wx.Button(id=wxID_EDITVARIABLEDIALOGDELETEBUTTON, label='Delete',
+##              name='DeleteButton', parent=self.MainPanel, pos=wx.Point(425, 340),
+##              size=wx.Size(72, 32), style=0)
+##        EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGDELETEBUTTON, self.OnDeleteButton)
+##
+##        self.UpButton = wx.Button(id=wxID_EDITVARIABLEDIALOGUPBUTTON, label='^',
+##              name='UpButton', parent=self.MainPanel, pos=wx.Point(505, 340),
+##              size=wx.Size(32, 32), style=0)
+##        EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGUPBUTTON, self.OnUpButton)
+##
+##        self.DownButton = wx.Button(id=wxID_EDITVARIABLEDIALOGDOWNBUTTON, label='v',
+##              name='DownButton', parent=self.MainPanel, pos=wx.Point(545, 340),
+##              size=wx.Size(32, 32), style=0)
+##        EVT_BUTTON(self, wxID_EDITVARIABLEDIALOGDOWNBUTTON, self.OnDownButton)
+##
+##        self._init_sizers()
+##
+##    def __init__(self, parent, name, pou_type, pou_is_used, filter = "All"):
+##        self._init_ctrls(parent, name)
+##        self.ButtonSizer = self.CreateButtonSizer(wxOK|wxCANCEL|wxCENTRE)
+##        self.flexGridSizer1.Add(self.ButtonSizer, 1, wxALIGN_RIGHT)
+##        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 = [wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_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 = [wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_LEFT, wxALIGN_CENTER, wxALIGN_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:
+##            wxCallAfter(self.WarningMessage, name)
+##
+##        EVT_BUTTON(self, self.ButtonSizer.GetAffirmativeButton().GetId(), self.OnOK)
+##    
+##    def WarningMessage(self, name):
+##        message = wxMessageDialog(self, "\"%s\" is used by one or more POUs. Its interface can't be changed!"%name, "WARNING", wxOK|wxICON_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 = wxMessageDialog(self, "Form isn't complete. %s must be filled!"%text, "Error", wxOK|wxICON_ERROR)
+##            message.ShowModal()
+##            message.Destroy()
+##        else:
+##            self.EndModal(wxID_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 = wxMessageDialog(self, "\"%s\" is not a valid identifier!"%value, "Error", wxOK|wxICON_ERROR)
+##                message.ShowModal()
+##                message.Destroy()
+##                event.Veto()
+##            elif value.upper() in IEC_KEYWORDS:
+##                message = wxMessageDialog(self, "\"%s\" is a keyword. It can't be used!"%value, "Error", wxOK|wxICON_ERROR)
+##                message.ShowModal()
+##                message.Destroy()
+##                event.Veto()
+##            elif value.upper() in self.PouNames:
+##                message = wxMessageDialog(self, "A pou with \"%s\" as name exists!"%value, "Error", wxOK|wxICON_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 = wxMessageDialog(self, "A variable with \"%s\" as name exists in this pou!"%value, "Error", wxOK|wxICON_ERROR)
+##                message.ShowModal()
+##                message.Destroy()
+##                event.Veto()
+##            else:
+##                event.Skip()
+##        else:
+##            event.Skip()
+##
+##    def OnVariablesGridSelectCell(self, event):
+##        wxCallAfter(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
--- a/TextViewer.py	Thu Jul 19 15:04:41 2007 +0200
+++ b/TextViewer.py	Fri Jul 20 18:28:03 2007 +0200
@@ -118,8 +118,18 @@
 
         EVT_KEY_DOWN(self, self.OnKeyDown)
         EVT_STC_STYLENEEDED(self, wxID_TEXTVIEWER, self.OnStyleNeeded)
+        EVT_STC_DO_DROP(self, wxID_TEXTVIEWER, self.OnDoDrop)
         EVT_KILL_FOCUS(self, self.OnKillFocus)
     
+    def OnDoDrop(self, event):
+        values = eval(event.GetDragText())
+        if isinstance(values, tuple):
+            if values[1] in ["functionBlock", "program"]:
+                event.SetDragText("")
+            else:
+                event.SetDragText(values[0])
+        event.Skip()
+    
     def SetTextSyntax(self, syntax):
         self.TextSyntax = syntax
     
--- a/Viewer.py	Thu Jul 19 15:04:41 2007 +0200
+++ b/Viewer.py	Fri Jul 20 18:28:03 2007 +0200
@@ -46,6 +46,44 @@
 ] = [wx.NewId() for _init_coll_ContextualMenu_Items in range(9)]
 
 
+class ViewerDropTarget(wx.TextDropTarget):
+    
+    def __init__(self, parent):
+        wx.TextDropTarget.__init__(self)
+        self.Parent = parent
+    
+    def OnDropText(self, x, y, data):
+        values = eval(data)
+        if values[1] in ["function", "functionBlock", "program"]:
+            id = self.Parent.GetNewId()
+            block = FBD_Block(self.Parent, values[0], "", id)
+            block.SetPosition(x, y)
+            width, height = block.GetMinSize()
+            block.SetSize(width, height)
+            self.Parent.AddBlock(block)
+            self.Parent.Controler.AddCurrentElementEditingBlock(id)
+            self.Parent.RefreshBlockModel(block)
+            self.Parent.RefreshScrollBars()
+            self.Parent.Refresh()
+        else:
+            id = self.Parent.GetNewId()
+            if values[1] == "Output":
+                var_type = OUTPUT
+            elif values[1] == "InOut":
+                var_type = INPUT
+            else:
+                var_type = INPUT
+            variable = FBD_Variable(self.Parent, var_type, values[0], values[2], id)
+            variable.SetPosition(x, y)
+            width, height = variable.GetMinSize()
+            variable.SetSize(width, height)
+            self.Parent.AddBlock(variable)
+            self.Parent.Controler.AddCurrentElementEditingVariable(id, var_type)
+            self.Parent.RefreshVariableModel(variable)
+            self.Parent.RefreshScrollBars()
+            self.Parent.Refresh()
+            
+
 """
 Class that implements a Viewer based on a wxScrolledWindow for drawing and 
 manipulating graphic elements
@@ -126,6 +164,8 @@
         self.Parent = window
         self.Controler = controler
         
+        self.SetDropTarget(ViewerDropTarget(self))
+        
         # Link Viewer event to corresponding methods
         EVT_PAINT(self, self.OnPaint)
         EVT_LEFT_DOWN(self, self.OnViewerLeftDown)
@@ -208,6 +248,12 @@
         self.Comments = {}
         self.SelectedElement = None
     
+    # Remove all elements
+    def CleanView(self):
+        for block in self.Blocks.keys():
+            block.Clean()
+        self.ResetView()
+    
     # Changes Viewer mode
     def SetMode(self, mode):
         if self.Mode != mode or mode == MODE_SELECTION:
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/__init__.py	Fri Jul 20 18:28:03 2007 +0200
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+#This file is part of PLCOpenEditor, a library implementing an IEC 61131-3 editor
+#based on the plcopen standard. 
+#
+#Copyright (C): Edouard TISSERANT and Laurent BESSARD
+#
+#See COPYING file for copyrights details.
+#
+#This library is free software; you can redistribute it and/or
+#modify it under the terms of the GNU General Public
+#License as published by the Free Software Foundation; either
+#version 2.1 of the License, or (at your option) any later version.
+#
+#This library is distributed in the hope that it will be useful,
+#but WITHOUT ANY WARRANTY; without even the implied warranty of
+#MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#Lesser General Public License for more details.
+#
+#You should have received a copy of the GNU General Public
+#License along with this library; if not, write to the Free Software
+#Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+# Package initialisation
+
--- a/examples/example.xml	Thu Jul 19 15:04:41 2007 +0200
+++ b/examples/example.xml	Fri Jul 20 18:28:03 2007 +0200
@@ -354,7 +354,7 @@
             <REAL/>
           </returnType>
           <inputVars>
-            <variable name="X1">
+            <variable name="X3">
               <type>
                 <REAL/>
               </type>
--- a/plcopen/plcopen.py	Thu Jul 19 15:04:41 2007 +0200
+++ b/plcopen/plcopen.py	Fri Jul 20 18:28:03 2007 +0200
@@ -45,7 +45,11 @@
 
 PLCOpenClasses = {}
 PLCOpenTypes = {}
-GenerateClassesFromXSD(os.path.join(sys.path[0], "plcopen/TC6_XML_V10_B.xsd"))
+base_folder = ""
+for path in sys.path:
+    if os.path.isfile(os.path.join(path, "plcopen/TC6_XML_V10_B.xsd")):
+        base_folder = path
+GenerateClassesFromXSD(os.path.join(base_folder, "plcopen/TC6_XML_V10_B.xsd"))
 CreateClasses(PLCOpenClasses, PLCOpenTypes)
 
 if "dataType" in PLCOpenClasses:
--- a/plcopen/structures.py	Thu Jul 19 15:04:41 2007 +0200
+++ b/plcopen/structures.py	Fri Jul 20 18:28:03 2007 +0200
@@ -263,13 +263,13 @@
 
 
 # Keywords for Instruction List
-IL_KEYWORDS = ["LD", "LDN", "ST", "STN", "S", "R", "AND", "ANDN", "OR", "ORN",
+IL_KEYWORDS = ["TRUE", "FALSE", "LD", "LDN", "ST", "STN", "S", "R", "AND", "ANDN", "OR", "ORN",
  "XOR", "XORN", "NOT", "ADD", "SUB", "MUL", "DIV", "MOD", "GT", "GE", "EQ", "NE",
  "LE", "LT", "JMP", "JMPC", "JMPNC", "CAL", "CALC", "CALNC", "RET", "RETC", "RETNC"]
 
 
 # Keywords for Instruction List and Structured Text
-ST_KEYWORDS = ["IF", "THEN", "ELSIF", "ELSE", "END_IF", "CASE", "OF", "END_CASE", 
+ST_KEYWORDS = ["TRUE", "FALSE", "IF", "THEN", "ELSIF", "ELSE", "END_IF", "CASE", "OF", "END_CASE", 
  "FOR", "TO", "BY", "DO", "END_FOR", "WHILE", "DO", "END_WHILE", "REPEAT", "UNTIL", 
  "END_REPEAT", "EXIT", "RETURN", "NOT", "MOD", "AND", "XOR", "OR"]