--- a/ProjectFlask/PyBabelCommandDialog.py Sat Nov 21 17:50:57 2020 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,202 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright (c) 2020 Detlev Offenbach <detlev@die-offenbachs.de> -# - -""" -Module implementing a dialog to run a flask command and show its output. -""" - -from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton - -from E5Gui import E5MessageBox - -from .Ui_FlaskCommandDialog import Ui_FlaskCommandDialog - - -class PyBabelCommandDialog(QDialog, Ui_FlaskCommandDialog): - """ - Class implementing a dialog to run a flask command and show its output. - """ - def __init__(self, project, title="", msgSuccess="", msgError="", - parent=None): - """ - Constructor - - @param project reference to the project object - @type Project - @param title window title of the dialog - @type str - @param msgSuccess success message to be shown - @type str - @param msgError message to be shown on error - @type str - @param parent reference to the parent widget - @type QWidget - """ - super(PyBabelCommandDialog, self).__init__(parent) - self.setupUi(self) - - if title: - self.setWindowTitle(title) - - self.__project = project - self.__successMessage = msgSuccess - self.__errorMessage = msgError - - self.__process = None - self.__argsLists = [] - self.__workdir = "" - - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) - - def startCommand(self, command, args, workdir, clearOutput=True): - """ - Public method to start a pybabel command and show its output. - - @param command pybabel command to be run - @type str - @param args list of command line arguments for the command - @type list of str - @param workdir working directory for the command - @type str - @param clearOutput flag indicating to clear the output - @type bool - @return flag indicating a successful start - @rtype bool - """ - babelCommand = self.__project.getBabelCommand() - - self.__process = QProcess() - self.__process.setWorkingDirectory(workdir) - self.__process.setProcessChannelMode(QProcess.MergedChannels) - - self.__process.readyReadStandardOutput.connect(self.__readStdOut) - self.__process.finished.connect(self.__processFinished) - - if clearOutput: - self.outputEdit.clear() - - babelArgs = [command] - if args: - babelArgs += args - - self.__process.start(babelCommand, babelArgs) - ok = self.__process.waitForStarted(10000) - if not ok: - E5MessageBox.critical( - None, - self.tr("Execute PyBabel Command"), - self.tr("""The pybabel process could not be started.""")) - else: - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) - self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setFocus( - Qt.OtherFocusReason) - - return ok - - def startBatchCommand(self, argsLists, workdir): - """ - Public method to start a pybabel command repeatedly with a list of - arguments and show the output. - - @param argsLists list of command line arguments for the batch commands - @type list of lists of str - @param workdir working directory for the command - @type str - @return flag indicating a successful start of the first process - @rtype bool - """ - self.__argsLists = argsLists[:] - self.__workdir = workdir - - # start the first process - args = self.__argsLists.pop(0) - res = self.startCommand(args[0], args[1:], workdir) - if not res: - self.__argsLists = [] - - return res - - def closeEvent(self, evt): - """ - Protected method handling the close event of the dialog. - - @param evt reference to the close event object - @type QCloseEvent - """ - self.__argsLists = [] - self.__cancelProcess() - evt.accept() - - @pyqtSlot() - def __readStdOut(self): - """ - Private slot to add the server process output to the output pane. - """ - if self.__process is not None: - out = str(self.__process.readAllStandardOutput(), "utf-8") - self.outputEdit.insertPlainText(out) - - def __processFinished(self, exitCode, exitStatus): - """ - Private slot connected to the finished signal. - - @param exitCode exit code of the process - @type int - @param exitStatus exit status of the process - @type QProcess.ExitStatus - """ - normal = (exitStatus == QProcess.NormalExit) and (exitCode == 0) - self.__cancelProcess() - - if self.__argsLists: - args = self.__argsLists.pop(0) - self.startCommand(args[0], args[1:], self.__workdir, - clearOutput=False) - return - - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) - self.buttonBox.button(QDialogButtonBox.Close).setFocus( - Qt.OtherFocusReason) - - if normal and self.__successMessage: - self.outputEdit.insertPlainText(self.__successMessage) - elif not normal and self.__errorMessage: - self.outputEdit.insertPlainText(self.__errorMessage) - - @pyqtSlot() - def __cancelProcess(self): - """ - Private slot to terminate the current process. - """ - if ( - self.__process is not None and - self.__process.state() != QProcess.NotRunning - ): - self.__process.terminate() - QTimer.singleShot(2000, self.__process.kill) - self.__process.waitForFinished(3000) - - self.__process = None - - @pyqtSlot(QAbstractButton) - def on_buttonBox_clicked(self, button): - """ - Private slot handling presses of the button box buttons. - - @param button reference to the button been clicked - @type QAbstractButton - """ - if button is self.buttonBox.button(QDialogButtonBox.Close): - self.close() - elif button is self.buttonBox.button(QDialogButtonBox.Cancel): - self.__argsLists = [] - self.__cancelProcess()