QCommandLineParser: Show usage and errors in message boxes on Windows.
Use the Windows MessageBox API if no console window can be obtained. [ChangeLog][QtCore][QCommandLineParser] Message boxes are used to display errors and usage if no console window can be obtained on Windows. Change-Id: I63ee8e4d8bd78db83e688fd69374779102562aa3 Reviewed-by: David Faure <david.faure@kdab.com>
This commit is contained in:
parent
c124ac42c7
commit
09e674849a
@ -82,14 +82,7 @@ int main(int argc, char *argv[])
|
|||||||
"qt.examples.imagegestures.debug=true\n");
|
"qt.examples.imagegestures.debug=true\n");
|
||||||
commandLineParser.setApplicationDescription(description);
|
commandLineParser.setApplicationDescription(description);
|
||||||
|
|
||||||
if (!commandLineParser.parse(QCoreApplication::arguments())) {
|
commandLineParser.process(QCoreApplication::arguments());
|
||||||
showHelp(commandLineParser, commandLineParser.errorText());
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (commandLineParser.isSet(helpOption)) {
|
|
||||||
showHelp(commandLineParser);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
QStringList arguments = commandLineParser.positionalArguments();
|
QStringList arguments = commandLineParser.positionalArguments();
|
||||||
if (!arguments.isEmpty() && !QFileInfo(arguments.front()).isDir()) {
|
if (!arguments.isEmpty() && !QFileInfo(arguments.front()).isDir()) {
|
||||||
|
@ -37,6 +37,10 @@
|
|||||||
#include <qcoreapplication.h>
|
#include <qcoreapplication.h>
|
||||||
#include <qhash.h>
|
#include <qhash.h>
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
|
#include <qdebug.h>
|
||||||
|
#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||||
|
# include <qt_windows.h>
|
||||||
|
#endif
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
@ -209,7 +213,10 @@ QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const
|
|||||||
platforms. These applications may not use the standard output or error channels
|
platforms. These applications may not use the standard output or error channels
|
||||||
since the output is either discarded or not accessible.
|
since the output is either discarded or not accessible.
|
||||||
|
|
||||||
For such GUI applications, it is recommended to display help texts and error messages
|
On Windows, QCommandLineParser uses message boxes to display usage information
|
||||||
|
and errors if no console window can be obtained.
|
||||||
|
|
||||||
|
For other platforms, it is recommended to display help texts and error messages
|
||||||
using a QMessageBox. To preserve the formatting of the help text, rich text
|
using a QMessageBox. To preserve the formatting of the help text, rich text
|
||||||
with \c <pre> elements should be used:
|
with \c <pre> elements should be used:
|
||||||
|
|
||||||
@ -219,36 +226,20 @@ QStringList QCommandLineParserPrivate::aliases(const QString &optionName) const
|
|||||||
case CommandLineOk:
|
case CommandLineOk:
|
||||||
break;
|
break;
|
||||||
case CommandLineError:
|
case CommandLineError:
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QMessageBox::warning(0, QGuiApplication::applicationDisplayName(),
|
QMessageBox::warning(0, QGuiApplication::applicationDisplayName(),
|
||||||
"<html><head/><body><h2>" + errorMessage + "</h2><pre>"
|
"<html><head/><body><h2>" + errorMessage + "</h2><pre>"
|
||||||
+ parser.helpText() + "</pre></body></html>");
|
+ parser.helpText() + "</pre></body></html>");
|
||||||
#else
|
|
||||||
fputs(qPrintable(errorMessage), stderr);
|
|
||||||
fputs("\n\n", stderr);
|
|
||||||
fputs(qPrintable(parser.helpText()), stderr);
|
|
||||||
#endif
|
|
||||||
return 1;
|
return 1;
|
||||||
case CommandLineVersionRequested:
|
case CommandLineVersionRequested:
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QMessageBox::information(0, QGuiApplication::applicationDisplayName(),
|
QMessageBox::information(0, QGuiApplication::applicationDisplayName(),
|
||||||
QGuiApplication::applicationDisplayName() + ' '
|
QGuiApplication::applicationDisplayName() + ' '
|
||||||
+ QCoreApplication::applicationVersion());
|
+ QCoreApplication::applicationVersion());
|
||||||
#else
|
|
||||||
printf("%s %s\n", QGuiApplication::applicationDisplayName(),
|
|
||||||
qPrintable(QCoreApplication::applicationVersion()));
|
|
||||||
#endif
|
|
||||||
return 0;
|
return 0;
|
||||||
case CommandLineHelpRequested:
|
case CommandLineHelpRequested:
|
||||||
#ifdef Q_OS_WIN
|
|
||||||
QMessageBox::warning(0, QGuiApplication::applicationDisplayName(),
|
QMessageBox::warning(0, QGuiApplication::applicationDisplayName(),
|
||||||
"<html><head/><body><pre>"
|
"<html><head/><body><pre>"
|
||||||
+ parser.helpText() + "</pre></body></html>");
|
+ parser.helpText() + "</pre></body></html>");
|
||||||
return 0;
|
return 0;
|
||||||
#else
|
|
||||||
parser.showHelp();
|
|
||||||
Q_UNREACHABLE();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
@ -489,6 +480,41 @@ QString QCommandLineParser::errorText() const
|
|||||||
return QString();
|
return QString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum MessageType { UsageMessage, ErrorMessage };
|
||||||
|
|
||||||
|
#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||||
|
// Return whether to use a message box. Use handles if a console can be obtained
|
||||||
|
// or we are run with redirected handles (for example, by QProcess).
|
||||||
|
static inline bool displayMessageBox()
|
||||||
|
{
|
||||||
|
if (GetConsoleWindow())
|
||||||
|
return false;
|
||||||
|
STARTUPINFO startupInfo;
|
||||||
|
startupInfo.cb = sizeof(STARTUPINFO);
|
||||||
|
GetStartupInfo(&startupInfo);
|
||||||
|
return !(startupInfo.dwFlags & STARTF_USESTDHANDLES);
|
||||||
|
}
|
||||||
|
#endif // Q_OS_WIN && !QT_BOOTSTRAPPED && !Q_OS_WIN && !Q_OS_WINRT
|
||||||
|
|
||||||
|
static void showParserMessage(const QString &message, MessageType type)
|
||||||
|
{
|
||||||
|
#if defined(Q_OS_WIN) && !defined(QT_BOOTSTRAPPED) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT)
|
||||||
|
if (displayMessageBox()) {
|
||||||
|
const UINT flags = MB_OK | MB_TOPMOST | MB_SETFOREGROUND
|
||||||
|
| (type == UsageMessage ? MB_ICONINFORMATION : MB_ICONERROR);
|
||||||
|
QString title;
|
||||||
|
if (QCoreApplication::instance())
|
||||||
|
title = QCoreApplication::instance()->property("applicationDisplayName").toString();
|
||||||
|
if (title.isEmpty())
|
||||||
|
title = QCoreApplication::applicationName();
|
||||||
|
MessageBoxW(0, reinterpret_cast<const wchar_t *>(message.utf16()),
|
||||||
|
reinterpret_cast<const wchar_t *>(title.utf16()), flags);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif // Q_OS_WIN && !QT_BOOTSTRAPPED && !Q_OS_WIN && !Q_OS_WINRT
|
||||||
|
fputs(qPrintable(message), type == UsageMessage ? stdout : stderr);
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
Processes the command line \a arguments.
|
Processes the command line \a arguments.
|
||||||
|
|
||||||
@ -505,7 +531,7 @@ QString QCommandLineParser::errorText() const
|
|||||||
void QCommandLineParser::process(const QStringList &arguments)
|
void QCommandLineParser::process(const QStringList &arguments)
|
||||||
{
|
{
|
||||||
if (!d->parse(arguments)) {
|
if (!d->parse(arguments)) {
|
||||||
fprintf(stderr, "%s\n", qPrintable(errorText()));
|
showParserMessage(errorText() + QLatin1Char('\n'), ErrorMessage);
|
||||||
::exit(EXIT_FAILURE);
|
::exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -911,7 +937,9 @@ QStringList QCommandLineParser::unknownOptionNames() const
|
|||||||
*/
|
*/
|
||||||
Q_NORETURN void QCommandLineParser::showVersion()
|
Q_NORETURN void QCommandLineParser::showVersion()
|
||||||
{
|
{
|
||||||
fprintf(stdout, "%s %s\n", qPrintable(QCoreApplication::applicationName()), qPrintable(QCoreApplication::applicationVersion()));
|
showParserMessage(QCoreApplication::applicationName() + QLatin1Char(' ')
|
||||||
|
+ QCoreApplication::applicationVersion() + QLatin1Char('\n'),
|
||||||
|
UsageMessage);
|
||||||
::exit(EXIT_SUCCESS);
|
::exit(EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -928,7 +956,7 @@ Q_NORETURN void QCommandLineParser::showVersion()
|
|||||||
*/
|
*/
|
||||||
Q_NORETURN void QCommandLineParser::showHelp(int exitCode)
|
Q_NORETURN void QCommandLineParser::showHelp(int exitCode)
|
||||||
{
|
{
|
||||||
fprintf(stdout, "%s", qPrintable(d->helpText()));
|
showParserMessage(d->helpText(), UsageMessage);
|
||||||
::exit(exitCode);
|
::exit(exitCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user