Wed, 11 Nov 2020 20:03:21 +0100
Continued implementing the "Run Server" function.
diff -r 550e5ea385cb -r d491ccab7343 PluginFlask.e4p --- a/PluginFlask.e4p Tue Nov 10 19:38:00 2020 +0100 +++ b/PluginFlask.e4p Wed Nov 11 20:03:21 2020 +0100 @@ -162,4 +162,294 @@ <FiletypeAssociation pattern="Ui_*.py" type="__IGNORE__"/> <FiletypeAssociation pattern="makefile" type="OTHERS"/> </FiletypeAssociations> + <Checkers> + <CheckersParams> + <dict> + <key> + <string>Pep8Checker</string> + </key> + <value> + <dict> + <key> + <string>AnnotationsChecker</string> + </key> + <value> + <dict> + <key> + <string>MaximumComplexity</string> + </key> + <value> + <int>3</int> + </value> + <key> + <string>MinimumCoverage</string> + </key> + <value> + <int>75</int> + </value> + </dict> + </value> + <key> + <string>BlankLines</string> + </key> + <value> + <tuple> + <int>2</int> + <int>1</int> + </tuple> + </value> + <key> + <string>BuiltinsChecker</string> + </key> + <value> + <dict> + <key> + <string>bytes</string> + </key> + <value> + <list> + <string>unicode</string> + </list> + </value> + <key> + <string>chr</string> + </key> + <value> + <list> + <string>unichr</string> + </list> + </value> + <key> + <string>str</string> + </key> + <value> + <list> + <string>unicode</string> + </list> + </value> + </dict> + </value> + <key> + <string>CommentedCodeChecker</string> + </key> + <value> + <dict> + <key> + <string>Aggressive</string> + </key> + <value> + <bool>False</bool> + </value> + </dict> + </value> + <key> + <string>CopyrightAuthor</string> + </key> + <value> + <string></string> + </value> + <key> + <string>CopyrightMinFileSize</string> + </key> + <value> + <int>0</int> + </value> + <key> + <string>DocstringType</string> + </key> + <value> + <string>eric</string> + </value> + <key> + <string>EnabledCheckerCategories</string> + </key> + <value> + <string>C, D, E, M, N, S, W</string> + </value> + <key> + <string>ExcludeFiles</string> + </key> + <value> + <string>*/Ui_*.py,</string> + </value> + <key> + <string>ExcludeMessages</string> + </key> + <value> + <string>C101,E265,E266,E305,E402,M201,M301,M302,M303,M304,M305,M306,M307,M308,M311,M312,M313,M314,M315,M321,M701,M702,M811,M834,N802,N803,N807,N808,N821,W293,W504</string> + </value> + <key> + <string>FixCodes</string> + </key> + <value> + <string></string> + </value> + <key> + <string>FixIssues</string> + </key> + <value> + <bool>False</bool> + </value> + <key> + <string>FutureChecker</string> + </key> + <value> + <string>unicode_literals</string> + </value> + <key> + <string>HangClosing</string> + </key> + <value> + <bool>False</bool> + </value> + <key> + <string>IncludeMessages</string> + </key> + <value> + <string></string> + </value> + <key> + <string>LineComplexity</string> + </key> + <value> + <int>20</int> + </value> + <key> + <string>LineComplexityScore</string> + </key> + <value> + <int>10</int> + </value> + <key> + <string>MaxCodeComplexity</string> + </key> + <value> + <int>10</int> + </value> + <key> + <string>MaxDocLineLength</string> + </key> + <value> + <int>79</int> + </value> + <key> + <string>MaxLineLength</string> + </key> + <value> + <int>79</int> + </value> + <key> + <string>NoFixCodes</string> + </key> + <value> + <string>E501</string> + </value> + <key> + <string>RepeatMessages</string> + </key> + <value> + <bool>True</bool> + </value> + <key> + <string>SecurityChecker</string> + </key> + <value> + <dict> + <key> + <string>CheckTypedException</string> + </key> + <value> + <bool>False</bool> + </value> + <key> + <string>HardcodedTmpDirectories</string> + </key> + <value> + <list> + <string>/tmp</string> + <string>/var/tmp</string> + <string>/dev/shm</string> + <string>~/tmp</string> + </list> + </value> + <key> + <string>InsecureHashes</string> + </key> + <value> + <list> + <string>md4</string> + <string>md5</string> + <string>sha</string> + <string>sha1</string> + </list> + </value> + <key> + <string>InsecureSslProtocolVersions</string> + </key> + <value> + <list> + <string>PROTOCOL_SSLv2</string> + <string>SSLv2_METHOD</string> + <string>SSLv23_METHOD</string> + <string>PROTOCOL_SSLv3</string> + <string>PROTOCOL_TLSv1</string> + <string>SSLv3_METHOD</string> + <string>TLSv1_METHOD</string> + </list> + </value> + <key> + <string>WeakKeySizeDsaHigh</string> + </key> + <value> + <string>1024</string> + </value> + <key> + <string>WeakKeySizeDsaMedium</string> + </key> + <value> + <string>2048</string> + </value> + <key> + <string>WeakKeySizeEcHigh</string> + </key> + <value> + <string>160</string> + </value> + <key> + <string>WeakKeySizeEcMedium</string> + </key> + <value> + <string>224</string> + </value> + <key> + <string>WeakKeySizeRsaHigh</string> + </key> + <value> + <string>1024</string> + </value> + <key> + <string>WeakKeySizeRsaMedium</string> + </key> + <value> + <string>2048</string> + </value> + </dict> + </value> + <key> + <string>ShowIgnored</string> + </key> + <value> + <bool>False</bool> + </value> + <key> + <string>ValidEncodings</string> + </key> + <value> + <string>latin-1, utf-8</string> + </value> + </dict> + </value> + </dict> + </CheckersParams> + </Checkers> </Project>
diff -r 550e5ea385cb -r d491ccab7343 PluginProjectFlask.py --- a/PluginProjectFlask.py Tue Nov 10 19:38:00 2020 +0100 +++ b/PluginProjectFlask.py Wed Nov 11 20:03:21 2020 +0100 @@ -154,6 +154,12 @@ # # "RecentNumberDatabaseNames": 10, } + if isWindowsPlatform(): + self.__defaults["AnsiColorScheme"] = "Windows 10" + elif isMacPlatform(): + self.__defaults["AnsiColorScheme"] = "xterm" + else: + self.__defaults["AnsiColorScheme"] = "Ubuntu" # if isWindowsPlatform(): # self.__defaults["ConsoleCommandNoClose"] = "cmd.exe /k" # self.__defaults["ConsoleCommand"] = "cmd.exe /c"
diff -r 550e5ea385cb -r d491ccab7343 ProjectFlask/AnsiTools.py --- a/ProjectFlask/AnsiTools.py Tue Nov 10 19:38:00 2020 +0100 +++ b/ProjectFlask/AnsiTools.py Wed Nov 11 20:03:21 2020 +0100 @@ -20,14 +20,6 @@ 5: QBrush(QColor(128, 0, 128)), 6: QBrush(QColor(0, 128, 128)), 7: QBrush(QColor(192, 192, 192)), - 10: QBrush(QColor(128, 128, 128)), - 11: QBrush(QColor(255, 0, 0)), - 12: QBrush(QColor(0, 255, 0)), - 13: QBrush(QColor(255, 255, 0)), - 14: QBrush(QColor(0, 0, 255)), - 15: QBrush(QColor(255, 0, 255)), - 16: QBrush(QColor(0, 255, 255)), - 17: QBrush(QColor(255, 255, 255)), }, "Windows 10": { 0: QBrush(QColor(12, 12, 12)), @@ -38,14 +30,6 @@ 5: QBrush(QColor(136, 23, 152)), 6: QBrush(QColor(58, 150, 221)), 7: QBrush(QColor(204, 204, 204)), - 10: QBrush(QColor(118, 118, 118)), - 11: QBrush(QColor(231, 72, 86)), - 12: QBrush(QColor(22, 198, 12)), - 13: QBrush(QColor(249, 241, 165)), - 14: QBrush(QColor(59, 12, 255)), - 15: QBrush(QColor(180, 0, 158)), - 16: QBrush(QColor(97, 214, 214)), - 17: QBrush(QColor(242, 242, 242)), }, "PuTTY": { 0: QBrush(QColor(0, 0, 0)), @@ -56,14 +40,6 @@ 5: QBrush(QColor(187, 0, 187)), 6: QBrush(QColor(0, 187, 187)), 7: QBrush(QColor(187, 187, 187)), - 10: QBrush(QColor(85, 85, 85)), - 11: QBrush(QColor(255, 85, 85)), - 12: QBrush(QColor(85, 255, 85)), - 13: QBrush(QColor(255, 255, 85)), - 14: QBrush(QColor(85, 85, 255)), - 15: QBrush(QColor(255, 85, 255)), - 16: QBrush(QColor(85, 255, 255)), - 17: QBrush(QColor(255, 255, 255)), }, "xterm": { 0: QBrush(QColor(0, 0, 0)), @@ -74,14 +50,6 @@ 5: QBrush(QColor(205, 0, 205)), 6: QBrush(QColor(0, 205, 205)), 7: QBrush(QColor(229, 229, 229)), - 10: QBrush(QColor(127, 127, 127)), - 11: QBrush(QColor(255, 0, 0)), - 12: QBrush(QColor(0, 255, 0)), - 13: QBrush(QColor(255, 255, 0)), - 14: QBrush(QColor(0, 0, 255)), - 15: QBrush(QColor(255, 0, 255)), - 16: QBrush(QColor(0, 255, 255)), - 17: QBrush(QColor(255, 255, 255)), }, "Ubuntu": { 0: QBrush(QColor(1, 1, 1)), @@ -92,14 +60,6 @@ 5: QBrush(QColor(118, 38, 113)), 6: QBrush(QColor(44, 181, 233)), 7: QBrush(QColor(204, 204, 204)), - 10: QBrush(QColor(128, 128, 128)), - 11: QBrush(QColor(255, 0, 0)), - 12: QBrush(QColor(0, 255, 0)), - 13: QBrush(QColor(255, 255, 0)), - 14: QBrush(QColor(0, 0, 255)), - 15: QBrush(QColor(255, 0, 255)), - 16: QBrush(QColor(0, 255, 255)), - 17: QBrush(QColor(255, 255, 255)), }, "Ubuntu (dark)": { 0: QBrush(QColor(96, 96, 96)), @@ -110,14 +70,6 @@ 5: QBrush(QColor(200, 64, 193)), 6: QBrush(QColor(48, 200, 255)), 7: QBrush(QColor(204, 204, 204)), - 10: QBrush(QColor(128, 128, 128)), - 11: QBrush(QColor(255, 0, 0)), - 12: QBrush(QColor(0, 255, 0)), - 13: QBrush(QColor(255, 255, 0)), - 14: QBrush(QColor(0, 0, 255)), - 15: QBrush(QColor(255, 0, 255)), - 16: QBrush(QColor(0, 255, 255)), - 17: QBrush(QColor(255, 255, 255)), }, "Breeze (dark)": { 0: QBrush(QColor(35, 38, 39)), @@ -128,14 +80,6 @@ 5: QBrush(QColor(155, 89, 182)), 6: QBrush(QColor(26, 188, 156)), 7: QBrush(QColor(252, 252, 252)), - 10: QBrush(QColor(127, 140, 141)), - 11: QBrush(QColor(192, 57, 43)), - 12: QBrush(QColor(28, 220, 154)), - 13: QBrush(QColor(253, 188, 75)), - 14: QBrush(QColor(61, 174, 233)), - 15: QBrush(QColor(142, 68, 173)), - 16: QBrush(QColor(22, 160, 133)), - 17: QBrush(QColor(255, 255, 255)), }, } @@ -154,12 +98,14 @@ """ Function to get the brush for a given scheme and color. - @paran scheme name of the color scheme + @param scheme name of the color scheme @type str @param color ANSI color code @type int + @return brush for the given parameters or None in case of error + @rtype QBrush or None """ try: return _AnsiColorSchemes[scheme][color] except KeyError: - return QBrush() + return None
diff -r 550e5ea385cb -r d491ccab7343 ProjectFlask/ConfigurationPage/FlaskPage.py --- a/ProjectFlask/ConfigurationPage/FlaskPage.py Tue Nov 10 19:38:00 2020 +0100 +++ b/ProjectFlask/ConfigurationPage/FlaskPage.py Wed Nov 11 20:03:21 2020 +0100 @@ -18,6 +18,8 @@ import UI.PixmapCache +from .. import AnsiTools + # TODO: add selection for the ANSI color scheme (see MicroPython) class FlaskPage(ConfigurationPageBase, Ui_FlaskPage): @@ -34,6 +36,9 @@ self.setupUi(self) self.setObjectName("FlaskPage") + self.colorSchemeComboBox.addItems( + sorted(AnsiTools.getAvailableColorSchemes())) + self.__plugin = plugin self.urlResetButton.setIcon( @@ -57,6 +62,10 @@ index = 0 self.py3VenvNameComboBox.setCurrentIndex(index) + self.colorSchemeComboBox.setCurrentIndex( + self.colorSchemeComboBox.findText( + self.__plugin.getPreferences("AnsiColorScheme"))) + self.urlEdit.setText( self.__plugin.getPreferences("FlaskDocUrl")) @@ -72,6 +81,10 @@ self.py3VenvNameComboBox.currentText()) self.__plugin.setPreferences( + "AnsiColorScheme", + self.colorSchemeComboBox.currentText()) + + self.__plugin.setPreferences( "FlaskDocUrl", self.urlEdit.text()) @pyqtSlot()
diff -r 550e5ea385cb -r d491ccab7343 ProjectFlask/ConfigurationPage/FlaskPage.ui --- a/ProjectFlask/ConfigurationPage/FlaskPage.ui Tue Nov 10 19:38:00 2020 +0100 +++ b/ProjectFlask/ConfigurationPage/FlaskPage.ui Wed Nov 11 20:03:21 2020 +0100 @@ -53,7 +53,7 @@ <item> <widget class="QGroupBox" name="flaskVirtualEnvironmentPy3Group"> <property name="title"> - <string>Flak Virtual Environment</string> + <string>Flask Virtual Environment</string> </property> <layout class="QVBoxLayout" name="verticalLayout_2"> <item> @@ -84,9 +84,38 @@ </widget> </item> <item> + <widget class="QGroupBox" name="groupBox"> + <property name="title"> + <string>Server Output</string> + </property> + <layout class="QGridLayout" name="gridLayout"> + <item row="0" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Color Scheme for ANSI Escape Codes:</string> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QComboBox" name="colorSchemeComboBox"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="toolTip"> + <string>Select the color scheme to be applied for ANSI color escape codes</string> + </property> + </widget> + </item> + </layout> + </widget> + </item> + <item> <widget class="QGroupBox" name="flaskDocumentationGroup"> <property name="title"> - <string>Pyramid Documentation</string> + <string>Flask Documentation</string> </property> <layout class="QHBoxLayout" name="horizontalLayout_2"> <item> @@ -128,6 +157,14 @@ </item> </layout> </widget> + <tabstops> + <tabstop>externalBrowserCheckBox</tabstop> + <tabstop>py3VenvNameComboBox</tabstop> + <tabstop>py3VenvNamesReloadButton</tabstop> + <tabstop>colorSchemeComboBox</tabstop> + <tabstop>urlEdit</tabstop> + <tabstop>urlResetButton</tabstop> + </tabstops> <resources/> <connections/> </ui>
diff -r 550e5ea385cb -r d491ccab7343 ProjectFlask/Project.py --- a/ProjectFlask/Project.py Tue Nov 10 19:38:00 2020 +0100 +++ b/ProjectFlask/Project.py Wed Nov 11 20:03:21 2020 +0100 @@ -85,6 +85,20 @@ self.runServerAct.triggered.connect(self.__runServer) self.actions.append(self.runServerAct) + self.runDevServerAct = E5Action( + self.tr('Run Development Server'), + self.tr('Run &Development Server'), + 0, 0, + self, 'flask_run_dev_server') + self.runDevServerAct.setStatusTip(self.tr( + 'Starts the Flask Web server in development mode')) + self.runDevServerAct.setWhatsThis(self.tr( + """<b>Run Development Server</b>""" + """<p>Starts the Flask Web server in development mode.</p>""" + )) + self.runDevServerAct.triggered.connect(self.__runDevelopmentServer) + self.actions.append(self.runDevServerAct) + ################################## ## documentation action below ## ################################## @@ -134,6 +148,7 @@ menu.setTearOffEnabled(True) menu.addAction(self.runServerAct) + menu.addAction(self.runDevServerAct) menu.addSeparator() menu.addAction(self.documentationAct) menu.addSeparator() @@ -175,6 +190,8 @@ """ Public method to handle the closing of a project. """ + if self.__serverDialog is not None: + self.__serverDialog.close() ## if self.__serverProc is not None: ## self.__serverProcFinished() @@ -384,32 +401,30 @@ ## slots below implement run functions ################################################################## - # TODO: does the flask server support logging? - def __runServer(self, logging=False): + @pyqtSlot() + def __runServer(self, development=False): """ Private slot to start the Flask Web server. - @param logging flag indicating to enable logging + @param development flag indicating development mode @type bool """ - # TODO: implement this (flask run) - workdir, env = self.prepareRuntimeEnvironment() - if env is not None: - cmd = self.getFlaskCommand() - - dlg = RunServerDialog() - if dlg.startServer(cmd, workdir, env): - dlg.show() - self.__serverDialog = dlg + if self.__serverDialog is not None: + self.__serverDialog.close() + + dlg = RunServerDialog(self.__plugin) + if dlg.startServer(self, development=development): + dlg.show() + self.__serverDialog = dlg - def __runDevelopmentServer(self, logging=False): + @pyqtSlot() + def __runDevelopmentServer(self): """ Private slot to start the Flask Web server in development mode. - - @param logging flag indicating to enable logging - @type bool """ - # TODO: implement this (flask run with FLASK_ENV=development) + self.__runServer(development=True) + + # TODO: add method to start a server with parameters ## def __serverProcFinished(self): ## """
diff -r 550e5ea385cb -r d491ccab7343 ProjectFlask/RunServerDialog.py --- a/ProjectFlask/RunServerDialog.py Tue Nov 10 19:38:00 2020 +0100 +++ b/ProjectFlask/RunServerDialog.py Wed Nov 11 20:03:21 2020 +0100 @@ -10,95 +10,105 @@ import re from PyQt5.QtCore import pyqtSlot, Qt, QProcess, QTimer -from PyQt5.QtWidgets import QDialog, QDialogButtonBox, QAbstractButton +from PyQt5.QtGui import QTextCharFormat +from PyQt5.QtWidgets import QDialog, QDialogButtonBox from E5Gui import E5MessageBox +from E5Gui.E5Application import e5App from .Ui_RunServerDialog import Ui_RunServerDialog +from . import AnsiTools + +# TODO: should this be placed into the sidebar as a sidebar widget? class RunServerDialog(QDialog, Ui_RunServerDialog): """ Class implementing a dialog to run the Flask server. """ - def __init__(self, parent=None): + def __init__(self, plugin, parent=None): """ Constructor + @param plugin reference to the plug-in object + @type PluginProjectFlask @param parent reference to the parent widget @type QWidget """ super(RunServerDialog, self).__init__(parent) self.setupUi(self) - self.__process = None + self.__plugin = plugin - self.__ansiRe = re.compile("(\\x1b\[\d+m)") + self.__process = None + self.__serverUrl = "" + + self.__ansiRe = re.compile(r"""(\\x1b\[\d+m)""") + + self.__urlRe = re.compile(r""" * Running on ([^(]+) \(.*""") self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.__defaultTextFormat = self.outputEdit.currentCharFormat() - def startServer(self, command, workdir, env): + def startServer(self, project, development=False): """ Public method to start the Flask server process. - @param command path of the flask command - @type str - @param workdir working directory for the Flask server - @type str - @param env environment for the Flask server process - @type QProcessEnvironment - @return flag indicating a successful start + @param project reference to the project object + @type Project + @param development flag indicating development mode + @type bool + @return flag indicating success @rtype bool """ - self.__process = QProcess() - self.__process.setProcessEnvironment(env) - self.__process.setWorkingDirectory(workdir) - self.__process.setProcessChannelMode(QProcess.MergedChannels) - - self.__process.readyReadStandardOutput.connect(self.__readStdOut) - self.__process.finished.connect(self.__processFinished) - - self.__process.start(command, ["run"]) - ok = self.__process.waitForStarted(10000) - if not ok: - E5MessageBox.critical( - None, - self.tr("Run Flask Server"), - self.tr("""The Flask server process could not be started.""")) + workdir, env = project.prepareRuntimeEnvironment( + development=development) + if env is not None: + command = project.getFlaskCommand() + + self.__process = QProcess() + self.__process.setProcessEnvironment(env) + self.__process.setWorkingDirectory(workdir) + self.__process.setProcessChannelMode(QProcess.MergedChannels) + + self.__process.readyReadStandardOutput.connect(self.__readStdOut) + self.__process.finished.connect(self.__processFinished) + + args = ["run"] +# if host: +# args += ["--host", host] +# if port: +# args += ["--port", str(port)] + + self.__process.start(command, args) + ok = self.__process.waitForStarted(10000) + if not ok: + E5MessageBox.critical( + None, + self.tr("Run Flask Server"), + self.tr("""The Flask server process could not be""" + """ started.""")) + else: + self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) + self.stopServerButton.setEnabled(True) + self.stopServerButton.setDefault(True) else: - self.buttonBox.button(QDialogButtonBox.Close).setEnabled(False) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setDefault(True) + ok = False return ok def closeEvent(self, evt): """ - Private method handling a close event. + Protected method handling a close event. @param evt reference to the close event @type QCloseEvent """ - self.__cancel() + self.on_stopServerButton_clicked() evt.accept() - @pyqtSlot(QAbstractButton) - def on_buttonBox_clicked(self, button): - """ - Private slot handling button presses. - - @param button button that was pressed - @type QAbstractButton - """ - if button is self.buttonBox.button(QDialogButtonBox.Cancel): - self.__cancel() - elif button is self.buttonBox.button(QDialogButtonBox.Close): - self.close() - @pyqtSlot() def __readStdOut(self): """ @@ -106,10 +116,27 @@ """ if self.__process is not None: out = str(self.__process.readAllStandardOutput(), "utf-8") + if not self.__serverUrl: + urlMatch = self.__urlRe.search(out) + if urlMatch: + self.__serverUrl = urlMatch.group(1) + self.startBrowserButton.setEnabled(True) + for txt in self.__ansiRe.split(out): if txt.startswith("\x1b["): - # TODO: process ANSI escape sequences for coloring - pass + color = int(txt[2:-1]) # strip off ANSI command parts + if color == 0: + self.outputEdit.setCurrentCharFormat( + self.__defaultTextFormat) + elif 30 <= color <= 37: + brush = AnsiTools.getColor( + self.__plugin.getPreferences("AnsiColorScheme"), + color - 30) + if brush is not None: + charFormat = QTextCharFormat( + self.__defaultTextFormat) + charFormat.setForeground(brush) + self.outputEdit.setCurrentCharFormat(charFormat) else: self.outputEdit.insertPlainText(txt) @@ -128,16 +155,28 @@ self.__process = None - + self.startBrowserButton.setEnabled(False) + self.stopServerButton.setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setEnabled(True) - self.buttonBox.button(QDialogButtonBox.Cancel).setEnabled(False) self.buttonBox.button(QDialogButtonBox.Close).setDefault(True) self.buttonBox.button(QDialogButtonBox.Close).setFocus( Qt.OtherFocusReason) @pyqtSlot() - def __cancel(self): + def on_stopServerButton_clicked(self): """ - Private slot to cancel the running server. + Private slot to stop the running server. """ self.__processFinished() + + @pyqtSlot() + def on_startBrowserButton_clicked(self): + """ + Private slot to start a web browser with the server URL. + """ + if self.__plugin.getPreferences("UseExternalBrowser"): + import webbrowser + webbrowser.open(self.__serverUrl) + else: + e5App().getObject("UserInterface").launchHelpViewer( + self.__serverUrl)
diff -r 550e5ea385cb -r d491ccab7343 ProjectFlask/RunServerDialog.ui --- a/ProjectFlask/RunServerDialog.ui Tue Nov 10 19:38:00 2020 +0100 +++ b/ProjectFlask/RunServerDialog.ui Wed Nov 11 20:03:21 2020 +0100 @@ -16,7 +16,7 @@ <property name="sizeGripEnabled"> <bool>true</bool> </property> - <layout class="QVBoxLayout" name="verticalLayout_3"> + <layout class="QVBoxLayout" name="verticalLayout_2"> <item> <widget class="QGroupBox" name="groupBox"> <property name="title"> @@ -43,17 +43,82 @@ </widget> </item> <item> - <widget class="QDialogButtonBox" name="buttonBox"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="standardButtons"> - <set>QDialogButtonBox::Cancel|QDialogButtonBox::Close</set> - </property> - </widget> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QPushButton" name="startBrowserButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Press to start a web browser with the server URL.</string> + </property> + <property name="text"> + <string>Start Browser</string> + </property> + </widget> + </item> + <item> + <widget class="QPushButton" name="stopServerButton"> + <property name="enabled"> + <bool>false</bool> + </property> + <property name="toolTip"> + <string>Press to stop the running server</string> + </property> + <property name="text"> + <string>Stop Server</string> + </property> + </widget> + </item> + <item> + <spacer name="horizontalSpacer"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>40</width> + <height>20</height> + </size> + </property> + </spacer> + </item> + <item> + <widget class="QDialogButtonBox" name="buttonBox"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="standardButtons"> + <set>QDialogButtonBox::Close</set> + </property> + </widget> + </item> + </layout> </item> </layout> </widget> + <tabstops> + <tabstop>outputEdit</tabstop> + <tabstop>startBrowserButton</tabstop> + <tabstop>stopServerButton</tabstop> + </tabstops> <resources/> - <connections/> + <connections> + <connection> + <sender>buttonBox</sender> + <signal>rejected()</signal> + <receiver>RunServerDialog</receiver> + <slot>reject()</slot> + <hints> + <hint type="sourcelabel"> + <x>505</x> + <y>474</y> + </hint> + <hint type="destinationlabel"> + <x>593</x> + <y>419</y> + </hint> + </hints> + </connection> + </connections> </ui>