PLCControler.py
changeset 431 c1c92d068ac5
parent 407 0a324a874981
parent 428 3b19c34bac04
child 435 893d04aff708
--- a/PLCControler.py	Mon Sep 21 12:06:51 2009 +0200
+++ b/PLCControler.py	Tue Sep 22 09:56:02 2009 +0200
@@ -251,7 +251,7 @@
     def GetProjectConfigNames(self, debug = False):
         project = self.GetProject(debug)
         if project is not None:
-            return [config.getName() for config in project.getconfigurations()]
+            return [config.getname() for config in project.getconfigurations()]
         return []
     
     # Return project pou variables
@@ -599,6 +599,51 @@
                 self.Project.insertpou(-1, new_pou)
                 self.BufferProject()
     
+    def PastePou(self, pou_type, pou_xml):
+        '''
+        Adds the POU defined by 'pou_xml' to the current project with type 'pou_type'
+        '''
+        try:
+            tree = minidom.parseString(pou_xml)
+            root = tree.childNodes[0]
+        except:
+            return _("Couldn't paste non-POU object.")
+
+        if root.nodeName == "pou":
+            new_pou = plcopen.pous_pou()
+            new_pou.loadXMLTree(root)
+
+            name = new_pou.getname()
+            orig_type = new_pou.getpouType()
+
+            # prevent violations of POU content restrictions:
+            # function blocks cannot be pasted as functions,
+            # programs cannot be pasted as functions or function blocks
+            if orig_type == 'functionBlock' and pou_type == 'function' or \
+            orig_type == 'program' and pou_type in ['function', 'functionBlock']:
+                return _('''%s "%s" can't be pasted as a %s.''') % (orig_type, name, pou_type)
+ 
+            while self.Project.getpou(name):
+                # a POU with that name already exists.
+                # make a new name and test if a POU with that name exists.
+
+                # append an incrementing numeric suffix to the POU name. it
+                # doesn't count up perfectly, but as long as it's unique who cares?
+                if name[-1] >= '0' and name[-1] <= '9':
+                    last_digit = int(name[-1])
+                    name = name[0:-1] + str(last_digit+1)
+                else:
+                    name = name + '1'
+
+            # we've found a name that does not already exist, use it
+            new_pou.setname(name)
+            new_pou.setpouType(pou_type)
+
+            self.Project.insertpou(-1, new_pou)
+            self.BufferProject()
+        else:
+            return _("Couldn't paste non-POU object.")
+
     # Remove a Pou from project
     def ProjectRemovePou(self, pou_name):
         if self.Project is not None:
@@ -737,9 +782,9 @@
     def ChangeConfigurationResourceName(self, config_name, old_name, new_name):
         if self.Project is not None:
             # Found the resource corresponding to old name and change its name to new name
-            resource = self.Project.getconfigurationResource(config_name)
+            resource = self.Project.getconfigurationResource(config_name, old_name)
             if resource is not None:
-                resource.setName(new_name)
+                resource.setname(new_name)
                 self.BufferProject()
     
     # Return the type of the pou given by its name
@@ -850,6 +895,7 @@
             # Create variable and change its properties
             tempvar = plcopen.varListPlain_variable()
             tempvar.setname(var["Name"])
+
             var_type = plcopen.dataType()
             if var["Type"] in self.GetBaseTypes():
                 if var["Type"] == "STRING":
@@ -863,6 +909,7 @@
                 derived_type.setname(var["Type"])
                 var_type.setcontent({"name" : "derived", "value" : derived_type})
             tempvar.settype(var_type)
+
             if var["Initial Value"] != "":
                 value = plcopen.value()
                 value.setvalue(var["Initial Value"])
@@ -871,9 +918,62 @@
                 tempvar.setaddress(var["Location"])
             else:
                 tempvar.setaddress(None)
+            if var['Documentation'] != "":
+                ft = plcopen.formattedText()
+                ft.settext(var['Documentation'])
+                tempvar.setdocumentation(ft)
+
             # Add variable to varList
             current_varlist.appendvariable(tempvar)
         return varlist_list
+    
+    def GetVariableDictionary(self, varlist, var):
+        '''
+        convert a PLC variable to the dictionary representation
+        returned by Get*Vars)
+        '''
+
+        tempvar = {"Name" : var.getname()}
+
+        vartype_content = var.gettype().getcontent()
+        if vartype_content["name"] == "derived":
+            tempvar["Type"] = vartype_content["value"].getname()
+        elif vartype_content["name"] in ["string", "wstring"]:
+            tempvar["Type"] = vartype_content["name"].upper()
+        else:
+            tempvar["Type"] = vartype_content["name"]
+
+        tempvar["Edit"] = True
+
+        initial = var.getinitialValue()
+        if initial:
+            tempvar["Initial Value"] = initial.getvalue()
+        else:
+            tempvar["Initial Value"] = ""
+
+        address = var.getaddress()
+        if address:
+            tempvar["Location"] = address
+        else:
+            tempvar["Location"] = ""
+
+        if varlist.getretain():
+            tempvar["Retain"] = "Yes"
+        else:
+            tempvar["Retain"] = "No"
+
+        if varlist.getconstant():
+            tempvar["Constant"] = "Yes"
+        else:
+            tempvar["Constant"] = "No"
+
+        doc = var.getdocumentation()
+        if doc:
+            tempvar["Documentation"] = doc.gettext()
+        else:
+            tempvar["Documentation"] = ""
+
+        return tempvar
 
     # Replace the configuration globalvars by those given
     def SetConfigurationGlobalVars(self, name, vars):
@@ -897,33 +997,8 @@
                 # Extract variables from every varLists
                 for varlist in configuration.getglobalVars():
                     for var in varlist.getvariable():
-                        tempvar = {"Name" : var.getname(), "Class" : "Global"}
-                        vartype_content = var.gettype().getcontent()
-                        if vartype_content["name"] == "derived":
-                            tempvar["Type"] = vartype_content["value"].getname()
-                        elif vartype_content["name"] in ["string", "wstring"]:
-                            tempvar["Type"] = vartype_content["name"].upper()
-                        else:
-                            tempvar["Type"] = vartype_content["name"]
-                        tempvar["Edit"] = True
-                        initial = var.getinitialValue()
-                        if initial:
-                            tempvar["Initial Value"] = initial.getvalue()
-                        else:
-                            tempvar["Initial Value"] = ""
-                        address = var.getaddress()
-                        if address:
-                            tempvar["Location"] = address
-                        else:
-                            tempvar["Location"] = ""
-                        if varlist.getretain():
-                            tempvar["Retain"] = "Yes"
-                        else:
-                            tempvar["Retain"] = "No"
-                        if varlist.getconstant():
-                            tempvar["Constant"] = "Yes"
-                        else:
-                            tempvar["Constant"] = "No"
+                        tempvar = self.GetVariableDictionary(varlist, var)
+                        tempvar["Class"] = "Global"
                         vars.append(tempvar)
         return vars
 
@@ -949,33 +1024,8 @@
                 # Extract variables from every varLists
                 for varlist in resource.getglobalVars():
                     for var in varlist.getvariable():
-                        tempvar = {"Name" : var.getname(), "Class" : "Global"}
-                        vartype_content = var.gettype().getcontent()
-                        if vartype_content["name"] == "derived":
-                            tempvar["Type"] = vartype_content["value"].getname()
-                        elif vartype_content["name"] in ["string", "wstring"]:
-                            tempvar["Type"] = vartype_content["name"].upper()
-                        else:
-                            tempvar["Type"] = vartype_content["name"]
-                        tempvar["Edit"] = True
-                        initial = var.getinitialValue()
-                        if initial:
-                            tempvar["Initial Value"] = initial.getvalue()
-                        else:
-                            tempvar["Initial Value"] = ""
-                        address = var.getaddress()
-                        if address:
-                            tempvar["Location"] = address
-                        else:
-                            tempvar["Location"] = ""
-                        if varlist.getretain():
-                            tempvar["Retain"] = "Yes"
-                        else:
-                            tempvar["Retain"] = "No"
-                        if varlist.getconstant():
-                            tempvar["Constant"] = "Yes"
-                        else:
-                            tempvar["Constant"] = "No"
+                        tempvar = self.GetVariableDictionary(varlist, var)
+                        tempvar["Class"] = "Global"
                         vars.append(tempvar)
         return vars
     
@@ -1014,7 +1064,7 @@
                             tree.append((element.getname(), element_type["name"], ([], [])))
                     return tree, []
         return [], []
-    
+
     # Return the interface for the given pou
     def GetPouInterfaceVars(self, pou, debug = False):
         vars = []
@@ -1023,36 +1073,16 @@
             # Extract variables from every varLists
             for type, varlist in pou.getvars():
                 for var in varlist.getvariable():
-                    tempvar = {"Name" : var.getname(), "Class" : type, "Tree" : ([], [])}
+                    tempvar = self.GetVariableDictionary(varlist, var)
+
+                    tempvar["Class"] = type
+                    tempvar["Tree"] = ([], [])
+
                     vartype_content = var.gettype().getcontent()
                     if vartype_content["name"] == "derived":
-                        tempvar["Type"] = vartype_content["value"].getname()
                         tempvar["Edit"] = not pou.hasblock(tempvar["Name"])
                         tempvar["Tree"] = self.GenerateVarTree(tempvar["Type"], debug)
-                    else:
-                        if vartype_content["name"] in ["string", "wstring"]:
-                            tempvar["Type"] = vartype_content["name"].upper()
-                        else:
-                            tempvar["Type"] = vartype_content["name"]
-                        tempvar["Edit"] = True
-                    initial = var.getinitialValue()
-                    if initial:
-                        tempvar["Initial Value"] = initial.getvalue()
-                    else:
-                        tempvar["Initial Value"] = ""
-                    address = var.getaddress()
-                    if address:
-                        tempvar["Location"] = address
-                    else:
-                        tempvar["Location"] = ""
-                    if varlist.getretain():
-                        tempvar["Retain"] = "Yes"
-                    else:
-                        tempvar["Retain"] = "No"
-                    if varlist.getconstant():
-                        tempvar["Constant"] = "Yes"
-                    else:
-                        tempvar["Constant"] = "No"
+
                     vars.append(tempvar)
         return vars
 
@@ -1231,9 +1261,13 @@
             return project.GetBaseType(type)
         return None
 
-    # Return Base Types
     def GetBaseTypes(self):
-        return [value for value in TypeHierarchy.keys() if not value.startswith("ANY")]
+        '''
+        return the list of datatypes defined in IEC 61131-3.
+        TypeHierarchy_list has a rough order to it (e.g. SINT, INT, DINT, ...),
+        which makes it easy for a user to find a type in a menu.
+        '''
+        return [x for x,y in TypeHierarchy_list if not x.startswith("ANY")]
 
     def IsOfType(self, type, reference, debug = False):
         project = self.GetProject(debug)
@@ -1661,9 +1695,13 @@
                 if root.nodeType == tree.ELEMENT_NODE and root.nodeName == "paste":
                     for child in root.childNodes:
                         if child.nodeType == tree.ELEMENT_NODE:
+                            if not child.nodeName in plcopen.ElementNameToClass:
+                                return _("\"%s\" element can't be pasted here!!!")%child.nodeName
+
                             classname = plcopen.ElementNameToClass[child.nodeName]
                             if not self.CheckPasteCompatibility[bodytype](classname):
-                                return _("\"%s\" element can't be paste here!!!")%child.nodeName
+                                return _("\"%s\" element can't be pasted here!!!")%child.nodeName
+
                             classobj = getattr(plcopen, classname, None)
                             if classobj is not None:
                                 instance = classobj()
@@ -1673,7 +1711,7 @@
                                     if blockname is not None:
                                         blocktype = instance.gettypeName()
                                         if element_type == "function":
-                                            return _("FunctionBlock \"%s\" can't be paste in a Function!!!")%blocktype
+                                            return _("FunctionBlock \"%s\" can't be pasted in a Function!!!")%blocktype
                                         blockname = self.GenerateNewName(tagname, blockname, "Block%d", debug=debug)
                                         exclude[blockname] = True
                                         instance.setinstanceName(blockname)