Пример #1
0
    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
Пример #2
0
    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
Пример #3
0
    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
Пример #4
0
    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)
Пример #5
0
    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()
Пример #6
0
    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)
Пример #7
0
    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}
Пример #8
0
    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()
Пример #9
0
    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