def insertProject(self, filename: str) -> bool: """ Insert another project into this one Args: filename: filename to open Returns: `True` if the operation succeeded """ # Load the file from org.pyut.persistence import IoFile BeginBusyCursor() io = IoFile.IoFile() try: io.open(filename, self) self._modified = False except (ValueError, Exception) as e: PyutUtils.displayError(_(f"Error loading file {e}")) EndBusyCursor() return False EndBusyCursor() # Update text self.updateTreeText() # Register to mediator if len(self._documents) > 0: frame = self._documents[0].getFrame() self._mediator.getFileHandling().registerUmlFrame(frame) # Return return True
def loadFromFilename(self, filename: str) -> bool: """ Load a project from a file Args: filename: filename to open Returns: `True` if the operation succeeded """ # Load the file self.logger.info(f'loadFromFilename: {filename=}') BeginBusyCursor() from org.pyut.persistence.IoFile import IoFile # Avoid Nuitka cyclical dependency io: IoFile = IoFile() wxYield() # to treat the uml frame refresh in newDiagram before loading # Load the file self._filename = filename try: io.open(filename, self) self._modified = False except (ValueError, Exception) as e: EndBusyCursor() self.logger.error(f"Error loading file: {e}") return False EndBusyCursor() self.updateTreeText() wxYield() from org.pyut.ui.TreeNotebookHandler import TreeNotebookHandler # avoid cyclical imports if len(self._documents) > 0: # self._mediator.getFileHandling().showFrame(self._documents[0].getFrame()) # self._documents[0].getFrame().Refresh() # self._mediator.getFileHandling().showFrame(documentFrame) documentFrame: UmlFrameType = self._documents[0].getFrame() mediator: Mediator = self._mediator tbh: TreeNotebookHandler = mediator.getFileHandling() self.logger.debug(f'{documentFrame=}') documentFrame.Refresh() tbh.showFrame(documentFrame) if self.logger.isEnabledFor(DEBUG): notebook = tbh.notebook self.logger.debug(f'{tbh.currentFrame=} {tbh.currentProject=} {notebook.GetSelection()=}') return True else: return False
def read(self, oglObjects, umlFrame: UmlClassDiagramsFrame): """ Reverse engineering Args: oglObjects: list of imported objects umlFrame: Pyut's UmlFrame """ # Ask the user which destination file he wants # directory=self._askForDirectoryImport() # if directory=="": # return False (lstFiles, directory) = self._askForFileImport(True) if len(lstFiles) == 0: return False BeginBusyCursor() wxYield() try: reverseEngineer: ReverseEngineerPython2 = ReverseEngineerPython2() reverseEngineer.reversePython(umlFrame=umlFrame, directoryName=directory, files=lstFiles) # TODO: Don't expose the internals self.logger.debug( f'classNames: {jsonDumps(reverseEngineer.visitor.classMethods, indent=4)}' ) self.logger.debug( f'methods: {jsonDumps(reverseEngineer.visitor.parameters, indent=4)}' ) except (ValueError, Exception) as e: MessageBox(f'{e}', 'Error', OK | ICON_ERROR) EndBusyCursor()
def OnToolPlugin(self, event: CommandEvent): """ Args: event: """ # Create a plugin instance cl = self.plugins[event.GetId()] obj = cl(self._ctrl.getUmlObjects(), self._ctrl.getUmlFrame()) # Do plugin functionality BeginBusyCursor() try: obj.callDoAction() self.logger.debug(f"After tool plugin do action") except (ValueError, Exception) as e: PyutUtils.displayError( _("An error occurred while executing the selected plugin"), _("Error..."), self) self.logger.error(f'{e}') EndBusyCursor() # Refresh screen umlFrame = self._ctrl.getUmlFrame() if umlFrame is not None: umlFrame.Refresh()
def onToolPlugin(self, event: CommandEvent): """ Args: event: """ # Create a plugin instance wxId: int = event.GetId() self.logger.warning(f'{wxId=}') clazz: type = self._toolPluginsMap[wxId] pluginInstance: PyutToPlugin = clazz(self._mediator.getUmlObjects(), self._mediator.getUmlFrame()) # Do plugin functionality BeginBusyCursor() try: pluginInstance.callDoAction() self.logger.debug(f"After tool plugin do action") except (ValueError, Exception) as e: PyutUtils.displayError( _("An error occurred while executing the selected plugin"), _("Error...")) self.logger.error(f'{e}') EndBusyCursor() # Refresh screen umlFrame = self._mediator.getUmlFrame() if umlFrame is not None: umlFrame.Refresh()
def addOglHierarchy(self): """ Calls addHierarchy with the Ogl class list. """ import org.pyut.experimental.PyutModelClasses as pdc BeginBusyCursor() gh: GraphicalHandler = GraphicalHandler(umlFrame=self, maxWidth=self.maxWidth, historyManager=self._history) gh.addHierarchy(pdc.OglClassNames) EndBusyCursor()
def loadFromFilename(self, filename: str) -> bool: """ Load a project from a file Args: filename: filename to open Returns: `True` if the operation succeeded """ # Load the file BeginBusyCursor() from org.pyut.persistence.IoFile import IoFile # Avoid Nuitka cyclical dependency io: IoFile = IoFile() wxYield() # to treat the uml frame refresh in newDiagram before loading # Load the file self._filename = filename try: io.open(filename, self) self._modified = False except (ValueError, Exception) as e: EndBusyCursor() PyutUtils.displayError(_(f"Error loading file: {e}")) return False EndBusyCursor() # Update text self.updateTreeText() # Register to mediator # if len(self._documents)>0: # self._ctrl.registerUMLFrame(self._documents[0].getFrame()) # print ">>>PyutProject-loadFromFilename-7" if len(self._documents) > 0: self._ctrl.getFileHandling().showFrame(self._documents[0].getFrame()) self._documents[0].getFrame().Refresh() return True else: return False
def saveXmlPyut(self): """ save the project """ from org.pyut.persistence.IoFile import IoFile io: IoFile = IoFile() BeginBusyCursor() try: io.save(self) self._modified = False self.updateTreeText() except (ValueError, Exception) as e: PyutUtils.displayError(_(f"An error occurred while saving project {e}")) EndBusyCursor()
def addPyutHierarchy(self): """ Calls addHierarchy with the Pyut class list. """ import org.pyut.experimental.PyutDataClasses as pdc BeginBusyCursor() gh: GraphicalHandler = GraphicalHandler(umlFrame=self, maxWidth=self.maxWidth, historyManager=self._history) gh.addHierarchy(pdc.display) EndBusyCursor()
def fastTextClassEditor(self, thePyutClass: PyutClass): plugs = self._appFrame.plugs cl = [ s for s in plugs.values() if s(None, None).getName() == "Fast text edition" ] if cl: obj = cl[0](self.getUmlObjects(), self.getUmlFrame()) else: # fallback self.standardClassEditor(thePyutClass) return # Do plugin functionality BeginBusyCursor() obj.callDoAction() EndBusyCursor() self.getUmlFrame().Refresh()
def OnImport(self, event): self._mainFileHandlingUI.newProject() self._mainFileHandlingUI.newDocument(DiagramType.CLASS_DIAGRAM) self._ctrl.updateTitle() cl = self.plugins[event.GetId()] obj = cl(self._ctrl.getUmlObjects(), self._ctrl.getUmlFrame()) # Do plugin functionality BeginBusyCursor() try: wxYield() # time to process the refresh in newDiagram obj.doImport() except (ValueError, Exception) as e: PyutUtils.displayError( _("An error occurred while executing the selected plugin"), _("Error..."), self) self.logger.error(f'{e}') EndBusyCursor() self.Refresh()
def runFile(self, event=None, fileName=None, focusOnExit='runner'): """Begin new process to run experiment. Parameters ---------- event : wx.Event or None Parameter for event information if this function is bound as a callback. Set as `None` if calling directly. fileName : str Path to the file to run. focusOnExit : str Which output window to focus on when the application exits. Can be either 'coder' or 'runner'. Default is 'runner'. Returns ------- bool True if the process has been started without error. """ # full path to the script fullPath = fileName.replace('.psyexp', '_lastrun.py') if not os.path.isfile(fullPath): fileNotFoundDlg = MessageDialog( None, "Cannot run script '{}', file not found!".format(fullPath), caption="File Not Found Error", style=OK | ICON_ERROR) fileNotFoundDlg.ShowModal() fileNotFoundDlg.Destroy() if event is not None: event.Skip() return False # provide a message that the script is running # format the output message runMsg = u"## Running: {} ##".format(fullPath) runMsg = runMsg.center(80, "#") + "\n" # if we have a runner frame, write to the output text box if hasattr(self.app, 'runner'): stdOut = StdStreamDispatcher.getInstance() stdOut.lenLastRun = len(self.app.runner.stdOut.getText()) else: # if not, just write to the standard output pipe stdOut = sys.stdout stdOut.write(runMsg) stdOut.flush() # interpreter path pyExec = sys.executable # optional flags for the subprocess execFlags = jobs.EXEC_ASYNC # all use `EXEC_ASYNC` if sys.platform == 'win32': execFlags |= jobs.EXEC_HIDE_CONSOLE else: execFlags |= jobs.EXEC_MAKE_GROUP_LEADER # build the shell command to run the script # pyExec = '"' + pyExec + '"' # use quotes to prevent issues with spaces # fullPath = '"' + fullPath + '"' command = [pyExec, '-u', fullPath] # passed to the Job object # create a new job with the user script self.scriptProcess = jobs.Job( self, command=command, # flags=execFlags, inputCallback=self._onInputCallback, # both treated the same errorCallback=self._onErrorCallback, terminateCallback=self._onTerminateCallback) BeginBusyCursor() # visual feedback # start the subprocess workingDir, _ = os.path.split(fullPath) workingDir = os.path.abspath(workingDir) # make absolute # move set CWD to Job.__init__ later pid = self.scriptProcess.start(cwd=workingDir) if pid < 1: # error starting the process on zero or negative PID errMsg = ( "Failed to run script '{}' in directory '{}'! Check whether " "the file or its directory exists and is accessible.".format( fullPath, workingDir)) fileNotFoundDlg = MessageDialog(None, errMsg, caption="Run Task Error", style=OK | ICON_ERROR) fileNotFoundDlg.ShowModal() fileNotFoundDlg.Destroy() # also log the error logging.error(errMsg) if event is not None: event.Skip() self.scriptProcess = None # reset EndBusyCursor() return False self.focusOnExit = focusOnExit return True
def _onTerminateCallback(self, pid, exitCode): """Callback invoked when the subprocess exits. Default behavior is to push remaining data to the Runner output window and show it by raising the Runner window. The 'Stop' button will be disabled in Runner (if available) since the process has ended and no longer can be stopped. Also restores the user's cursor to the default. Parameters ---------- pid : int Process ID number for the terminated subprocess. exitCode : int Program exit code. """ # write a close message, shows the exit code closeMsg = \ " Experiment ended with exit code {} [pid:{}] ".format( exitCode, pid) closeMsg = closeMsg.center(80, '#') + '\n' self._writeOutput(closeMsg) self.scriptProcess = None # reset # disable the stop button after exiting, no longer needed if hasattr(self, 'stopBtn'): # relies on this being a mixin class self.stopBtn.Disable() # reactivate the current selection after running if hasattr(self, 'expCtrl') and hasattr(self, 'runBtn'): itemIdx = self.expCtrl.GetFirstSelected() if itemIdx >= 0: self.expCtrl.Select(itemIdx) self.runBtn.Enable() def _focusOnOutput(win): """Subroutine to focus on a given output window.""" win.Show() win.Raise() win.Iconize(False) # set focus to output window if self.app is not None: if self.focusOnExit == 'coder' and hasattr(self.app, 'coder'): if self.app.coder is not None: _focusOnOutput(self.app.coder) self.app.coder.shelf.SetSelection( 1) # page for the console output self.app.coder.shell.SetFocus() else: # coder is closed, open runner and show output instead if hasattr(self.app, 'runner') and \ hasattr(self.app, 'showRunner'): # show runner if available if self.app.runner is None: self.app.showRunner() _focusOnOutput(self.app.runner) self.app.runner.stdOut.SetFocus() elif self.focusOnExit == 'runner' and hasattr(self.app, 'runner'): if self.app.runner is not None: _focusOnOutput(self.app.runner) self.app.runner.stdOut.SetFocus() EndBusyCursor()