Skip to content

Commit

Permalink
<Enhancement>[update for Pyut]: <description>
Browse files Browse the repository at this point in the history
[
* Additional options for IOPluginInterface
* PluginManager was using .doAction instead of .executeTool on Tool Plugins (bug)
* Update OglObjectType
* Update several plugins with new options
* Implement a couple more PluginAdapter methods to ensure the plugin code "as-is" works
* Align UMLFrame more with the "real" UmlFrame;  I really need a component here
* Version update for Pyut
]

[hasii2011/pyut#319]
  • Loading branch information
Humberto Sanchez II committed Oct 27, 2022
1 parent eb8738b commit 4af7302
Show file tree
Hide file tree
Showing 15 changed files with 245 additions and 108 deletions.
74 changes: 49 additions & 25 deletions core/IOPluginInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,47 +43,71 @@ def __init__(self, pluginAdapter: IPluginAdapter):
self._selectedOglObjects: OglObjects = cast(OglObjects, None) # The selected Ogl Objects requested by .executeExport()
self._frameInformation: FrameInformation = cast(FrameInformation, None) # The frame information requested by .executeExport()

#
# Input plugins that require an active frame or frame(s) should set this value to `True`
# Some output plugins may create their own frame or ever their own project and frame. These should set this value to `False`
# Plugins should set the value the need in their constructor
#
self._requireActiveFrame: bool = True
#
# Some Output plugins may offer the option of exporting only selected objects; Others may just export
# the entire project or the current frame
#
# Plugins should set the value the need in their constructor
self._requireSelection: bool = True
#
#
# prefs: PyutPreferences = PyutPreferences()
# if prefs.pyutIoPluginAutoSelectAll is True: TODO: Need plugin preferences
# self._autoSelectAll: bool = True
# else
self._autoSelectAll: bool = False

def executeImport(self):
"""
Called by Pyut to begin the import process. Checks to see if an import format is
supported if not returns None; Checks to see if there are any import options;
If the method return True the import proceeds
Returns:
None if cancelled, else a list of OglObjects
Called by Pyut to begin the import process.
"""
if self.inputFormat is None:
self._oglObjects = None
else:
if self.setImportOptions() is True:
self._oglObjects = self.read()
else:
self._oglObjects = None
# TODO Fix later
# noinspection PyTypeChecker
self._pluginAdapter.getFrameInformation(callback=self._executeImport) # type ignore

return self._oglObjects
def _executeImport(self, frameInformation: FrameInformation):
"""
The callback necessary to start the import process;
Args:
frameInformation:
"""
assert self.inputFormat is not None, 'Developer error. We cannot import w/o an import format'
if self._requireActiveFrame is True:
if frameInformation.frameActive is False:
self.displayNoUmlFrame()
return
if self.setImportOptions() is True:
self.read()

def executeExport(self):
"""
Called by Pyut to begin the export process.
"""
if self._autoSelectAll is True:
self._pluginAdapter.selectAllOglObjects()
self._pluginAdapter.getFrameInformation(callback=self._executeExport)

def _executeExport(self, frameInformation: FrameInformation):

assert self.outputFormat is not None, 'Developer error. We cannot export w/o and output format'
assert self.outputFormat is not None, 'Developer error. We cannot export w/o an output format'

self._frameInformation = frameInformation

if frameInformation.frameActive is False:
self.displayNoUmlFrame()
else:
if self.setExportOptions() is True:
self._frameInformation = frameInformation
self._selectedOglObjects = frameInformation.selectedOglObjects # syntactic sugar
# prefs: PyutPreferences = PyutPreferences()
# if prefs.pyutIoPluginAutoSelectAll is True: TODO: Need plugin preferences
# pluginAdapter.selectAllShapes()

if len(self._selectedOglObjects) == 0:
self.displayNoSelectedOglObjects()
else:
self._selectedOglObjects = frameInformation.selectedOglObjects # syntactic sugar

if len(self._selectedOglObjects) == 0:
self.displayNoSelectedOglObjects()
else:
if self.setExportOptions() is True:
self.write(self._selectedOglObjects)
self._pluginAdapter.deselectAllOglObjects()

Expand Down
17 changes: 8 additions & 9 deletions core/PluginManager.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,15 +152,14 @@ def doToolAction(self, wxId: int):
# Create a plugin instance
pluginInstance: ToolPluginInterface = clazz(pluginAdapter=self._pluginAdapter)

if pluginInstance.setOptions() is True:
# Do plugin functionality
BeginBusyCursor()
try:
pluginInstance.doAction()
self.logger.debug(f"After tool plugin do action")
except (ValueError, Exception) as e:
self.logger.error(f'{e}')
EndBusyCursor()
# Do plugin functionality
BeginBusyCursor()
try:
pluginInstance.executeTool()
self.logger.debug(f"After tool plugin do action")
except (ValueError, Exception) as e:
self.logger.error(f'{e}')
EndBusyCursor()

def doImport(self, wxId: int):
"""
Expand Down
1 change: 1 addition & 0 deletions core/ToolPluginInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def executeTool(self):
"""
This is used by Pyut to invoke the tool. This should NOT
be overridden
TODO: Check for active frame
"""
if self.setOptions() is True:
self.doAction()
Expand Down
2 changes: 1 addition & 1 deletion core/types/Types.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
OglSDInstances = NewType('OglSDInstances', Dict[int, OglSDInstance])
OglSDMessages = NewType('OglSDMessages', Dict[int, OglSDMessage])

OglObjectType = Union[OglClass, OglLink, OglNote, OglText, OglActor, OglUseCase, OglInterface2]
OglObjectType = Union[OglClass, OglLink, OglNote, OglText, OglActor, OglUseCase, OglInterface2, OglSDMessage, OglSDInstance, OglUseCase, OglActor]

OglObjects = NewType('OglObjects', List[OglObjectType])
PyutLinks = NewType('PyutLinks', List[PyutLink])
Expand Down
2 changes: 2 additions & 0 deletions plugins/io/IOGML.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ def __init__(self, pluginAdapter: IPluginAdapter):
self._inputFormat = cast(InputFormat, None)
self._outputFormat = OutputFormat(formatName=FORMAT_NAME, extension=PLUGIN_EXTENSION, description=PLUGIN_DESCRIPTION)

self._autoSelectAll = False # Temp until we have plugin preferences

def setImportOptions(self) -> bool:
"""
Prepare the import.
Expand Down
2 changes: 2 additions & 0 deletions plugins/io/IOPdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ def __init__(self, pluginAdapter: IPluginAdapter):

self._imageOptions.imageFormat = ImageFormat.PDF

self._autoSelectAll = True # we are taking a picture of the entire diagram

def setImportOptions(self) -> bool:
return False

Expand Down
35 changes: 4 additions & 31 deletions plugins/io/IOWxImage.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ def __init__(self, pluginAdapter: IPluginAdapter):
self._inputFormat = cast(InputFormat, None)
self._outputFormat = OutputFormat(formatName=FORMAT_NAME, extension=PLUGIN_EXTENSION, description=PLUGIN_DESCRIPTION)

self._autoSelectAll = True # we are taking a picture of the entire diagram

def setImportOptions(self) -> bool:
return False

Expand Down Expand Up @@ -85,18 +87,15 @@ def write(self, oglObjects: OglObjects):
Args:
oglObjects: list of exported objects
"""
# self._pluginAdapter.getFrameInformation(callback=self._gotFrameInfo)
mediator: IPluginAdapter = self._pluginAdapter
pluginAdapter: IPluginAdapter = self._pluginAdapter
frameInformation: FrameInformation = self._frameInformation
mediator.deselectAllOglObjects()
pluginAdapter.deselectAllOglObjects()

imageType: BitmapType = WxImageFormat.toWxBitMapType(self._imageFormat)

# window: ScrolledWindow = self._pluginAdapter.umlFrame
context: ClientDC = frameInformation.clientDC
memory: MemoryDC = MemoryDC()

# x, y = window.GetSize()
x: int = frameInformation.frameSize.width
y: int = frameInformation.frameSize.height
emptyBitmap: Bitmap = Bitmap(x, y, -1)
Expand All @@ -112,29 +111,3 @@ def write(self, oglObjects: OglObjects):
status: bool = img.SaveFile(filename, imageType)
if status is False:
self.logger.error(f'Error on image write to {filename}')

# def _gotFrameInfo(self, frameInformation: FrameInformation):
#
# x = frameInformation.frameSize.width
# y = frameInformation.frameSize.height
# context: ClientDC = frameInformation.clientDC
# imageType: BitmapType = WxImageFormat.toWxBitMapType(self._imageFormat)
#
# # window: ScrolledWindow = self._pluginAdapter.umlFrame
# # context: ClientDC = ClientDC(window)
# memory: MemoryDC = MemoryDC()
#
# # x, y = window.GetSize()
# emptyBitmap: Bitmap = Bitmap(x, y, -1)
#
# memory.SelectObject(emptyBitmap)
# memory.Blit(source=context, xsrc=0, height=y, xdest=0, ydest=0, ysrc=0, width=x)
# memory.SelectObject(NullBitmap)
#
# img: Image = emptyBitmap.ConvertToImage()
# extension: str = self._imageFormat.__str__()
#
# filename: str = f'{self._outputFileName}.{extension}'
# status: bool = img.SaveFile(filename, imageType)
# if status is False:
# self.logger.error(f'Error on image write to {filename}')
2 changes: 2 additions & 0 deletions plugins/io/IOXml.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ def __init__(self, pluginAdapter: IPluginAdapter):
self._fileToExport: str = ''
self._fileToImport: str = ''

self._requireActiveFrame = False

def setImportOptions(self) -> bool:
"""
We do need to ask for the input file names
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

setup(
name="pyutplugincore",
version="0.5.9",
version="0.5.10",
author='Humberto A. Sanchez II',
author_email='[email protected]',
maintainer='Humberto A. Sanchez II',
Expand Down
2 changes: 1 addition & 1 deletion tests/scaffoldv2/PluginAdapterV2.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ def deselectAllOglObjects(self):
wxYield()

def addShape(self, shape: OglObjectType):
pass
self._eventEngine.sendEvent(EventType.AddShape, shapeToAdd=shape)

def loadProject(self, pluginProject: PluginProject):
"""
Expand Down
38 changes: 31 additions & 7 deletions tests/scaffoldv2/ScaffoldFrame.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
from core.types.PluginDataTypes import PluginIDMap

from tests.scaffoldv2.PluginAdapterV2 import PluginAdapterV2
from tests.scaffoldv2.PyutDiagramType import PyutDiagramType
from tests.scaffoldv2.ScaffoldUI import ScaffoldUI
from tests.scaffoldv2.eventengine.EventEngine import EventEngine
from tests.scaffoldv2.eventengine.Events import EventType
Expand Down Expand Up @@ -100,6 +101,11 @@ def loadXmlFile(self, fqFileName: str):

def _createApplicationMenuBar(self):

self._loadXmlFileWxId: int = NewIdRef()
self._newClassDiagramWxId: int = NewIdRef()
self._newUseCaseDiagramWxId: int = NewIdRef()
self._newSequenceDiagramWxId: int = NewIdRef()

menuBar: MenuBar = MenuBar()
fileMenu: Menu = Menu()
editMenu: Menu = Menu()
Expand All @@ -115,27 +121,34 @@ def _createApplicationMenuBar(self):

self.SetMenuBar(menuBar)

self._loadXmlFileWxId: int = NewIdRef()

self.Bind(EVT_MENU, self.Close, id=ID_EXIT)

def _makeFileMenu(self, fileMenu: Menu) -> Menu:

fileMenu.Append(self._loadXmlFileWxId, 'Load Xml Diagram')

importSubMenu: Menu = self._makeImportSubMenu()
exportSubMenu: Menu = self._makeExportSubMenu()
newDiagramSubMenu: Menu = self._makeNewDiagramSubMenu()
importSubMenu: Menu = self._makeImportSubMenu()
exportSubMenu: Menu = self._makeExportSubMenu()

fileMenu.AppendSubMenu(newDiagramSubMenu, 'New')
fileMenu.AppendSubMenu(importSubMenu, 'Import')
fileMenu.AppendSubMenu(exportSubMenu, 'Export')
self.Bind(EVT_MENU, self._onLoadXmlFile, id=self._loadXmlFileWxId)

return fileMenu

# noinspection PyUnusedLocal
def _onLoadXmlFile(self, event: CommandEvent):
def _makeNewDiagramSubMenu(self) -> Menu:
subMenu: Menu = Menu()

self._displayError(message='Use the import plugin')
subMenu.Append(self._newClassDiagramWxId, 'Class Diagram')
subMenu.Append(self._newUseCaseDiagramWxId, 'Use Case Diagram')
subMenu.Append(self._newSequenceDiagramWxId, 'Sequence Diagram')

self.Bind(EVT_MENU, self._onNewDiagram, id=self._newClassDiagramWxId)
self.Bind(EVT_MENU, self._onNewDiagram, id=self._newUseCaseDiagramWxId)
self.Bind(EVT_MENU, self._onNewDiagram, id=self._newSequenceDiagramWxId)
return subMenu

def _makeToolsMenu(self, toolsMenu: Menu) -> Menu:
"""
Expand Down Expand Up @@ -220,6 +233,17 @@ def _onExport(self, event: CommandEvent):
self.logger.info(f'Export: {wxId=}')
self._pluginManager.doExport(wxId=wxId)

# noinspection PyUnusedLocal
def _onLoadXmlFile(self, event: CommandEvent):

self._displayError(message='Use the import plugin')

def _onNewDiagram(self, event: CommandEvent):
eventId: int = event.GetId()

if eventId == self._newClassDiagramWxId:
self._eventEngine.sendEvent(EventType.NewDiagram, diagramType=PyutDiagramType.CLASS_DIAGRAM)

def _askForXMLFileToImport(self) -> RequestResponse:
"""
TODO: This belongs in another class
Expand Down
Loading

0 comments on commit 4af7302

Please sign in to comment.