--- 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 = "<paste>%s</paste>"%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 = {}