Ejemplo n.º 1
0
    def __create__(self):

        self.__gridSize = 35

        self.__isGridActive = True
        self.__isAltModifier = False
        self.__isControlModifier = False
        self.__isNodePressed = False

        self.__kDummy = EDummy()
        self.__kDummy.setGridSize(self.__gridSize)
        self.__kDummy.onPress.connect(self.__onNodePressed)
        self.__kDummy.onEditEnd.connect(self.__onDummyEdit)

        self.addItem(self.__kDummy)

        self.__kSelected = ESceneSelection()

        self.addItem(self.__kSelected)

        self.__kCutLine = QGraphicsLineItem()
        self.__kCutLine.hide()

        self.addItem(self.__kCutLine)

        self.__nodes = {}
        self.__connections = {}

        self.__graphHandle = EGraphHandle()
        self.__graphHandle.Message.connect(self.__messageFilter)

        self.__propEditor = EPropertyEditor()
        self.addItem(self.__propEditor)
Ejemplo n.º 2
0
    def __create__(self):

        self.__gridSize = 35

        self.__isGridActive = True
        self.__isAltModifier = False
        self.__isControlModifier = False

        self.__kDummy = EDummy()
        self.__kDummy.setGridSize(self.__gridSize)
        self.__kDummy.onPress.connect(self.__onNodePressed)

        self.addItem(self.__kDummy)

        self.__nodes = {}
        self.__connections = {}

        self.__graphHandle = EGraphHandle()
        self.__graphHandle.Message.connect(self.__messageFilter)
Ejemplo n.º 3
0
    def __init__(self):
        EObject.__init__(self)

        self.__scene = None
        self.__regNodes = {}
        self.__graphHandle = EGraphHandle()
Ejemplo n.º 4
0
class EController(EObject):

    kMessageNodeAdded = EObject()
    kMessageNodeRemoved = EObject()

    kMessageNodeUpdate = EObject()

    kMessageEditBegin = EObject()
    kMessageEditEnd = EObject()

    kMessageUnknown = EObject()
    kMessageInternalError = EObject()

    kMessageConnectionMade = EObject()
    kMessageConnectionBroke = EObject()

    def __init__(self):
        EObject.__init__(self)

        self.__scene = None
        self.__regNodes = {}
        self.__graphHandle = EGraphHandle()

    @property
    def Handle(self):
        return self.__graphHandle

    @property
    def NodeTypes(self):
        return self.__regNodes.keys()

    def setScene(self, scene):
        self.__scene = scene

    def getScene(self):
        return self.__scene

    def registerNode(self, nodeName, nodeHandle):
        nodeHandle.NodeType = nodeName
        self.__regNodes[nodeName] = nodeHandle

    def getNode(self, theNode):
        if isinstance(theNode, uuid.UUID):
            return self.__scene.getNodes()[theNode].Handle

        elif isinstance(theNode, basestring):
            for nodeId, node in self.__scene.getNodes().iteritems():
                if theNode == node.Name:
                    return node.Handle

        return None

    def getTransform(self, theNode):

        node = None

        if isinstance(theNode, ENodeHandle):
            return self.__scene.getNodes()[self.getNode(theNode.Id).Id]

        if isinstance(theNode, basestring):
            return self.__scene.getNodes()[self.getNode(theNode).Id]

        return node

    def createNode(self, nodeType, nodeName=None):

        if self.__regNodes.has_key(nodeType):
            nodeHandle = self.__graphHandle.addHandle(self.__regNodes[nodeType]())

            if nodeName is None:
                nodeName = nodeHandle.NodeType

            self.Message.emit(self.kMessageNodeAdded.setData([nodeHandle, nodeName]))

            return nodeHandle

        return None

    def deleteNode(self, node):

        node = self.getNode(node)

        for conn in node.getConnections():
            self.Message.emit(self.kMessageConnectionBroke.setData(conn))

        theId = self.__graphHandle.delHandle(node.Id)

        self.Message.emit(self.kMessageNodeRemoved.setData(theId))

    def toInternal(self, data):

        if isinstance(data, EAttribute):
            return data

        if isinstance(data, basestring):
            splitResult = data.split('.')

            if len(splitResult) == 2:
                if splitResult[0] in self.ls():
                    node = self.getNode(splitResult[0])

                    if splitResult[1] in [attr.Name for attr in node.lsAttributes()]:
                        return node.getAttribute(splitResult[1])

            return None

        if isinstance(data, uuid.UUID):
            data = self.__graphHandle.getAttributeFromId(data)
            return data

        return None

    def fromInternal(self, data):

        if isinstance(data, uuid.UUID):
            self.__graphHandle.getAttributeFromId(data)

        return

    def connectAttr(self, attributeOne, attributeTwo):

        attrOne = self.toInternal(attributeOne)
        attrTwo = self.toInternal(attributeTwo)

        if not attrOne or not attrTwo:
            return False

        if attrOne.Handle.matches(attrTwo.Handle):
            return False

        if attrOne.Handle.isInput(attrOne.Id) and attrTwo.Handle.isInput(attrTwo.Id):
            return False

        if attrOne.Handle.isOutput(attrOne.Id) and attrTwo.Handle.isOutput(attrTwo.Id):
            return False

        if attrOne.Handle.isInput(attrOne.Id):
            inputAttr = attrOne
            outputAttr = attrTwo
        else:
            inputAttr = attrTwo
            outputAttr = attrOne

        if inputAttr.IsConnected:
            for connId in self.__graphHandle.getConnectionsFromAttributeId(inputAttr.Id):
                conn = self.__graphHandle.getConnection(connId)
                self.disconnectAttr(conn.Source, conn.Destination)

        connection = EConnection(outputAttr, inputAttr)
        self.__graphHandle.addConnection(connection)

        self.Message.emit(self.kMessageConnectionMade.setData([outputAttr.Id, inputAttr.Id, connection.Id]))

        return True

    def disconnectAttr(self, attrOne, attrTwo):

        connections = self.__graphHandle.getConnectionsFromAttributeId(self.toInternal(attrOne).Id)
        connections.extend(self.__graphHandle.getConnectionsFromAttributeId(self.toInternal(attrTwo).Id))

        for connId in list(set([x for x in connections if connections.count(x) > 1])):
            self.__graphHandle.delConnection(connId)
            self.Message.emit(self.kMessageConnectionBroke.setData(connId))

        return True

    def ls(self):
        return [node.Name for node in self.__scene.getNodes().itervalues()]

    def reset(self):

        for node in self.ls():
            self.deleteNode(node)

    def __getNodeCreateCmd(self, nodeTransform):

        props = {}

        for prop in nodeTransform.Handle.lsProperties():
            if prop.Type.matches(EAttribute.kTypeFloat):
                props[prop.Name] = float(prop.Data)

            if any([prop.Type.matches(EAttribute.kTypeVector3d),
                    prop.Type.matches(EAttribute.kTypeVector2d)]):

                props[prop.Name] = [float(item.Data) for item in prop.Data]

            if any([prop.Type.matches(EAttribute.kTypeString),
                    prop.Type.matches(EAttribute.kTypePath)]):

                props[prop.Name] = str(prop.Data)

        return dict({'REQUEST': nodeTransform.Handle.NodeType,
                     'PX': nodeTransform.scenePos().x(),
                     'PY': nodeTransform.scenePos().y(), 'PROPS': props})

    def __getNodePropertySetCmd(self, nodeTransform):
        return

    def __getConnectionCreateCmd(self, connection):
        headNode = self.getNode(self.__graphHandle.getAttributeHandleId(connection.Source.Id))
        tailNode = self.getNode(self.__graphHandle.getAttributeHandleId(connection.Destination.Id))
        return dict({'HEAD': '%s.%s' % (self.getTransform(headNode).Name, connection.Source.Name),
                     'TAIL': '%s.%s' % (self.getTransform(tailNode).Name, connection.Destination.Name)})

    def save(self, sceneFile):
        saveData = dict({'NODES': {}, 'CONNECTIONS': []})

        for nodeName in self.ls():
            saveData['NODES'][nodeName] = self.__getNodeCreateCmd(self.getTransform(nodeName))

        for conn in self.__scene.getConnections():
            tConn = self.__graphHandle.getConnection(conn)
            saveData['CONNECTIONS'].append(self.__getConnectionCreateCmd(tConn))

        sceneFile = open(sceneFile, 'w')
        sceneFile.write(json.dumps(saveData, indent=4, separators=(',', ': ')))
        sceneFile.close()

    def load(self, sceneFile):
        loadData = json.loads(open(sceneFile).read())

        for nodeName, nodeData in loadData['NODES'].iteritems():

            node = self.createNode(nodeData['REQUEST'], nodeName)
            self.getTransform(node).setPos(nodeData['PX'], nodeData['PY'])

            for propName, propData in nodeData['PROPS'].iteritems():
                attr = node.getAttribute(propName)
                if any([attr.Type.matches(EAttribute.kTypeList),
                        attr.Type.matches(EAttribute.kTypeVector3d),
                        attr.Type.matches(EAttribute.kTypeVector2d)]):

                    for index, attr in enumerate(attr.Data):
                        attr.Data = propData[index]

                    continue

                attr.Data = propData

            node.compute()

        for connData in loadData['CONNECTIONS']:
            self.connectAttr(connData['HEAD'], connData['TAIL'])

        self.__graphHandle.updateConnections()
Ejemplo n.º 5
0
class EScene(QGraphicsScene):

    def __init__(self, view=None, parent=None):
        QGraphicsScene.__init__(self, parent)

        if view is None:
            raise AttributeError

        self.__view = view
        self.__create__()

    def __create__(self):

        self.__gridSize = 35

        self.__isGridActive = True
        self.__isAltModifier = False
        self.__isControlModifier = False
        self.__isNodePressed = False

        self.__kDummy = EDummy()
        self.__kDummy.setGridSize(self.__gridSize)
        self.__kDummy.onPress.connect(self.__onNodePressed)
        self.__kDummy.onEditEnd.connect(self.__onDummyEdit)

        self.addItem(self.__kDummy)

        self.__kSelected = ESceneSelection()

        self.addItem(self.__kSelected)

        self.__kCutLine = QGraphicsLineItem()
        self.__kCutLine.hide()

        self.addItem(self.__kCutLine)

        self.__nodes = {}
        self.__connections = {}

        self.__graphHandle = EGraphHandle()
        self.__graphHandle.Message.connect(self.__messageFilter)

        self.__propEditor = EPropertyEditor()
        self.addItem(self.__propEditor)

    def __isNode(self, EObject):
        return isinstance(EObject, ENode)

    def __isEdge(self, EObject):
        return isinstance(EObject, EEdge)

    def __onNodePressed(self):

        if self.__isNode(self.sender()):
            self.__graphHandle.process(self.sender().mapFromPoint(self.__kDummy.scenePos()))
            return

        if not self.__kDummy.isEditMode():
            self.__graphHandle.process(self.__kDummy.Id)

    def __onDummyEdit(self, line):

        if self.__isNode(self.itemAt(line.p1())) and self.__isNode(self.itemAt(line.p2())):
            return

        self.__kCutLine.setLine(line)

        result = []

        for item in self.__kCutLine.collidingItems():
            if isinstance(item, EEdge):

                if self.__kCutLine.collidesWithPath(item.shape()):
                    result.append(item.Id)

        self.__graphHandle.process(result)

    def __getDataFromId(self, theId):
        handle = self.__graphHandle.getHandleFromId(theId)
        if handle:
            return self.__nodes[handle].mapFromId(theId)

        return None

    def __messageFilter(self, message):

        if message.match(EGraphHandle.kMessageEditBegin):
            self.__kDummy.toggleEditMode()
            return

        if message.match(EGraphHandle.kMessageEditEnd):
            if self.__kDummy.isEditMode():
                self.__kDummy.toggleEditMode()
            return

        if message.match(EGraphHandle.kMessageNodeAdded):
            self.addItem(ENode(message.getData()))
            return

        if message.match(EGraphHandle.kMessageNodeRemoved):
            return

        if message.match(EGraphHandle.kMessageConnectionMade):

            dataOne = self.__getDataFromId(message.getData()[0])
            dataTwo = self.__getDataFromId(message.getData()[1])

            if dataOne and dataTwo:

                conn = EEdge(dataOne, dataTwo, message.getData()[2])
                self.__connections[conn.Id] = conn
                self.addItem(conn)

                headData = conn.Head
                tailData = conn.Tail

                print 'Result: Connected %s.%s to %s.%s' % (headData[ENode.kGuiAttributeParentName],
                                                            headData[ENode.kGuiAttributeLongName],
                                                            tailData[ENode.kGuiAttributeParentName],
                                                            tailData[ENode.kGuiAttributeLongName])

            return

        if message.match(EGraphHandle.kMessageConnectionBroke):
            if message.getData() in self.__connections.keys():
                self.removeItem(self.__connections[message.getData()])

                self.__connections.pop(message.getData(), None)

                self.update()

                #print "Disconnected..."

            return

        if message.match(EGraphHandle.kMessageUnknown) or message.match(EGraphHandle.kMessageInternalError):
            print 'Result: No event <%s>' % message.getData()
            if self.__kDummy.isEditMode():
                self.__kDummy.toggleEditMode()
                self.update()

    def build(self, handle):
        if not isinstance(handle, EGraphHandle):
            raise AttributeError

    def addItem(self, QGraphicsItem):

        if self.__isNode(QGraphicsItem):
            QGraphicsItem.setZValue(1.0)
            QGraphicsItem.onPress.connect(self.__onNodePressed)

            self.__nodes[QGraphicsItem.Id] = QGraphicsItem

        QGraphicsScene.addItem(self, QGraphicsItem)

    def cwd(self):
        return self.__graphHandle

    def ls(self, sl=False):
        if sl:
            return self.__kSelected

        return self.__nodes.values()

    def drawBackground(self, painter, rect):
        self.update()

        if self.__isGridActive:

            painter.setPen(Qt.NoPen)
            painter.fillRect(rect, Qt.lightGray)

            left = int(rect.left()) - (int(rect.left()) % self.__gridSize)
            top = int(rect.top()) - (int(rect.top()) % self.__gridSize)
            lines = []
            right = int(rect.right())
            bottom = int(rect.bottom())
            for x in range(left, right, self.__gridSize):
                lines.append(QLineF(x, rect.top(), x, rect.bottom()))
            for y in range(top, bottom, self.__gridSize):
                lines.append(QLineF(rect.left(), y, rect.right(), y))

            painter.setPen(QPen(Qt.gray, 1, Qt.SolidLine))
            painter.drawLines(lines)
            return

        painter.fillRect(rect, Qt.lightGray)

    def mouseMoveEvent(self, mouseEvent):
        QGraphicsScene.mouseMoveEvent(self, mouseEvent)

        self.__kDummy.setPos(mouseEvent.scenePos())

        self.update()

    def mousePressEvent(self, mouseEvent):
        QGraphicsScene.mousePressEvent(self, mouseEvent)

        item = self.itemAt(mouseEvent.scenePos())

        if self.__isControlModifier:
            return

        if self.__isNode(item):
            #print item.Properties
            self.__kSelected.Item = item
            self.__propEditor.rebuild(self.__kSelected.Item.Handle.Name, self.__kSelected.Item.Handle.lsProperties())

        elif isinstance(item, EDummy):
            self.__kSelected.Item = None
            self.__propEditor.rebuild("", [])

        if mouseEvent.button() == Qt.RightButton:
            if self.__isNode(self.itemAt(mouseEvent.scenePos())):
                self.__isNodePressed = True
                return

            self.__kDummy.toggleEditMode()

    def mouseReleaseEvent(self, mouseEvent):

        if mouseEvent.button() == Qt.RightButton:
            if self.__isNodePressed:
                self.__isNodePressed = False
                return

            self.__kDummy.toggleEditMode()

        self.update()

        QGraphicsScene.mouseReleaseEvent(self, mouseEvent)

    def keyPressEvent(self, keyEvent):
        QGraphicsScene.keyPressEvent(self, keyEvent)

        if keyEvent.key() == Qt.Key_Control:
            self.__view.setDragMode(QGraphicsView.ScrollHandDrag)
            self.__isControlModifier = True

        if keyEvent.key() == Qt.Key_Alt:
            self.__isAltModifier = True
            self.__previousSelectedNode = None

        if keyEvent.key() == 88:
            self.__kDummy.setSnapMode(True)

    def keyReleaseEvent(self, keyEvent):
        QGraphicsScene.keyReleaseEvent(self, keyEvent)

        if keyEvent.key() == Qt.Key_Control:
            self.__view.setDragMode(QGraphicsView.NoDrag)
            self.__isControlModifier = False

        if keyEvent.key() == Qt.Key_Alt:
            self.__isAltModifier = False
            self.__previousSelectedNode = None

        if keyEvent.key() == 88:
            self.__kDummy.setSnapMode(False)
Ejemplo n.º 6
0
class EController(EObject):

    kMessageNodeAdded = EObject()
    kMessageNodeRemoved = EObject()

    kMessageNodeUpdate = EObject()

    kMessageEditBegin = EObject()
    kMessageEditEnd = EObject()

    kMessageUnknown = EObject()
    kMessageInternalError = EObject()

    kMessageConnectionMade = EObject()
    kMessageConnectionBroke = EObject()

    def __init__(self):
        EObject.__init__(self)

        self.__scene = None
        self.__regNodes = {}
        self.__graphHandle = EGraphHandle()

    @property
    def Handle(self):
        return self.__graphHandle

    @property
    def NodeTypes(self):
        return self.__regNodes.keys()

    def setScene(self, scene):
        self.__scene = scene

    def getScene(self):
        return self.__scene

    def registerNode(self, nodeName, nodeHandle):
        self.__regNodes[nodeName] = nodeHandle

    def getNode(self, theNode):
        if isinstance(theNode, uuid.UUID):
            return self.__scene.getNodes()[theNode].Handle

        elif isinstance(theNode, basestring):
            for nodeId, node in self.__scene.getNodes().iteritems():
                if theNode == node.Name:
                    return node.Handle

        return None

    def getTransform(self, theNode):

        node = None

        if isinstance(theNode, ENodeHandle):
            return self.__scene.getNodes()[self.getNode(theNode.Id).Id]

        if isinstance(theNode, basestring):
            return self.__scene.getNodes()[self.getNode(theNode).Id]

        return node

    def createNode(self, nodeType, nodeName=None):

        if self.__regNodes.has_key(nodeType):
            nodeHandle = self.__graphHandle.addHandle(self.__regNodes[nodeType]())

            self.Message.emit(self.kMessageNodeAdded.setData([nodeHandle, nodeName]))

            return nodeHandle

        return None

    def deleteNode(self, node):

        if isinstance(node, basestring):
            node = self.getNode(node)
            theId = self.__graphHandle.delHandle(node.Id)

        elif isinstance(node, uuid.UUID):
            theId = self.__graphHandle.delHandle(node)

        self.Message.emit(self.kMessageNodeRemoved.setData(theId))

    def connectAttr(self, attrOne, attrTwo):

        data = []

        if isinstance(attrOne, EAttribute) and isinstance(attrTwo, EAttribute):
            data = self.__graphHandle.connectAttributes(attrOne, attrTwo)

        elif isinstance(attrOne, basestring) and isinstance(attrTwo, basestring):

            nodeOneName, attrOneName = attrOne.split(".")
            nodeTwoName, attrTwoName = attrTwo.split(".")

            attrOne = self.getNode(nodeOneName).getAttributeByName(attrOneName)
            attrTwo = self.getNode(nodeTwoName).getAttributeByName(attrTwoName)

            if attrOne and attrTwo:
                data = self.__graphHandle.connectAttributes(attrOne, attrTwo)

        elif isinstance(attrOne, uuid.UUID) and isinstance(attrTwo, uuid.UUID):
            attrOne = self.__graphHandle.getAttributeFromId(attrOne)
            attrTwo = self.__graphHandle.getAttributeFromId(attrTwo)

            data = self.__graphHandle.connectAttributes(attrOne, attrTwo)

        self.Message.emit(self.kMessageConnectionMade.setData(data))

        return data

    def ls(self):
        return [node.Name for node in self.__scene.getNodes().itervalues()]

    def reset(self):
        self.__graphHandle.reset()

    def __getNodeCreateCmd(self, nodeTransform):

        return dict(
            {
                "TYPE": nodeTransform.Handle.NodeType,
                "PX": nodeTransform.scenePos().x(),
                "PY": nodeTransform.scenePos().y(),
            }
        )

    def __getNodePropertySetCmd(self, nodeTransform):
        return

    def __getConnectionCreateCmd(self, connection):
        headNode = self.getNode(self.__graphHandle.getAttributeHandleId(connection.Head.Id))
        tailNode = self.getNode(self.__graphHandle.getAttributeHandleId(connection.Tail.Id))
        return dict(
            {
                "HEAD": "%s.%s" % (self.getTransform(headNode).Name, connection.Head.Name),
                "TAIL": "%s.%s" % (self.getTransform(tailNode).Name, connection.Tail.Name),
            }
        )

    def save(self, sceneFile):
        saveData = dict({"NODES": {}, "CONNECTIONS": []})

        for nodeName in self.ls():
            saveData["NODES"][nodeName] = self.__getNodeCreateCmd(self.getTransform(nodeName))

        for conn in self.__scene.getConnections():
            tConn = self.__graphHandle.getConnection(conn)
            saveData["CONNECTIONS"].append(self.__getConnectionCreateCmd(tConn))

        sceneFile = open(sceneFile, "w")
        sceneFile.write(json.dumps(saveData, indent=4, separators=(",", ": ")))
        sceneFile.close()

    def load(self, sceneFile):
        loadData = json.loads(open(sceneFile).read())

        for nodeName, nodeData in loadData["NODES"].iteritems():
            self.getTransform(self.createNode(nodeData["TYPE"], nodeName)).setPos(nodeData["PX"], nodeData["PY"])

        for connData in loadData["CONNECTIONS"]:
            self.connectAttr(connData["HEAD"], connData["TAIL"])
Ejemplo n.º 7
0
class EScene(QGraphicsScene):

    def __init__(self, view=None, parent=None):
        QGraphicsScene.__init__(self, parent)

        if view is None:
            raise AttributeError

        self.__view = view
        self.__create__()

    def __create__(self):

        self.__gridSize = 35

        self.__isGridActive = True
        self.__isAltModifier = False
        self.__isControlModifier = False

        self.__kDummy = EDummy()
        self.__kDummy.setGridSize(self.__gridSize)
        self.__kDummy.onPress.connect(self.__onNodePressed)

        self.addItem(self.__kDummy)

        self.__nodes = {}
        self.__connections = {}

        self.__graphHandle = EGraphHandle()
        self.__graphHandle.Message.connect(self.__messageFilter)

    def __isNode(self, EObject):
        return isinstance(EObject, ENode)

    def __onNodePressed(self):
        if self.__isNode(self.sender()):
            self.__graphHandle.process(self.sender().mapFromPoint(self.__kDummy.scenePos()))
            return

        if not self.__kDummy.isEditMode():
            self.__graphHandle.process(self.__kDummy.Id)

    def __getDataFromId(self, theId):
        handle = self.__graphHandle.getHandleFromId(theId)
        if handle:
            return self.__nodes[handle].mapFromId(theId)

        return None

    def __getResultMessageFromConnection(self, conn):
        return

    def __messageFilter(self, message):

        if message.match(EGraphHandle.kMessageEditBegin):
            #print 'Debug message: Edit begin...'
            self.__kDummy.toggleEditMode()
            return

        if message.match(EGraphHandle.kMessageEditEnd):
            #print 'Debug message: Edit end...'
            if self.__kDummy.isEditMode():
                self.__kDummy.toggleEditMode()
            return

        if message.match(EGraphHandle.kMessageNodeAdded):
            self.addItem(ENode(message.getData()))
            return

        if message.match(EGraphHandle.kMessageNodeRemoved):
            return

        if message.match(EGraphHandle.kMessageConnectionMade):

            dataOne = self.__getDataFromId(message.getData()[0])
            dataTwo = self.__getDataFromId(message.getData()[1])

            if dataOne and dataTwo:

                conn = EEdge(dataOne, dataTwo, message.getData()[2])
                self.__connections[conn.Id] = conn
                self.addItem(conn)

                headData = conn.Head
                tailData = conn.Tail

                print 'Result: Connected %s.%s to %s.%s' % (headData[ENode.kGuiAttributeParentName],
                                                            headData[ENode.kGuiAttributeLongName],
                                                            tailData[ENode.kGuiAttributeParentName],
                                                            tailData[ENode.kGuiAttributeLongName])

            return

        if message.match(EGraphHandle.kMessageConnectionBroke):
            if message.getData() in self.__connections.keys():
                self.removeItem(self.__connections[message.getData()])

                self.__connections.pop(message.getData(), None)

                self.update()

                #print "Disconnected..."

            return

        if message.match(EGraphHandle.kMessageUnknown) or message.match(EGraphHandle.kMessageInternalError):
            print 'No event <%s>' % message.getData()
            if self.__kDummy.isEditMode():
                self.__kDummy.toggleEditMode()
                self.update()

    @property
    def Handle(self):
        return self.__graphHandle

    def build(self, handle):
        if not isinstance(handle, EGraphHandle):
            raise AttributeError

    def addItem(self, QGraphicsItem):

        if self.__isNode(QGraphicsItem):
            QGraphicsItem.setZValue(0.0)
            QGraphicsItem.onPress.connect(self.__onNodePressed)

            self.__nodes[QGraphicsItem.Id] = QGraphicsItem

        QGraphicsScene.addItem(self, QGraphicsItem)

    def cwd(self):
        return self.__graphHandle

    def ls(self):
        return self.__nodes.values()

    def drawBackground(self, painter, rect):
        self.update()

        if self.__isGridActive:

            painter.setPen(Qt.NoPen)
            painter.fillRect(rect, Qt.lightGray)

            left = int(rect.left()) - (int(rect.left()) % self.__gridSize)
            top = int(rect.top()) - (int(rect.top()) % self.__gridSize)
            lines = []
            right = int(rect.right())
            bottom = int(rect.bottom())
            for x in range(left, right, self.__gridSize):
                lines.append(QLineF(x, rect.top(), x, rect.bottom()))
            for y in range(top, bottom, self.__gridSize):
                lines.append(QLineF(rect.left(), y, rect.right(), y))

            painter.setPen(QPen(Qt.gray, 1, Qt.SolidLine))
            painter.drawLines(lines)
            return

        painter.fillRect(rect, Qt.lightGray)

    def mouseMoveEvent(self, mouseEvent):
        QGraphicsScene.mouseMoveEvent(self, mouseEvent)

        self.__kDummy.setPos(mouseEvent.scenePos())

    def mousePressEvent(self, mouseEvent):
        QGraphicsScene.mousePressEvent(self, mouseEvent)

        if self.__isControlModifier:
            return

        if mouseEvent.button() == Qt.RightButton:
            self.__kDummy.toggleEditMode()

    def mouseReleaseEvent(self, mouseEvent):

        if mouseEvent.button() == Qt.RightButton:
            self.__kDummy.toggleEditMode()

        self.update()

        QGraphicsScene.mouseReleaseEvent(self, mouseEvent)

    def keyPressEvent(self, keyEvent):
        QGraphicsScene.keyPressEvent(self, keyEvent)

        if keyEvent.key() == Qt.Key_Control:
            self.__view.setDragMode(QGraphicsView.ScrollHandDrag)
            self.__isControlModifier = True

        if keyEvent.key() == Qt.Key_Alt:
            self.__isAltModifier = True
            self.__previousSelectedNode = None

        if keyEvent.key() == 88:
            self.__kDummy.setSnapMode(True)

    def keyReleaseEvent(self, keyEvent):
        QGraphicsScene.keyReleaseEvent(self, keyEvent)

        if keyEvent.key() == Qt.Key_Control:
            self.__view.setDragMode(QGraphicsView.NoDrag)
            self.__isControlModifier = False

        if keyEvent.key() == Qt.Key_Alt:
            self.__isAltModifier = False
            self.__previousSelectedNode = None

        if keyEvent.key() == 88:
            self.__kDummy.setSnapMode(False)