diff -r 25ffba02b6a8 -r ed27a676d5c9 PLCControler.py --- a/PLCControler.py Fri Jul 24 10:47:35 2009 +0200 +++ b/PLCControler.py Fri Jul 24 11:07:33 2009 +0200 @@ -1580,6 +1580,148 @@ return self.GetProjectPouVariables(words[1], debug) return [] + def GetEditedElementCopy(self, tagname, debug = False): + element = self.GetEditedElement(tagname, debug) + if element is not None: + name = element.__class__.__name__ + return element.generateXMLText(name.split("_")[-1], 0) + return "" + + def GetEditedElementInstancesCopy(self, tagname, blocks_id = None, wires = None, debug = False): + element = self.GetEditedElement(tagname, debug) + text = "" + if element is not None: + wires = dict([(wire, True) for wire in wires if wire[0] in blocks_id and wire[1] in blocks_id]) + for id in blocks_id: + instance = element.getinstance(id) + if instance is not None: + instance_copy = self.Copy(instance) + instance_copy.filterConnections(wires) + name = instance_copy.__class__.__name__ + text += instance_copy.generateXMLText(name.split("_")[-1], 0) + return text + + def GenerateNewName(self, tagname, name, format, exclude={}, debug=False): + names = exclude.copy() + names.update(dict([(varname.upper(), True) for varname in self.GetEditedElementVariables(tagname, debug)])) + element = self.GetEditedElement(tagname, debug) + if element is not None: + for instance in element.getinstances(): + if isinstance(instance, (plcopen.sfcObjects_step, plcopen.commonObjects_connector, plcopen.commonObjects_continuation)): + names[instance.getname()] = True + i = 1 + while names.get(name.upper(), False): + name = (format%i) + i += 1 + return name + + CheckPasteCompatibility = {"SFC": lambda name: True, + "LD": lambda name: not name.startswith("sfcObjects"), + "FBD": lambda name: name.startswith("fbdObjects") or name.startswith("commonObjects")} + + def PasteEditedElementInstances(self, tagname, text, new_pos, middle=False, debug=False): + element = self.GetEditedElement(tagname, debug) + element_name, element_type = self.GetEditedElementType(tagname, debug) + if element is not None: + bodytype = element.getbodyType() + + # Get edited element type scaling + scaling = None + project = self.GetProject(debug) + if project is not None: + properties = project.getcontentHeader() + scaling = properties["scaling"][bodytype] + + # Get ids already by all the instances in edited element + used_id = dict([(instance.getlocalId(), True) for instance in element.getinstances()]) + new_id = {} + + text = "%s"%text + + try: + tree = minidom.parseString(text) + except: + return _("Invalid plcopen element(s)!!!") + instances = [] + exclude = {} + for root in tree.childNodes: + if root.nodeType == tree.ELEMENT_NODE and root.nodeName == "paste": + for child in root.childNodes: + if child.nodeType == tree.ELEMENT_NODE: + classname = plcopen.ElementNameToClass[child.nodeName] + if not self.CheckPasteCompatibility[bodytype](classname): + return _("\"%s\" element can't be paste here!!!")%child.nodeName + classobj = getattr(plcopen, classname, None) + if classobj is not None: + instance = classobj() + instance.loadXMLTree(child) + if child.nodeName == "block": + blockname = instance.getinstanceName() + if blockname is not None: + blocktype = instance.gettypeName() + if element_type == "function": + return _("FunctionBlock \"%s\" can't be paste in a Function!!!")%blocktype + blockname = self.GenerateNewName(tagname, blockname, "Block%d", debug=debug) + exclude[blockname] = True + instance.setinstanceName(blockname) + self.AddEditedElementPouVar(tagname, blocktype, blockname) + elif child.nodeName == "step": + stepname = self.GenerateNewName(tagname, instance.getname(), "Step%d", exclude, debug) + exclude[stepname] = True + instance.setname(stepname) + localid = instance.getlocalId() + if not used_id.has_key(localid): + new_id[localid] = True + instances.append((child.nodeName, instance)) + + if len(instances) == 0: + return _("Invalid plcopen element(s)!!!") + + idx = 1 + translate_id = {} + bbox = plcopen.rect() + for name, instance in instances: + localId = instance.getlocalId() + bbox.union(instance.getBoundingBox()) + if used_id.has_key(localId): + while used_id.has_key(idx) or new_id.has_key(idx): + idx += 1 + new_id[idx] = True + instance.setlocalId(idx) + translate_id[localId] = idx + + x, y, width, height = bbox.bounding_box() + if middle: + new_pos[0] -= width / 2 + new_pos[1] -= height / 2 + else: + new_pos = map(lambda x: x + 30, new_pos) + if scaling[0] != 0 and scaling[1] != 0: + min_pos = map(lambda x: 30 / x, scaling) + minx = round(min_pos[0]) + if int(min_pos[0]) == round(min_pos[0]): + minx += 1 + miny = round(min_pos[1]) + if int(min_pos[1]) == round(min_pos[1]): + miny += 1 + minx *= scaling[0] + miny *= scaling[1] + new_pos = (max(minx, round(new_pos[0] / scaling[0]) * scaling[0]), + max(miny, round(new_pos[1] / scaling[1]) * scaling[1])) + else: + new_pos = (max(30, new_pos[0]), max(30, new_pos[1])) + diff = (new_pos[0] - x, new_pos[1] - y) + + connections = {} + for name, instance in instances: + connections.update(instance.updateConnectionsId(translate_id)) + if getattr(instance, "setexecutionOrderId", None) is not None: + instance.setexecutionOrderId(0) + instance.translate(*diff) + element.addinstance(name, instance) + + return new_id, connections + # Return the current pou editing informations def GetEditedElementInstanceInfos(self, tagname, id = None, exclude = [], debug = False): infos = {}