eric6/Graphics/ModuleItem.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
child 7229
53054eb5b15a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric6/Graphics/ModuleItem.py	Sun Apr 14 15:09:21 2019 +0200
@@ -0,0 +1,210 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2007 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a module item.
+"""
+
+from __future__ import unicode_literals
+
+from PyQt5.QtGui import QFont
+from PyQt5.QtWidgets import QGraphicsSimpleTextItem, QStyle
+
+from .UMLItem import UMLModel, UMLItem
+
+
+class ModuleModel(UMLModel):
+    """
+    Class implementing the module model.
+    """
+    def __init__(self, name, classlist=None):
+        """
+        Constructor
+        
+        @param name the module name (string)
+        @param classlist list of class names (list of strings)
+        """
+        super(ModuleModel, self).__init__(name)
+        
+        self.classlist = [] if classlist is None else classlist[:]
+    
+    def addClass(self, classname):
+        """
+        Public method to add a class to the module model.
+        
+        @param classname class name to be added (string)
+        """
+        self.classlist.append(classname)
+    
+    def getClasses(self):
+        """
+        Public method to retrieve the classes of the module.
+        
+        @return list of class names (list of strings)
+        """
+        return self.classlist[:]
+
+
+class ModuleItem(UMLItem):
+    """
+    Class implementing a module item.
+    """
+    ItemType = "module"
+    
+    def __init__(self, model=None, x=0, y=0, rounded=False,
+                 parent=None, scene=None):
+        """
+        Constructor
+        
+        @param model module model containing the module data (ModuleModel)
+        @param x x-coordinate (integer)
+        @param y y-coordinate (integer)
+        @keyparam rounded flag indicating a rounded corner (boolean)
+        @keyparam parent reference to the parent object (QGraphicsItem)
+        @keyparam scene reference to the scene object (QGraphicsScene)
+        """
+        UMLItem.__init__(self, model, x, y, rounded, parent)
+        
+        scene.addItem(self)
+        
+        if self.model:
+            self.__createTexts()
+            self.__calculateSize()
+        
+    def __createTexts(self):
+        """
+        Private method to create the text items of the module item.
+        """
+        if self.model is None:
+            return
+        
+        boldFont = QFont(self.font)
+        boldFont.setBold(True)
+        
+        classes = self.model.getClasses()
+        
+        x = self.margin + self.rect().x()
+        y = self.margin + self.rect().y()
+        self.header = QGraphicsSimpleTextItem(self)
+        self.header.setFont(boldFont)
+        self.header.setText(self.model.getName())
+        self.header.setPos(x, y)
+        y += self.header.boundingRect().height() + self.margin
+        if classes:
+            txt = "\n".join(classes)
+        else:
+            txt = " "
+        self.classes = QGraphicsSimpleTextItem(self)
+        self.classes.setFont(self.font)
+        self.classes.setText(txt)
+        self.classes.setPos(x, y)
+        
+    def __calculateSize(self):
+        """
+        Private method to calculate the size of the module item.
+        """
+        if self.model is None:
+            return
+        
+        width = self.header.boundingRect().width()
+        height = self.header.boundingRect().height()
+        if self.classes:
+            width = max(width, self.classes.boundingRect().width())
+            height = height + self.classes.boundingRect().height()
+        self.setSize(width + 2 * self.margin, height + 2 * self.margin)
+    
+    def setModel(self, model):
+        """
+        Public method to set the module model.
+        
+        @param model module model containing the module data (ModuleModel)
+        """
+        self.scene().removeItem(self.header)
+        self.header = None
+        if self.classes:
+            self.scene().removeItem(self.classes)
+            self.meths = None
+        self.model = model
+        self.__createTexts()
+        self.__calculateSize()
+        
+    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.setFont(self.font)
+        
+        offsetX = self.rect().x()
+        offsetY = self.rect().y()
+        w = self.rect().width()
+        h = self.rect().height()
+        
+        painter.drawRect(offsetX, offsetY, w, h)
+        y = self.margin + self.header.boundingRect().height()
+        painter.drawLine(offsetX, offsetY + y, offsetX + w - 1, offsetY + y)
+        
+        self.adjustAssociations()
+    
+    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)
+        """
+        entries = [
+            "name={0}".format(self.model.getName()),
+        ]
+        classes = self.model.getClasses()
+        if classes:
+            entries.append("classes={0}".format("||".join(classes)))
+        
+        return ", " + ", ".join(entries)
+    
+    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)
+        """
+        parts = data.split(", ")
+        if len(parts) < 1:
+            return False
+        
+        name = ""
+        classes = []
+        
+        for part in parts:
+            key, value = part.split("=", 1)
+            if key == "name":
+                name = value.strip()
+            elif key == "classes":
+                classes = value.strip().split("||")
+            else:
+                return False
+        
+        self.model = ModuleModel(name, classes)
+        self.__createTexts()
+        self.__calculateSize()
+        
+        return True

eric ide

mercurial