--- a/plcopen/plcopen.py Fri Jul 24 10:47:35 2009 +0200
+++ b/plcopen/plcopen.py Fri Jul 24 11:07:33 2009 +0200
@@ -45,8 +45,54 @@
QualifierList = {"N" : False, "R" : False, "S" : False, "L" : True, "D" : True,
"P" : False, "P0" : False, "P1" : False, "SD" : True, "DS" : True, "SL" : True}
+
+def _init_and_compare(function, v1, v2):
+ if v1 is None:
+ return v2
+ if v2 is not None:
+ return function(v1, v2)
+ return v1
+
+"""
+Helper class for bounding_box calculation
+"""
+class rect:
+
+ def __init__(self, x=None, y=None, width=None, height=None):
+ self.x_min = x
+ self.x_max = None
+ self.y_min = y
+ self.y_max = None
+ if width is not None and x is not None:
+ self.x_max = x + width
+ if height is not None and y is not None:
+ self.y_max = y + height
+
+ def update(self, x, y):
+ self.x_min = _init_and_compare(min, self.x_min, x)
+ self.x_max = _init_and_compare(max, self.x_max, x)
+ self.y_min = _init_and_compare(min, self.y_min, y)
+ self.y_max = _init_and_compare(max, self.y_max, y)
+
+ def union(self, rect):
+ self.x_min = _init_and_compare(min, self.x_min, rect.x_min)
+ self.x_max = _init_and_compare(max, self.x_max, rect.x_max)
+ self.y_min = _init_and_compare(min, self.y_min, rect.y_min)
+ self.y_max = _init_and_compare(max, self.y_max, rect.y_max)
+
+ def bounding_box(self):
+ width = height = None
+ if self.x_min is not None and self.x_max is not None:
+ width = self.x_max - self.x_min
+ if self.y_min is not None and self.y_max is not None:
+ height = self.y_max - self.y_min
+ return self.x_min, self.y_min, width, height
+
+
PLCOpenClasses = GenerateClassesFromXSD(os.path.join(os.path.split(__file__)[0], "TC6_XML_V10_B.xsd"))
+ElementNameToClass = {}
+
cls = PLCOpenClasses.get("formattedText", None)
if cls:
def updateElementName(self, old_name, new_name):
@@ -1223,10 +1269,120 @@
def sety(self, y):
self.position.sety(y)
+def _getBoundingBox(self):
+ return rect(self.getx(), self.gety(), self.getwidth(), self.getheight())
+
+def _getConnectionsBoundingBox(connectionPointIn):
+ bbox = rect()
+ connections = connectionPointIn.getconnections()
+ if connections is not None:
+ for connection in connections:
+ for x, y in connection.getpoints():
+ bbox.update(x, y)
+ return bbox
+
+def _getBoundingBoxSingle(self):
+ bbox = _getBoundingBox(self)
+ if self.connectionPointIn is not None:
+ bbox.union(_getConnectionsBoundingBox(self.connectionPointIn))
+ return bbox
+
+def _getBoundingBoxMultiple(self):
+ bbox = _getBoundingBox(self)
+ for connectionPointIn in self.getconnectionPointIn():
+ bbox.union(_getConnectionsBoundingBox(connectionPointIn))
+ return bbox
+
+def _filterConnections(connectionPointIn, localId, connections):
+ in_connections = connectionPointIn.getconnections()
+ if in_connections is not None:
+ to_delete = []
+ for i, connection in enumerate(in_connections):
+ connected = connection.getrefLocalId()
+ if not connections.has_key((localId, connected)) and \
+ not connections.has_key((connected, localId)):
+ to_delete.append(i)
+ to_delete.reverse()
+ for i in to_delete:
+ connectionPointIn.removeconnection(i)
+
+def _filterConnectionsSingle(self, connections):
+ if self.connectionPointIn is not None:
+ _filterConnections(self.connectionPointIn, self.localId, connections)
+
+def _filterConnectionsMultiple(self, connections):
+ for connectionPointIn in self.getconnectionPointIn():
+ _filterConnections(connectionPointIn, self.localId, connections)
+
+def _getconnectionsdefinition(instance, connections_end):
+ id = instance.getlocalId()
+ return dict([((id, end), True) for end in connections_end])
+
+def _updateConnectionsId(connectionPointIn, translation):
+ connections_end = []
+ connections = connectionPointIn.getconnections()
+ if connections is not None:
+ for connection in connections:
+ refLocalId = connection.getrefLocalId()
+ new_reflocalId = translation.get(refLocalId, refLocalId)
+ connection.setrefLocalId(new_reflocalId)
+ connections_end.append(new_reflocalId)
+ return connections_end
+
+def _updateConnectionsIdSingle(self, translation):
+ connections_end = []
+ if self.connectionPointIn is not None:
+ connections_end = _updateConnectionsId(self.connectionPointIn, translation)
+ return _getconnectionsdefinition(self, connections_end)
+
+def _updateConnectionsIdMultiple(self, translation):
+ connections_end = []
+ for connectionPointIn in self.getconnectionPointIn():
+ connections_end.extend(_updateConnectionsId(connectionPointIn, translation))
+ return _getconnectionsdefinition(self, connections_end)
+
+def _translate(self, dx, dy):
+ self.setx(self.getx() + dx)
+ self.sety(self.gety() + dy)
+
+def _translateConnections(connectionPointIn, dx, dy):
+ connections = connectionPointIn.getconnections()
+ if connections is not None:
+ for connection in connections:
+ for position in connection.getposition():
+ position.setx(position.getx() + dx)
+ position.sety(position.gety() + dy)
+
+def _translateSingle(self, dx, dy):
+ _translate(self, dx, dy)
+ if self.connectionPointIn is not None:
+ _translateConnections(self.connectionPointIn, dx, dy)
+
+def _translateMultiple(self, dx, dy):
+ _translate(self, dx, dy)
+ for connectionPointIn in self.getconnectionPointIn():
+ _translateConnections(connectionPointIn, dx, dy)
+
def _updateElementName(self, old_name, new_name):
pass
+_connectionsFunctions = {
+ "bbox": {"none": _getBoundingBox,
+ "single": _getBoundingBoxSingle,
+ "multiple": _getBoundingBoxMultiple},
+ "translate": {"none": _translate,
+ "single": _translateSingle,
+ "multiple": _translateMultiple},
+ "filter": {"none": lambda self, connections: None,
+ "single": _filterConnectionsSingle,
+ "multiple": _filterConnectionsMultiple},
+ "update": {"none": lambda self, translation: None,
+ "single": _updateConnectionsIdSingle,
+ "multiple": _updateConnectionsIdMultiple}
+}
+
def _initElementClass(name, classname, connectionPointInType="none"):
+ ElementNameToClass[name] = classname
cls = PLCOpenClasses.get(classname, None)
if cls:
setattr(cls, "getx", getx)
@@ -1234,6 +1390,10 @@
setattr(cls, "setx", setx)
setattr(cls, "sety", sety)
setattr(cls, "updateElementName", _updateElementName)
+ setattr(cls, "getBoundingBox", _connectionsFunctions["bbox"][connectionPointInType])
+ setattr(cls, "translate", _connectionsFunctions["translate"][connectionPointInType])
+ setattr(cls, "filterConnections", _connectionsFunctions["filter"][connectionPointInType])
+ setattr(cls, "updateConnectionsId", _connectionsFunctions["update"][connectionPointInType])
return cls
def _getexecutionOrder(instance, specific_values):
@@ -1414,6 +1574,24 @@
self.typeName = new_name
setattr(cls, "updateElementName", updateElementName)
+ def filterConnections(self, connections):
+ for input in self.inputVariables.getvariable():
+ _filterConnections(input.connectionPointIn, self.localId, connections)
+ setattr(cls, "filterConnections", filterConnections)
+
+ def updateConnectionsId(self, translation):
+ connections_end = []
+ for input in self.inputVariables.getvariable():
+ connections_end.extend(_updateConnectionsId(input.connectionPointIn, translation))
+ return _getconnectionsdefinition(self, connections_end)
+ setattr(cls, "updateConnectionsId", updateConnectionsId)
+
+ def translate(self, dx, dy):
+ _translate(self, dx, dy)
+ for input in self.inputVariables.getvariable():
+ _translateConnections(input.connectionPointIn, dx, dy)
+ setattr(cls, "translate", translate)
+
cls = _initElementClass("leftPowerRail", "ldObjects_leftPowerRail")
if cls:
setattr(cls, "getinfos", _getpowerrailinfosFunction("leftPowerRail"))