diff -r 197414ba11cc -r b3eefd7e58d1 eric6/Graphics/UMLGraphicsView.py --- a/eric6/Graphics/UMLGraphicsView.py Sat May 01 14:27:38 2021 +0200 +++ b/eric6/Graphics/UMLGraphicsView.py Thu Jun 03 11:39:23 2021 +0200 @@ -39,8 +39,10 @@ """ Constructor - @param scene reference to the scene object (QGraphicsScene) - @param parent parent widget of the view (QWidget) + @param scene reference to the scene object + @type QGraphicsScene + @param parent parent widget of the view + @type QWidget """ E5GraphicsView.__init__(self, scene, parent) self.setObjectName("UMLGraphicsView") @@ -169,7 +171,17 @@ self.alignMapper.setMapping( self.alignBottomAct, Qt.AlignmentFlag.AlignBottom) self.alignBottomAct.triggered.connect(self.alignMapper.map) + + def setLayoutActionsEnabled(self, enable): + """ + Public method to enable or disable the layout related actions. + @param enable flag indicating the desired enable state + @type bool + """ + self.rescanAct.setEnabled(enable) + self.relayoutAct.setEnabled(enable) + def __checkSizeActions(self): """ Private slot to set the enabled state of the size actions. @@ -189,7 +201,8 @@ """ Private slot called when the scene changes. - @param areas list of rectangles that contain changes (list of QRectF) + @param areas list of rectangles that contain changes + @type list of QRectF """ if len(self.scene().selectedItems()) > 0: self.deleteShapeAct.setEnabled(True) @@ -214,7 +227,8 @@ """ Public method to populate a toolbar with our actions. - @return the populated toolBar (QToolBar) + @return the populated toolBar + @rtype QToolBar """ toolBar = QToolBar(self.tr("Graphics"), self) toolBar.setIconSize(UI.Config.ToolBarIconSize) @@ -243,9 +257,11 @@ Public method to filter a list of items. @param items list of items as returned by the scene object - (QGraphicsItem) - @param itemType type to be filtered (class) - @return list of interesting collision items (QGraphicsItem) + @type QGraphicsItem + @param itemType type to be filtered + @type class + @return list of interesting collision items + @rtype QGraphicsItem """ return [itm for itm in items if isinstance(itm, itemType)] @@ -253,7 +269,8 @@ """ Public method to select the given items. - @param items list of items to be selected (list of QGraphicsItemItem) + @param items list of items to be selected + @type list of QGraphicsItemItem """ # step 1: deselect all items self.unselectItems() @@ -267,7 +284,8 @@ """ Public method to select an item. - @param item item to be selected (QGraphicsItemItem) + @param item item to be selected + @type QGraphicsItemItem """ if isinstance(item, UMLItem): item.setSelected(not item.isSelected()) @@ -329,7 +347,8 @@ Public method to adjust the scene size to the diagram size. @param limit flag indicating to limit the scene to the - initial size (boolean) + initial size + @type bool """ super().autoAdjustSceneSize(limit=limit) self.__checkSizeActions() @@ -411,7 +430,7 @@ """ Public slot called to print the diagram. """ - printer = QPrinter(mode=QPrinter.PrinterMode.ScreenResolution) + printer = QPrinter(mode=QPrinter.PrinterMode.PrinterResolution) printer.setFullPage(True) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.ColorMode.Color) @@ -443,7 +462,7 @@ """ from PyQt5.QtPrintSupport import QPrintPreviewDialog - printer = QPrinter(mode=QPrinter.PrinterMode.ScreenResolution) + printer = QPrinter(mode=QPrinter.PrinterMode.PrinterResolution) printer.setFullPage(True) if Preferences.getPrinter("ColorMode"): printer.setColorMode(QPrinter.ColorMode.Color) @@ -472,7 +491,8 @@ """ Private slot to generate a print preview. - @param printer reference to the printer object (QPrinter) + @param printer reference to the printer object + @type QPrinter """ super().printDiagram(printer, self.diagramName) @@ -480,7 +500,8 @@ """ Public slot to set the diagram name. - @param name diagram name (string) + @param name diagram name + @type str """ self.diagramName = name @@ -488,7 +509,8 @@ """ Private slot to align the selected shapes. - @param alignment alignment type (Qt.AlignmentFlag) + @param alignment alignment type + @type Qt.AlignmentFlag """ # step 1: get all selected items items = self.scene().selectedItems() @@ -564,8 +586,10 @@ """ Private method to calculate the bounding rectangle of the given items. - @param items list of items to operate on (list of UMLItem) - @return bounding rectangle (QRectF) + @param items list of items to operate on + @type list of UMLItem + @return bounding rectangle + @rtype QRectF """ rect = self.scene().sceneRect() right = rect.left() @@ -584,7 +608,8 @@ """ Protected method handling key press events. - @param evt reference to the key event (QKeyEvent) + @param evt reference to the key event + @type QKeyEvent """ key = evt.key() if key in [Qt.Key.Key_Up, Qt.Key.Key_Down, Qt.Key.Key_Left, @@ -618,7 +643,8 @@ """ Protected method to handle wheel events. - @param evt reference to the wheel event (QWheelEvent) + @param evt reference to the wheel event + @type QWheelEvent """ if evt.modifiers() & Qt.KeyboardModifier.ControlModifier: delta = evt.angleDelta().y() @@ -635,8 +661,10 @@ """ Public method handling events. - @param evt reference to the event (QEvent) - @return flag indicating, if the event was handled (boolean) + @param evt reference to the event + @type QEvent + @return flag indicating, if the event was handled + @rtype bool """ if evt.type() == QEvent.Type.Gesture: self.gestureEvent(evt) @@ -648,7 +676,8 @@ """ Protected method handling gesture events. - @param evt reference to the gesture event (QGestureEvent + @param evt reference to the gesture event + @type QGestureEvent """ pinch = evt.gesture(Qt.GestureType.PinchGesture) if pinch: @@ -662,7 +691,8 @@ """ Public method to get the ID to be assigned to an item. - @return item ID (integer) + @return item ID + @rtype int """ self.__itemId += 1 return self.__itemId @@ -671,8 +701,10 @@ """ Public method to find an UML item based on the ID. - @param itemId of the item to search for (integer) - @return item found (UMLItem) or None + @param itemId of the item to search for + @type int + @return item found or None + @rtype UMLItem """ for item in self.scene().items(): try: @@ -687,8 +719,10 @@ """ Public method to find an UML item based on its name. - @param name name to look for (string) - @return item found (UMLItem) or None + @param name name to look for + @type str + @return item found or None + @rtype UMLItem """ for item in self.scene().items(): try: @@ -703,7 +737,8 @@ """ Public method to get a list of data to be persisted. - @return list of data to be persisted (list of strings) + @return list of data to be persisted + @rtype list of str """ lines = [ "diagram_name: {0}".format(self.diagramName), @@ -725,10 +760,13 @@ """ Public method to parse persisted data. - @param version version of the data (string) - @param data persisted data to be parsed (list of string) + @param version version of the data + @type str + @param data persisted data to be parsed + @type list of str @return tuple of flag indicating success (boolean) and faulty line - number (integer) + number + @rtype int """ umlItems = {} @@ -754,14 +792,15 @@ y = float(y.split("=", 1)[1].strip()) itemType = itemType.split("=", 1)[1].strip() if itemType == ClassItem.ItemType: - itm = ClassItem(x=x, y=y, scene=self.scene(), + itm = ClassItem(x=0, y=0, scene=self.scene(), colors=self.getDrawingColors()) elif itemType == ModuleItem.ItemType: - itm = ModuleItem(x=x, y=y, scene=self.scene(), + itm = ModuleItem(x=0, y=0, scene=self.scene(), colors=self.getDrawingColors()) elif itemType == PackageItem.ItemType: - itm = PackageItem(x=x, y=y, scene=self.scene(), + itm = PackageItem(x=0, y=0, scene=self.scene(), colors=self.getDrawingColors()) + itm.setPos(x, y) itm.setId(itemId) umlItems[itemId] = itm if not itm.parseItemDataString(version, itemData): @@ -778,3 +817,77 @@ self.scene().addItem(assoc) return True, -1 + + def toDict(self): + """ + Public method to collect data to be persisted. + + @return dictionary containing data to be persisted + @rtype dict + """ + items = [ + item.toDict() + for item in self.filteredItems(self.scene().items(), UMLItem) + ] + + from .AssociationItem import AssociationItem + associations = [ + assoc.toDict() + for assoc in self.filteredItems(self.scene().items(), + AssociationItem) + ] + + data = { + "diagram_name": self.diagramName, + "items": items, + "associations": associations, + } + + return data + + def fromDict(self, version, data): + """ + Public method to populate the class with data persisted by 'toDict()'. + + @param version version of the data + @type str + @param data dictionary containing the persisted data + @type dict + @return flag indicating success + @rtype bool + """ + from .UMLItem import UMLItem + from .ClassItem import ClassItem + from .ModuleItem import ModuleItem + from .PackageItem import PackageItem + from .AssociationItem import AssociationItem + + umlItems = {} + + try: + self.diagramName = data["diagram_name"] + for itemData in data["items"]: + if itemData["type"] == UMLItem.ItemType: + itm = UMLItem.fromDict( + itemData, colors=self.getDrawingColors()) + elif itemData["type"] == ClassItem.ItemType: + itm = ClassItem.fromDict( + itemData, colors=self.getDrawingColors()) + elif itemData["type"] == ModuleItem.ItemType: + itm = ModuleItem.fromDict( + itemData, colors=self.getDrawingColors()) + elif itemData["type"] == PackageItem.ItemType: + itm = PackageItem.fromDict( + itemData, colors=self.getDrawingColors()) + if itm is not None: + umlItems[itm.getId()] = itm + self.scene().addItem(itm) + + for assocData in data["associations"]: + assoc = AssociationItem.fromDict( + assocData, umlItems, colors=self.getDrawingColors()) + self.scene().addItem(assoc) + + return True + except KeyError: + return False