Custom wizard: Add validation rules.

Add XML-elements allowing for Javascript-based
validation rules along with error messages.
Rubber-stamped-by: Erik Verbruggen <erik.verbruggen@nokia.com>
This commit is contained in:
Friedemann Kleint
2010-09-27 13:52:34 +02:00
parent 272d22f130
commit 7ccb80aa5a
9 changed files with 184 additions and 34 deletions

View File

@@ -67,4 +67,11 @@ Custom class wizard example configuration file. -->
<fielddescription xml:lang="de">Datentyp:</fielddescription> <fielddescription xml:lang="de">Datentyp:</fielddescription>
</field> </field>
</fields> </fields>
<!-- Example of a validation rule -->
<validationrules>
<validationrule condition='"%ClassName%" != "QAbstractListModel"'>
<message>%ClassName% cannot be used as class name.</message>
<message xml:lang="de">%ClassName% kann nicht als Klassenname verwendet werden.</message>
</validationrule>
</validationrules>
</wizard> </wizard>

View File

@@ -2,5 +2,5 @@ let $prefix := string("QT_TRANSLATE_NOOP(&quot;ProjectExplorer::CustomWizard&quo
let $suffix := concat("&quot;)", codepoints-to-string(10)) let $suffix := concat("&quot;)", codepoints-to-string(10))
for $file in tokenize($files, string("\|")) for $file in tokenize($files, string("\|"))
let $doc := doc($file) let $doc := doc($file)
for $text in ($doc/*:wizard/*:description, $doc/*:wizard/*:displayname, $doc/*:wizard/*:displaycategory, $doc/*:wizard/*:fieldpagetitle, $doc/*:wizard/*:fields/*:field/*:fielddescription, $doc/*:wizard/*:fields/*:field/*:fieldcontrol/*:comboentries/*:comboentry/*:comboentrytext) for $text in ($doc/*:wizard/*:description, $doc/*:wizard/*:displayname, $doc/*:wizard/*:displaycategory, $doc/*:wizard/*:fieldpagetitle, $doc/*:wizard/*:fields/*:field/*:fielddescription, $doc/*:wizard/*:fields/*:field/*:fieldcontrol/*:comboentries/*:comboentry/*:comboentrytext, $doc/*:wizard/*:validationrules/*:validationrule/*:message)
return fn:concat($prefix, data($text), $suffix) return fn:concat($prefix, data($text), $suffix)

View File

@@ -114,7 +114,7 @@ void CustomWizard::initWizardDialog(Utils::Wizard *wizard, const QString &defaul
QTC_ASSERT(!parameters().isNull(), return); QTC_ASSERT(!parameters().isNull(), return);
d->m_context->reset(); d->m_context->reset();
Internal::CustomWizardPage *customPage = new Internal::CustomWizardPage(d->m_context, parameters()->fields); Internal::CustomWizardPage *customPage = new Internal::CustomWizardPage(d->m_context, parameters());
customPage->setPath(defaultPath); customPage->setPath(defaultPath);
addWizardPage(wizard, customPage, parameters()->firstPageId); addWizardPage(wizard, customPage, parameters()->firstPageId);
if (!parameters()->fieldPageTitle.isEmpty()) if (!parameters()->fieldPageTitle.isEmpty())
@@ -298,15 +298,7 @@ Core::GeneratedFiles CustomWizard::generateWizardFiles(QString *errorMessage) co
// Create a replacement map of static base fields + wizard dialog fields // Create a replacement map of static base fields + wizard dialog fields
CustomWizard::FieldReplacementMap CustomWizard::replacementMap(const QWizard *w) const CustomWizard::FieldReplacementMap CustomWizard::replacementMap(const QWizard *w) const
{ {
FieldReplacementMap fieldReplacementMap = d->m_context->baseReplacements; return Internal::CustomWizardFieldPage::replacementMap(w, context(), d->m_parameters->fields);
foreach(const Internal::CustomWizardField &field, d->m_parameters->fields) {
const QString value = w->field(field.name).toString();
fieldReplacementMap.insert(field.name, value);
}
// Insert paths for generator scripts.
fieldReplacementMap.insert(QLatin1String("Path"), QDir::toNativeSeparators(context()->path));
fieldReplacementMap.insert(QLatin1String("TargetPath"), QDir::toNativeSeparators(context()->targetPath));
return fieldReplacementMap;
} }
CustomWizard::CustomWizardParametersPtr CustomWizard::parameters() const CustomWizard::CustomWizardParametersPtr CustomWizard::parameters() const
@@ -501,7 +493,7 @@ void CustomProjectWizard::initProjectWizardDialog(BaseProjectWizardDialog *w,
w->setWindowTitle(displayName()); w->setWindowTitle(displayName());
if (!pa->fields.isEmpty()) { if (!pa->fields.isEmpty()) {
Internal::CustomWizardFieldPage *cp = new Internal::CustomWizardFieldPage(ctx, pa->fields); Internal::CustomWizardFieldPage *cp = new Internal::CustomWizardFieldPage(ctx, pa);
addWizardPage(w, cp, parameters()->firstPageId); addWizardPage(w, cp, parameters()->firstPageId);
if (!pa->fieldPageTitle.isEmpty()) if (!pa->fieldPageTitle.isEmpty())
cp->setTitle(pa->fieldPageTitle); cp->setTitle(pa->fieldPageTitle);

View File

@@ -35,14 +35,17 @@
#include <QtCore/QRegExp> #include <QtCore/QRegExp>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtGui/QWizardPage> #include <QtGui/QWizardPage>
#include <QtGui/QFormLayout> #include <QtGui/QFormLayout>
#include <QtGui/QVBoxLayout>
#include <QtGui/QLineEdit> #include <QtGui/QLineEdit>
#include <QtGui/QLabel> #include <QtGui/QLabel>
#include <QtGui/QRegExpValidator> #include <QtGui/QRegExpValidator>
#include <QtGui/QComboBox> #include <QtGui/QComboBox>
#include <QtGui/QTextEdit> #include <QtGui/QTextEdit>
#include <QtGui/QSpacerItem>
enum { debug = 0 }; enum { debug = 0 };
@@ -127,18 +130,26 @@ CustomWizardFieldPage::TextEditData::TextEditData(QTextEdit* le, const QString &
} }
CustomWizardFieldPage::CustomWizardFieldPage(const QSharedPointer<CustomWizardContext> &ctx, CustomWizardFieldPage::CustomWizardFieldPage(const QSharedPointer<CustomWizardContext> &ctx,
const FieldList &fields, const QSharedPointer<CustomWizardParameters> &parameters,
QWidget *parent) : QWidget *parent) :
QWizardPage(parent), QWizardPage(parent),
m_parameters(parameters),
m_context(ctx), m_context(ctx),
m_formLayout(new QFormLayout) m_formLayout(new QFormLayout),
m_errorLabel(new QLabel)
{ {
QVBoxLayout *vLayout = new QVBoxLayout;
m_formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); m_formLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow);
if (debug) if (debug)
qDebug() << Q_FUNC_INFO << fields.size(); qDebug() << Q_FUNC_INFO << parameters->fields.size();
foreach(const CustomWizardField &f, fields) foreach(const CustomWizardField &f, parameters->fields)
addField(f); addField(f);
setLayout(m_formLayout); vLayout->addLayout(m_formLayout);
m_errorLabel->setVisible(false);
m_errorLabel->setStyleSheet(QLatin1String("background: red"));
vLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding));
vLayout->addWidget(m_errorLabel);
setLayout(vLayout);
} }
CustomWizardFieldPage::~CustomWizardFieldPage() CustomWizardFieldPage::~CustomWizardFieldPage()
@@ -150,6 +161,18 @@ void CustomWizardFieldPage::addRow(const QString &name, QWidget *w)
m_formLayout->addRow(name, w); m_formLayout->addRow(name, w);
} }
void CustomWizardFieldPage::showError(const QString &m)
{
m_errorLabel->setText(m);
m_errorLabel->setVisible(true);
}
void CustomWizardFieldPage::clearError()
{
m_errorLabel->setText(QString());
m_errorLabel->setVisible(false);
}
// Create widget a control based on the control attributes map // Create widget a control based on the control attributes map
// and register it with the QWizard. // and register it with the QWizard.
void CustomWizardFieldPage::addField(const CustomWizardField &field)\ void CustomWizardFieldPage::addField(const CustomWizardField &field)\
@@ -294,6 +317,7 @@ QWidget *CustomWizardFieldPage::registerLineEdit(const QString &fieldName,
void CustomWizardFieldPage::initializePage() void CustomWizardFieldPage::initializePage()
{ {
QWizardPage::initializePage(); QWizardPage::initializePage();
clearError();
// Note that the field mechanism will always restore the value // Note that the field mechanism will always restore the value
// set on it when entering the page, so, there is no point in // set on it when entering the page, so, there is no point in
// trying to preserve user modifications of the text. // trying to preserve user modifications of the text.
@@ -315,6 +339,7 @@ void CustomWizardFieldPage::initializePage()
bool CustomWizardFieldPage::validatePage() bool CustomWizardFieldPage::validatePage()
{ {
clearError();
// Check line edits with validators // Check line edits with validators
foreach(const LineEditData &led, m_lineEdits) { foreach(const LineEditData &led, m_lineEdits) {
if (const QValidator *val = led.lineEdit->validator()) { if (const QValidator *val = led.lineEdit->validator()) {
@@ -326,15 +351,40 @@ bool CustomWizardFieldPage::validatePage()
} }
} }
} }
// Any user validation rules -> Check all and display messages with
// place holders applied.
if (!m_parameters->rules.isEmpty()) {
const QMap<QString, QString> values = replacementMap(wizard(), m_context, m_parameters->fields);
QString message;
if (!CustomWizardValidationRule::validateRules(m_parameters->rules, values, &message)) {
showError(message);
return false;
}
}
return QWizardPage::validatePage(); return QWizardPage::validatePage();
} }
QMap<QString, QString> CustomWizardFieldPage::replacementMap(const QWizard *w,
const QSharedPointer<CustomWizardContext> &ctx,
const FieldList &f)
{
QMap<QString, QString> fieldReplacementMap = ctx->baseReplacements;
foreach(const Internal::CustomWizardField &field, f) {
const QString value = w->field(field.name).toString();
fieldReplacementMap.insert(field.name, value);
}
// Insert paths for generator scripts.
fieldReplacementMap.insert(QLatin1String("Path"), QDir::toNativeSeparators(ctx->path));
fieldReplacementMap.insert(QLatin1String("TargetPath"), QDir::toNativeSeparators(ctx->targetPath));
return fieldReplacementMap;
}
// --------------- CustomWizardPage // --------------- CustomWizardPage
CustomWizardPage::CustomWizardPage(const QSharedPointer<CustomWizardContext> &ctx, CustomWizardPage::CustomWizardPage(const QSharedPointer<CustomWizardContext> &ctx,
const FieldList &f, const QSharedPointer<CustomWizardParameters> &parameters,
QWidget *parent) : QWidget *parent) :
CustomWizardFieldPage(ctx, f, parent), CustomWizardFieldPage(ctx, parameters, parent),
m_pathChooser(new Utils::PathChooser) m_pathChooser(new Utils::PathChooser)
{ {
addRow(tr("Path:"), m_pathChooser); addRow(tr("Path:"), m_pathChooser);

View File

@@ -39,6 +39,7 @@ QT_BEGIN_NAMESPACE
class QFormLayout; class QFormLayout;
class QLineEdit; class QLineEdit;
class QTextEdit; class QTextEdit;
class QLabel;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace Utils { namespace Utils {
@@ -110,23 +111,30 @@ private:
// as page 2 of a BaseProjectWizardDialog if there are any fields. // as page 2 of a BaseProjectWizardDialog if there are any fields.
// Uses the 'field' functionality of QWizard. // Uses the 'field' functionality of QWizard.
// Implements validatePage() as the field logic cannot be tied up // Implements validatePage() as the field logic cannot be tied up
// with additional validation. // with additional validation. Performs checking of the Javascript-based
// validation rules of the parameters and displays error messages in a red
// warning label.
class CustomWizardFieldPage : public QWizardPage { class CustomWizardFieldPage : public QWizardPage {
Q_OBJECT Q_OBJECT
public: public:
typedef QList<CustomWizardField> FieldList; typedef QList<CustomWizardField> FieldList;
explicit CustomWizardFieldPage(const QSharedPointer<CustomWizardContext> &ctx, explicit CustomWizardFieldPage(const QSharedPointer<CustomWizardContext> &ctx,
const FieldList &f, const QSharedPointer<CustomWizardParameters> &parameters,
QWidget *parent = 0); QWidget *parent = 0);
virtual ~CustomWizardFieldPage(); virtual ~CustomWizardFieldPage();
virtual bool validatePage(); virtual bool validatePage();
virtual void initializePage(); virtual void initializePage();
static QMap<QString, QString> replacementMap(const QWizard *w,
const QSharedPointer<CustomWizardContext> &ctx,
const FieldList &f);
protected: protected:
inline void addRow(const QString &name, QWidget *w); inline void addRow(const QString &name, QWidget *w);
void showError(const QString &);
void clearError();
private: private:
struct LineEditData { struct LineEditData {
explicit LineEditData(QLineEdit* le = 0, const QString &defText = QString()); explicit LineEditData(QLineEdit* le = 0, const QString &defText = QString());
@@ -150,10 +158,12 @@ private:
const CustomWizardField &field); const CustomWizardField &field);
void addField(const CustomWizardField &f); void addField(const CustomWizardField &f);
const QSharedPointer<CustomWizardParameters> m_parameters;
const QSharedPointer<CustomWizardContext> m_context; const QSharedPointer<CustomWizardContext> m_context;
QFormLayout *m_formLayout; QFormLayout *m_formLayout;
LineEditDataList m_lineEdits; LineEditDataList m_lineEdits;
TextEditDataList m_textEdits; TextEditDataList m_textEdits;
QLabel *m_errorLabel;
}; };
// A custom wizard page presenting the fields to be used and a path chooser // A custom wizard page presenting the fields to be used and a path chooser
@@ -164,7 +174,7 @@ class CustomWizardPage : public CustomWizardFieldPage {
Q_OBJECT Q_OBJECT
public: public:
explicit CustomWizardPage(const QSharedPointer<CustomWizardContext> &ctx, explicit CustomWizardPage(const QSharedPointer<CustomWizardContext> &ctx,
const FieldList &f, const QSharedPointer<CustomWizardParameters> &parameters,
QWidget *parent = 0); QWidget *parent = 0);
QString path() const; QString path() const;

View File

@@ -46,6 +46,7 @@
#include <QtCore/QXmlStreamReader> #include <QtCore/QXmlStreamReader>
#include <QtCore/QXmlStreamAttribute> #include <QtCore/QXmlStreamAttribute>
#include <QtCore/QTemporaryFile> #include <QtCore/QTemporaryFile>
#include <QtScript/QScriptEngine>
#include <QtGui/QIcon> #include <QtGui/QIcon>
@@ -90,6 +91,11 @@ static const char fileSourceAttributeC[] = "source";
static const char fileTargetAttributeC[] = "target"; static const char fileTargetAttributeC[] = "target";
static const char fileBinaryAttributeC[] = "binary"; static const char fileBinaryAttributeC[] = "binary";
static const char rulesElementC[] = "validationrules";
static const char ruleElementC[] = "validationrule";
static const char ruleConditionAttributeC[] = "condition";
static const char ruleMessageElementC[] = "message";
enum ParseState { enum ParseState {
ParseBeginning, ParseBeginning,
ParseWithinWizard, ParseWithinWizard,
@@ -104,6 +110,9 @@ enum ParseState {
ParseWithinFile, ParseWithinFile,
ParseWithinScript, ParseWithinScript,
ParseWithinScriptArguments, ParseWithinScriptArguments,
ParseWithinValidationRules,
ParseWithinValidationRule,
ParseWithinValidationRuleMessage,
ParseError ParseError
}; };
@@ -142,6 +151,38 @@ CustomWizardFile::CustomWizardFile() :
{ {
} }
bool CustomWizardValidationRule::validateRules(const QList<CustomWizardValidationRule> &rules,
const QMap<QString, QString> &replacementMap,
QString *errorMessage)
{
errorMessage->clear();
if (rules.isEmpty())
return true;
QScriptEngine engine;
foreach(const CustomWizardValidationRule &rule, rules)
if (!rule.validate(engine, replacementMap)) {
*errorMessage = rule.message;
CustomWizardContext::replaceFields(replacementMap, errorMessage);
return false;
}
return true;
}
bool CustomWizardValidationRule::validate(QScriptEngine &engine, const QMap<QString, QString> &replacementMap) const
{
// Apply parameters and evaluate using JavaScript
QString cond = condition;
CustomWizardContext::replaceFields(replacementMap, &cond);
bool valid = false;
QString errorMessage;
if (!evaluateBooleanJavaScriptExpression(engine, cond, &valid, &errorMessage)) {
qWarning("Error in custom wizard validation expression '%s': %s",
qPrintable(cond), qPrintable(errorMessage));
return false;
}
return valid;
}
CustomWizardParameters::CustomWizardParameters() : CustomWizardParameters::CustomWizardParameters() :
firstPageId(-1) firstPageId(-1)
{ {
@@ -155,6 +196,7 @@ void CustomWizardParameters::clear()
filesGeneratorScript.clear(); filesGeneratorScript.clear();
filesGeneratorScriptArguments.clear(); filesGeneratorScriptArguments.clear();
firstPageId = -1; firstPageId = -1;
rules.clear();
} }
// Resolve icon file path relative to config file directory. // Resolve icon file path relative to config file directory.
@@ -296,6 +338,8 @@ static ParseState nextOpeningState(ParseState in, const QStringRef &name)
return ParseWithinFiles; return ParseWithinFiles;
if (name == QLatin1String(generatorScriptElementC)) if (name == QLatin1String(generatorScriptElementC))
return ParseWithinScript; return ParseWithinScript;
if (name == QLatin1String(rulesElementC))
return ParseWithinValidationRules;
break; break;
case ParseWithinFields: case ParseWithinFields:
if (name == QLatin1String(fieldElementC)) if (name == QLatin1String(fieldElementC))
@@ -327,11 +371,20 @@ static ParseState nextOpeningState(ParseState in, const QStringRef &name)
if (name == QLatin1String(generatorScriptArgumentElementC)) if (name == QLatin1String(generatorScriptArgumentElementC))
return ParseWithinScriptArguments; return ParseWithinScriptArguments;
break; break;
case ParseWithinValidationRules:
if (name == QLatin1String(ruleElementC))
return ParseWithinValidationRule;
break;
case ParseWithinValidationRule:
if (name == QLatin1String(ruleMessageElementC))
return ParseWithinValidationRuleMessage;
break;
case ParseWithinFieldDescription: // No subelements case ParseWithinFieldDescription: // No subelements
case ParseWithinComboEntryText: case ParseWithinComboEntryText:
case ParseWithinFile: case ParseWithinFile:
case ParseError: case ParseError:
case ParseWithinScriptArguments: case ParseWithinScriptArguments:
case ParseWithinValidationRuleMessage:
break; break;
} }
return ParseError; return ParseError;
@@ -391,6 +444,12 @@ static ParseState nextClosingState(ParseState in, const QStringRef &name)
if (name == QLatin1String(generatorScriptArgumentElementC)) if (name == QLatin1String(generatorScriptArgumentElementC))
return ParseWithinScript; return ParseWithinScript;
break; break;
case ParseWithinValidationRuleMessage:
return ParseWithinValidationRule;
case ParseWithinValidationRule:
return ParseWithinValidationRules;
case ParseWithinValidationRules:
return ParseWithinWizard;
case ParseError: case ParseError:
break; break;
} }
@@ -575,6 +634,18 @@ CustomWizardParameters::ParseResult
filesGeneratorScriptArguments.push_back(argument); filesGeneratorScriptArguments.push_back(argument);
} }
break; break;
case ParseWithinValidationRule: {
CustomWizardValidationRule rule;
rule.condition = reader.attributes().value(QLatin1String(ruleConditionAttributeC)).toString();
rules.push_back(rule);
}
break;
case ParseWithinValidationRuleMessage:
QTC_ASSERT(!rules.isEmpty(), return ParseFailed; )
// This reads away the end tag, set state here.
assignLanguageElementText(reader, language, &(rules.back().message));
state = ParseWithinValidationRule;
break;
default: default:
break; break;
} }
@@ -664,6 +735,8 @@ QString CustomWizardParameters::toString() const
} }
str << '\n'; str << '\n';
} }
foreach(const CustomWizardValidationRule &r, rules)
str << " Rule: '" << r.condition << "'->'" << r.message << '\n';
return rc; return rc;
} }

View File

@@ -40,6 +40,7 @@ QT_BEGIN_NAMESPACE
class QIODevice; class QIODevice;
class QDebug; class QDebug;
class QTemporaryFile; class QTemporaryFile;
class QScriptEngine;
QT_END_NAMESPACE QT_END_NAMESPACE
namespace ProjectExplorer { namespace ProjectExplorer {
@@ -71,6 +72,22 @@ struct CustomWizardFile {
bool binary; bool binary;
}; };
// A validation rule based on Javascript-expressions over the field placeholders.
// Placeholder replacement is performed on the condition and it is evaluated
// using Javascript. So, for example '"%ProjectName%" != "untitled" would block
// default names. On failure, the message is displayed in a red warning label
// in the wizard page. Placeholder replacement is also performed on the message
// prior to displaying.
struct CustomWizardValidationRule {
// Validate a set of rules and return false + message on the first failing one.
static bool validateRules(const QList<CustomWizardValidationRule> &rules,
const QMap<QString, QString> &replacementMap,
QString *errorMessage);
bool validate(QScriptEngine &, const QMap<QString, QString> &replacementMap) const;
QString condition;
QString message;
};
// Argument to the generator script containing placeholders to // Argument to the generator script containing placeholders to
// be replaced by field values or file names // be replaced by field values or file names
// as in '--class-name=%ClassName%' or '--description=%Description%'. // as in '--class-name=%ClassName%' or '--description=%Description%'.
@@ -110,6 +127,7 @@ public:
QString fieldPageTitle; QString fieldPageTitle;
QList<CustomWizardField> fields; QList<CustomWizardField> fields;
QList<CustomWizardValidationRule> rules;
int firstPageId; int firstPageId;
}; };

View File

@@ -81,7 +81,6 @@ public:
private: private:
void reset(); void reset();
bool evaluateExpression(const QString &expression, bool *result, QString *errorMessage);
PreprocessorSection preprocessorLine(const QString & in, QString *ifExpression) const; PreprocessorSection preprocessorLine(const QString & in, QString *ifExpression) const;
mutable QRegExp m_ifPattern; mutable QRegExp m_ifPattern;
@@ -134,17 +133,15 @@ PreprocessorSection PreprocessContext::preprocessorLine(const QString &in,
} }
// Evaluate an expression within an 'if'/'elsif' to a bool via QScript // Evaluate an expression within an 'if'/'elsif' to a bool via QScript
bool PreprocessContext::evaluateExpression(const QString &expression, bool evaluateBooleanJavaScriptExpression(QScriptEngine &engine, const QString &expression, bool *result, QString *errorMessage)
bool *result,
QString *errorMessage)
{ {
errorMessage->clear(); errorMessage->clear();
*result = false; *result = false;
m_scriptEngine.clearExceptions(); engine.clearExceptions();
const QScriptValue value = m_scriptEngine.evaluate(expression); const QScriptValue value = engine.evaluate(expression);
if (m_scriptEngine.hasUncaughtException()) { if (engine.hasUncaughtException()) {
*errorMessage = QString::fromLatin1("Error in '%1': %2"). *errorMessage = QString::fromLatin1("Error in '%1': %2").
arg(expression, m_scriptEngine.uncaughtException().toString()); arg(expression, engine.uncaughtException().toString());
return false; return false;
} }
// Try to convert to bool, be that an int or whatever. // Try to convert to bool, be that an int or whatever.
@@ -196,7 +193,7 @@ bool PreprocessContext::process(const QString &in, QString *out, QString *errorM
case IfSection: case IfSection:
// '@If': Push new section // '@If': Push new section
if (top.parentEnabled) { if (top.parentEnabled) {
if (!evaluateExpression(expression, &expressionValue, errorMessage)) { if (!evaluateBooleanJavaScriptExpression(m_scriptEngine, expression, &expressionValue, errorMessage)) {
*errorMessage = QString::fromLatin1("Error in @if at %1: %2"). *errorMessage = QString::fromLatin1("Error in @if at %1: %2").
arg(l + 1).arg(*errorMessage); arg(l + 1).arg(*errorMessage);
return false; return false;
@@ -214,7 +211,7 @@ bool PreprocessContext::process(const QString &in, QString *out, QString *errorM
return false; return false;
} }
if (top.parentEnabled) { if (top.parentEnabled) {
if (!evaluateExpression(expression, &expressionValue, errorMessage)) { if (!evaluateBooleanJavaScriptExpression(m_scriptEngine, expression, &expressionValue, errorMessage)) {
*errorMessage = QString::fromLatin1("Error in @elsif at %1: %2"). *errorMessage = QString::fromLatin1("Error in @elsif at %1: %2").
arg(l + 1).arg(*errorMessage); arg(l + 1).arg(*errorMessage);
return false; return false;

View File

@@ -32,6 +32,8 @@
#include <QtCore/QString> #include <QtCore/QString>
QT_FORWARD_DECLARE_CLASS(QScriptEngine)
namespace ProjectExplorer { namespace ProjectExplorer {
namespace Internal { namespace Internal {
@@ -51,7 +53,8 @@ Blup
*/ */
bool customWizardPreprocess(const QString &in, QString *out, QString *errorMessage); bool customWizardPreprocess(const QString &in, QString *out, QString *errorMessage);
/* Helper to evaluate an expression. */
bool evaluateBooleanJavaScriptExpression(QScriptEngine &engine, const QString &expression, bool *result, QString *errorMessage);
} // namespace Internal } // namespace Internal
} // namespace ProjectExplorer } // namespace ProjectExplorer