Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
    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()
Beispiel #4
0
    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()
Beispiel #5
0
    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()
Beispiel #6
0
    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()
Beispiel #7
0
    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
Beispiel #8
0
 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()
Beispiel #9
0
    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()
Beispiel #10
0
    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()
Beispiel #11
0
    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()
Beispiel #12
0
    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
Beispiel #13
0
    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()