Add support for Drag'n dropping located variables to function block creating global located variable in configuration and external variable in function block
authorLaurent Bessard
Thu, 23 May 2013 22:22:53 +0200
changeset 1171 a506e4de8f84
parent 1170 074e46cdedbc
child 1172 dff0a4e40808
Add support for Drag'n dropping located variables to function block creating global located variable in configuration and external variable in function block
IDEFrame.py
PLCControler.py
controls/VariablePanel.py
plcopen/plcopen.py
--- a/IDEFrame.py	Thu May 23 20:39:10 2013 +0200
+++ b/IDEFrame.py	Thu May 23 22:22:53 2013 +0200
@@ -1576,7 +1576,7 @@
                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames() if name != old_name]:
                         message = _("\"%s\" pou already exists!")%new_name
                         abort = True
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames()]:
                         messageDialog = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION)
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
@@ -1590,7 +1590,7 @@
                 elif item_infos["type"] == ITEM_TRANSITION:
                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
                         message = _("A POU named \"%s\" already exists!")%new_name
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames(pou_name) if name != old_name]:
                         message = _("A variable with \"%s\" as name already exists in this pou!")%new_name
                     else:
                         words = item_infos["tagname"].split("::")
@@ -1601,7 +1601,7 @@
                 elif item_infos["type"] == ITEM_ACTION:
                     if new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouNames()]:
                         message = _("A POU named \"%s\" already exists!")%new_name
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables(pou_name) if name != old_name]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames(pou_name) if name != old_name]:
                         message = _("A variable with \"%s\" as name already exists in this pou!")%new_name
                     else:
                         words = item_infos["tagname"].split("::")
@@ -1618,7 +1618,7 @@
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
                         messageDialog.Destroy()
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames()]:
                         messageDialog = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION)
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
@@ -1637,7 +1637,7 @@
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
                         messageDialog.Destroy()
-                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariables()]:
+                    elif new_name.upper() in [name.upper() for name in self.Controler.GetProjectPouVariableNames()]:
                         messageDialog = wx.MessageDialog(self, _("A POU has an element named \"%s\". This could cause a conflict. Do you wish to continue?")%new_name, _("Error"), wx.YES_NO|wx.ICON_QUESTION)
                         if messageDialog.ShowModal() == wx.ID_NO:
                             abort = True
@@ -2263,7 +2263,7 @@
         def OnAddPouMenu(event):
             dialog = PouDialog(self, pou_type)
             dialog.SetPouNames(self.Controler.GetProjectPouNames())
-            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables())
+            dialog.SetPouElementNames(self.Controler.GetProjectPouVariableNames())
             dialog.SetValues({"pouName": self.Controler.GenerateNewName(None, None, "%s%%d" % pou_type)})
             if dialog.ShowModal() == wx.ID_OK:
                 values = dialog.GetValues()
@@ -2278,7 +2278,7 @@
         def OnAddTransitionMenu(event):
             dialog = PouTransitionDialog(self)
             dialog.SetPouNames(self.Controler.GetProjectPouNames())
-            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name))
+            dialog.SetPouElementNames(self.Controler.GetProjectPouVariableNames(pou_name))
             dialog.SetValues({"transitionName": self.Controler.GenerateNewName(None, None, "transition%d")})
             if dialog.ShowModal() == wx.ID_OK: 
                 values = dialog.GetValues()
@@ -2293,7 +2293,7 @@
         def OnAddActionMenu(event):
             dialog = PouActionDialog(self)
             dialog.SetPouNames(self.Controler.GetProjectPouNames())
-            dialog.SetPouElementNames(self.Controler.GetProjectPouVariables(pou_name))
+            dialog.SetPouElementNames(self.Controler.GetProjectPouVariableNames(pou_name))
             dialog.SetValues({"actionName": self.Controler.GenerateNewName(None, None, "action%d")})
             if dialog.ShowModal() == wx.ID_OK:
                 values = dialog.GetValues()
--- a/PLCControler.py	Thu May 23 20:39:10 2013 +0200
+++ b/PLCControler.py	Thu May 23 22:22:53 2013 +0200
@@ -266,8 +266,8 @@
             return [config.getname() for config in project.getconfigurations()]
         return []
     
-    # Return project pou variables
-    def GetProjectPouVariables(self, pou_name = None, debug = False):
+    # Return project pou variable names
+    def GetProjectPouVariableNames(self, pou_name = None, debug = False):
         variables = []
         project = self.GetProject(debug)
         if project is not None:
@@ -1261,6 +1261,16 @@
             tempvar["Documentation"] = ""
 
         return tempvar
+    
+    # Add a global var to configuration to configuration
+    def AddConfigurationGlobalVar(self, config_name, type, var_name, 
+                                           location="", description=""):
+        if self.Project is not None:
+            # Found the configuration corresponding to name
+            configuration = self.Project.getconfiguration(config_name)
+            if configuration is not None:
+                # Set configuration global vars
+                configuration.addglobalVar(type, var_name, location, description)
 
     # Replace the configuration globalvars by those given
     def SetConfigurationGlobalVars(self, name, vars):
@@ -1289,6 +1299,20 @@
                         vars.append(tempvar)
         return vars
 
+    # Return configuration variable names
+    def GetConfigurationVariableNames(self, config_name = None, debug = False):
+        variables = []
+        project = self.GetProject(debug)
+        if project is not None:
+            for configuration in self.Project.getconfigurations():
+                if config_name is None or config_name == configuration.getname():
+                    variables.extend(
+                        [var.getname() for var in reduce(
+                            lambda x, y: x + y, [varlist.getvariable() 
+                                for varlist in configuration.globalVars],
+                            [])])
+        return variables
+
     # Replace the resource globalvars by those given
     def SetConfigurationResourceGlobalVars(self, config_name, name, vars):
         if self.Project is not None:
@@ -1316,6 +1340,23 @@
                         vars.append(tempvar)
         return vars
     
+    # Return resource variable names
+    def GetConfigurationResourceVariableNames(self, 
+                config_name = None, resource_name = None, debug = False):
+        variables = []
+        project = self.GetProject(debug)
+        if project is not None:
+            for configuration in self.Project.getconfigurations():
+                if config_name is None or config_name == configuration.getname():
+                    for resource in configuration.getresource():
+                        if resource_name is None or resource.getname() == resource_name:
+                            variables.extend(
+                                [var.getname() for var in reduce(
+                                    lambda x, y: x + y, [varlist.getvariable() 
+                                        for varlist in resource.globalVars],
+                                    [])])
+        return variables
+    
     # Recursively generate element name tree for a structured variable
     def GenerateVarTree(self, typename, debug = False):
         project = self.GetProject(debug)
@@ -2076,7 +2117,13 @@
     def GetEditedElementVariables(self, tagname, debug = False):
         words = tagname.split("::")
         if words[0] in ["P","T","A"]:
-            return self.GetProjectPouVariables(words[1], debug)
+            return self.GetProjectPouVariableNames(words[1], debug)
+        elif words[0] in ["C", "R"]:
+            names = self.GetConfigurationVariableNames(words[1], debug)
+            if words[0] == "R":
+                names.extend(self.GetConfigurationResourceVariableNames(
+                    words[1], words[2], debug))
+            return names
         return []
 
     def GetEditedElementCopy(self, tagname, debug = False):
--- a/controls/VariablePanel.py	Thu May 23 20:39:10 2013 +0200
+++ b/controls/VariablePanel.py	Thu May 23 22:22:53 2013 +0200
@@ -300,24 +300,59 @@
                         self.ParentWindow.SaveValues()
             elif (element_type not in ["config", "resource", "function"] and values[1] == "Global" and 
                   self.ParentWindow.Filter in ["All", "Interface", "External"] or
-                  element_type in ["config", "resource", "program"] and values[1] == "location"):
+                  element_type != "function" and values[1] == "location"):
                 if values[1] == "location":
                     var_name = values[3]
                 else:
                     var_name = values[0]
                 tagname = self.ParentWindow.GetTagName()
-                if var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetProjectPouNames(self.ParentWindow.Debug)]:
+                if var_name.upper() in [name.upper() 
+                        for name in self.ParentWindow.Controler.\
+                            GetProjectPouNames(self.ParentWindow.Debug)]:
                     message = _("\"%s\" pou already exists!")%var_name
-                elif not var_name.upper() in [name.upper() for name in self.ParentWindow.Controler.GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
+                elif not var_name.upper() in [name.upper() 
+                        for name in self.ParentWindow.Controler.\
+                            GetEditedElementVariables(tagname, self.ParentWindow.Debug)]:
                     var_infos = self.ParentWindow.DefaultValue.copy()
                     var_infos["Name"] = var_name
                     var_infos["Type"] = values[2]
                     if values[1] == "location":
-                        if element_type == "program":
-                            var_infos["Class"] = "Local"
+                        location = values[0]
+                        if not location.startswith("%"):
+                            dialog = wx.SingleChoiceDialog(self.ParentWindow.ParentWindow.ParentWindow, 
+                                  _("Select a variable class:"), _("Variable class"), 
+                                  ["Input", "Output", "Memory"], 
+                                  wx.DEFAULT_DIALOG_STYLE|wx.OK|wx.CANCEL)
+                            if dialog.ShowModal() == wx.ID_OK:
+                                selected = dialog.GetSelection()
+                            else:
+                                selected = None
+                            dialog.Destroy()
+                            if selected is None:
+                                return
+                            if selected == 0:
+                                location = "%I" + location
+                            elif selected == 1:
+                                location = "%Q" + location
+                            else:
+                                location = "%M" + location
+                        if element_type == "functionBlock":
+                            configs = self.ParentWindow.Controler.GetProjectConfigNames(
+                                                                self.ParentWindow.Debug)
+                            if len(configs) == 0:
+                                return
+                            if not var_name.upper() in [name.upper() 
+                                for name in self.ParentWindow.Controler.\
+                                    GetConfigurationVariableNames(configs[0])]:
+                                self.ParentWindow.Controler.AddConfigurationGlobalVar(
+                                    configs[0], values[2], var_name, location, "")
+                            var_infos["Class"] = "External"
                         else:
-                            var_infos["Class"] = "Global"
-                        var_infos["Location"] = values[0]
+                            if element_type == "program":
+                                var_infos["Class"] = "Local"
+                            else:
+                                var_infos["Class"] = "Global"
+                            var_infos["Location"] = location
                     else:
                         var_infos["Class"] = "External"
                     var_infos["Number"] = len(self.ParentWindow.Values)
--- a/plcopen/plcopen.py	Thu May 23 20:39:10 2013 +0200
+++ b/plcopen/plcopen.py	Thu May 23 22:22:53 2013 +0200
@@ -855,6 +855,35 @@
 
 cls = PLCOpenClasses.get("configurations_configuration", None)
 if cls:
+    
+    def addglobalVar(self, type, name, location="", description=""):
+        globalvars = self.getglobalVars()
+        if len(globalvars) == 0:
+            globalvars.append(PLCOpenClasses["varList"]())
+        var = PLCOpenClasses["varListPlain_variable"]()
+        var.setname(name)
+        var_type = PLCOpenClasses["dataType"]()
+        if type in [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]:
+            if type == "STRING":
+                var_type.setcontent({"name" : "string", "value" : PLCOpenClasses["elementaryTypes_string"]()})
+            elif type == "WSTRING":
+                var_type.setcontent({"name" : "wstring", "value" : PLCOpenClasses["elementaryTypes_wstring"]()})
+            else:
+                var_type.setcontent({"name" : type, "value" : None})
+        else:
+            derived_type = PLCOpenClasses["derivedTypes_derived"]()
+            derived_type.setname(type)
+            var_type.setcontent({"name" : "derived", "value" : derived_type})
+        var.settype(var_type)
+        if location != "":
+            var.setaddress(location)
+        if description != "":
+            ft = PLCOpenClasses["formattedText"]()
+            ft.settext(description)
+            var.setdocumentation(ft)
+        globalvars[-1].appendvariable(var)
+    setattr(cls, "addglobalVar", addglobalVar)
+    
     def updateElementName(self, old_name, new_name):
         _updateConfigurationResourceElementName(self, old_name, new_name)
         for resource in self.getresource():