diff -r 9ab97d517ae8 -r c1c92d068ac5 PLCControler.py --- 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)