def buildNodeFromShapeNode(self, item, element): """ Build a node using the given item type and QDomElement. :type item: Item :type element: QDomElement :rtype: AbstractNode """ data = element.firstChildElement('data') while not data.isNull(): if data.attribute('key', '') == self.keys['node_key']: shapeNode = data.firstChildElement('y:ShapeNode') geometry = shapeNode.firstChildElement('y:Geometry') kwargs = { 'id': element.attribute('id'), 'height': float(geometry.attribute('height')), 'width': float(geometry.attribute('width')), } node = self.factory.create(item, self.scene, **kwargs) # yEd uses the TOP-LEFT corner as (0,0) coordinate => we need to translate our # position (0,0), which is instead at the center of the shape, so that the TOP-LEFT # corner of the shape in yEd matches the TOP-LEFT corner of the shape in Eddy. # Additionally we force-snap the position to the grid so that items say aligned. pos = QPointF(float(geometry.attribute('x')), float(geometry.attribute('y'))) pos = pos + QPointF(node.width() / 2, node.height() / 2) pos = QPointF(snapF(pos.x(), DiagramScene.GridSize), snapF(pos.y(), DiagramScene.GridSize)) node.setPos(pos) return node data = data.nextSiblingElement('data') return None
def buildNodeFromUMLNoteNode(self, item, element): """ Build a node using the given item type and QDomElement. :type item: Item :type element: QDomElement :rtype: AbstractNode """ data = element.firstChildElement('data') while not data.isNull(): if data.attribute('key', '') == self.keys['node_key']: umlNoteNode = data.firstChildElement('y:UMLNoteNode') geometry = umlNoteNode.firstChildElement('y:Geometry') nodeLabel = umlNoteNode.firstChildElement('y:NodeLabel') kwargs = { 'id': element.attribute('id'), 'height': float(geometry.attribute('height')), 'width': float(geometry.attribute('width')), } node = self.factory.create(item, self.scene, **kwargs) # yEd uses the TOP-LEFT corner as (0,0) coordinate => we need to translate our # position (0,0), which is instead at the center of the shape, so that the TOP-LEFT # corner of the shape in yEd matches the TOP-LEFT corner of the shape in Eddy. # Additionally we force-snap the position to the grid so that items say aligned. pos = QPointF(float(geometry.attribute('x')), float(geometry.attribute('y'))) pos = pos + QPointF(node.width() / 2, node.height() / 2) pos = QPointF(snapF(pos.x(), DiagramScene.GridSize), snapF(pos.y(), DiagramScene.GridSize)) node.setPos(pos) node.setText(nodeLabel.text()) return node data = data.nextSiblingElement('data') return None
def buildEdgeFromGenericEdge(self, item, element): """ Build an edge using the given item type and QDomElement. :type item: Item :type element: QDomElement :rtype: AbstractEdge """ data = element.firstChildElement('data') while not data.isNull(): if data.attribute('key', '') == self.keys['edge_key']: points = [] polyLineEdge = data.firstChildElement('y:PolyLineEdge') path = polyLineEdge.firstChildElement('y:Path') collection = path.elementsByTagName('y:Point') for i in range(0, collection.count()): point = collection.at(i).toElement() pos = QPointF(float(point.attribute('x')), float(point.attribute('y'))) pos = QPointF(snapF(pos.x(), DiagramScene.GridSize), snapF(pos.y(), DiagramScene.GridSize)) points.append(pos) kwargs = { 'id': element.attribute('id'), 'source': self.scene.node(element.attribute('source')), 'target': self.scene.node(element.attribute('target')), 'breakpoints': points, } edge = self.factory.create(item, self.scene, **kwargs) # yEd, differently from the node pos whose origin matches the TOP-LEFT corner, # consider the center of the shape as original anchor point (0,0). So if the # anchor point hs a negative X it's moved a bit on the left with respect to # the center of the shape (the same applies for the Y axis) sourceP = QPointF(float(path.attribute('sx')), float(path.attribute('sy'))) sourceP = edge.source.pos() + sourceP sourceP = QPointF(snapF(sourceP.x(), DiagramScene.GridSize), snapF(sourceP.y(), DiagramScene.GridSize)) targetP = QPointF(float(path.attribute('tx')), float(path.attribute('ty'))) targetP = edge.target.pos() + targetP targetP = QPointF(snapF(targetP.x(), DiagramScene.GridSize), snapF(targetP.y(), DiagramScene.GridSize)) painterPath = edge.source.painterPath() if painterPath.contains(edge.source.mapFromScene(sourceP)): edge.source.setAnchor(edge, sourceP) painterPath = edge.target.painterPath() if painterPath.contains(edge.target.mapFromScene(targetP)): edge.target.setAnchor(edge, targetP) edge.source.addEdge(edge) edge.target.addEdge(edge) return edge data = data.nextSiblingElement('data') return None
def interactiveResize(self, mousePos): """ Handle the interactive resize of the shape. :type mousePos: QPointF """ scene = self.scene() snap = scene.mainwindow.snapToGrid size = scene.GridSize offset = self.handleSize + self.handleMove moved = self.label.moved R = QRectF(self.boundingRect()) D = QPointF(0, 0) minBoundW = self.minwidth + offset * 2 minBoundH = self.minheight + offset * 2 self.prepareGeometryChange() if self.mousePressHandle == self.handleTL: fromX = self.mousePressBound.left() fromY = self.mousePressBound.top() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() toX = snapF(toX, size, -offset, snap) toY = snapF(toY, size, -offset, snap) D.setX(toX - fromX) D.setY(toY - fromY) R.setLeft(toX) R.setTop(toY) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() - minBoundW + R.width()) R.setLeft(R.left() - minBoundW + R.width()) if R.height() < minBoundH: D.setY(D.y() - minBoundH + R.height()) R.setTop(R.top() - minBoundH + R.height()) self.selection.setLeft(R.left()) self.selection.setTop(R.top()) self.background[self.indexT] = QPointF(R.left() + R.width() / 2, R.top()) self.background[self.indexB] = QPointF( R.left() + R.width() / 2, self.background[self.indexB].y()) self.background[self.indexL] = QPointF(R.left(), R.top() + R.height() / 2) self.background[self.indexE] = QPointF(R.left(), R.top() + R.height() / 2) self.background[self.indexR] = QPointF( self.background[self.indexR].x(), R.top() + R.height() / 2) self.polygon[self.indexT] = QPointF(R.left() + R.width() / 2, R.top() + offset) self.polygon[self.indexB] = QPointF(R.left() + R.width() / 2, self.polygon[self.indexB].y()) self.polygon[self.indexL] = QPointF(R.left() + offset, R.top() + R.height() / 2) self.polygon[self.indexE] = QPointF(R.left() + offset, R.top() + R.height() / 2) self.polygon[self.indexR] = QPointF(self.polygon[self.indexR].x(), R.top() + R.height() / 2) elif self.mousePressHandle == self.handleTM: fromY = self.mousePressBound.top() toY = fromY + mousePos.y() - self.mousePressPos.y() toY = snapF(toY, size, -offset, snap) D.setY(toY - fromY) R.setTop(toY) ## CLAMP SIZE if R.height() < minBoundH: D.setY(D.y() - minBoundH + R.height()) R.setTop(R.top() - minBoundH + R.height()) self.selection.setTop(R.top()) self.background[self.indexT] = QPointF( self.background[self.indexT].x(), R.top()) self.background[self.indexL] = QPointF( self.background[self.indexL].x(), R.top() + R.height() / 2) self.background[self.indexE] = QPointF( self.background[self.indexE].x(), R.top() + R.height() / 2) self.background[self.indexR] = QPointF( self.background[self.indexR].x(), R.top() + R.height() / 2) self.polygon[self.indexT] = QPointF(self.polygon[self.indexT].x(), R.top() + offset) self.polygon[self.indexL] = QPointF(self.polygon[self.indexL].x(), R.top() + R.height() / 2) self.polygon[self.indexE] = QPointF(self.polygon[self.indexE].x(), R.top() + R.height() / 2) self.polygon[self.indexR] = QPointF(self.polygon[self.indexR].x(), R.top() + R.height() / 2) elif self.mousePressHandle == self.handleTR: fromX = self.mousePressBound.right() fromY = self.mousePressBound.top() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() toX = snapF(toX, size, +offset, snap) toY = snapF(toY, size, -offset, snap) D.setX(toX - fromX) D.setY(toY - fromY) R.setRight(toX) R.setTop(toY) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() + minBoundW - R.width()) R.setRight(R.right() + minBoundW - R.width()) if R.height() < minBoundH: D.setY(D.y() - minBoundH + R.height()) R.setTop(R.top() - minBoundH + R.height()) self.selection.setRight(R.right()) self.selection.setTop(R.top()) self.background[self.indexT] = QPointF(R.right() - R.width() / 2, R.top()) self.background[self.indexB] = QPointF( R.right() - R.width() / 2, self.background[self.indexB].y()) self.background[self.indexL] = QPointF( self.background[self.indexL].x(), R.top() + R.height() / 2) self.background[self.indexE] = QPointF( self.background[self.indexE].x(), R.top() + R.height() / 2) self.background[self.indexR] = QPointF(R.right(), R.top() + R.height() / 2) self.polygon[self.indexT] = QPointF(R.right() - R.width() / 2, R.top() + offset) self.polygon[self.indexB] = QPointF(R.right() - R.width() / 2, self.polygon[self.indexB].y()) self.polygon[self.indexL] = QPointF(self.polygon[self.indexL].x(), R.top() + R.height() / 2) self.polygon[self.indexE] = QPointF(self.polygon[self.indexE].x(), R.top() + R.height() / 2) self.polygon[self.indexR] = QPointF(R.right() - offset, R.top() + R.height() / 2) elif self.mousePressHandle == self.handleML: fromX = self.mousePressBound.left() toX = fromX + mousePos.x() - self.mousePressPos.x() toX = snapF(toX, size, -offset, snap) D.setX(toX - fromX) R.setLeft(toX) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() - minBoundW + R.width()) R.setLeft(R.left() - minBoundW + R.width()) self.selection.setLeft(R.left()) self.background[self.indexL] = QPointF( R.left(), self.mousePressBound.top() + self.mousePressBound.height() / 2) self.background[self.indexE] = QPointF( R.left(), self.mousePressBound.top() + self.mousePressBound.height() / 2) self.background[self.indexT] = QPointF( R.left() + R.width() / 2, self.background[self.indexT].y()) self.background[self.indexB] = QPointF( R.left() + R.width() / 2, self.background[self.indexB].y()) self.polygon[self.indexL] = QPointF( R.left() + offset, self.mousePressBound.top() + self.mousePressBound.height() / 2) self.polygon[self.indexE] = QPointF( R.left() + offset, self.mousePressBound.top() + self.mousePressBound.height() / 2) self.polygon[self.indexT] = QPointF(R.left() + R.width() / 2, self.polygon[self.indexT].y()) self.polygon[self.indexB] = QPointF(R.left() + R.width() / 2, self.polygon[self.indexB].y()) elif self.mousePressHandle == self.handleMR: fromX = self.mousePressBound.right() toX = fromX + mousePos.x() - self.mousePressPos.x() toX = snapF(toX, size, +offset, snap) D.setX(toX - fromX) R.setRight(toX) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() + minBoundW - R.width()) R.setRight(R.right() + minBoundW - R.width()) self.selection.setRight(R.right()) self.background[self.indexR] = QPointF( R.right(), self.mousePressBound.top() + self.mousePressBound.height() / 2) self.background[self.indexT] = QPointF( R.right() - R.width() / 2, self.background[self.indexT].y()) self.background[self.indexB] = QPointF( R.right() - R.width() / 2, self.background[self.indexB].y()) self.polygon[self.indexR] = QPointF( R.right() - offset, self.mousePressBound.top() + self.mousePressBound.height() / 2) self.polygon[self.indexT] = QPointF(R.right() - R.width() / 2, self.polygon[self.indexT].y()) self.polygon[self.indexB] = QPointF(R.right() - R.width() / 2, self.polygon[self.indexB].y()) elif self.mousePressHandle == self.handleBL: fromX = self.mousePressBound.left() fromY = self.mousePressBound.bottom() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() toX = snapF(toX, size, -offset, snap) toY = snapF(toY, size, +offset, snap) D.setX(toX - fromX) D.setY(toY - fromY) R.setLeft(toX) R.setBottom(toY) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() - minBoundW + R.width()) R.setLeft(R.left() - minBoundW + R.width()) if R.height() < minBoundH: D.setY(D.y() + minBoundH - R.height()) R.setBottom(R.bottom() + minBoundH - R.height()) self.selection.setLeft(R.left()) self.selection.setBottom(R.bottom()) self.background[self.indexT] = QPointF( R.left() + R.width() / 2, self.background[self.indexT].y()) self.background[self.indexB] = QPointF(R.left() + R.width() / 2, R.bottom()) self.background[self.indexL] = QPointF(R.left(), R.bottom() - R.height() / 2) self.background[self.indexE] = QPointF(R.left(), R.bottom() - R.height() / 2) self.background[self.indexR] = QPointF( self.background[self.indexR].x(), R.bottom() - R.height() / 2) self.polygon[self.indexT] = QPointF(R.left() + R.width() / 2, self.polygon[self.indexT].y()) self.polygon[self.indexB] = QPointF(R.left() + R.width() / 2, R.bottom() - offset) self.polygon[self.indexL] = QPointF(R.left() + offset, R.bottom() - R.height() / 2) self.polygon[self.indexE] = QPointF(R.left() + offset, R.bottom() - R.height() / 2) self.polygon[self.indexR] = QPointF(self.polygon[self.indexR].x(), R.bottom() - R.height() / 2) elif self.mousePressHandle == self.handleBM: fromY = self.mousePressBound.bottom() toY = fromY + mousePos.y() - self.mousePressPos.y() toY = snapF(toY, size, +offset, snap) D.setY(toY - fromY) R.setBottom(toY) ## CLAMP SIZE if R.height() < minBoundH: D.setY(D.y() + minBoundH - R.height()) R.setBottom(R.bottom() + minBoundH - R.height()) self.selection.setBottom(R.bottom()) self.background[self.indexB] = QPointF( self.background[self.indexB].x(), R.bottom()) self.background[self.indexL] = QPointF( self.background[self.indexL].x(), R.top() + R.height() / 2) self.background[self.indexE] = QPointF( self.background[self.indexE].x(), R.top() + R.height() / 2) self.background[self.indexR] = QPointF( self.background[self.indexR].x(), R.top() + R.height() / 2) self.polygon[self.indexB] = QPointF(self.polygon[self.indexB].x(), R.bottom() - offset) self.polygon[self.indexL] = QPointF(self.polygon[self.indexL].x(), R.top() + R.height() / 2) self.polygon[self.indexE] = QPointF(self.polygon[self.indexE].x(), R.top() + R.height() / 2) self.polygon[self.indexR] = QPointF(self.polygon[self.indexR].x(), R.top() + R.height() / 2) elif self.mousePressHandle == self.handleBR: fromX = self.mousePressBound.right() fromY = self.mousePressBound.bottom() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() toX = snapF(toX, size, +offset, snap) toY = snapF(toY, size, +offset, snap) D.setX(toX - fromX) D.setY(toY - fromY) R.setRight(toX) R.setBottom(toY) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() + minBoundW - R.width()) R.setRight(R.right() + minBoundW - R.width()) if R.height() < minBoundH: D.setY(D.y() + minBoundH - R.height()) R.setBottom(R.bottom() + minBoundH - R.height()) self.selection.setRight(R.right()) self.selection.setBottom(R.bottom()) self.background[self.indexT] = QPointF( R.right() - R.width() / 2, self.background[self.indexT].y()) self.background[self.indexB] = QPointF(R.right() - R.width() / 2, R.bottom()) self.background[self.indexL] = QPointF( self.background[self.indexL].x(), R.bottom() - R.height() / 2) self.background[self.indexE] = QPointF( self.background[self.indexE].x(), R.bottom() - R.height() / 2) self.background[self.indexR] = QPointF(R.right(), R.bottom() - R.height() / 2) self.polygon[self.indexT] = QPointF(R.right() - R.width() / 2, self.polygon[self.indexT].y()) self.polygon[self.indexB] = QPointF(R.right() - R.width() / 2, R.bottom() - offset) self.polygon[self.indexL] = QPointF(self.polygon[self.indexL].x(), R.bottom() - R.height() / 2) self.polygon[self.indexE] = QPointF(self.polygon[self.indexE].x(), R.bottom() - R.height() / 2) self.polygon[self.indexR] = QPointF(R.right() - offset, R.bottom() - R.height() / 2) self.updateHandles() self.updateTextPos(moved=moved) self.updateAnchors(self.mousePressData, D)
def run(self): """ Perform ontology import from .graphml file format. """ file = QFile(self.filepath) try: if not file.open(QIODevice.ReadOnly): raise IOError('File not found: {}'.format(self.filepath)) document = QDomDocument() if not document.setContent(file): raise ParseError('could not initialize DOM document') # 1) INITIALIZE XML ROOT ELEMENT root = document.documentElement() # 2) READ KEYS FROM THE DOCUMENT key = root.firstChildElement('key') while not key.isNull(): if key.attribute('yfiles.type', '') == 'nodegraphics': self.keys['node_key'] = key.attribute('id') if key.attribute('yfiles.type', '') == 'edgegraphics': self.keys['edge_key'] = key.attribute('id') key = key.nextSiblingElement('key') # 3) GENERATE ARBITRARY DIAGRAM SCENE self.scene = self.mainwindow.createScene(DiagramScene.MaxSize, DiagramScene.MaxSize) # 4) INITIALIZE GRAPH ELEMENT graph = root.firstChildElement('graph') # 5) GENERATE NODES element = graph.firstChildElement('node') while not element.isNull(): # noinspection PyArgumentList QApplication.processEvents() node = None item = self.itemFromGraphmlNode(element) try: if item is Item.AttributeNode: node = self.buildAttributeNode(element) elif item is Item.ComplementNode: node = self.buildComplementNode(element) elif item is Item.ConceptNode: node = self.buildConceptNode(element) elif item is Item.DatatypeRestrictionNode: node = self.buildDatatypeRestrictionNode(element) elif item is Item.DisjointUnionNode: node = self.buildDisjointUnionNode(element) elif item is Item.DomainRestrictionNode: node = self.buildDomainRestrictionNode(element) elif item is Item.EnumerationNode: node = self.buildEnumerationNode(element) elif item is Item.IndividualNode: node = self.buildIndividualNode(element) elif item is Item.IntersectionNode: node = self.buildIntersectionNode(element) elif item is Item.RangeRestrictionNode: node = self.buildRangeRestrictionNode(element) elif item is Item.RoleNode: node = self.buildRoleNode(element) elif item is Item.RoleChainNode: node = self.buildRoleChainNode(element) elif item is Item.RoleInverseNode: node = self.buildRoleInverseNode(element) elif item is Item.UnionNode: node = self.buildUnionNode(element) elif item is Item.ValueDomainNode: node = self.buildValueDomainNode(element) elif item is Item.ValueRestrictionNode: node = self.buildValueRestrictionNode(element) if not node: raise ValueError('unknown node with id {}'.format(element.attribute('id'))) except Exception as e: self.errors.append(e) else: self.scene.addItem(node) self.scene.sgnItemAdded.emit(node) self.scene.guid.update(node.id) finally: element = element.nextSiblingElement('node') # 6) GENERATE EDGES element = graph.firstChildElement('edge') while not element.isNull(): # noinspection PyArgumentList QApplication.processEvents() edge = None item = self.itemFromGraphmlNode(element) try: if item is Item.InclusionEdge: edge = self.buildInclusionEdge(element) elif item is Item.InputEdge: edge = self.buildInputEdge(element) elif item is Item.InstanceOfEdge: edge = self.buildInstanceOfEdge(element) if not edge: raise ValueError('unknown edge with id {}'.format(element.attribute('id'))) except Exception as e: self.errors.append(e) else: self.scene.addItem(edge) self.scene.sgnItemAdded.emit(edge) self.scene.guid.update(edge.id) edge.updateEdge() finally: element = element.nextSiblingElement('edge') # 7) CENTER DIAGRAM R1 = self.scene.sceneRect() R2 = self.scene.visibleRect(margin=0) moveX = snapF(((R1.right() - R2.right()) - (R2.left() - R1.left())) / 2, DiagramScene.GridSize) moveY = snapF(((R1.bottom() - R2.bottom()) - (R2.top() - R1.top())) / 2, DiagramScene.GridSize) if moveX or moveY: collection = [x for x in self.scene.items() if x.node or x.edge] for item in collection: # noinspection PyArgumentList QApplication.processEvents() item.moveBy(moveX, moveY) for item in collection: # noinspection PyArgumentList QApplication.processEvents() if item.edge: item.updateEdge() # 8) RESIZE DIAGRAM SCENE R3 = self.scene.visibleRect(margin=20) size = max(R3.width(), R3.height(), DiagramScene.MinSize) self.scene.setSceneRect(QRectF(-size / 2, -size / 2, size, size)) finally: file.close()
def interactiveResize(self, mousePos): """ Handle the interactive resize of the shape. :type mousePos: QPointF """ scene = self.scene() snap = scene.mainwindow.snapToGrid size = scene.GridSize offset = self.handleSize + self.handleMove moved = self.label.moved R = QRectF(self.boundingRect()) D = QPointF(0, 0) minBoundW = self.minwidth + offset * 2 minBoundH = self.minheight + offset * 2 self.prepareGeometryChange() if self.mousePressHandle == self.handleTL: fromX = self.mousePressBound.left() fromY = self.mousePressBound.top() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() toX = snapF(toX, size, -offset, snap) toY = snapF(toY, size, -offset, snap) D.setX(toX - fromX) D.setY(toY - fromY) R.setLeft(toX) R.setTop(toY) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() - minBoundW + R.width()) R.setLeft(R.left() - minBoundW + R.width()) if R.height() < minBoundH: D.setY(D.y() - minBoundH + R.height()) R.setTop(R.top() - minBoundH + R.height()) self.background.setLeft(R.left()) self.background.setTop(R.top()) self.selection.setLeft(R.left()) self.selection.setTop(R.top()) self.polygon.setLeft(R.left() + offset) self.polygon.setTop(R.top() + offset) elif self.mousePressHandle == self.handleTM: fromY = self.mousePressBound.top() toY = fromY + mousePos.y() - self.mousePressPos.y() toY = snapF(toY, size, -offset, snap) D.setY(toY - fromY) R.setTop(toY) ## CLAMP SIZE if R.height() < minBoundH: D.setY(D.y() - minBoundH + R.height()) R.setTop(R.top() - minBoundH + R.height()) self.background.setTop(R.top()) self.selection.setTop(R.top()) self.polygon.setTop(R.top() + offset) elif self.mousePressHandle == self.handleTR: fromX = self.mousePressBound.right() fromY = self.mousePressBound.top() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() toX = snapF(toX, size, +offset, snap) toY = snapF(toY, size, -offset, snap) D.setX(toX - fromX) D.setY(toY - fromY) R.setRight(toX) R.setTop(toY) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() + minBoundW - R.width()) R.setRight(R.right() + minBoundW - R.width()) if R.height() < minBoundH: D.setY(D.y() - minBoundH + R.height()) R.setTop(R.top() - minBoundH + R.height()) self.background.setRight(R.right()) self.background.setTop(R.top()) self.selection.setRight(R.right()) self.selection.setTop(R.top()) self.polygon.setRight(R.right() - offset) self.polygon.setTop(R.top() + offset) elif self.mousePressHandle == self.handleML: fromX = self.mousePressBound.left() toX = fromX + mousePos.x() - self.mousePressPos.x() toX = snapF(toX, size, -offset, snap) D.setX(toX - fromX) R.setLeft(toX) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() - minBoundW + R.width()) R.setLeft(R.left() - minBoundW + R.width()) self.background.setLeft(R.left()) self.selection.setLeft(R.left()) self.polygon.setLeft(R.left() + offset) elif self.mousePressHandle == self.handleMR: fromX = self.mousePressBound.right() toX = fromX + mousePos.x() - self.mousePressPos.x() toX = snapF(toX, size, +offset, snap) D.setX(toX - fromX) R.setRight(toX) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() + minBoundW - R.width()) R.setRight(R.right() + minBoundW - R.width()) self.background.setRight(R.right()) self.selection.setRight(R.right()) self.polygon.setRight(R.right() - offset) elif self.mousePressHandle == self.handleBL: fromX = self.mousePressBound.left() fromY = self.mousePressBound.bottom() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() toX = snapF(toX, size, -offset, snap) toY = snapF(toY, size, +offset, snap) D.setX(toX - fromX) D.setY(toY - fromY) R.setLeft(toX) R.setBottom(toY) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() - minBoundW + R.width()) R.setLeft(R.left() - minBoundW + R.width()) if R.height() < minBoundH: D.setY(D.y() + minBoundH - R.height()) R.setBottom(R.bottom() + minBoundH - R.height()) self.background.setLeft(R.left()) self.background.setBottom(R.bottom()) self.selection.setLeft(R.left()) self.selection.setBottom(R.bottom()) self.polygon.setLeft(R.left() + offset) self.polygon.setBottom(R.bottom() - offset) elif self.mousePressHandle == self.handleBM: fromY = self.mousePressBound.bottom() toY = fromY + mousePos.y() - self.mousePressPos.y() toY = snapF(toY, size, +offset, snap) D.setY(toY - fromY) R.setBottom(toY) ## CLAMP SIZE if R.height() < minBoundH: D.setY(D.y() + minBoundH - R.height()) R.setBottom(R.bottom() + minBoundH - R.height()) self.background.setBottom(R.bottom()) self.selection.setBottom(R.bottom()) self.polygon.setBottom(R.bottom() - offset) elif self.mousePressHandle == self.handleBR: fromX = self.mousePressBound.right() fromY = self.mousePressBound.bottom() toX = fromX + mousePos.x() - self.mousePressPos.x() toY = fromY + mousePos.y() - self.mousePressPos.y() toX = snapF(toX, size, +offset, snap) toY = snapF(toY, size, +offset, snap) D.setX(toX - fromX) D.setY(toY - fromY) R.setRight(toX) R.setBottom(toY) ## CLAMP SIZE if R.width() < minBoundW: D.setX(D.x() + minBoundW - R.width()) R.setRight(R.right() + minBoundW - R.width()) if R.height() < minBoundH: D.setY(D.y() + minBoundH - R.height()) R.setBottom(R.bottom() + minBoundH - R.height()) self.background.setRight(R.right()) self.background.setBottom(R.bottom()) self.selection.setRight(R.right()) self.selection.setBottom(R.bottom()) self.polygon.setRight(R.right() - offset) self.polygon.setBottom(R.bottom() - offset) self.updateHandles() self.updateTextPos(moved=moved) self.updateAnchors(self.mousePressData, D)
def propertyAxiomComposition(self, source, restriction): """ Returns a collection of items to be added to the given source node to compose a property axiom. :type source: AbstractNode :type restriction: class :rtype: set """ node = restriction(scene=self) edge = InputEdge(scene=self, source=source, target=node) size = DiagramScene.GridSize offsets = ( QPointF(snapF(+source.width() / 2 + 70, size), 0), QPointF(snapF(-source.width() / 2 - 70, size), 0), QPointF(0, snapF(-source.height() / 2 - 70, size)), QPointF(0, snapF(+source.height() / 2 + 70, size)), QPointF(snapF(+source.width() / 2 + 70, size), snapF(-source.height() / 2 - 70, size)), QPointF(snapF(-source.width() / 2 - 70, size), snapF(-source.height() / 2 - 70, size)), QPointF(snapF(+source.width() / 2 + 70, size), snapF(+source.height() / 2 + 70, size)), QPointF(snapF(-source.width() / 2 - 70, size), snapF(+source.height() / 2 + 70, size)), ) pos = None num = sys.maxsize rad = QPointF(node.width() / 2, node.height() / 2) for o in offsets: count = len(self.items(QRectF(source.pos() + o - rad, source.pos() + o + rad))) if count < num: num = count pos = source.pos() + o node.setPos(pos) return {node, edge}
def run(self): """ Perform ontology import from .graphml file format. """ file = QFile(self.filepath) try: if not file.open(QIODevice.ReadOnly): raise IOError('File not found: {}'.format(self.filepath)) document = QDomDocument() if not document.setContent(file): raise ParseError('could not initialize DOM document') # 1) INITIALIZE XML ROOT ELEMENT root = document.documentElement() # 2) READ KEYS FROM THE DOCUMENT key = root.firstChildElement('key') while not key.isNull(): if key.attribute('yfiles.type', '') == 'nodegraphics': self.keys['node_key'] = key.attribute('id') if key.attribute('yfiles.type', '') == 'edgegraphics': self.keys['edge_key'] = key.attribute('id') key = key.nextSiblingElement('key') # 3) GENERATE ARBITRARY DIAGRAM SCENE self.scene = self.mainwindow.createScene(DiagramScene.MaxSize, DiagramScene.MaxSize) # 4) INITIALIZE GRAPH ELEMENT graph = root.firstChildElement('graph') # 5) GENERATE NODES element = graph.firstChildElement('node') while not element.isNull(): # noinspection PyArgumentList QApplication.processEvents() node = None item = self.itemFromGraphmlNode(element) try: if item is Item.AttributeNode: node = self.buildAttributeNode(element) elif item is Item.ComplementNode: node = self.buildComplementNode(element) elif item is Item.ConceptNode: node = self.buildConceptNode(element) elif item is Item.DatatypeRestrictionNode: node = self.buildDatatypeRestrictionNode(element) elif item is Item.DisjointUnionNode: node = self.buildDisjointUnionNode(element) elif item is Item.DomainRestrictionNode: node = self.buildDomainRestrictionNode(element) elif item is Item.EnumerationNode: node = self.buildEnumerationNode(element) elif item is Item.IndividualNode: node = self.buildIndividualNode(element) elif item is Item.IntersectionNode: node = self.buildIntersectionNode(element) elif item is Item.RangeRestrictionNode: node = self.buildRangeRestrictionNode(element) elif item is Item.RoleNode: node = self.buildRoleNode(element) elif item is Item.RoleChainNode: node = self.buildRoleChainNode(element) elif item is Item.RoleInverseNode: node = self.buildRoleInverseNode(element) elif item is Item.UnionNode: node = self.buildUnionNode(element) elif item is Item.ValueDomainNode: node = self.buildValueDomainNode(element) elif item is Item.ValueRestrictionNode: node = self.buildValueRestrictionNode(element) if not node: raise ValueError('unknown node with id {}'.format( element.attribute('id'))) except Exception as e: self.errors.append(e) else: self.scene.addItem(node) self.scene.sgnItemAdded.emit(node) self.scene.guid.update(node.id) finally: element = element.nextSiblingElement('node') # 6) GENERATE EDGES element = graph.firstChildElement('edge') while not element.isNull(): # noinspection PyArgumentList QApplication.processEvents() edge = None item = self.itemFromGraphmlNode(element) try: if item is Item.InclusionEdge: edge = self.buildInclusionEdge(element) elif item is Item.InputEdge: edge = self.buildInputEdge(element) elif item is Item.InstanceOfEdge: edge = self.buildInstanceOfEdge(element) if not edge: raise ValueError('unknown edge with id {}'.format( element.attribute('id'))) except Exception as e: self.errors.append(e) else: self.scene.addItem(edge) self.scene.sgnItemAdded.emit(edge) self.scene.guid.update(edge.id) edge.updateEdge() finally: element = element.nextSiblingElement('edge') # 7) CENTER DIAGRAM R1 = self.scene.sceneRect() R2 = self.scene.visibleRect(margin=0) moveX = snapF( ((R1.right() - R2.right()) - (R2.left() - R1.left())) / 2, DiagramScene.GridSize) moveY = snapF( ((R1.bottom() - R2.bottom()) - (R2.top() - R1.top())) / 2, DiagramScene.GridSize) if moveX or moveY: collection = [ x for x in self.scene.items() if x.node or x.edge ] for item in collection: # noinspection PyArgumentList QApplication.processEvents() item.moveBy(moveX, moveY) for item in collection: # noinspection PyArgumentList QApplication.processEvents() if item.edge: item.updateEdge() # 8) RESIZE DIAGRAM SCENE R3 = self.scene.visibleRect(margin=20) size = max(R3.width(), R3.height(), DiagramScene.MinSize) self.scene.setSceneRect(QRectF(-size / 2, -size / 2, size, size)) finally: file.close()