示例#1
0
    def mouseMoveEvent(self, mouseEvent):
        """
        Executed when then mouse is moved on the scene.
        :type mouseEvent: QGraphicsSceneMouseEvent
        """
        mouseButtons = mouseEvent.buttons()
        mousePos = mouseEvent.scenePos()

        if mouseButtons & QtCore.Qt.LeftButton:
            if self.mode is DiagramMode.LabelMove:

                #############################################
                # LABEL MOVE
                #################################

                if self.isLabelMove():
                    snapToGrid = self.session.action('toggle_grid').isChecked()
                    point = self.mp_LabelPos + mousePos - self.mp_Pos
                    point = snap(point, BlackBirdDiagram.GridSize / 2,
                                 snapToGrid)
                    delta = point - self.mp_LabelPos
                    self.mp_Label.setPos(self.mp_LabelPos + delta)

            else:

                if self.mode is DiagramMode.Idle:
                    if self.mp_Node:
                        self.setMode(DiagramMode.NodeMove)

                if self.mode is DiagramMode.NodeMove:

                    #############################################
                    # ITEM MOVEMENT
                    #################################

                    if self.isNodeMove():

                        snapToGrid = self.session.action(
                            'toggle_grid').isChecked()
                        point = self.mp_NodePos + mousePos - self.mp_Pos
                        point = snap(point, BlackBirdDiagram.GridSize,
                                     snapToGrid)
                        delta = point - self.mp_NodePos
                        edges = set()

                        for edge, breakpoints in self.mp_Data['edges'].items():
                            for i in range(len(breakpoints)):
                                edge.breakpoints[i] = breakpoints[i] + delta

                        for node, data in self.mp_Data['nodes'].items():
                            edges |= set(node.edges)
                            node.setPos(data['pos'] + delta)
                            for edge, pos in data['anchors'].items():
                                node.setAnchor(edge, pos + delta)

                        for edge in edges:
                            edge.updateEdge()

        super().mouseMoveEvent(mouseEvent)
示例#2
0
    def breakPointMove(self, breakpoint, mousePos):
        """
        Move the selected breakpoint.
        :type breakpoint: int
        :type mousePos: QtCore.QPointF
        """
        snapToGrid = self.session.action('toggle_grid').isChecked()
        mousePos = snap(mousePos, self.diagram.GridSize, snapToGrid)
        source = self.source
        target = self.target
        breakpointPos = self.breakpoints[breakpoint]
        sourcePath = self.mapFromItem(source, source.painterPath())
        targetPath = self.mapFromItem(target, target.painterPath())
        if sourcePath.contains(mousePos):
            # Mouse is inside the source node, use the intersection as the breakpoint position if it exists.
            pos = source.intersection(
                QtCore.QLineF(source.pos(), breakpointPos)) or mousePos
        elif targetPath.contains(mousePos):
            # Mouse is inside the target node, use the intersection as the breakpoint position if it exists.
            pos = target.intersection(
                QtCore.QLineF(target.pos(), breakpointPos)) or mousePos
        else:
            # Mouse is outside both source and target node, use this as the breakpoint position.
            pos = mousePos

        self.breakpoints[breakpoint] = pos
示例#3
0
 def breakPointMove(self, breakpoint, mousePos):
     """
     Move the selected breakpoint.
     :type breakpoint: int
     :type mousePos: QtCore.QPointF
     """
     snapToGrid = self.session.action('toggle_grid').isChecked()
     self.breakpoints[breakpoint] = snap(mousePos, self.diagram.GridSize, snapToGrid)
示例#4
0
 def breakPointMove(self, breakpoint, mousePos):
     """
     Move the selected breakpoint.
     :type breakpoint: int
     :type mousePos: QtCore.QPointF
     """
     snapToGrid = self.session.action('toggle_grid').isChecked()
     self.breakpoints[breakpoint] = snap(mousePos, self.diagram.GridSize,
                                         snapToGrid)
示例#5
0
    def dropEvent(self, dropEvent):
        """
        Executed when a dragged element is dropped on the diagram.
        :type dropEvent: QGraphicsSceneDragDropEvent
        """
        super().dropEvent(dropEvent)
        if dropEvent.mimeData().hasFormat('text/plain') and Item.valueOf(dropEvent.mimeData().text()):
            snapToGrid = self.session.action('toggle_grid').isChecked()
            node = self.factory.create(Item.valueOf(dropEvent.mimeData().text()))
            data = dropEvent.mimeData().data(dropEvent.mimeData().text())
            iri = None

            if data is not None:
                data_str = ''

                for i in range(0, data.size()):
                    data_str = data_str + data.at(i)

                if data_str is not '':
                    data_comma_seperated = data_str.split(',')
                    iri = data_comma_seperated[0]
                    rc = data_comma_seperated[1]
                    txt = data_comma_seperated[2]
                    node.setText(txt)
                    node.remaining_characters = rc

            node.setPos(snap(dropEvent.scenePos(), Diagram.GridSize, snapToGrid))
            commands = []

            if iri is not None:
                Duplicate_dict_1 = self.project.copy_IRI_prefixes_nodes_dictionaries(self.project.IRI_prefixes_nodes_dict, dict())
                Duplicate_dict_2 = self.project.copy_IRI_prefixes_nodes_dictionaries(self.project.IRI_prefixes_nodes_dict, dict())
                Duplicate_dict_1 = self.project.addIRINodeEntry(Duplicate_dict_1, iri, node)

                if Duplicate_dict_1 is not None:
                    pass

                commands.append(CommandProjectDisconnectSpecificSignals(self.project))
                commands.append(CommandProjetSetIRIPrefixesNodesDict(self.project, Duplicate_dict_2, Duplicate_dict_1, [iri], None))
            commands.append(CommandNodeAdd(self, node))

            if iri is not None:
                commands.append(CommandProjetSetIRIPrefixesNodesDict(self.project, Duplicate_dict_2, Duplicate_dict_1, [iri], None))
                commands.append(CommandProjectConnectSpecificSignals(self.project))

            if any(commands):
                self.session.undostack.beginMacro('node Add - {0}'.format(node.name))
                for command in commands:
                    if command:
                        self.session.undostack.push(command)
                self.session.undostack.endMacro()

            self.sgnItemInsertionCompleted.emit(node, dropEvent.modifiers())
            dropEvent.setDropAction(QtCore.Qt.CopyAction)
            dropEvent.accept()
        else:
            dropEvent.ignore()
示例#6
0
 def parseAnchorPos(edge, node, x, y):
     """
     Parse the given edge
     :type edge: AbstractEdge
     :type node: AbstractNode
     :type x: str
     :type y: str
     :rtype: QtCore.QPointF
     """
     path = node.painterPath()
     pos = QtCore.QPointF(float(x), float(y))
     if path.contains(pos):
         return snap(node.mapToScene(pos), Diagram.GridSize)
     return node.anchor(edge)
示例#7
0
 def parsePos(geometry):
     """
     Parse the position of the node properly translating it from yEd coordinate system.
     :type geometry: QDomElement
     :rtype: QtCore.QPointF
     """
     # 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.
     # We additionally snap the position to the grid so that items stay perfectly aligned.
     x = float(geometry.attribute('x'))
     y = float(geometry.attribute('y'))
     w = float(geometry.attribute('width'))
     h = float(geometry.attribute('height'))
     return snap(QtCore.QPointF(x, y) + QtCore.QPointF(w / 2, h / 2), Diagram.GridSize)
示例#8
0
 def dropEvent(self, dropEvent):
     """
     Executed when a dragged element is dropped on the diagram.
     :type dropEvent: QGraphicsSceneDragDropEvent
     """
     super().dropEvent(dropEvent)
     if dropEvent.mimeData().hasFormat('text/plain'):
         snapToGrid = self.session.action('toggle_grid').isChecked()
         node = self.factory.create(Item.forValue(dropEvent.mimeData().text()))
         node.setPos(snap(dropEvent.scenePos(), Diagram.GridSize, snapToGrid))
         self.session.undostack.push(CommandNodeAdd(self, node))
         self.sgnItemInsertionCompleted.emit(node, dropEvent.modifiers())
         dropEvent.setDropAction(QtCore.Qt.CopyAction)
         dropEvent.accept()
     else:
         dropEvent.ignore()
示例#9
0
 def dropEvent(self, dropEvent):
     """
     Executed when a dragged element is dropped on the diagram.
     :type dropEvent: QGraphicsSceneDragDropEvent
     """
     super().dropEvent(dropEvent)
     if dropEvent.mimeData().hasFormat('text/plain'):
         snapToGrid = self.session.action('toggle_grid').isChecked()
         node = self.factory.create(
             Item.valueOf(dropEvent.mimeData().text()))
         node.setPos(
             snap(dropEvent.scenePos(), Diagram.GridSize, snapToGrid))
         self.session.undostack.push(CommandNodeAdd(self, node))
         self.sgnItemInsertionCompleted.emit(node, dropEvent.modifiers())
         dropEvent.setDropAction(QtCore.Qt.CopyAction)
         dropEvent.accept()
     else:
         dropEvent.ignore()
示例#10
0
    def anchorMove(self, node, mousePos):
        """
        Move the selected anchor point.
        :type node: AbstractNode
        :type mousePos: QtCore.QPointF
        """
        nodePos = node.pos()
        snapToGrid = self.session.action('toggle_grid').isChecked()
        mousePos = snap(mousePos, self.diagram.GridSize, snapToGrid)
        path = self.mapFromItem(node, node.painterPath())
        if path.contains(mousePos):
            # Mouse is inside the shape => use this position as anchor point.
            pos = nodePos if distance(mousePos, nodePos) < 10.0 else mousePos
        else:
            # Mouse is outside the shape => use the intersection point as anchor point.
            pos = node.intersection(QtCore.QLineF(mousePos, nodePos))
            for pair in set(permutations([-1, -1, 0, 0, 1, 1], 2)):
                p = pos + QtCore.QPointF(*pair)
                if path.contains(p):
                    pos = p
                    break

        node.setAnchor(self, pos)
示例#11
0
    def anchorMove(self, node, mousePos):
        """
        Move the selected anchor point.
        :type node: AbstractNode
        :type mousePos: QtCore.QPointF
        """
        nodePos = node.pos()
        snapToGrid = self.session.action('toggle_grid').isChecked()
        mousePos = snap(mousePos, self.diagram.GridSize, snapToGrid)
        path = self.mapFromItem(node, node.painterPath())
        if path.contains(mousePos):
            # Mouse is inside the shape => use this position as anchor point.
            pos = nodePos if distance(mousePos, nodePos) < 10.0 else mousePos
        else:
            # Mouse is outside the shape => use the intersection point as anchor point.
            pos = node.intersection(QtCore.QLineF(mousePos, nodePos))
            for pair in set(permutations([-1, -1, 0, 0, 1, 1], 2)):
                p = pos + QtCore.QPointF(*pair)
                if path.contains(p):
                    pos = p
                    break

        node.setAnchor(self, pos)
示例#12
0
    def dropEvent(self, dropEvent):
        """
        Executed when a dragged element is dropped on the diagram.
        :type dropEvent: QGraphicsSceneDragDropEvent
        """
        super().dropEvent(dropEvent)
        if dropEvent.mimeData().hasFormat('text/plain') and Item.valueOf(
                dropEvent.mimeData().text()):
            snapToGrid = self.session.action('toggle_grid').isChecked()
            #TODO
            nodeType = dropEvent.mimeData().text()
            if Item.ConceptIRINode <= int(
                    dropEvent.mimeData().text()) <= Item.IndividualIRINode:
                #New node associated with IRI object
                #node = ConceptNode(diagram=self)
                node = self.factory.create(
                    Item.valueOf(dropEvent.mimeData().text()))
                node.setPos(
                    snap(dropEvent.scenePos(), Diagram.GridSize, snapToGrid))
                data = dropEvent.mimeData().data(dropEvent.mimeData().text())
                if not data:
                    #new element
                    if isinstance(node, FacetNode):
                        self.session.doOpenConstrainingFacetBuilder(node)
                    elif isinstance(node, OntologyEntityNode) or isinstance(
                            node, OntologyEntityResizableNode):
                        self.session.doOpenIRIBuilder(node)
                    elif isinstance(node, LiteralNode):
                        self.session.doOpenLiteralBuilder(node)
                else:
                    #copy of existing element (e.g. drag and drop from ontology explorer)
                    data_str = str(data, encoding='utf-8')
                    iri = self.project.getIRI(data_str)
                    node.iri = iri
                    self.doAddOntologyEntityNode(node)
                    node.doUpdateNodeLabel()
            else:
                #Old node type
                node = self.factory.create(
                    Item.valueOf(dropEvent.mimeData().text()))
                data = dropEvent.mimeData().data(dropEvent.mimeData().text())
                iri = None

                if data is not None:
                    data_str = str(data, encoding='utf-8')
                    if data_str is not '':
                        data_comma_seperated = data_str.split(',')
                        iri = data_comma_seperated[0]
                        rc = data_comma_seperated[1]
                        txt = data_comma_seperated[2]
                        node.setText(txt)
                        node.remaining_characters = rc

                node.setPos(
                    snap(dropEvent.scenePos(), Diagram.GridSize, snapToGrid))
                commands = []
                #node.emptyMethod()

                if iri is not None:
                    Duplicate_dict_1 = self.project.copy_IRI_prefixes_nodes_dictionaries(
                        self.project.IRI_prefixes_nodes_dict, dict())
                    Duplicate_dict_2 = self.project.copy_IRI_prefixes_nodes_dictionaries(
                        self.project.IRI_prefixes_nodes_dict, dict())
                    Duplicate_dict_1 = self.project.addIRINodeEntry(
                        Duplicate_dict_1, iri, node)

                    if Duplicate_dict_1 is not None:
                        pass

                    #commands.append(CommandProjetSetIRIPrefixesNodesDict(self.project, Duplicate_dict_2, Duplicate_dict_1, [iri], None))
                commands.append(CommandNodeAdd(self, node))

                if any(commands):
                    self.session.undostack.beginMacro('node Add - {0}'.format(
                        node.name))
                    for command in commands:
                        if command:
                            self.session.undostack.push(command)
                    self.session.undostack.endMacro()

            self.sgnItemInsertionCompleted.emit(node, dropEvent.modifiers())
            dropEvent.setDropAction(QtCore.Qt.CopyAction)
            dropEvent.accept()
        else:
            dropEvent.ignore()
示例#13
0
    def anchorMove(self, node, mousePos):
        """
        Move the selected anchor point.
        :type node: AbstractNode
        :type mousePos: QtCore.QPointF
        """
        # Only allow anchor movement for concept nodes
        if node.type() != Item.ConceptIRINode:
            node.setAnchor(self, node.pos())
            return

        nodePos = node.pos()
        snapToGrid = self.session.action('toggle_grid').isChecked()
        mousePos = snap(mousePos, self.diagram.GridSize, snapToGrid)
        path = self.mapFromItem(node, node.painterPath())
        breakpoint = (self.breakpoints[-1] if node == self.target else self.breakpoints[0]) \
            if len(self.breakpoints) > 0 else self.other(node).anchor(self)

        if path.contains(breakpoint):
            # If the source is inside the node then there will be no intersection
            if path.contains(self.other(node).anchor(self)):
                return

            # Breakpoint is inside the shape => use the source anchor
            breakpoint = self.other(node).anchor(self)

        if path.contains(mousePos):
            # Mouse is inside the shape => use its position as the endpoint.
            endpoint = mousePos
        else:
            # Mouse is outside the shape => use the intersection as the endpoint.
            endpoint = node.intersection(QtCore.QLineF(nodePos, mousePos))

        if distance(nodePos, endpoint) < 10.0:
            # When close enough use the node center as the anchor point.
            pos = nodePos
        else:
            # Otherwise compute the closest intersection between the breakpoint and the endpoint.
            pos = node.intersection(QtCore.QLineF(breakpoint, endpoint))
            minDistance = distance(breakpoint, pos)
            for intersection in node.intersections(
                    QtCore.QLineF(breakpoint, endpoint)):
                intersDistance = distance(breakpoint, intersection)
                if (intersDistance < minDistance):
                    minDistance = intersDistance
                    pos = intersection

            if not path.contains(pos):
                # Ensure anchor is inside the path
                lineToBreakpoint = QtCore.QLineF(breakpoint, endpoint)
                direction = lineToBreakpoint.unitVector()
                normal = lineToBreakpoint.normalVector().unitVector()
                if path.contains(
                        pos + QtCore.QPointF(direction.dx(), direction.dy())):
                    pos = pos + QtCore.QPointF(direction.dx(), direction.dy())
                elif path.contains(
                        pos - QtCore.QPointF(direction.dx(), direction.dy())):
                    pos = pos - QtCore.QPointF(direction.dx(), direction.dy())
                elif path.contains(pos +
                                   QtCore.QPointF(normal.dx(), normal.dy())):
                    pos = pos + QtCore.QPointF(normal.dx(), normal.dy())
                elif path.contains(pos -
                                   QtCore.QPointF(normal.dx(), normal.dy())):
                    pos = pos - QtCore.QPointF(normal.dx(), normal.dy())
                else:  # Lower right corner
                    pos = pos - QtCore.QPointF(0.5, 0.5)

        node.setAnchor(self, pos)
示例#14
0
    def mouseMoveEvent(self, mouseEvent):
        """
        Executed when then mouse is moved on the scene.
        :type mouseEvent: QGraphicsSceneMouseEvent
        """
        mouseButtons = mouseEvent.buttons()
        mousePos = mouseEvent.scenePos()

        if mouseButtons & QtCore.Qt.LeftButton:

            if self.mode is DiagramMode.EdgeAdd:

                #############################################
                # EDGE INSERTION
                #################################

                if self.isEdgeAdd():

                    statusBar = self.session.statusBar()
                    edge = self.mp_Edge
                    edge.updateEdge(target=mousePos)

                    previousNode = self.mo_Node
                    if previousNode:
                        previousNode.updateNode(selected=False)

                    currentNode = first(self.items(mousePos, edges=False, skip={edge.source}))
                    if currentNode:
                        self.mo_Node = currentNode
                        pvr = self.project.profile.checkEdge(edge.source, edge, currentNode)
                        currentNode.updateNode(selected=False, valid=pvr.isValid())
                        if not pvr.isValid():
                            statusBar.showMessage(pvr.message())
                        else:
                            statusBar.clearMessage()
                    else:
                        statusBar.clearMessage()
                        self.mo_Node = None
                        self.project.profile.reset()

            elif self.mode is DiagramMode.LabelMove:

                #############################################
                # LABEL MOVE
                #################################

                if self.isLabelMove():

                    snapToGrid = self.session.action('toggle_grid').isChecked()
                    point = self.mp_LabelPos + mousePos - self.mp_Pos
                    point = snap(point, Diagram.GridSize / 2, snapToGrid)
                    delta = point - self.mp_LabelPos
                    self.mp_Label.setPos(self.mp_LabelPos + delta)

            else:

                if self.mode is DiagramMode.Idle:
                    if self.mp_Node:
                        self.setMode(DiagramMode.NodeMove)

                if self.mode is DiagramMode.NodeMove:

                    #############################################
                    # ITEM MOVEMENT
                    #################################

                    if self.isNodeMove():

                        snapToGrid = self.session.action('toggle_grid').isChecked()
                        point = self.mp_NodePos + mousePos - self.mp_Pos
                        point = snap(point, Diagram.GridSize, snapToGrid)
                        delta = point - self.mp_NodePos
                        edges = set()

                        for edge, breakpoints in self.mp_Data['edges'].items():
                            for i in range(len(breakpoints)):
                                edge.breakpoints[i] = breakpoints[i] + delta

                        for node, data in self.mp_Data['nodes'].items():
                            edges |= set(node.edges)
                            node.setPos(data['pos'] + delta)
                            for edge, pos in data['anchors'].items():
                                node.setAnchor(edge, pos + delta)

                        for edge in edges:
                            edge.updateEdge()

        super().mouseMoveEvent(mouseEvent)
示例#15
0
    def mousePressEvent(self, mouseEvent):
        """
        Executed when a mouse button is clicked on the scene.
        :type mouseEvent: QGraphicsSceneMouseEvent
        """
        mouseModifiers = mouseEvent.modifiers()
        mouseButtons = mouseEvent.buttons()
        mousePos = mouseEvent.scenePos()

        if mouseButtons & QtCore.Qt.LeftButton:

            if self.mode is DiagramMode.NodeAdd:

                #############################################
                # NODE INSERTION
                #################################

                snapToGrid = self.session.action('toggle_grid').isChecked()
                node = self.factory.create(Item.forValue(self.modeParam))
                node.setPos(snap(mousePos, Diagram.GridSize, snapToGrid))
                self.session.undostack.push(CommandNodeAdd(self, node))
                self.sgnItemInsertionCompleted.emit(node, mouseEvent.modifiers())

            elif self.mode is DiagramMode.EdgeAdd:

                #############################################
                # EDGE INSERTION
                #################################

                node = first(self.items(mousePos, edges=False))
                if node:
                    edge = self.factory.create(Item.forValue(self.modeParam), source=node)
                    edge.updateEdge(target=mousePos)
                    self.mp_Edge = edge
                    self.addItem(edge)

            else:

                # Execute super at first since this may change the diagram
                # mode: some actions are directly handle by graphics items
                # (i.e: edge breakpoint move, edge anchor move, node shape
                # resize) and we need to check whether any of them is being
                # performed before handling the even locally.
                super().mousePressEvent(mouseEvent)

                if self.mode is DiagramMode.Idle:

                    if mouseModifiers & QtCore.Qt.ShiftModifier:

                        #############################################
                        # LABEL MOVE
                        #################################

                        item = first(self.items(mousePos, nodes=False, edges=False, labels=True))
                        if item and item.isMovable():
                            self.clearSelection()
                            self.mp_Label = item
                            self.mp_LabelPos = item.pos()
                            self.mp_Pos = mousePos
                            self.setMode(DiagramMode.LabelMove)

                    else:

                        #############################################
                        # ITEM SELECTION
                        #################################

                        item = first(self.items(mousePos, labels=True))
                        if item:

                            if item.isLabel():
                                # If we are hitting a label, check whether the label
                                # is overlapping it's parent item and such item is
                                # also intersecting the current mouse position: if so,
                                # use the parent item as placeholder for the selection.
                                parent = item.parentItem()
                                items = self.items(mousePos)
                                item =  parent if parent in items else None

                            if item:

                                if mouseModifiers & QtCore.Qt.ControlModifier:
                                    # CTRL => support item multi selection.
                                    item.setSelected(not item.isSelected())
                                else:
                                    if self.selectedItems():
                                        # Some elements have been already selected in the
                                        # diagram, during a previous mouse press event.
                                        if not item.isSelected():
                                            # There are some items selected but we clicked
                                            # on a node which is not currently selected, so
                                            # make this node the only selected one.
                                            self.clearSelection()
                                            item.setSelected(True)
                                    else:
                                        # No item (nodes or edges) is selected and we just
                                        # clicked on one so make sure to select this item and
                                        # because selectedItems() filters out item Label's,
                                        # clear out the selection on the diagram.
                                        self.clearSelection()
                                        item.setSelected(True)

                                # If we have some nodes selected we need to prepare data for a
                                # possible item move operation: we need to make sure to retrieve
                                # the node below the mouse cursor that will act as as mouse grabber
                                # to compute delta  movements for each component in the selection.
                                selected = self.selectedNodes()
                                if selected:
                                    self.mp_Node = first(self.items(mousePos, edges=False))
                                    if self.mp_Node:
                                        self.mp_NodePos = self.mp_Node.pos()
                                        self.mp_Pos = mousePos
                                        self.mp_Data = {
                                            'nodes': {
                                                node: {
                                                    'anchors': {k: v for k, v in node.anchors.items()},
                                                    'pos': node.pos(),
                                                } for node in selected},
                                            'edges': {}
                                        }
                                        # Figure out if the nodes we are moving are sharing edges:
                                        # if that's the case, move the edge together with the nodes
                                        # (which actually means moving the edge breakpoints).
                                        for node in self.mp_Data['nodes']:
                                            for edge in node.edges:
                                                if edge not in self.mp_Data['edges']:
                                                    if edge.other(node).isSelected():
                                                        self.mp_Data['edges'][edge] = edge.breakpoints[:]
示例#16
0
    def mousePressEvent(self, mouseEvent):
        """
        Executed when a mouse button is clicked on the scene.
        :type mouseEvent: QGraphicsSceneMouseEvent
        """
        self.project.colour_items_in_case_of_unsatisfiability_or_inconsistent_ontology(
        )

        mouseModifiers = mouseEvent.modifiers()
        mouseButtons = mouseEvent.buttons()
        mousePos = mouseEvent.scenePos()

        if mouseButtons & QtCore.Qt.LeftButton:

            if self.mode is DiagramMode.NodeAdd:

                #############################################
                # NODE INSERTION
                #################################

                snapToGrid = self.session.action('toggle_grid').isChecked()
                node = self.factory.create(Item.valueOf(self.modeParam))
                node.setPos(snap(mousePos, Diagram.GridSize, snapToGrid))
                if isinstance(node, OntologyEntityNode) or isinstance(
                        node, OntologyEntityResizableNode):
                    self.session.doOpenIRIBuilder(node)
                elif isinstance(node, FacetNode):
                    self.session.doOpenConstrainingFacetBuilder(node)
                elif isinstance(node, LiteralNode):
                    self.session.doOpenLiteralBuilder(node)
                else:
                    self.session.undostack.push(CommandNodeAdd(self, node))
                self.sgnItemInsertionCompleted.emit(node,
                                                    mouseEvent.modifiers())

            elif self.mode is DiagramMode.EdgeAdd:

                #############################################
                # EDGE INSERTION
                #################################

                node = first(self.items(mousePos, edges=False))
                if node:
                    edge = self.factory.create(Item.valueOf(self.modeParam),
                                               source=node)
                    edge.updateEdge(target=mousePos)
                    self.mp_Edge = edge
                    self.addItem(edge)

            else:

                # Execute super at first since this may change the diagram
                # mode: some actions are directly handle by graphics items
                # (i.e: edge breakpoint move, edge anchor move, node shape
                # resize) and we need to check whether any of them is being
                # performed before handling the even locally.
                super().mousePressEvent(mouseEvent)

                if self.mode is DiagramMode.Idle:

                    if mouseModifiers & QtCore.Qt.ShiftModifier:

                        #############################################
                        # LABEL MOVE
                        #################################

                        item = first(
                            self.items(mousePos,
                                       nodes=False,
                                       edges=False,
                                       labels=True))
                        if item and item.isMovable():
                            self.clearSelection()
                            self.mp_Label = item
                            self.mp_LabelPos = item.pos()
                            self.mp_Pos = mousePos
                            self.setMode(DiagramMode.LabelMove)

                    else:

                        #############################################
                        # ITEM SELECTION
                        #################################

                        item = first(self.items(mousePos, labels=True))
                        if item:

                            if item.isLabel():
                                # If we are hitting a label, check whether the label
                                # is overlapping it's parent item and such item is
                                # also intersecting the current mouse position: if so,
                                # use the parent item as placeholder for the selection.
                                parent = item.parentItem()
                                items = self.items(mousePos)
                                item = parent if parent in items else None

                            if item:

                                if mouseModifiers & QtCore.Qt.ControlModifier:
                                    # CTRL => support item multi selection.
                                    item.setSelected(not item.isSelected())
                                else:
                                    if self.selectedItems():
                                        # Some elements have been already selected in the
                                        # diagram, during a previous mouse press event.
                                        if not item.isSelected():
                                            # There are some items selected but we clicked
                                            # on a node which is not currently selected, so
                                            # make this node the only selected one.
                                            self.clearSelection()
                                            item.setSelected(True)
                                    else:
                                        # No item (nodes or edges) is selected and we just
                                        # clicked on one so make sure to select this item and
                                        # because selectedItems() filters out item Label's,
                                        # clear out the selection on the diagram.
                                        self.clearSelection()
                                        item.setSelected(True)

                                # If we have some nodes selected we need to prepare data for a
                                # possible item move operation: we need to make sure to retrieve
                                # the node below the mouse cursor that will act as as mouse grabber
                                # to compute delta  movements for each component in the selection.
                                selected = self.selectedNodes()
                                if selected:
                                    self.mp_Node = first(
                                        self.items(mousePos, edges=False))
                                    if self.mp_Node:
                                        self.mp_NodePos = self.mp_Node.pos()
                                        self.mp_Pos = mousePos
                                        self.mp_Data = self.setupMove(selected)
示例#17
0
    def mouseMoveEvent(self, mouseEvent):
        """
        Executed when then mouse is moved on the scene.
        :type mouseEvent: QGraphicsSceneMouseEvent
        """
        mouseButtons = mouseEvent.buttons()
        mousePos = mouseEvent.scenePos()

        if mouseButtons & QtCore.Qt.LeftButton:

            if self.mode is DiagramMode.EdgeAdd:

                #############################################
                # EDGE INSERTION
                #################################

                if self.isEdgeAdd():

                    statusBar = self.session.statusBar()
                    edge = self.mp_Edge
                    edge.updateEdge(target=mousePos)

                    previousNode = self.mo_Node
                    if previousNode:
                        previousNode.updateNode(selected=False)

                    currentNode = first(
                        self.items(mousePos, edges=False, skip={edge.source}))
                    if currentNode:
                        self.mo_Node = currentNode
                        pvr = self.project.profile.checkEdge(
                            edge.source, edge, currentNode)
                        currentNode.updateNode(selected=False,
                                               valid=pvr.isValid())
                        if not pvr.isValid():
                            statusBar.showMessage(pvr.message())
                        else:
                            statusBar.clearMessage()
                    else:
                        statusBar.clearMessage()
                        self.mo_Node = None
                        self.project.profile.reset()

            elif self.mode is DiagramMode.LabelMove:

                #############################################
                # LABEL MOVE
                #################################

                if self.isLabelMove():

                    snapToGrid = self.session.action('toggle_grid').isChecked()
                    point = self.mp_LabelPos + mousePos - self.mp_Pos
                    point = snap(point, Diagram.GridSize / 2, snapToGrid)
                    delta = point - self.mp_LabelPos
                    self.mp_Label.setPos(self.mp_LabelPos + delta)

            else:

                if self.mode is DiagramMode.Idle:
                    if self.mp_Node:
                        self.setMode(DiagramMode.NodeMove)

                if self.mode is DiagramMode.NodeMove:

                    #############################################
                    # ITEM MOVEMENT
                    #################################

                    if self.isNodeMove():

                        snapToGrid = self.session.action(
                            'toggle_grid').isChecked()
                        point = self.mp_NodePos + mousePos - self.mp_Pos
                        point = snap(point, Diagram.GridSize, snapToGrid)
                        delta = point - self.mp_NodePos
                        edges = set()

                        for edge, breakpoints in self.mp_Data['edges'].items():
                            for i in range(len(breakpoints)):
                                edge.breakpoints[i] = breakpoints[i] + delta

                        for node, data in self.mp_Data['nodes'].items():
                            edges |= set(node.edges)
                            node.setPos(data['pos'] + delta)
                            for edge, pos in data['anchors'].items():
                                node.setAnchor(edge, pos + delta)

                        for edge in edges:
                            edge.updateEdge()

        super().mouseMoveEvent(mouseEvent)