Graphics/UMLItem.py

Tue, 11 Sep 2012 18:46:46 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Tue, 11 Sep 2012 18:46:46 +0200
changeset 2038
72557ef75de1
parent 2034
8de0fc1f7fef
child 2039
fa41ccd7f7bc
permissions
-rw-r--r--

Added ability to move graphics items in the diagram via the cursor keys and to limit the item position to the scene.

# -*- coding: utf-8 -*-

# Copyright (c) 2004 - 2012 Detlev Offenbach <detlev@die-offenbachs.de>
#

"""
Module implementing the UMLItem base class.
"""

from PyQt4.QtCore import Qt, QSizeF
from PyQt4.QtGui import QGraphicsItem, QGraphicsRectItem, QStyle

import Preferences


class UMLItem(QGraphicsRectItem):
    """
    Class implementing the UMLItem base class.
    """
    ItemType = "UMLItem"
    
    def __init__(self, x=0, y=0, rounded=False, parent=None):
        """
        Constructor
        
        @param x x-coordinate (integer)
        @param y y-coordinate (integer)
        @param rounded flag indicating a rounded corner (boolean)
        @keyparam parent reference to the parent object (QGraphicsItem)
        """
        super().__init__(parent)
        self.font = Preferences.getGraphics("Font")
        self.margin = 5
        self.associations = []
        self.shouldAdjustAssociations = False
        self.__id = -1
        
        self.setRect(x, y, 60, 30)
        
        if rounded:
            p = self.pen()
            p.setCapStyle(Qt.RoundCap)
            p.setJoinStyle(Qt.RoundJoin)
        
        self.setFlag(QGraphicsItem.ItemIsMovable, True)
        self.setFlag(QGraphicsItem.ItemIsSelectable, True)
        try:
            self.setFlag(QGraphicsItem.ItemSendsGeometryChanges, True)
        except AttributeError:
            # only available for Qt 4.6.0 and newer
            pass
        
    def setSize(self, width, height):
        """
        Public method to set the rectangles size.
        
        @param width width of the rectangle (float)
        @param height height of the rectangle (float)
        """
        rect = self.rect()
        rect.setSize(QSizeF(width, height))
        self.setRect(rect)
        
    def addAssociation(self, assoc):
        """
        Method to add an association to this widget.
        
        @param assoc association to be added (AssociationWidget)
        """
        if assoc and not assoc in self.associations:
            self.associations.append(assoc)
        
    def removeAssociation(self, assoc):
        """
        Method to remove an association to this widget.
        
        @param assoc association to be removed (AssociationWidget)
        """
        if assoc and assoc in self.associations:
            self.associations.remove(assoc)
        
    def removeAssociations(self):
        """
        Method to remove all associations of this widget.
        """
        for assoc in self.associations[:]:
            assoc.unassociate()
            assoc.hide()
            del assoc
        
    def adjustAssociations(self):
        """
        Method to adjust the associations to widget movements.
        """
        if self.shouldAdjustAssociations:
            for assoc in self.associations:
                assoc.widgetMoved()
            self.shouldAdjustAssociations = False
        
    def moveBy(self, dx, dy):
        """
        Overriden method to move the widget relative.
        
        @param dx relative movement in x-direction (float)
        @param dy relative movement in y-direction (float)
        """
        super().moveBy(dx, dy)
        self.adjustAssociations()
        
    def setPos(self, x, y):
        """
        Overriden method to set the items position.
        
        @param x absolute x-position (float)
        @param y absolute y-position (float)
        """
        super().setPos(x, y)
        self.adjustAssociations()
        
    def itemChange(self, change, value):
        """
        Protected method called when an items state changes.
        
        @param change the item's change (QGraphicsItem.GraphicsItemChange)
        @param value the value of the change
        @return adjusted values
        """
        if change == QGraphicsItem.ItemPositionChange:
            # 1. remember to adjust associations
            self.shouldAdjustAssociations = True
            
            # 2. ensure the new position is inside the scene
            rect = self.scene().sceneRect()
            if not rect.contains(value):
                # keep the item inside the scene
                value.setX(min(rect.right(), max(value.x(), rect.left())))
                value.setY(min(rect.bottom(), max(value.y(), rect.top())))
                return value
            
        return QGraphicsItem.itemChange(self, change, value)
        
    def paint(self, painter, option, widget=None):
        """
        Public method to paint the item in local coordinates.
        
        @param painter reference to the painter object (QPainter)
        @param option style options (QStyleOptionGraphicsItem)
        @param widget optional reference to the widget painted on (QWidget)
        """
        pen = self.pen()
        if (option.state & QStyle.State_Selected) == QStyle.State(QStyle.State_Selected):
            pen.setWidth(2)
        else:
            pen.setWidth(1)
        
        painter.setPen(pen)
        painter.setBrush(self.brush())
        painter.drawRect(self.rect())
        self.adjustAssociations()
        
    def setId(self, id):
        """
        Public method to assign an ID to the item.
        
        @param id assigned ID (integer)
        """
        self.__id = id
    
    def getId(self):
        """
        Public method to get the item ID.
        
        @return ID of the item (integer)
        """
        return self.__id
    
    def getItemType(self):
        """
        Public method to get the item's type.
        
        @return item type (string)
        """
        return self.ItemType
    
    def buildItemDataString(self):
        """
        Public method to build a string to persist the specific item data.
        
        This string must start with ", " and should be built like
        "attribute=value" with pairs separated by ", ". value must not contain ", "
        or newlines.
        
        @return persistence data (string)
        """
        return ""
    
    def parseItemDataString(self, version, data):
        """
        Public method to parse the given persistence data.
        
        @param version version of the data (string)
        @param data persisted data to be parsed (string)
        @return flag indicating success (boolean)
        """
        return True

eric ide

mercurial