Renamed the E5Graphics stuff to EricGraphics. eric7

Fri, 21 May 2021 18:01:11 +0200

author
Detlev Offenbach <detlev@die-offenbachs.de>
date
Fri, 21 May 2021 18:01:11 +0200
branch
eric7
changeset 8348
f4775ae8f441
parent 8347
ca9ef7600df7
child 8350
74a3b2a6a944

Renamed the E5Graphics stuff to EricGraphics.

eric7.epj file | annotate | diff | comparison | revisions
eric7/E5Graphics/E5ArrowItem.py file | annotate | diff | comparison | revisions
eric7/E5Graphics/E5GraphicsView.py file | annotate | diff | comparison | revisions
eric7/E5Graphics/__init__.py file | annotate | diff | comparison | revisions
eric7/EricGraphics/EricArrowItem.py file | annotate | diff | comparison | revisions
eric7/EricGraphics/EricGraphicsView.py file | annotate | diff | comparison | revisions
eric7/EricGraphics/__init__.py file | annotate | diff | comparison | revisions
eric7/Graphics/ApplicationDiagramBuilder.py file | annotate | diff | comparison | revisions
eric7/Graphics/AssociationItem.py file | annotate | diff | comparison | revisions
eric7/Graphics/ClassItem.py file | annotate | diff | comparison | revisions
eric7/Graphics/ImportsDiagramBuilder.py file | annotate | diff | comparison | revisions
eric7/Graphics/ModuleItem.py file | annotate | diff | comparison | revisions
eric7/Graphics/PackageDiagramBuilder.py file | annotate | diff | comparison | revisions
eric7/Graphics/PackageItem.py file | annotate | diff | comparison | revisions
eric7/Graphics/UMLClassDiagramBuilder.py file | annotate | diff | comparison | revisions
eric7/Graphics/UMLDiagramBuilder.py file | annotate | diff | comparison | revisions
eric7/Graphics/UMLDialog.py file | annotate | diff | comparison | revisions
eric7/Graphics/UMLGraphicsView.py file | annotate | diff | comparison | revisions
eric7/Graphics/UMLItem.py file | annotate | diff | comparison | revisions
--- a/eric7.epj	Fri May 21 17:54:15 2021 +0200
+++ b/eric7.epj	Fri May 21 18:01:11 2021 +0200
@@ -1072,9 +1072,6 @@
       "eric7/DocumentationTools/TemplatesListsStyle.py",
       "eric7/DocumentationTools/TemplatesListsStyleCSS.py",
       "eric7/DocumentationTools/__init__.py",
-      "eric7/E5Graphics/E5ArrowItem.py",
-      "eric7/E5Graphics/E5GraphicsView.py",
-      "eric7/E5Graphics/__init__.py",
       "eric7/E5Gui/E5Action.py",
       "eric7/E5Gui/E5AnimatedLabel.py",
       "eric7/E5Gui/E5AnimatedWidget.py",
@@ -2278,7 +2275,10 @@
       "eric7/eric7_unittest.py",
       "eric7/eric7_unittest.pyw",
       "eric7/eric7config.py",
-      "eric7/DebugClients/Python/eric7dbgstub.py"
+      "eric7/DebugClients/Python/eric7dbgstub.py",
+      "eric7/EricGraphics/__init__.py",
+      "eric7/EricGraphics/EricArrowItem.py",
+      "eric7/EricGraphics/EricGraphicsView.py"
     ],
     "SPELLEXCLUDES": "Dictionaries/excludes.dic",
     "SPELLLANGUAGE": "en_US",
--- a/eric7/E5Graphics/E5ArrowItem.py	Fri May 21 17:54:15 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,163 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a graphics item subclass for an arrow.
-"""
-
-import enum
-import math
-
-from PyQt6.QtCore import QPointF, QRectF, QSizeF, QLineF, Qt
-from PyQt6.QtGui import QPen, QPolygonF, QColor
-from PyQt6.QtWidgets import QAbstractGraphicsShapeItem, QGraphicsItem, QStyle
-
-ArrowheadAngleFactor = 0.26179938779914941
-# That is: 0.5 * math.atan(math.sqrt(3.0) / 3.0)
-
-
-class E5ArrowType(enum.Enum):
-    """
-    Class defining the arrow types.
-    """
-    NORMAL = 1
-    WIDE = 2
-
-
-class E5ArrowItem(QAbstractGraphicsShapeItem):
-    """
-    Class implementing an arrow graphics item subclass.
-    """
-    def __init__(self, origin=None, end=None,
-                 filled=False, arrowType=E5ArrowType.NORMAL, colors=None,
-                 parent=None):
-        """
-        Constructor
-        
-        @param origin origin of the arrow
-        @type QPointF
-        @param end end point of the arrow
-        @type QPointF
-        @param filled flag indicating a filled arrow head
-        @type bool
-        @param arrowType arrow type
-        @type E5ArrowType
-        @param colors tuple containing the foreground and background colors
-        @type tuple of (QColor, QColor)
-        @param parent reference to the parent object
-        @type QGraphicsItem
-        """
-        super().__init__(parent)
-        
-        self._origin = QPointF() if origin is None else QPointF(origin)
-        self._end = QPointF() if end is None else QPointF(end)
-        self._filled = filled
-        self.__type = arrowType
-        
-        if colors is None:
-            self._colors = (QColor(Qt.GlobalColor.black),
-                            QColor(Qt.GlobalColor.white))
-        else:
-            self._colors = colors
-        
-        self._halfLength = 13.0
-        
-        self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, True)
-        self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsSelectable, True)
-        
-    def setPoints(self, xa, ya, xb, yb):
-        """
-        Public method to set the start and end points of the line.
-        
-        <b>Note:</b> This method does not redraw the item.
-        
-        @param xa x-coordinate of the start point (float)
-        @param ya y-coordinate of the start point (float)
-        @param xb x-coordinate of the end point (float)
-        @param yb y-coordinate of the end point (float)
-        """
-        self._origin = QPointF(xa, ya)
-        self._end = QPointF(xb, yb)
-        
-    def setStartPoint(self, x, y):
-        """
-        Public method to set the start point.
-        
-        <b>Note:</b> This method does not redraw the item.
-        
-        @param x x-coordinate of the start point (float)
-        @param y y-coordinate of the start point (float)
-        """
-        self._origin = QPointF(x, y)
-        
-    def setEndPoint(self, x, y):
-        """
-        Public method to set the end point.
-        
-        <b>Note:</b> This method does not redraw the item.
-        
-        @param x x-coordinate of the end point (float)
-        @param y y-coordinate of the end point (float)
-        """
-        self._end = QPointF(x, y)
-        
-    def boundingRect(self):
-        """
-        Public method to return the bounding rectangle.
-        
-        @return bounding rectangle (QRectF)
-        """
-        extra = self._halfLength / 2.0
-        return QRectF(self._origin, QSizeF(self._end.x() - self._origin.x(),
-                                           self._end.y() - self._origin.y())
-                      ).normalized().adjusted(-extra, -extra, extra, extra)
-        
-    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)
-        """
-        width = 2 if (
-            (option.state & QStyle.StateFlag.State_Selected) ==
-            QStyle.State(QStyle.StateFlag.State_Selected)
-        ) else 1
-        
-        # draw the line first
-        line = QLineF(self._origin, self._end)
-        painter.setPen(
-            QPen(self._colors[0], width, Qt.PenStyle.SolidLine,
-                 Qt.PenCapStyle.FlatCap, Qt.PenJoinStyle.MiterJoin))
-        painter.drawLine(line)
-        
-        # draw the arrow head
-        arrowAngle = (
-            ArrowheadAngleFactor
-            if self.__type == E5ArrowType.NORMAL else
-            2 * ArrowheadAngleFactor
-        )
-        slope = math.atan2(line.dy(), line.dx())
-        
-        # Calculate left arrow point
-        arrowSlope = slope + arrowAngle
-        a1 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope),
-                     self._end.y() - self._halfLength * math.sin(arrowSlope))
-        
-        # Calculate right arrow point
-        arrowSlope = slope - arrowAngle
-        a2 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope),
-                     self._end.y() - self._halfLength * math.sin(arrowSlope))
-        
-        if self._filled:
-            painter.setBrush(self._colors[0])
-        else:
-            painter.setBrush(self._colors[1])
-        polygon = QPolygonF()
-        polygon.append(line.p2())
-        polygon.append(a1)
-        polygon.append(a2)
-        painter.drawPolygon(polygon)
--- a/eric7/E5Graphics/E5GraphicsView.py	Fri May 21 17:54:15 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,411 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Module implementing a canvas view class.
-"""
-
-import sys
-
-from PyQt6.QtCore import pyqtSignal, QRectF, QSize, QSizeF, Qt
-from PyQt6.QtGui import QBrush, QPainter, QPixmap, QFont, QColor
-from PyQt6.QtWidgets import QGraphicsView
-
-from E5Gui.E5Application import e5App
-
-import Preferences
-
-
-class E5GraphicsView(QGraphicsView):
-    """
-    Class implementing a graphics view.
-    
-    @signal zoomValueChanged(int) emitted to signal a change of the zoom value
-    """
-    zoomValueChanged = pyqtSignal(int)
-    
-    ZoomLevels = [
-        1, 3, 5, 7, 9,
-        10, 20, 30, 50, 67, 80, 90,
-        100,
-        110, 120, 133, 150, 170, 200, 240, 300, 400,
-        500, 600, 700, 800, 900, 1000,
-    ]
-    ZoomLevelDefault = 100
-    
-    def __init__(self, scene, parent=None):
-        """
-        Constructor
-        
-        @param scene reference to the scene object (QGraphicsScene)
-        @param parent parent widget (QWidget)
-        """
-        super().__init__(scene, parent)
-        self.setObjectName("E5GraphicsView")
-        
-        self.__initialSceneSize = self.scene().sceneRect().size()
-        self.setBackgroundBrush(QBrush(self.getBackgroundColor()))
-        self.setRenderHint(QPainter.RenderHint.Antialiasing, True)
-        self.setDragMode(QGraphicsView.DragMode.RubberBandDrag)
-        self.setAlignment(
-            Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop)
-        self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
-        self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
-        self.setViewportUpdateMode(
-            QGraphicsView.ViewportUpdateMode.SmartViewportUpdate)
-        
-        self.setWhatsThis(self.tr(
-            "<b>Graphics View</b>\n"
-            "<p>This graphics view is used to show a diagram. \n"
-            "There are various actions available to manipulate the \n"
-            "shown items.</p>\n"
-            "<ul>\n"
-            "<li>Clicking on an item selects it.</li>\n"
-            "<li>Ctrl-clicking adds an item to the selection.</li>\n"
-            "<li>Ctrl-clicking a selected item deselects it.</li>\n"
-            "<li>Clicking on an empty spot of the canvas resets the selection."
-            "</li>\n"
-            "<li>Dragging the mouse over the canvas spans a rubberband to \n"
-            "select multiple items.</li>\n"
-            "<li>Dragging the mouse over a selected item moves the \n"
-            "whole selection.</li>\n"
-            "</ul>\n"
-        ))
-    
-    def getDrawingColors(self):
-        """
-        Public method to get the configured drawing colors.
-        
-        @return tuple containing the foreground and background colors
-        @rtype tuple of (QColor, QColor)
-        """
-        drawingMode = Preferences.getGraphics("DrawingMode")
-        if drawingMode == "automatic":
-            if e5App().usesDarkPalette():
-                drawingMode = "white_black"
-            else:
-                drawingMode = "black_white"
-        
-        if drawingMode == "white_black":
-            return (QColor("#ffffff"), QColor("#262626"))
-        else:
-            return (QColor("#000000"), QColor("#ffffff"))
-    
-    def getForegroundColor(self):
-        """
-        Public method to get the configured foreground color.
-        
-        @return foreground color
-        @rtype QColor
-        """
-        return self.getDrawingColors()[0]
-    
-    def getBackgroundColor(self):
-        """
-        Public method to get the configured background color.
-        
-        @return background color
-        @rtype QColor
-        """
-        return self.getDrawingColors()[1]
-    
-    def __levelForZoom(self, zoom):
-        """
-        Private method determining the zoom level index given a zoom factor.
-        
-        @param zoom zoom factor (integer)
-        @return index of zoom factor (integer)
-        """
-        try:
-            index = E5GraphicsView.ZoomLevels.index(zoom)
-        except ValueError:
-            for index in range(len(E5GraphicsView.ZoomLevels)):
-                if zoom <= E5GraphicsView.ZoomLevels[index]:
-                    break
-        return index
-    
-    def zoomIn(self):
-        """
-        Public method to zoom in.
-        """
-        index = self.__levelForZoom(self.zoom())
-        if index < len(E5GraphicsView.ZoomLevels) - 1:
-            self.setZoom(E5GraphicsView.ZoomLevels[index + 1])
-        
-    def zoomOut(self):
-        """
-        Public method to zoom out.
-        """
-        index = self.__levelForZoom(self.zoom())
-        if index > 0:
-            self.setZoom(E5GraphicsView.ZoomLevels[index - 1])
-    
-    def zoomReset(self):
-        """
-        Public method to handle the reset the zoom value.
-        """
-        self.setZoom(
-            E5GraphicsView.ZoomLevels[E5GraphicsView.ZoomLevelDefault])
-        
-    def setZoom(self, value):
-        """
-        Public method to set the zoom value in percent.
-        
-        @param value zoom value in percent (integer)
-        """
-        if value != self.zoom():
-            self.resetTransform()
-            factor = value / 100.0
-            self.scale(factor, factor)
-            self.zoomValueChanged.emit(value)
-        
-    def zoom(self):
-        """
-        Public method to get the current zoom factor in percent.
-        
-        @return current zoom factor in percent (integer)
-        """
-        return int(self.transform().m11() * 100.0)
-       
-    def resizeScene(self, amount, isWidth=True):
-        """
-        Public method to resize the scene.
-        
-        @param amount size increment (integer)
-        @param isWidth flag indicating width is to be resized (boolean)
-        """
-        sceneRect = self.scene().sceneRect()
-        width = sceneRect.width()
-        height = sceneRect.height()
-        if isWidth:
-            width += amount
-        else:
-            height += amount
-        rect = self._getDiagramRect(10)
-        if width < rect.width():
-            width = rect.width()
-        if height < rect.height():
-            height = rect.height()
-        
-        self.setSceneSize(width, height)
-        
-    def setSceneSize(self, width, height):
-        """
-        Public method to set the scene size.
-        
-        @param width width for the scene (real)
-        @param height height for the scene (real)
-        """
-        rect = self.scene().sceneRect()
-        rect.setHeight(height)
-        rect.setWidth(width)
-        self.scene().setSceneRect(rect)
-        
-    def autoAdjustSceneSize(self, limit=False):
-        """
-        Public method to adjust the scene size to the diagram size.
-        
-        @param limit flag indicating to limit the scene to the
-            initial size (boolean)
-        """
-        size = self._getDiagramSize(10)
-        if limit:
-            newWidth = max(size.width(), self.__initialSceneSize.width())
-            newHeight = max(size.height(), self.__initialSceneSize.height())
-        else:
-            newWidth = size.width()
-            newHeight = size.height()
-        self.setSceneSize(newWidth, newHeight)
-        
-    def _getDiagramRect(self, border=0):
-        """
-        Protected method to calculate the minimum rectangle fitting the
-        diagram.
-        
-        @param border border width to include in the calculation (integer)
-        @return the minimum rectangle (QRectF)
-        """
-        startx = sys.maxsize
-        starty = sys.maxsize
-        endx = 0
-        endy = 0
-        items = self.filteredItems(list(self.scene().items()))
-        for itm in items:
-            rect = itm.sceneBoundingRect()
-            itmEndX = rect.x() + rect.width()
-            itmEndY = rect.y() + rect.height()
-            itmStartX = rect.x()
-            itmStartY = rect.y()
-            if startx >= itmStartX:
-                startx = itmStartX
-            if starty >= itmStartY:
-                starty = itmStartY
-            if endx <= itmEndX:
-                endx = itmEndX
-            if endy <= itmEndY:
-                endy = itmEndY
-        if border:
-            startx -= border
-            starty -= border
-            endx += border
-            endy += border
-            
-        return QRectF(startx, starty, endx - startx + 1, endy - starty + 1)
-        
-    def _getDiagramSize(self, border=0):
-        """
-        Protected method to calculate the minimum size fitting the diagram.
-        
-        @param border border width to include in the calculation (integer)
-        @return the minimum size (QSizeF)
-        """
-        endx = 0
-        endy = 0
-        items = self.filteredItems(list(self.scene().items()))
-        for itm in items:
-            rect = itm.sceneBoundingRect()
-            itmEndX = rect.x() + rect.width()
-            itmEndY = rect.y() + rect.height()
-            if endx <= itmEndX:
-                endx = itmEndX
-            if endy <= itmEndY:
-                endy = itmEndY
-        if border:
-            endx += border
-            endy += border
-            
-        return QSizeF(endx + 1, endy + 1)
-        
-    def __getDiagram(self, rect, imageFormat="PNG", filename=None):
-        """
-        Private method to retrieve the diagram from the scene fitting it
-        in the minimum rectangle.
-        
-        @param rect minimum rectangle fitting the diagram
-        @type QRectF
-        @param imageFormat format for the image file
-        @type str
-        @param filename name of the file for non pixmaps
-        str
-        @return paint device containing the diagram
-        @rtype QPixmap or QSvgGenerator
-        """
-        selectedItems = self.scene().selectedItems()
-        
-        # step 1: deselect all widgets
-        if selectedItems:
-            for item in selectedItems:
-                item.setSelected(False)
-            
-        # step 2: grab the diagram
-        if imageFormat == "PNG":
-            paintDevice = QPixmap(int(rect.width()), int(rect.height()))
-            paintDevice.fill(self.backgroundBrush().color())
-        else:
-            from PyQt6.QtSvg import QSvgGenerator
-            paintDevice = QSvgGenerator()
-            paintDevice.setResolution(100)  # 100 dpi
-            paintDevice.setSize(QSize(int(rect.width()), int(rect.height())))
-            paintDevice.setViewBox(rect)
-            paintDevice.setFileName(filename)
-        painter = QPainter(paintDevice)
-        painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
-        self.scene().render(painter, QRectF(), rect)
-        
-        # step 3: reselect the widgets
-        if selectedItems:
-            for item in selectedItems:
-                item.setSelected(True)
-        
-        return paintDevice
-        
-    def saveImage(self, filename, imageFormat="PNG"):
-        """
-        Public method to save the scene to a file.
-        
-        @param filename name of the file to write the image to (string)
-        @param imageFormat format for the image file (string)
-        @return flag indicating success (boolean)
-        """
-        rect = self._getDiagramRect(self.border)
-        if imageFormat == "SVG":
-            self.__getDiagram(rect, imageFormat=imageFormat, filename=filename)
-            return True
-        else:
-            pixmap = self.__getDiagram(rect)
-            return pixmap.save(filename, imageFormat)
-        
-    def printDiagram(self, printer, diagramName=""):
-        """
-        Public method to print the diagram.
-        
-        @param printer reference to a ready configured printer object
-            (QPrinter)
-        @param diagramName name of the diagram (string)
-        """
-        painter = QPainter(printer)
-        
-        font = QFont(["times"], 10)
-        painter.setFont(font)
-        fm = painter.fontMetrics()
-        fontHeight = fm.lineSpacing()
-        marginX = (
-            printer.pageLayout().paintRectPixels(printer.resolution()).x() -
-            printer.pageLayout().fullRectPixels(printer.resolution()).x()
-        )
-        marginX = (
-            Preferences.getPrinter("LeftMargin") *
-            int(printer.resolution() / 2.54) - marginX
-        )
-        marginY = (
-            printer.pageLayout().paintRectPixels(printer.resolution()).y() -
-            printer.pageLayout().fullRectPixels(printer.resolution()).y()
-        )
-        marginY = (
-            Preferences.getPrinter("TopMargin") *
-            int(printer.resolution() / 2.54) - marginY
-        )
-        
-        width = (
-            printer.width() - marginX -
-            Preferences.getPrinter("RightMargin") *
-            int(printer.resolution() / 2.54)
-        )
-        height = (
-            printer.height() - fontHeight - 4 - marginY -
-            Preferences.getPrinter("BottomMargin") *
-            int(printer.resolution() / 2.54)
-        )
-        
-        self.scene().render(painter,
-                            target=QRectF(marginX, marginY, width, height))
-        
-        # write a foot note
-        tc = QColor(50, 50, 50)
-        painter.setPen(tc)
-        painter.drawRect(marginX, marginY, width, height)
-        painter.drawLine(marginX, marginY + height + 2,
-                         marginX + width, marginY + height + 2)
-        painter.setFont(font)
-        painter.drawText(marginX, marginY + height + 4, width,
-                         fontHeight, Qt.AlignmentFlag.AlignRight, diagramName)
-        
-        painter.end()
-    
-    ###########################################################################
-    ## The methods below should be overridden by subclasses to get special
-    ## behavior.
-    ###########################################################################
-    
-    def filteredItems(self, items):
-        """
-        Public method to filter a list of items.
-        
-        @param items list of items as returned by the scene object
-            (QGraphicsItem)
-        @return list of interesting collision items (QGraphicsItem)
-        """
-        # just return the list unchanged
-        return items
--- a/eric7/E5Graphics/__init__.py	Fri May 21 17:54:15 2021 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,8 +0,0 @@
-# -*- coding: utf-8 -*-
-
-# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
-#
-
-"""
-Package implementing some QGraphicsView related general purpoe classes.
-"""
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricGraphics/EricArrowItem.py	Fri May 21 18:01:11 2021 +0200
@@ -0,0 +1,164 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a graphics item subclass for an arrow.
+"""
+# TODO: rename this module to EricArrowItem
+
+import enum
+import math
+
+from PyQt6.QtCore import QPointF, QRectF, QSizeF, QLineF, Qt
+from PyQt6.QtGui import QPen, QPolygonF, QColor
+from PyQt6.QtWidgets import QAbstractGraphicsShapeItem, QGraphicsItem, QStyle
+
+ArrowheadAngleFactor = 0.26179938779914941
+# That is: 0.5 * math.atan(math.sqrt(3.0) / 3.0)
+
+
+class EricArrowType(enum.Enum):
+    """
+    Class defining the arrow types.
+    """
+    NORMAL = 1
+    WIDE = 2
+
+
+class EricArrowItem(QAbstractGraphicsShapeItem):
+    """
+    Class implementing an arrow graphics item subclass.
+    """
+    def __init__(self, origin=None, end=None,
+                 filled=False, arrowType=EricArrowType.NORMAL, colors=None,
+                 parent=None):
+        """
+        Constructor
+        
+        @param origin origin of the arrow
+        @type QPointF
+        @param end end point of the arrow
+        @type QPointF
+        @param filled flag indicating a filled arrow head
+        @type bool
+        @param arrowType arrow type
+        @type EricArrowType
+        @param colors tuple containing the foreground and background colors
+        @type tuple of (QColor, QColor)
+        @param parent reference to the parent object
+        @type QGraphicsItem
+        """
+        super().__init__(parent)
+        
+        self._origin = QPointF() if origin is None else QPointF(origin)
+        self._end = QPointF() if end is None else QPointF(end)
+        self._filled = filled
+        self.__type = arrowType
+        
+        if colors is None:
+            self._colors = (QColor(Qt.GlobalColor.black),
+                            QColor(Qt.GlobalColor.white))
+        else:
+            self._colors = colors
+        
+        self._halfLength = 13.0
+        
+        self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, True)
+        self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsSelectable, True)
+        
+    def setPoints(self, xa, ya, xb, yb):
+        """
+        Public method to set the start and end points of the line.
+        
+        <b>Note:</b> This method does not redraw the item.
+        
+        @param xa x-coordinate of the start point (float)
+        @param ya y-coordinate of the start point (float)
+        @param xb x-coordinate of the end point (float)
+        @param yb y-coordinate of the end point (float)
+        """
+        self._origin = QPointF(xa, ya)
+        self._end = QPointF(xb, yb)
+        
+    def setStartPoint(self, x, y):
+        """
+        Public method to set the start point.
+        
+        <b>Note:</b> This method does not redraw the item.
+        
+        @param x x-coordinate of the start point (float)
+        @param y y-coordinate of the start point (float)
+        """
+        self._origin = QPointF(x, y)
+        
+    def setEndPoint(self, x, y):
+        """
+        Public method to set the end point.
+        
+        <b>Note:</b> This method does not redraw the item.
+        
+        @param x x-coordinate of the end point (float)
+        @param y y-coordinate of the end point (float)
+        """
+        self._end = QPointF(x, y)
+        
+    def boundingRect(self):
+        """
+        Public method to return the bounding rectangle.
+        
+        @return bounding rectangle (QRectF)
+        """
+        extra = self._halfLength / 2.0
+        return QRectF(self._origin, QSizeF(self._end.x() - self._origin.x(),
+                                           self._end.y() - self._origin.y())
+                      ).normalized().adjusted(-extra, -extra, extra, extra)
+        
+    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)
+        """
+        width = 2 if (
+            (option.state & QStyle.StateFlag.State_Selected) ==
+            QStyle.State(QStyle.StateFlag.State_Selected)
+        ) else 1
+        
+        # draw the line first
+        line = QLineF(self._origin, self._end)
+        painter.setPen(
+            QPen(self._colors[0], width, Qt.PenStyle.SolidLine,
+                 Qt.PenCapStyle.FlatCap, Qt.PenJoinStyle.MiterJoin))
+        painter.drawLine(line)
+        
+        # draw the arrow head
+        arrowAngle = (
+            ArrowheadAngleFactor
+            if self.__type == EricArrowType.NORMAL else
+            2 * ArrowheadAngleFactor
+        )
+        slope = math.atan2(line.dy(), line.dx())
+        
+        # Calculate left arrow point
+        arrowSlope = slope + arrowAngle
+        a1 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope),
+                     self._end.y() - self._halfLength * math.sin(arrowSlope))
+        
+        # Calculate right arrow point
+        arrowSlope = slope - arrowAngle
+        a2 = QPointF(self._end.x() - self._halfLength * math.cos(arrowSlope),
+                     self._end.y() - self._halfLength * math.sin(arrowSlope))
+        
+        if self._filled:
+            painter.setBrush(self._colors[0])
+        else:
+            painter.setBrush(self._colors[1])
+        polygon = QPolygonF()
+        polygon.append(line.p2())
+        polygon.append(a1)
+        polygon.append(a2)
+        painter.drawPolygon(polygon)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricGraphics/EricGraphicsView.py	Fri May 21 18:01:11 2021 +0200
@@ -0,0 +1,412 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Module implementing a canvas view class.
+"""
+# TODO: rename this module to EricGraphicsView
+
+import sys
+
+from PyQt6.QtCore import pyqtSignal, QRectF, QSize, QSizeF, Qt
+from PyQt6.QtGui import QBrush, QPainter, QPixmap, QFont, QColor
+from PyQt6.QtWidgets import QGraphicsView
+
+from E5Gui.E5Application import e5App
+
+import Preferences
+
+
+class EricGraphicsView(QGraphicsView):
+    """
+    Class implementing a graphics view.
+    
+    @signal zoomValueChanged(int) emitted to signal a change of the zoom value
+    """
+    zoomValueChanged = pyqtSignal(int)
+    
+    ZoomLevels = [
+        1, 3, 5, 7, 9,
+        10, 20, 30, 50, 67, 80, 90,
+        100,
+        110, 120, 133, 150, 170, 200, 240, 300, 400,
+        500, 600, 700, 800, 900, 1000,
+    ]
+    ZoomLevelDefault = 100
+    
+    def __init__(self, scene, parent=None):
+        """
+        Constructor
+        
+        @param scene reference to the scene object (QGraphicsScene)
+        @param parent parent widget (QWidget)
+        """
+        super().__init__(scene, parent)
+        self.setObjectName("EricGraphicsView")
+        
+        self.__initialSceneSize = self.scene().sceneRect().size()
+        self.setBackgroundBrush(QBrush(self.getBackgroundColor()))
+        self.setRenderHint(QPainter.RenderHint.Antialiasing, True)
+        self.setDragMode(QGraphicsView.DragMode.RubberBandDrag)
+        self.setAlignment(
+            Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignTop)
+        self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
+        self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOn)
+        self.setViewportUpdateMode(
+            QGraphicsView.ViewportUpdateMode.SmartViewportUpdate)
+        
+        self.setWhatsThis(self.tr(
+            "<b>Graphics View</b>\n"
+            "<p>This graphics view is used to show a diagram. \n"
+            "There are various actions available to manipulate the \n"
+            "shown items.</p>\n"
+            "<ul>\n"
+            "<li>Clicking on an item selects it.</li>\n"
+            "<li>Ctrl-clicking adds an item to the selection.</li>\n"
+            "<li>Ctrl-clicking a selected item deselects it.</li>\n"
+            "<li>Clicking on an empty spot of the canvas resets the selection."
+            "</li>\n"
+            "<li>Dragging the mouse over the canvas spans a rubberband to \n"
+            "select multiple items.</li>\n"
+            "<li>Dragging the mouse over a selected item moves the \n"
+            "whole selection.</li>\n"
+            "</ul>\n"
+        ))
+    
+    def getDrawingColors(self):
+        """
+        Public method to get the configured drawing colors.
+        
+        @return tuple containing the foreground and background colors
+        @rtype tuple of (QColor, QColor)
+        """
+        drawingMode = Preferences.getGraphics("DrawingMode")
+        if drawingMode == "automatic":
+            if e5App().usesDarkPalette():
+                drawingMode = "white_black"
+            else:
+                drawingMode = "black_white"
+        
+        if drawingMode == "white_black":
+            return (QColor("#ffffff"), QColor("#262626"))
+        else:
+            return (QColor("#000000"), QColor("#ffffff"))
+    
+    def getForegroundColor(self):
+        """
+        Public method to get the configured foreground color.
+        
+        @return foreground color
+        @rtype QColor
+        """
+        return self.getDrawingColors()[0]
+    
+    def getBackgroundColor(self):
+        """
+        Public method to get the configured background color.
+        
+        @return background color
+        @rtype QColor
+        """
+        return self.getDrawingColors()[1]
+    
+    def __levelForZoom(self, zoom):
+        """
+        Private method determining the zoom level index given a zoom factor.
+        
+        @param zoom zoom factor (integer)
+        @return index of zoom factor (integer)
+        """
+        try:
+            index = EricGraphicsView.ZoomLevels.index(zoom)
+        except ValueError:
+            for index in range(len(EricGraphicsView.ZoomLevels)):
+                if zoom <= EricGraphicsView.ZoomLevels[index]:
+                    break
+        return index
+    
+    def zoomIn(self):
+        """
+        Public method to zoom in.
+        """
+        index = self.__levelForZoom(self.zoom())
+        if index < len(EricGraphicsView.ZoomLevels) - 1:
+            self.setZoom(EricGraphicsView.ZoomLevels[index + 1])
+        
+    def zoomOut(self):
+        """
+        Public method to zoom out.
+        """
+        index = self.__levelForZoom(self.zoom())
+        if index > 0:
+            self.setZoom(EricGraphicsView.ZoomLevels[index - 1])
+    
+    def zoomReset(self):
+        """
+        Public method to handle the reset the zoom value.
+        """
+        self.setZoom(
+            EricGraphicsView.ZoomLevels[EricGraphicsView.ZoomLevelDefault])
+        
+    def setZoom(self, value):
+        """
+        Public method to set the zoom value in percent.
+        
+        @param value zoom value in percent (integer)
+        """
+        if value != self.zoom():
+            self.resetTransform()
+            factor = value / 100.0
+            self.scale(factor, factor)
+            self.zoomValueChanged.emit(value)
+        
+    def zoom(self):
+        """
+        Public method to get the current zoom factor in percent.
+        
+        @return current zoom factor in percent (integer)
+        """
+        return int(self.transform().m11() * 100.0)
+       
+    def resizeScene(self, amount, isWidth=True):
+        """
+        Public method to resize the scene.
+        
+        @param amount size increment (integer)
+        @param isWidth flag indicating width is to be resized (boolean)
+        """
+        sceneRect = self.scene().sceneRect()
+        width = sceneRect.width()
+        height = sceneRect.height()
+        if isWidth:
+            width += amount
+        else:
+            height += amount
+        rect = self._getDiagramRect(10)
+        if width < rect.width():
+            width = rect.width()
+        if height < rect.height():
+            height = rect.height()
+        
+        self.setSceneSize(width, height)
+        
+    def setSceneSize(self, width, height):
+        """
+        Public method to set the scene size.
+        
+        @param width width for the scene (real)
+        @param height height for the scene (real)
+        """
+        rect = self.scene().sceneRect()
+        rect.setHeight(height)
+        rect.setWidth(width)
+        self.scene().setSceneRect(rect)
+        
+    def autoAdjustSceneSize(self, limit=False):
+        """
+        Public method to adjust the scene size to the diagram size.
+        
+        @param limit flag indicating to limit the scene to the
+            initial size (boolean)
+        """
+        size = self._getDiagramSize(10)
+        if limit:
+            newWidth = max(size.width(), self.__initialSceneSize.width())
+            newHeight = max(size.height(), self.__initialSceneSize.height())
+        else:
+            newWidth = size.width()
+            newHeight = size.height()
+        self.setSceneSize(newWidth, newHeight)
+        
+    def _getDiagramRect(self, border=0):
+        """
+        Protected method to calculate the minimum rectangle fitting the
+        diagram.
+        
+        @param border border width to include in the calculation (integer)
+        @return the minimum rectangle (QRectF)
+        """
+        startx = sys.maxsize
+        starty = sys.maxsize
+        endx = 0
+        endy = 0
+        items = self.filteredItems(list(self.scene().items()))
+        for itm in items:
+            rect = itm.sceneBoundingRect()
+            itmEndX = rect.x() + rect.width()
+            itmEndY = rect.y() + rect.height()
+            itmStartX = rect.x()
+            itmStartY = rect.y()
+            if startx >= itmStartX:
+                startx = itmStartX
+            if starty >= itmStartY:
+                starty = itmStartY
+            if endx <= itmEndX:
+                endx = itmEndX
+            if endy <= itmEndY:
+                endy = itmEndY
+        if border:
+            startx -= border
+            starty -= border
+            endx += border
+            endy += border
+            
+        return QRectF(startx, starty, endx - startx + 1, endy - starty + 1)
+        
+    def _getDiagramSize(self, border=0):
+        """
+        Protected method to calculate the minimum size fitting the diagram.
+        
+        @param border border width to include in the calculation (integer)
+        @return the minimum size (QSizeF)
+        """
+        endx = 0
+        endy = 0
+        items = self.filteredItems(list(self.scene().items()))
+        for itm in items:
+            rect = itm.sceneBoundingRect()
+            itmEndX = rect.x() + rect.width()
+            itmEndY = rect.y() + rect.height()
+            if endx <= itmEndX:
+                endx = itmEndX
+            if endy <= itmEndY:
+                endy = itmEndY
+        if border:
+            endx += border
+            endy += border
+            
+        return QSizeF(endx + 1, endy + 1)
+        
+    def __getDiagram(self, rect, imageFormat="PNG", filename=None):
+        """
+        Private method to retrieve the diagram from the scene fitting it
+        in the minimum rectangle.
+        
+        @param rect minimum rectangle fitting the diagram
+        @type QRectF
+        @param imageFormat format for the image file
+        @type str
+        @param filename name of the file for non pixmaps
+        str
+        @return paint device containing the diagram
+        @rtype QPixmap or QSvgGenerator
+        """
+        selectedItems = self.scene().selectedItems()
+        
+        # step 1: deselect all widgets
+        if selectedItems:
+            for item in selectedItems:
+                item.setSelected(False)
+            
+        # step 2: grab the diagram
+        if imageFormat == "PNG":
+            paintDevice = QPixmap(int(rect.width()), int(rect.height()))
+            paintDevice.fill(self.backgroundBrush().color())
+        else:
+            from PyQt6.QtSvg import QSvgGenerator
+            paintDevice = QSvgGenerator()
+            paintDevice.setResolution(100)  # 100 dpi
+            paintDevice.setSize(QSize(int(rect.width()), int(rect.height())))
+            paintDevice.setViewBox(rect)
+            paintDevice.setFileName(filename)
+        painter = QPainter(paintDevice)
+        painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
+        self.scene().render(painter, QRectF(), rect)
+        
+        # step 3: reselect the widgets
+        if selectedItems:
+            for item in selectedItems:
+                item.setSelected(True)
+        
+        return paintDevice
+        
+    def saveImage(self, filename, imageFormat="PNG"):
+        """
+        Public method to save the scene to a file.
+        
+        @param filename name of the file to write the image to (string)
+        @param imageFormat format for the image file (string)
+        @return flag indicating success (boolean)
+        """
+        rect = self._getDiagramRect(self.border)
+        if imageFormat == "SVG":
+            self.__getDiagram(rect, imageFormat=imageFormat, filename=filename)
+            return True
+        else:
+            pixmap = self.__getDiagram(rect)
+            return pixmap.save(filename, imageFormat)
+        
+    def printDiagram(self, printer, diagramName=""):
+        """
+        Public method to print the diagram.
+        
+        @param printer reference to a ready configured printer object
+            (QPrinter)
+        @param diagramName name of the diagram (string)
+        """
+        painter = QPainter(printer)
+        
+        font = QFont(["times"], 10)
+        painter.setFont(font)
+        fm = painter.fontMetrics()
+        fontHeight = fm.lineSpacing()
+        marginX = (
+            printer.pageLayout().paintRectPixels(printer.resolution()).x() -
+            printer.pageLayout().fullRectPixels(printer.resolution()).x()
+        )
+        marginX = (
+            Preferences.getPrinter("LeftMargin") *
+            int(printer.resolution() / 2.54) - marginX
+        )
+        marginY = (
+            printer.pageLayout().paintRectPixels(printer.resolution()).y() -
+            printer.pageLayout().fullRectPixels(printer.resolution()).y()
+        )
+        marginY = (
+            Preferences.getPrinter("TopMargin") *
+            int(printer.resolution() / 2.54) - marginY
+        )
+        
+        width = (
+            printer.width() - marginX -
+            Preferences.getPrinter("RightMargin") *
+            int(printer.resolution() / 2.54)
+        )
+        height = (
+            printer.height() - fontHeight - 4 - marginY -
+            Preferences.getPrinter("BottomMargin") *
+            int(printer.resolution() / 2.54)
+        )
+        
+        self.scene().render(painter,
+                            target=QRectF(marginX, marginY, width, height))
+        
+        # write a foot note
+        tc = QColor(50, 50, 50)
+        painter.setPen(tc)
+        painter.drawRect(marginX, marginY, width, height)
+        painter.drawLine(marginX, marginY + height + 2,
+                         marginX + width, marginY + height + 2)
+        painter.setFont(font)
+        painter.drawText(marginX, marginY + height + 4, width,
+                         fontHeight, Qt.AlignmentFlag.AlignRight, diagramName)
+        
+        painter.end()
+    
+    ###########################################################################
+    ## The methods below should be overridden by subclasses to get special
+    ## behavior.
+    ###########################################################################
+    
+    def filteredItems(self, items):
+        """
+        Public method to filter a list of items.
+        
+        @param items list of items as returned by the scene object
+            (QGraphicsItem)
+        @return list of interesting collision items (QGraphicsItem)
+        """
+        # just return the list unchanged
+        return items
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/eric7/EricGraphics/__init__.py	Fri May 21 18:01:11 2021 +0200
@@ -0,0 +1,9 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
+#
+
+"""
+Package implementing some QGraphicsView related general purpoe classes.
+"""
+# TODO: rename this package to EricGraphics
--- a/eric7/Graphics/ApplicationDiagramBuilder.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/ApplicationDiagramBuilder.py	Fri May 21 18:01:11 2021 +0200
@@ -388,16 +388,6 @@
                 colors=self.umlView.getDrawingColors())
             self.scene.addItem(assoc)
     
-    def getPersistenceData(self):
-        """
-        Public method to get a string for data to be persisted.
-        
-        @return persisted data string
-        @rtype str
-        """
-        return "project={0}, no_modules={1}".format(
-            self.project.getProjectFile(), self.noModules)
-    
     def parsePersistenceData(self, version, data):
         """
         Public method to parse persisted data.
--- a/eric7/Graphics/AssociationItem.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/AssociationItem.py	Fri May 21 18:01:11 2021 +0200
@@ -12,7 +12,7 @@
 from PyQt6.QtCore import QPointF, QRectF, QLineF
 from PyQt6.QtWidgets import QGraphicsItem
 
-from E5Graphics.E5ArrowItem import E5ArrowItem, E5ArrowType
+from EricGraphics.EricArrowItem import EricArrowItem, EricArrowType
 
 import Utilities
 
@@ -42,7 +42,7 @@
     CENTER = 9
 
 
-class AssociationItem(E5ArrowItem):
+class AssociationItem(EricArrowItem):
     """
     Class implementing a graphics item for an association between two items.
     
@@ -69,13 +69,13 @@
         @type QGraphicsItem
         """
         if assocType in (AssociationType.NORMAL, AssociationType.IMPORTS):
-            arrowType = E5ArrowType.NORMAL
+            arrowType = EricArrowType.NORMAL
             arrowFilled = True
         elif assocType == AssociationType.GENERALISATION:
-            arrowType = E5ArrowType.WIDE
+            arrowType = EricArrowType.WIDE
             arrowFilled = False
         
-        E5ArrowItem.__init__(self, QPointF(0, 0), QPointF(100, 100),
+        EricArrowItem.__init__(self, QPointF(0, 0), QPointF(100, 100),
                              arrowFilled, arrowType, colors, parent)
         
         self.setFlag(QGraphicsItem.GraphicsItemFlag.ItemIsMovable, False)
@@ -555,24 +555,6 @@
         self.itemA.removeAssociation(self)
         self.itemB.removeAssociation(self)
     
-    def buildAssociationItemDataString(self):
-        """
-        Public method to build a string to persist the specific item data.
-        
-        This string should be built like "attribute=value" with pairs separated
-        by ", ". value must not contain ", " or newlines.
-        
-        @return persistence data
-        @rtype str
-        """
-        entries = [
-            "src={0}".format(self.itemA.getId()),
-            "dst={0}".format(self.itemB.getId()),
-            "type={0}".format(self.assocType.value),
-            "topToBottom={0}".format(self.topToBottom)
-        ]
-        return ", ".join(entries)
-    
     @classmethod
     def parseAssociationItemDataString(cls, data):
         """
--- a/eric7/Graphics/ClassItem.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/ClassItem.py	Fri May 21 18:01:11 2021 +0200
@@ -316,37 +316,6 @@
         """
         return self.external
     
-    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
-        @rtype str
-        """
-        entries = [
-            "is_external={0}".format(self.external),
-            "no_attributes={0}".format(self.noAttrs),
-            "name={0}".format(self.model.getName()),
-        ]
-        instanceAttributes = self.model.getInstanceAttributes()
-        if instanceAttributes:
-            entries.append("attributes={0}".format(
-                "||".join(instanceAttributes)))
-        methods = self.model.getMethods()
-        if methods:
-            entries.append("methods={0}".format(
-                "||".join(methods)))
-        classAttributes = self.model.getClassAttributes()
-        if classAttributes:
-            entries.append("class_attributes={0}".format(
-                "||".join(classAttributes)))
-        
-        return ", " + ", ".join(entries)
-    
     def parseItemDataString(self, version, data):
         """
         Public method to parse the given persistence data.
--- a/eric7/Graphics/ImportsDiagramBuilder.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/ImportsDiagramBuilder.py	Fri May 21 18:01:11 2021 +0200
@@ -328,16 +328,6 @@
                 colors=self.umlView.getDrawingColors())
             self.scene.addItem(assoc)
     
-    def getPersistenceData(self):
-        """
-        Public method to get a string for data to be persisted.
-        
-        @return persisted data string
-        @rtype str
-        """
-        return "package={0}, show_external={1}".format(
-            self.packagePath, self.showExternalImports)
-    
     def parsePersistenceData(self, version, data):
         """
         Public method to parse persisted data.
--- a/eric7/Graphics/ModuleItem.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/ModuleItem.py	Fri May 21 18:01:11 2021 +0200
@@ -176,26 +176,6 @@
         
         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
-        @rtype str
-        """
-        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.
--- a/eric7/Graphics/PackageDiagramBuilder.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/PackageDiagramBuilder.py	Fri May 21 18:01:11 2021 +0200
@@ -474,16 +474,6 @@
                     colors=self.umlView.getDrawingColors())
                 self.scene.addItem(assoc)
     
-    def getPersistenceData(self):
-        """
-        Public method to get a string for data to be persisted.
-        
-        @return persisted data string
-        @rtype str
-        """
-        return "package={0}, no_attributes={1}".format(
-            self.package, self.noAttrs)
-    
     def parsePersistenceData(self, version, data):
         """
         Public method to parse persisted data.
--- a/eric7/Graphics/PackageItem.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/PackageItem.py	Fri May 21 18:01:11 2021 +0200
@@ -202,27 +202,6 @@
         
         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
-        @rtype str
-        """
-        entries = [
-            "no_modules={0}".format(self.noModules),
-            "name={0}".format(self.model.getName()),
-        ]
-        modules = self.model.getModules()
-        if modules:
-            entries.append("modules={0}".format("||".join(modules)))
-        
-        return ", " + ", ".join(entries)
-    
     def parseItemDataString(self, version, data):
         """
         Public method to parse the given persistence data.
--- a/eric7/Graphics/UMLClassDiagramBuilder.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/UMLClassDiagramBuilder.py	Fri May 21 18:01:11 2021 +0200
@@ -314,15 +314,6 @@
                     colors=self.umlView.getDrawingColors())
                 self.scene.addItem(assoc)
     
-    def getPersistenceData(self):
-        """
-        Public method to get a string for data to be persisted.
-        
-        @return persisted data string
-        @rtype str
-        """
-        return "file={0}, no_attributes={1}".format(self.file, self.noAttrs)
-    
     def parsePersistenceData(self, version, data):
         """
         Public method to parse persisted data.
--- a/eric7/Graphics/UMLDiagramBuilder.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/UMLDiagramBuilder.py	Fri May 21 18:01:11 2021 +0200
@@ -65,15 +65,6 @@
         raise NotImplementedError(
             "Method 'buildDiagram' must be implemented in subclasses.")
     
-    def getPersistenceData(self):
-        """
-        Public method to get a string for data to be persisted.
-        
-        @return persisted data string
-        @rtype str
-        """
-        return ""
-    
     def parsePersistenceData(self, version, data):
         """
         Public method to parse persisted data.
--- a/eric7/Graphics/UMLDialog.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/UMLDialog.py	Fri May 21 18:01:11 2021 +0200
@@ -265,18 +265,13 @@
                     return
             filename = fname
         
-        res = (
-            self.__writeLineBasedGraphicsFile(filename)
-            if filename.endswith(".e5g") else
-            # JSON format is the default
-            self.__writeJsonGraphicsFile(filename)
-        )
+        res = self.__writeJsonGraphicsFile(filename)
         
         if res:
             # save the file name only in case of success
             self.__fileName = filename
     
-    # TODO: eric7: delete the current one
+    # Note: remove loading of eric6 line based diagram format after 22.6
     def load(self, filename=""):
         """
         Public method to load a diagram from a file.
@@ -406,42 +401,42 @@
         
         return True
     
-    def __writeLineBasedGraphicsFile(self, filename):
-        """
-        Private method to write an eric graphics file using the old line
-        based file format.
-        
-        @param filename name of the file to write to
-        @type str
-        @return flag indicating a successful write
-        @rtype bool
-        """
-        lines = [
-            "version: 1.0",
-            "diagram_type: {0} ({1})".format(
-                self.__diagramType.value,
-                self.__getDiagramTitel(self.__diagramType)),
-            "scene_size: {0};{1}".format(self.scene.width(),
-                                         self.scene.height()),
-        ]
-        persistenceData = self.builder.getPersistenceData()
-        if persistenceData:
-            lines.append("builder_data: {0}".format(persistenceData))
-        lines.extend(self.umlView.getPersistenceData())
-        
-        try:
-            with open(filename, "w", encoding="utf-8") as f:
-                f.write("\n".join(lines))
-            return True
-        except OSError as err:
-            E5MessageBox.critical(
-                self,
-                self.tr("Save Diagram"),
-                self.tr(
-                    """<p>The file <b>{0}</b> could not be saved.</p>"""
-                    """<p>Reason: {1}</p>""").format(filename, str(err)))
-            return False
-    
+##    def __writeLineBasedGraphicsFile(self, filename):
+##        """
+##        Private method to write an eric graphics file using the old line
+##        based file format.
+##        
+##        @param filename name of the file to write to
+##        @type str
+##        @return flag indicating a successful write
+##        @rtype bool
+##        """
+##        lines = [
+##            "version: 1.0",
+##            "diagram_type: {0} ({1})".format(
+##                self.__diagramType.value,
+##                self.__getDiagramTitel(self.__diagramType)),
+##            "scene_size: {0};{1}".format(self.scene.width(),
+##                                         self.scene.height()),
+##        ]
+##        persistenceData = self.builder.getPersistenceData()
+##        if persistenceData:
+##            lines.append("builder_data: {0}".format(persistenceData))
+##        lines.extend(self.umlView.getPersistenceData())
+##        
+##        try:
+##            with open(filename, "w", encoding="utf-8") as f:
+##                f.write("\n".join(lines))
+##            return True
+##        except OSError as err:
+##            E5MessageBox.critical(
+##                self,
+##                self.tr("Save Diagram"),
+##                self.tr(
+##                    """<p>The file <b>{0}</b> could not be saved.</p>"""
+##                    """<p>Reason: {1}</p>""").format(filename, str(err)))
+##            return False
+##    
     def __showInvalidDataMessage(self, filename, linenum=-1):
         """
         Private slot to show a message dialog indicating an invalid data file.
--- a/eric7/Graphics/UMLGraphicsView.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/UMLGraphicsView.py	Fri May 21 18:01:11 2021 +0200
@@ -4,7 +4,7 @@
 #
 
 """
-Module implementing a subclass of E5GraphicsView for our diagrams.
+Module implementing a subclass of EricGraphicsView for our diagrams.
 """
 
 from PyQt6.QtCore import (
@@ -14,7 +14,7 @@
 from PyQt6.QtWidgets import QGraphicsView, QToolBar, QDialog
 from PyQt6.QtPrintSupport import QPrinter, QPrintDialog
 
-from E5Graphics.E5GraphicsView import E5GraphicsView
+from EricGraphics.EricGraphicsView import EricGraphicsView
 
 from E5Gui import E5MessageBox, E5FileDialog
 from E5Gui.E5ZoomWidget import E5ZoomWidget
@@ -27,9 +27,9 @@
 import Preferences
 
 
-class UMLGraphicsView(E5GraphicsView):
+class UMLGraphicsView(EricGraphicsView):
     """
-    Class implementing a specialized E5GraphicsView for our diagrams.
+    Class implementing a specialized EricGraphicsView for our diagrams.
     
     @signal relayout() emitted to indicate a relayout of the diagram
         is requested
@@ -45,7 +45,7 @@
         @param parent parent widget of the view
         @type QWidget
         """
-        E5GraphicsView.__init__(self, scene, parent)
+        EricGraphicsView.__init__(self, scene, parent)
         self.setObjectName("UMLGraphicsView")
         self.setViewportUpdateMode(
             QGraphicsView.ViewportUpdateMode.FullViewportUpdate)
@@ -62,7 +62,7 @@
             UI.PixmapCache.getPixmap("zoomReset"), self)
         parent.statusBar().addPermanentWidget(self.__zoomWidget)
         self.__zoomWidget.setMapping(
-            E5GraphicsView.ZoomLevels, E5GraphicsView.ZoomLevelDefault)
+            EricGraphicsView.ZoomLevels, EricGraphicsView.ZoomLevelDefault)
         self.__zoomWidget.valueChanged.connect(self.setZoom)
         self.zoomValueChanged.connect(self.__zoomWidget.setValue)
         
@@ -734,29 +734,6 @@
         
         return None
     
-    def getPersistenceData(self):
-        """
-        Public method to get a list of data to be persisted.
-        
-        @return list of data to be persisted
-        @rtype list of str
-        """
-        lines = [
-            "diagram_name: {0}".format(self.diagramName),
-        ]
-        
-        for item in self.filteredItems(self.scene().items(), UMLItem):
-            lines.append("item: id={0}, x={1}, y={2}, item_type={3}{4}".format(
-                item.getId(), item.x(), item.y(), item.getItemType(),
-                item.buildItemDataString()))
-        
-        from .AssociationItem import AssociationItem
-        for item in self.filteredItems(self.scene().items(), AssociationItem):
-            lines.append("association: {0}".format(
-                item.buildAssociationItemDataString()))
-        
-        return lines
-    
     def parsePersistenceData(self, version, data):
         """
         Public method to parse persisted data.
--- a/eric7/Graphics/UMLItem.py	Fri May 21 17:54:15 2021 +0200
+++ b/eric7/Graphics/UMLItem.py	Fri May 21 18:01:11 2021 +0200
@@ -253,19 +253,6 @@
         """
         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
-        @rtype str
-        """
-        return ""
-    
     def parseItemDataString(self, version, data):
         """
         Public method to parse the given persistence data.

eric ide

mercurial