def createLollipopInterface(self, implementor: OglClass, attachmentAnchor: SelectAnchorPoint): from org.pyut.ui.UmlClassDiagramsFrame import UmlClassDiagramsFrame from org.pyut.commands.CreateOglInterfaceCommand import CreateOglInterfaceCommand from org.pyut.commands.CommandGroup import CommandGroup self.logger.info( f'implementor: {implementor} attachmentAnchor: {attachmentAnchor}') umlFrame: UmlClassDiagramsFrame = self.getFileHandling( ).getCurrentFrame() self.__removeUnneededAnchorPoints(implementor, attachmentAnchor) umlFrame.Refresh() pyutInterface: PyutInterface = PyutInterface() pyutInterface.addImplementor(implementor.getPyutObject().getName()) with DlgEditInterface(umlFrame, ID_ANY, pyutInterface) as dlg: if dlg.ShowModal() == OK: self.logger.info(f'model: {pyutInterface}') pyutClass: PyutClass = implementor.getPyutObject() pyutClass.addInterface(pyutInterface) cmd: CreateOglInterfaceCommand = CreateOglInterfaceCommand( pyutInterface, attachmentAnchor) group: CommandGroup = CommandGroup("Create lollipop") group.addCommand(cmd) umlFrame.getHistory().addCommandGroup(group) umlFrame.getHistory().execute() else: self.logger.info(f'Cancelled')
def _readFoundationCoreClass(self, coreClass): """ Read one Foundation.Core.Class @param coreClass : Foundation.Core.Class element @author C.Dutoit """ # Get class name className = self._readFoundationCoreClassName(coreClass) self.logger.info("Reading class ", className, end=' ') # Get class ID classID = str(coreClass.getAttribute("xmi.id")) self.logger.info("id = ", classID, end=' ') # Save class pyutClass = PyutClass(className) # Get class abstract status isAbstract = self._readFoundationCoreClassIsAbstract(coreClass) self.logger.info("isAbstract = ", isAbstract) if isAbstract: pyutClass.setStereotype("Abstract") # Get class features self._readFoundationCoreClassifierFeature(coreClass, pyutClass) # Make the PyutClass visible oglClass = OglClass(pyutClass) x = (len(self._dicOglClasses) % 10) * 100 y = len(self._dicOglClasses) / 10 * 100 self._umlFrame.addShape(oglClass, x, y) oglClass.autoResize() self._dicOglClasses[classID] = oglClass
def createInterfaceLink(self, src: OglClass, dst: OglClass) -> OglInterface: """ Adds an OglInterface link between src and dst. Args: src: source of the link dst: destination of the link Returns: the created OglInterface link """ pyutLink: PyutLink = PyutLink(linkType=LinkType.INTERFACE, source=src, destination=dst) oglInterface: OglInterface = OglInterface(srcShape=src, pyutLink=pyutLink, dstShape=dst) src.addLink(oglInterface) dst.addLink(oglInterface) self._diagram.AddShape(oglInterface) self.Refresh() return oglInterface
def _createInheritanceLink(self, child: OglClass, parent: OglClass) -> OglLink: """ Add a parent link between the child and parent objects. Args: child: Child PyutClass parent: Parent PyutClass Returns: The inheritance OglLink """ sourceClass: PyutClass = cast(PyutClass, child.pyutObject) destinationClass: PyutClass = cast(PyutClass, parent.pyutObject) pyutLink: PyutLink = PyutLink("", linkType=LinkType.INHERITANCE, source=sourceClass, destination=destinationClass) oglLink: OglLink = getOglLinkFactory().getOglLink( child, pyutLink, parent, LinkType.INHERITANCE) child.addLink(oglLink) parent.addLink(oglLink) # add it to the PyutClass # child.getPyutObject().addParent(parent.getPyutObject()) childPyutClass: PyutClass = cast(PyutClass, child.pyutObject) parentPyutClass: PyutClass = cast(PyutClass, parent.pyutObject) childPyutClass.addParent(parentPyutClass) return oglLink
def createInheritanceLink(self, child: OglClass, parent: OglClass) -> OglLink: """ TODO: this is a duplicate of CreateOglLinkCommandCommand._createInheritanceLink (this code adds it to the frame) Add a parent link between the child and parent objects. Args: child: Child PyutClass parent: Parent PyutClass Returns: The inheritance OglLink """ pyutLink = PyutLink("", linkType=LinkType.INHERITANCE, source=child.getPyutObject(), destination=parent.getPyutObject()) oglLink = getOglLinkFactory().getOglLink(child, pyutLink, parent, LinkType.INHERITANCE) child.addLink(oglLink) parent.addLink(oglLink) # add it to the PyutClass # child.getPyutObject().addParent(parent.getPyutObject()) childPyutClass: PyutClass = child.getPyutObject() parentPyutClass: PyutClass = parent.getPyutObject() childPyutClass.addParent(parentPyutClass) self._diagram.AddShape(oglLink) self.Refresh() return oglLink
def createLink(self, src: OglClass, dst: OglClass, linkType: LinkType = LinkType.AGGREGATION): """ Used to create links; It is still the caller's responsibility to add the created shape to the appropriate diagram Args: src: The source OglClass dst: The destination OglClass linkType: The type of link """ pyutLink = PyutLink("", linkType=linkType, source=src.getPyutObject(), destination=dst.getPyutObject()) oglLinkFactory = getOglLinkFactory() oglLink = oglLinkFactory.getOglLink(src, pyutLink, dst, linkType) src.addLink(oglLink) dst.addLink(oglLink) src.getPyutObject().addLink(pyutLink) return oglLink
def _createNewClass(self, x, y): """ Add a new class at (x, y). @return PyutClass : the newly created PyutClass @since 1.4 @author L. Burgbacher <*****@*****.**> """ from org.pyut.general.Mediator import getMediator from org.pyut.model.PyutClass import PyutClass from org.pyut.ogl.OglClass import OglClass med = getMediator() umlFrame = med.getFileHandling().getCurrentFrame() pyutClass = PyutClass(_("NoName")) oglClass = OglClass(pyutClass) med.classEditor(pyutClass) # med.autoResize(pyutClass) umlFrame.addShape(oglClass, x, y, withModelUpdate=True) med.autoResize(pyutClass) umlFrame.Refresh() return oglClass
def write(self, oglObject: OglClass, file: TextIO): """ Write data to filename. Format: ```python Class Name <<stereotype_optional>> +method([param[:type]]*)[:type_return] +field[:type][=value_initial] ``` Args: oglObject: The Ogl object to edit file: The text file to write to """ o: PyutClass = cast(PyutClass, oglObject.getPyutObject()) file.write(o.getName() + osLineSep) if o.getStereotype() is not None: file.write(str(o.getStereotype()) + osLineSep) for method in o.methods: file.write(method.getString() + osLineSep) for field in o.fields: file.write(str(field) + osLineSep) file.close()
def _determineAttachmentPoint(self, attachmentPoint: AttachmentPoint, oglClass: OglClass) -> OglPosition: oglPosition: OglPosition = OglPosition() dw, dh = oglClass.GetSize() if attachmentPoint == AttachmentPoint.NORTH: northX: int = dw // 2 northY: int = 0 oglPosition.x = northX oglPosition.y = northY elif attachmentPoint == AttachmentPoint.SOUTH: southX = dw // 2 southY = dh oglPosition.x = southX oglPosition.y = southY elif attachmentPoint == AttachmentPoint.WEST: westX: int = 0 westY: int = dh // 2 oglPosition.x = westX oglPosition.y = westY elif attachmentPoint == AttachmentPoint.EAST: eastX: int = dw eastY: int = dh // 2 oglPosition.x = eastX oglPosition.y = eastY else: self.logger.warning(f'Unknown attachment point: {attachmentPoint}') assert False, 'Unknown attachment point' return oglPosition
def _getOglClasses(self, xmlOglClasses, dicoOglObjects, umlFrame, oldData): """ Parse the XMI elements given and build data layer for PyUT classes. If file is version 1.0, the dictionary given will contain, for key, the name of the OGL object. Otherwise, it will be the ID (multi-same-name support from version 1.1). Everything is fixed later. @param Element[] xmlOglClasses : XMI 'GraphicClass' elements @param {id / srcName, OglObject} dicoOglObjects : OGL objects loaded @param UmlFrame umlFrame : Where to draw @param int oldData : If old data (v1.0), 1 else 0 @since 2.0 @author Philippe Waelti <*****@*****.**> """ pyutClass = PyutClass() # adding name for this class className = xmlOglClasses.getElementsByTagName("Foundation.Core.ModelElement.name") self.logger.debug(f'Ogl class name: {className}') if len(className) > 0: name = className[0].firstChild if name.nodeType == name.TEXT_NODE: pyutClass.setName(name.data) oglClass = OglClass(pyutClass, 50, 50) # adding methods for this class pyutClass.setMethods(self._getMethods(xmlOglClasses)) # adding fields for this class pyutClass.fields = self._getFields(xmlOglClasses) # for class id classId = xmlOglClasses.getAttribute("xmi.id") self.logger.debug(f"Class ID: {classId}") # for all the classes who are an inheritance link for fathers in xmlOglClasses.getElementsByTagName("Foundation.Core.Generalization"): linkId = fathers.getAttribute("xmi.idref") self.logger.debug(f"parent: {linkId}") if linkId not in self.dicoFather: self.dicoFather[linkId] = {} self.dicoFather[linkId][classId] = oglClass # for all class whos are link for links in xmlOglClasses.getElementsByTagName("Foundation.Core.Classifier.associationEnd"): for link in links.getElementsByTagName("Foundation.Core.AssociationEnd"): linkId = link.getAttribute("xmi.idref") self.logger.debug(f"linkId: {linkId}") if linkId not in self.dicoLinks: self.dicoLinks[linkId] = oglClass pyutClassId = pyutClass.getId() self.logger.debug(f'pyutClassId: {pyutClassId}') dicoOglObjects[pyutClassId] = oglClass umlFrame.addShape(oglClass, 100, 100)
def testDeSerializeLink(self): """ This test ensures that we correctly deserialize an inheritance link. This is a results of issue https://github.com/hasii2011/PyUt/issues/315 So we have set up the mock values to correctly build it """ mockUmlFrame: Mock = Mock(spec=UmlClassDiagramsFrame) mockHistoryManager: Mock = Mock(spec=HistoryManager) mockCommandGroup: Mock = Mock(spec=CommandGroup) mockUmlFrame.getUmlObjectById.side_effect = self._getUmlObjectByIdSideEffect mockCommandGroup.getHistory.return_value = mockHistoryManager mockHistoryManager.getFrame.return_value = mockUmlFrame Shape.ID = 0 # reset this since it runs in the entire unit test context self._parent: OglClass = OglClass() self._child: OglClass = OglClass() cmd: CreateOglLinkCommand = CreateOglLinkCommand( src=self._child, dst=self._parent) # inheritance points back to parent cmd._group = mockCommandGroup serializedLink: str = ( '<BEGIN_COMMAND_GROUP>' '<GROUP_COMMENT=Create link>' '<BEGIN_COMMAND>' '<COMMAND_MODULE=org.pyut.history.commands.CreateOglLinkCommand>' '<COMMAND_CLASS=CreateOglLinkCommand>' f'<srcId={CHILD_ID}><dstId={PARENT_ID}>' '<srcPos=(264.0, 195.0)><dstPos=(414.0, 450.0)><linkType=INHERITANCE><linkId=2>' '<END_COMMAND>' '<END_COMMAND_GROUP>') cmd.deserialize(serializedInfo=serializedLink) link: OglInheritance = cmd._link self.assertIsNotNone(link, 'We should have created it') self.assertTrue(isinstance(link, OglInheritance), 'Create wrong type of link') self.assertEqual(self._child.GetID(), CHILD_ID, 'Incorrect child') self.assertEqual(self._parent.GetID(), PARENT_ID, 'Incorrect parent') self.logger.debug(f'{link}')
def testCacheOglClass(self): oglClass: OglClass = OglClass(pyutClass=self._pyutClass) doppleGanger: OglClass = oglClass initialId: int = self._idFactory.getID(oglClass) nextId: int = self._idFactory.getID(doppleGanger) self.assertEqual(initialId, nextId, 'Should be the same')
def __removeUnneededAnchorPoints(self, implementor: OglClass, attachmentAnchor: SelectAnchorPoint): attachmentPoint: AttachmentPoint = attachmentAnchor.attachmentPoint for anchor in implementor.GetAnchors(): if isinstance(anchor, SelectAnchorPoint): anchor: SelectAnchorPoint = cast(SelectAnchorPoint, anchor) if anchor.attachmentPoint != attachmentPoint: anchor.SetProtected(False) anchor.Detach()
def createClass(self, oglClass: OglClass): x, y = oglClass.GetPosition() cmdGroup: CommandGroup = CommandGroup("Create class") cmd: CreateOglClassCommand = CreateOglClassCommand(x=x, y=y, oglClass=oglClass) cmdGroup.addCommand(cmd) self.getHistory().addCommandGroup(cmdGroup) cmd.execute()
def _generateOglClasses(self, umlFrame: UmlClassDiagramsFrame): for pyutClassName in self._pyutClasses: try: pyutClass: PyutClass = self._pyutClasses[pyutClassName] oglClass: OglClass = OglClass(pyutClass) umlFrame.addShape(oglClass, 0, 0) oglClass.autoResize() self._oglClasses[pyutClassName] = oglClass except (ValueError, Exception) as e: self.logger.error(f"Error while creating class {pyutClassName}, {e}")
def createNewClass(self, x, y): """ Add a new class at (x, y). @return PyutClass : the newly created PyutClass """ pyutClass: PyutClass = PyutClass(_("NoName")) oglClass: OglClass = OglClass(pyutClass) self.addShape(oglClass, x, y) self.Refresh() return pyutClass
def getOglClasses(self, xmlOglClasses: NodeList) -> OglClasses: """ Loads to OGL objects Parse the XML elements given and build data model for the Pyut classes. Args: xmlOglClasses: XML 'GraphicClass' elements Returns: The built dictionary uses an ID for the key and an OglClass for the value """ oglObjects: OglClasses = cast(OglClasses, {}) for xmlOglClass in xmlOglClasses: xmlOglClass: Element = cast(Element, xmlOglClass) pyutClass: PyutClass = PyutClass() height: float = float(xmlOglClass.getAttribute(PyutXmlConstants.ATTR_HEIGHT)) width: float = float(xmlOglClass.getAttribute(PyutXmlConstants.ATTR_WIDTH)) oglClass: OglClass = OglClass(pyutClass, width, height) xmlClass: Element = xmlOglClass.getElementsByTagName(PyutXmlConstants.ELEMENT_MODEL_CLASS)[0] pyutClass.setId(int(xmlClass.getAttribute(PyutXmlConstants.ATTR_ID))) pyutClass.setName(xmlClass.getAttribute(PyutXmlConstants.ATTR_NAME)) pyutClass.description = xmlClass.getAttribute(PyutXmlConstants.ATTR_DESCRIPTION) if xmlClass.hasAttribute(PyutXmlConstants.ATTR_STEREOTYPE): pyutClass.setStereotype(getPyutStereotype(xmlClass.getAttribute(PyutXmlConstants.ATTR_STEREOTYPE))) # adding display properties (cd) value = PyutUtils.secureBoolean(xmlClass.getAttribute(PyutXmlConstants.ATTR_SHOW_STEREOTYPE)) pyutClass.setShowStereotype(value) value = PyutUtils.secureBoolean(xmlClass.getAttribute(PyutXmlConstants.ATTR_SHOW_METHODS)) pyutClass.showMethods = value value = PyutUtils.secureBoolean(xmlClass.getAttribute(PyutXmlConstants.ATTR_SHOW_FIELDS)) pyutClass.showFields = value pyutClass.setFilename(xmlClass.getAttribute(PyutXmlConstants.ATTR_FILENAME)) pyutClass.methods = self._getMethods(xmlClass) pyutClass.fields = self._getFields(xmlClass) # Adding properties necessary to place shape on a diagram frame x = float(xmlOglClass.getAttribute(PyutXmlConstants.ATTR_X)) y = float(xmlOglClass.getAttribute(PyutXmlConstants.ATTR_Y)) oglClass.SetPosition(x, y) oglObjects[pyutClass.getId()] = oglClass return oglObjects
def __createAnchorHints(self, destinationClass: OglClass, anchorX: float, anchorY: float, attachmentPoint: AttachmentPoint, umlFrame): anchorHint: SelectAnchorPoint = SelectAnchorPoint( x=anchorX, y=anchorY, attachmentPoint=attachmentPoint, parent=destinationClass) anchorHint.SetProtected(True) destinationClass.AddAnchorPoint(anchorHint) umlFrame.getDiagram().AddShape(anchorHint)
def _createNewClass(self) -> OglClass: """ Create a new class Returns: the newly created OglClass """ className: str = f'{self._prefs.className}{CreateOglClassCommand.clsCounter}' pyutClass: PyutClass = PyutClass(className) oglClass: OglClass = OglClass(pyutClass) CreateOglClassCommand.clsCounter += 1 return oglClass
def addToDiagram(self, pyutClassDef: PyutClass) -> OglClass: """ Add graphical version of data class to diagram Args: pyutClassDef: The class data Returns: The graphical element created to represent the above in the diagram """ oglClassDef: OglClass = OglClass(pyutClassDef) self._umlFrame.addShape(oglClassDef, 0, 0) oglClassDef.autoResize() return oglClassDef
def _createNewClass(self) -> OglClass: """ Create a new class Returns: the newly created OglClass """ className: str = f'{self._preferences.className}{TestOglToMiniDomV10.clsCounter}' pyutClass: PyutClass = PyutClass(className) pyutClass.addMethod(self._generateAMethod()) pyutClass.fileName = '/Users/humberto.a.sanchez.ii/PycharmProjects/PyUt/src/UnitTest.py' oglClass: OglClass = OglClass(pyutClass) TestOglToMiniDomV10.clsCounter += 1 return oglClass
def testSerialize(self): pyutClass: PyutClass = PyutClass(name='Implementor') implementor: OglClass = OglClass(pyutClass=pyutClass) attachmentAnchor: SelectAnchorPoint = SelectAnchorPoint( x=100, y=100, attachmentPoint=AttachmentPoint.NORTH) cOglXFaceCmd: CreateOglInterfaceCommand = CreateOglInterfaceCommand( implementor=implementor, attachmentAnchor=attachmentAnchor) # # Override the created OglInterface2 # oglInterface: OglInterface2 = cOglXFaceCmd._shape pyutInterface: PyutInterface = cOglXFaceCmd._pyutInterface floatMethod: PyutMethod = TestCommandCommon.createTestMethod( 'floatMethod', PyutVisibilityEnum.PRIVATE, PyutType('float')) intMethod: PyutMethod = TestCommandCommon.createTestMethod( 'intMethod', PyutVisibilityEnum.PROTECTED, PyutType('int')) pyutInterface.methods = [intMethod, floatMethod] oglInterface.pyutInterface = pyutInterface cOglXFaceCmd._shape = oglInterface serializedShape: str = cOglXFaceCmd.serialize() self.logger.debug(f'{serializedShape=}') self.assertIsNotNone(serializedShape, 'Something must come back') self.maxDiff = None self.logger.debug( f'{len(self._serializedCommand)=} {len(serializedShape)=}') import re fixedSerializedShape = re.sub('shapeId=[0-9]*', 'shapeId=2', serializedShape) self.logger.debug(f'{fixedSerializedShape=}') expectedValue: str = self._serializedCommand actualValue: str = fixedSerializedShape self.assertEqual(expectedValue, actualValue, 'Oops, something changed')
def _OglClass2xml(self, oglClass: OglClass, xmlDoc: Document): """ Exporting an OglClass to an miniDom Element. @param oglClass : Class to save @param xmlDoc xmlDoc : xml document @return Element : XML Node """ root = xmlDoc.createElement('GraphicClass') # Append OGL object base (size and pos) self._appendOglBase(oglClass, root) # adding the data layer object root.appendChild(self._PyutClass2xml(oglClass.getPyutObject(), xmlDoc)) return root
def __createPotentialAttachmentPoints(self, destinationClass: OglClass, umlFrame): dw, dh = destinationClass.GetSize() southX, southY = dw / 2, dh northX, northY = dw / 2, 0 westX, westY = 0.0, dh / 2 eastX, eastY = dw, dh / 2 self.__createAnchorHints(destinationClass, southX, southY, AttachmentPoint.SOUTH, umlFrame) self.__createAnchorHints(destinationClass, northX, northY, AttachmentPoint.NORTH, umlFrame) self.__createAnchorHints(destinationClass, westX, westY, AttachmentPoint.WEST, umlFrame) self.__createAnchorHints(destinationClass, eastX, eastY, AttachmentPoint.EAST, umlFrame)
def onPaste(self, event: CommandEvent): """ Args: event: """ if len(self._clipboard) == 0: return self.logger.info(f'Pasting {len(self._clipboard)} objects') frame = self._mediator.getUmlFrame() if frame == -1: PyutUtils.displayError(_("No frame to paste into")) return # put the objects in the clipboard and remove them from the diagram x, y = 100, 100 for clipboardObject in self._clipboard: obj: PyutObject = copy(clipboardObject) if isinstance(obj, PyutClass): po: OglObject = OglClass(obj) elif isinstance(obj, PyutNote): po = OglNote(obj) elif isinstance(obj, PyutActor): po = OglActor(obj) elif isinstance(obj, PyutUseCase): po = OglUseCase(obj) else: self.logger.error(f'Error when try to paste object: {obj}') return self.logger.info(f'Pasting: {po=}') self._mediator.getUmlFrame().addShape(po, x, y) x += 20 y += 20 canvas = po.GetDiagram().GetPanel() # the frame that contains the shape # specify the canvas on which we will paint dc: ClientDC = ClientDC(canvas) canvas.PrepareDC(dc) self._treeNotebookHandler.setModified(True) self._mediator.updateTitle() canvas.Refresh()
def _OglClass2xml(self, oglClass: OglClass, xmlDoc): """ Exporting an OglClass to an miniDom Element. @param PyutMethod oglClass : Class to save @param xmlDoc : xml Document instance @return Element : XML Node @author Deve Roux <*****@*****.**> """ # lang.importLanguage() root = xmlDoc.createElement("GraphicClass") # Append OGL object base (size and pos) self._appendOglBase(oglClass, root) # adding the data layer object root.appendChild(self._PyutClass2xml(oglClass.getPyutObject(), xmlDoc)) return root
def oglClassToXml(self, oglClass: OglClass, xmlDoc: Document) -> Element: """ Exports an OglClass to a minidom Element. Args: oglClass: Graphic Class to save xmlDoc: The document to append to Returns: The newly created `GraphicClass` element """ root: Element = xmlDoc.createElement( PyutXmlConstants.ELEMENT_GRAPHIC_CLASS) root = self.__appendOglBase(oglClass, root) # adding the data layer object root.appendChild(self._pyutClassToXml(oglClass.getPyutObject(), xmlDoc)) return root
def __addClass(self, className: str) -> OglClass: """ Add a class to the dictionary of classes Args: className: Name of the class to be added Returns: OglClass instance for the class """ # If the class name exists already, return the instance if className in self._classes: return self._classes[className] # Create the class pc: PyutClass = PyutClass(className) # A new PyutClass po: OglClass = OglClass(pc) # A new OglClass self._classes[className] = po return po
def createClasses(self, name: str, x: int, y: int) -> CreatedClassesType: """ Create a pair of classes (pyutClass and oglClass) Args: name: Class Name x: x-coordinate on the uml frame oglClass y: y coordinate on the uml frame oglClass Returns: A named tuple with attributes: pyutClass and oglClass """ pyutClass: PyutClass = PyutClass() pyutClass.setName(name) oglClass: OglClass = OglClass(pyutClass, 50, 50) # To make this code capable of being debugged oglClass.SetPosition(x=x, y=y) self.addShape(oglClass, x, y) createdClasses: CreatedClassesType = CreatedClassesType( pyutClass=pyutClass, oglClass=oglClass) return createdClasses
def createClasses(self, name: str, x: float, y: float) -> CreatedClassesType: """ Create a pair of classes (pyutClass and oglClass) Args: name: Class Name x: x-coordinate on the uml frame oglClass y: y coordinate on the uml frame oglClass Returns: A tuple with one of each: pyutClass and oglClass """ pyutClass: PyutClass = PyutClass() pyutClass.setName(name) oglClass: OglClass = OglClass(pyutClass, 50, 50) # To make this code capable of being debugged oglClass.SetPosition(x=x, y=y) self.addShape(oglClass, x, y) retData: CreatedClassesType = cast(CreatedClassesType, (pyutClass, oglClass)) return retData