forked from qt-creator/qt-creator
Qmake: Rudimentary support for prompt() in .pro file
This is good enough to open Qt5's toplevel .pro, but not much more. Ideally, prompt() should not be used in files that are meant to be used non-interactively. Task-number: QTCREATORBUG-18220 Change-Id: I842d3c1a8c742d55cbe89a8d0980f34d179ec011 Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
@@ -35,6 +35,8 @@
|
|||||||
#include <utils/macroexpander.h>
|
#include <utils/macroexpander.h>
|
||||||
#include <utils/process.h>
|
#include <utils/process.h>
|
||||||
|
|
||||||
|
#include <QInputDialog>
|
||||||
|
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
using namespace Utils;
|
using namespace Utils;
|
||||||
using namespace ProjectExplorer;
|
using namespace ProjectExplorer;
|
||||||
@@ -94,6 +96,36 @@ void QtSupportPlugin::initialize()
|
|||||||
{
|
{
|
||||||
theProcessRunner() = processRunnerCallback;
|
theProcessRunner() = processRunnerCallback;
|
||||||
|
|
||||||
|
thePrompter() = [this](const QString &msg, const QStringList &context) -> std::optional<QString> {
|
||||||
|
std::optional<QString> res;
|
||||||
|
QEventLoop loop;
|
||||||
|
|
||||||
|
QMetaObject::invokeMethod(this, [msg, context, &res, &loop] {
|
||||||
|
QString text;
|
||||||
|
if (!context.isEmpty()) {
|
||||||
|
text = "Preceding lines:<i><br> ..."
|
||||||
|
+ context.join("<br> ")
|
||||||
|
+ "</i><p>";
|
||||||
|
}
|
||||||
|
text += msg;
|
||||||
|
bool ok = false;
|
||||||
|
const QString line = QInputDialog::getText(
|
||||||
|
ICore::dialogParent(),
|
||||||
|
/*title*/ "QMake Prompt",
|
||||||
|
/*label*/ text,
|
||||||
|
/*echo mode*/ QLineEdit::Normal,
|
||||||
|
/*text*/ QString(),
|
||||||
|
/*ok*/ &ok,
|
||||||
|
/*flags*/ Qt::WindowFlags(),
|
||||||
|
/*QInputMethodHints*/ Qt::ImhNone);
|
||||||
|
if (ok)
|
||||||
|
res = line;
|
||||||
|
loop.quit();
|
||||||
|
}, Qt::QueuedConnection);
|
||||||
|
loop.exec(QEventLoop::ExcludeUserInputEvents);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
QMakeParser::initialize();
|
QMakeParser::initialize();
|
||||||
ProFileEvaluator::initialize();
|
ProFileEvaluator::initialize();
|
||||||
new ProFileCacheManager(this);
|
new ProFileCacheManager(this);
|
||||||
|
@@ -441,6 +441,13 @@ QMAKE_EXPORT std::function<void(ProcessData *data)> &theProcessRunner()
|
|||||||
return runner;
|
return runner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QMAKE_EXPORT std::function<std::optional<QString>(const QString &, const QStringList &)>
|
||||||
|
&thePrompter()
|
||||||
|
{
|
||||||
|
static std::function<std::optional<QString>(const QString &, const QStringList &)> prompter;
|
||||||
|
return prompter;
|
||||||
|
}
|
||||||
|
|
||||||
void QMakeEvaluator::runProcessHelper(ProcessData *data) const
|
void QMakeEvaluator::runProcessHelper(ProcessData *data) const
|
||||||
{
|
{
|
||||||
const QString root = deviceRoot();
|
const QString root = deviceRoot();
|
||||||
@@ -1161,12 +1168,12 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#ifdef PROEVALUATOR_FULL
|
//#ifdef PROEVALUATOR_FULL
|
||||||
case E_PROMPT: {
|
case E_PROMPT: {
|
||||||
if (args.count() != 1 && args.count() != 2) {
|
if (args.count() != 1 && args.count() != 2) {
|
||||||
evalError(fL1S("prompt(question, [decorate=true]) requires one or two arguments."));
|
evalError(fL1S("prompt(question, [decorate=true]) requires one or two arguments."));
|
||||||
// } else if (currentFileName() == QLatin1String("-")) {
|
} else if (currentFileName() == QLatin1String("-")) {
|
||||||
// evalError(fL1S("prompt(question) cannot be used when '-o -' is used"));
|
evalError(fL1S("prompt(question) cannot be used when '-o -' is used"));
|
||||||
} else {
|
} else {
|
||||||
QString msg = m_option->expandEnvVars(args.at(0).toQString(m_tmp1));
|
QString msg = m_option->expandEnvVars(args.at(0).toQString(m_tmp1));
|
||||||
bool decorate = true;
|
bool decorate = true;
|
||||||
@@ -1179,20 +1186,32 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinExpand(
|
|||||||
} else {
|
} else {
|
||||||
fputs(qPrintable(msg), stderr);
|
fputs(qPrintable(msg), stderr);
|
||||||
}
|
}
|
||||||
QFile qfile;
|
|
||||||
if (qfile.open(stdin, QIODevice::ReadOnly)) {
|
if (thePrompter()) {
|
||||||
QTextStream t(&qfile);
|
std::optional<QString> line = thePrompter()(msg, m_logBuffer);
|
||||||
const QString &line = t.readLine();
|
m_logBuffer.clear();
|
||||||
if (t.atEnd()) {
|
if (!line) {
|
||||||
fputs("\n", stderr);
|
fputs("\n", stderr);
|
||||||
evalError(fL1S("Unexpected EOF."));
|
evalError(fL1S("Unexpected EOF."));
|
||||||
return ReturnError;
|
return ReturnError;
|
||||||
}
|
}
|
||||||
ret = split_value_list(QStringView(line));
|
ret = split_value_list(QStringView(*line));
|
||||||
}
|
} else {
|
||||||
|
QFile qfile;
|
||||||
|
if (qfile.open(stdin, QIODevice::ReadOnly)) {
|
||||||
|
QTextStream t(&qfile);
|
||||||
|
const QString &line = t.readLine();
|
||||||
|
if (t.atEnd()) {
|
||||||
|
fputs("\n", stderr);
|
||||||
|
evalError(fL1S("Unexpected EOF."));
|
||||||
|
return ReturnError;
|
||||||
|
}
|
||||||
|
ret = split_value_list(QStringView(line));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break; }
|
break; }
|
||||||
#endif
|
//#endif
|
||||||
case E_REPLACE:
|
case E_REPLACE:
|
||||||
if (args.count() != 3 ) {
|
if (args.count() != 3 ) {
|
||||||
evalError(fL1S("replace(var, before, after) requires three arguments."));
|
evalError(fL1S("replace(var, before, after) requires three arguments."));
|
||||||
@@ -1827,6 +1846,9 @@ QMakeEvaluator::VisitReturn QMakeEvaluator::evaluateBuiltinConditional(
|
|||||||
const QString &msg = m_option->expandEnvVars(args.at(0).toQString(m_tmp2));
|
const QString &msg = m_option->expandEnvVars(args.at(0).toQString(m_tmp2));
|
||||||
if (!m_skipLevel) {
|
if (!m_skipLevel) {
|
||||||
if (func_t == T_LOG) {
|
if (func_t == T_LOG) {
|
||||||
|
m_logBuffer.append(msg);
|
||||||
|
if (m_logBuffer.size() > 15)
|
||||||
|
m_logBuffer.takeFirst();
|
||||||
#ifdef PROEVALUATOR_FULL
|
#ifdef PROEVALUATOR_FULL
|
||||||
fputs(msg.toLatin1().constData(), stderr);
|
fputs(msg.toLatin1().constData(), stderr);
|
||||||
#endif
|
#endif
|
||||||
|
@@ -48,6 +48,10 @@ public:
|
|||||||
QT_BEGIN_NAMESPACE
|
QT_BEGIN_NAMESPACE
|
||||||
|
|
||||||
QMAKE_EXPORT std::function<void(ProcessData *data)> &theProcessRunner();
|
QMAKE_EXPORT std::function<void(ProcessData *data)> &theProcessRunner();
|
||||||
|
|
||||||
|
QMAKE_EXPORT std::function<std::optional<QString>(const QString &, const QStringList &)> &
|
||||||
|
thePrompter();
|
||||||
|
|
||||||
QMAKE_EXPORT QString removeHostAndScheme(const QString &remotePath);
|
QMAKE_EXPORT QString removeHostAndScheme(const QString &remotePath);
|
||||||
|
|
||||||
class QMakeGlobals;
|
class QMakeGlobals;
|
||||||
@@ -296,6 +300,7 @@ public:
|
|||||||
QStringList m_qmakepath;
|
QStringList m_qmakepath;
|
||||||
QStringList m_qmakefeatures;
|
QStringList m_qmakefeatures;
|
||||||
QStringList m_mkspecPaths;
|
QStringList m_mkspecPaths;
|
||||||
|
QStringList m_logBuffer;
|
||||||
QExplicitlySharedDataPointer<QMakeFeatureRoots> m_featureRoots;
|
QExplicitlySharedDataPointer<QMakeFeatureRoots> m_featureRoots;
|
||||||
ProString m_dirSep;
|
ProString m_dirSep;
|
||||||
ProFunctionDefs m_functionDefs;
|
ProFunctionDefs m_functionDefs;
|
||||||
|
Reference in New Issue
Block a user