Utils: Allow validators operating on a single string in FancyLineEdit

Change-Id: I68f21e96efab05e9f5aa6c18973cbdb20c0c3417
Reviewed-by: Alessandro Portale <alessandro.portale@qt.io>
This commit is contained in:
hjk
2025-04-17 17:10:56 +02:00
parent 5d45e339a7
commit c1603c2e75
24 changed files with 100 additions and 87 deletions

View File

@@ -35,9 +35,7 @@ ClassNameValidatingLineEdit::ClassNameValidatingLineEdit(QWidget *parent) :
FancyLineEdit(parent), FancyLineEdit(parent),
d(new ClassNameValidatingLineEditPrivate) d(new ClassNameValidatingLineEditPrivate)
{ {
setValidationFunction([this](FancyLineEdit *edit) { setValidationFunction([this](const QString &text) { return validateClassName(text); });
return validateClassName(edit);
});
updateRegExp(); updateRegExp();
} }
@@ -73,18 +71,17 @@ void ClassNameValidatingLineEdit::setNamespaceDelimiter(const QString &delimiter
d->m_namespaceDelimiter = delimiter; d->m_namespaceDelimiter = delimiter;
} }
Result<> ClassNameValidatingLineEdit::validateClassName(FancyLineEdit *edit) const Result<> ClassNameValidatingLineEdit::validateClassName(const QString &text) const
{ {
QTC_ASSERT(d->m_nameRegexp.isValid(), return ResultError(ResultAssert)); QTC_ASSERT(d->m_nameRegexp.isValid(), return ResultError(ResultAssert));
const QString value = edit->text(); if (!d->m_namespacesEnabled && text.contains(d->m_namespaceDelimiter))
if (!d->m_namespacesEnabled && value.contains(d->m_namespaceDelimiter))
return ResultError(Tr::tr("The class name must not contain namespace delimiters.")); return ResultError(Tr::tr("The class name must not contain namespace delimiters."));
if (value.isEmpty()) if (text.isEmpty())
return ResultError(Tr::tr("Please enter a class name.")); return ResultError(Tr::tr("Please enter a class name."));
if (!d->m_nameRegexp.match(value).hasMatch()) if (!d->m_nameRegexp.match(text).hasMatch())
return ResultError(Tr::tr("The class name contains invalid characters.")); return ResultError(Tr::tr("The class name contains invalid characters."));
return ResultOk; return ResultOk;

View File

@@ -42,7 +42,7 @@ signals:
void updateFileName(const QString &t); void updateFileName(const QString &t);
protected: protected:
Result<> validateClassName(FancyLineEdit *edit) const; Result<> validateClassName(const QString &text) const;
void handleChanged(const QString &t) override; void handleChanged(const QString &t) override;
QString fixInputString(const QString &string) override; QString fixInputString(const QString &string) override;

View File

@@ -481,11 +481,11 @@ FancyLineEdit::ValidationFunction FancyLineEdit::defaultValidationFunction()
return &FancyLineEdit::validateWithValidator; return &FancyLineEdit::validateWithValidator;
} }
Result<> FancyLineEdit::validateWithValidator(FancyLineEdit *edit) Result<> FancyLineEdit::validateWithValidator(FancyLineEdit &edit)
{ {
if (const QValidator *v = edit->validator()) { if (const QValidator *v = edit.validator()) {
QString tmp = edit->text(); QString tmp = edit.text();
int pos = edit->cursorPosition(); int pos = edit.cursorPosition();
if (v->validate(tmp, pos) != QValidator::Acceptable) if (v->validate(tmp, pos) != QValidator::Acceptable)
return ResultError(QString()); return ResultError(QString());
} }
@@ -611,7 +611,7 @@ void FancyLineEdit::validate()
} }
if (d->m_validationFunction.index() == 1) { if (d->m_validationFunction.index() == 1) {
auto &validationFunction = std::get<1>(d->m_validationFunction); SynchronousValidationFunction &validationFunction = std::get<1>(d->m_validationFunction);
if (!validationFunction) if (!validationFunction)
return; return;
@@ -626,7 +626,31 @@ void FancyLineEdit::validate()
Result<QString> result; Result<QString> result;
if (const Result<> validates = validationFunction(this)) if (const Result<> validates = validationFunction(*this))
result = t;
else
result = ResultError(validates.error());
handleValidationResult(result, t);
}
if (d->m_validationFunction.index() == 2) {
SimpleSynchronousValidationFunction &validationFunction = std::get<2>(d->m_validationFunction);
if (!validationFunction)
return;
const QString t = text();
if (d->m_isFiltering) {
if (t != d->m_lastFilterText) {
d->m_lastFilterText = t;
emit filterChanged(t);
}
}
Result<QString> result;
if (const Result<> validates = validationFunction(t))
result = t; result = t;
else else
result = ResultError(validates.error()); result = ResultError(validates.error());

View File

@@ -105,8 +105,13 @@ public:
using AsyncValidationResult = Result<QString>; using AsyncValidationResult = Result<QString>;
using AsyncValidationFuture = QFuture<AsyncValidationResult>; using AsyncValidationFuture = QFuture<AsyncValidationResult>;
using AsyncValidationFunction = std::function<AsyncValidationFuture(QString)>; using AsyncValidationFunction = std::function<AsyncValidationFuture(QString)>;
using SynchronousValidationFunction = std::function<Result<>(FancyLineEdit *)>; using SynchronousValidationFunction = std::function<Result<>(FancyLineEdit &)>;
using ValidationFunction = std::variant<AsyncValidationFunction, SynchronousValidationFunction>; using SimpleSynchronousValidationFunction = std::function<Result<>(const QString &)>;
using ValidationFunction = std::variant<
AsyncValidationFunction,
SynchronousValidationFunction,
SimpleSynchronousValidationFunction
>;
enum State { Invalid, DisplayingPlaceholderText, Valid }; enum State { Invalid, DisplayingPlaceholderText, Valid };
@@ -149,7 +154,7 @@ private:
void handleValidationResult(AsyncValidationResult result, const QString &oldText); void handleValidationResult(AsyncValidationResult result, const QString &oldText);
static Result<> validateWithValidator(FancyLineEdit *edit); static Result<> validateWithValidator(FancyLineEdit &edit);
// Unimplemented, to force the user to make a decision on // Unimplemented, to force the user to make a decision on
// whether to use setHistoryCompleter() or setSpecialCompleter(). // whether to use setHistoryCompleter() or setSpecialCompleter().
void setCompleter(QCompleter *); void setCompleter(QCompleter *);

View File

@@ -48,10 +48,10 @@ FileNameValidatingLineEdit::FileNameValidatingLineEdit(QWidget *parent) :
m_allowDirectories(false), m_allowDirectories(false),
m_forceFirstCapitalLetter(false) m_forceFirstCapitalLetter(false)
{ {
setValidationFunction([this](FancyLineEdit *edit) { setValidationFunction([this](const QString &text) {
if (const Result<> res = validateFileNameExtension(edit->text(), requiredExtensions()); !res) if (const Result<> res = validateFileNameExtension(text, requiredExtensions()); !res)
return res; return res;
if (const Result<> res = validateFileName(edit->text(), allowDirectories()); !res) if (const Result<> res = validateFileName(text, allowDirectories()); !res)
return res; return res;
return ResultOk; return ResultOk;
}); });

View File

@@ -99,8 +99,8 @@ ProjectIntroPage::ProjectIntroPage(QWidget *parent) :
d->m_nameLineEdit->setPlaceholderText(Tr::tr("Enter project name")); d->m_nameLineEdit->setPlaceholderText(Tr::tr("Enter project name"));
d->m_nameLineEdit->setObjectName("nameLineEdit"); d->m_nameLineEdit->setObjectName("nameLineEdit");
d->m_nameLineEdit->setFocus(); d->m_nameLineEdit->setFocus();
d->m_nameLineEdit->setValidationFunction([this](FancyLineEdit *edit) { d->m_nameLineEdit->setValidationFunction([this](const QString &text) {
return validateProjectName(edit->text()); return validateProjectName(text);
}); });
d->m_projectLabel = new QLabel(Tr::tr("Add to project:")); d->m_projectLabel = new QLabel(Tr::tr("Add to project:"));

View File

@@ -111,8 +111,8 @@ GTestFramework::GTestFramework()
gtestFilter.setToolTip(Tr::tr("Set the GTest filter to be used for grouping.\nSee Google Test " gtestFilter.setToolTip(Tr::tr("Set the GTest filter to be used for grouping.\nSee Google Test "
"documentation for further information on GTest filters.")); "documentation for further information on GTest filters."));
gtestFilter.setValidationFunction([](FancyLineEdit *edit) -> Result<> { gtestFilter.setValidationFunction([](const QString &text) -> Result<> {
if (edit && GTestUtils::isValidGTestFilter(edit->text())) if (GTestUtils::isValidGTestFilter(text))
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());
}); });

View File

@@ -442,8 +442,8 @@ DashboardSettingsWidget::DashboardSettingsWidget(QWidget *parent, QPushButton *o
{ {
m_dashboardUrl.setLabelText(Tr::tr("Dashboard URL:")); m_dashboardUrl.setLabelText(Tr::tr("Dashboard URL:"));
m_dashboardUrl.setDisplayStyle(StringAspect::LineEditDisplay); m_dashboardUrl.setDisplayStyle(StringAspect::LineEditDisplay);
m_dashboardUrl.setValidationFunction([](FancyLineEdit *edit) -> Result<> { m_dashboardUrl.setValidationFunction([](const QString &text) -> Result<> {
if (isUrlValid(edit->text())) if (isUrlValid(text))
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());
}); });
@@ -502,18 +502,17 @@ public:
{ {
m_projectName.setLabelText(Tr::tr("Project name:")); m_projectName.setLabelText(Tr::tr("Project name:"));
m_projectName.setDisplayStyle(StringAspect::LineEditDisplay); m_projectName.setDisplayStyle(StringAspect::LineEditDisplay);
m_projectName.setValidationFunction([](FancyLineEdit *edit) -> Result<> { m_projectName.setValidationFunction([](const QString &text) -> Result<> {
QTC_ASSERT(edit, return ResultError(ResultAssert)); if (text.isEmpty())
if (edit->text().isEmpty())
return ResultError(Tr::tr("Project name must be non-empty.")); return ResultError(Tr::tr("Project name must be non-empty."));
return ResultOk; return ResultOk;
}); });
m_analysisPath.setLabelText(Tr::tr("Analysis path:")); m_analysisPath.setLabelText(Tr::tr("Analysis path:"));
m_analysisPath.setDisplayStyle(StringAspect::LineEditDisplay); m_analysisPath.setDisplayStyle(StringAspect::LineEditDisplay);
m_analysisPath.setValidationFunction([](FancyLineEdit *edit) -> Result<> { m_analysisPath.setValidationFunction([](const QString &text) -> Result<> {
QTC_ASSERT(edit, return ResultError(ResultAssert)); QString input = text;
// do NOT use fromUserInput() as this also cleans the path // do NOT use fromUserInput() as this also cleans the path
const FilePath fp = FilePath::fromString(edit->text().replace('\\', '/')); const FilePath fp = FilePath::fromString(input.replace('\\', '/'));
return analysisPathValid(fp); return analysisPathValid(fp);
}); });
m_localPath.setLabelText(Tr::tr("Local path:")); m_localPath.setLabelText(Tr::tr("Local path:"));

View File

@@ -496,7 +496,7 @@ ShortcutInput::ShortcutInput()
m_warningLabel->setPalette(palette); m_warningLabel->setPalette(palette);
connect(m_warningLabel, &QLabel::linkActivated, this, &ShortcutInput::showConflictsRequested); connect(m_warningLabel, &QLabel::linkActivated, this, &ShortcutInput::showConflictsRequested);
m_shortcutEdit->setValidationFunction([this](FancyLineEdit *) -> Result<> { m_shortcutEdit->setValidationFunction([this](const QString &) -> Result<> {
QString warningMessage; QString warningMessage;
const QKeySequence key = keySequenceFromEditString(m_shortcutEdit->text()); const QKeySequence key = keySequenceFromEditString(m_shortcutEdit->text());
const bool isValid = checkValidity(key, &warningMessage); const bool isValid = checkValidity(key, &warningMessage);

View File

@@ -174,7 +174,7 @@ FindToolBar::FindToolBar(CurrentDocumentFind *currentDocumentFind)
m_findEdit->setFiltering(true); m_findEdit->setFiltering(true);
m_findEdit->setPlaceholderText(QString()); m_findEdit->setPlaceholderText(QString());
m_findEdit->button(Utils::FancyLineEdit::Left)->setFocusPolicy(Qt::TabFocus); m_findEdit->button(Utils::FancyLineEdit::Left)->setFocusPolicy(Qt::TabFocus);
m_findEdit->setValidationFunction([this](FancyLineEdit *) -> Result<> { m_findEdit->setValidationFunction([this](const QString &) -> Result<> {
if (m_lastResult != IFindSupport::NotFound) if (m_lastResult != IFindSupport::NotFound)
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());

View File

@@ -30,13 +30,13 @@ namespace Core::Internal {
static FindToolWindow *m_instance = nullptr; static FindToolWindow *m_instance = nullptr;
static Result<> validateRegExp(FancyLineEdit *edit) static Result<> validateRegExp(const QString &text)
{ {
if (edit->text().isEmpty()) if (text.isEmpty())
return ResultError(Tr::tr("Empty search term.")); return ResultError(Tr::tr("Empty search term."));
if (Find::hasFindFlag(FindRegularExpression)) { if (Find::hasFindFlag(FindRegularExpression)) {
QRegularExpression regexp(edit->text()); QRegularExpression regexp(text);
if (!regexp.isValid()) if (!regexp.isValid())
return ResultError(regexp.errorString()); return ResultError(regexp.errorString());
} }

View File

@@ -224,8 +224,8 @@ public:
auto layout = new QFormLayout(&dlg); auto layout = new QFormLayout(&dlg);
auto funcNameEdit = new FancyLineEdit; auto funcNameEdit = new FancyLineEdit;
funcNameEdit->setValidationFunction([](FancyLineEdit *edit) -> Result<> { funcNameEdit->setValidationFunction([](const QString &text) -> Result<> {
if (ExtractFunctionOptions::isValidFunctionName(edit->text())) if (ExtractFunctionOptions::isValidFunctionName(text))
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());
}); });

View File

@@ -493,11 +493,10 @@ FakeVimExCommandsMappings::FakeVimExCommandsMappings()
m_commandEdit->setPlaceholderText(QString()); m_commandEdit->setPlaceholderText(QString());
connect(m_commandEdit, &FancyLineEdit::textChanged, connect(m_commandEdit, &FancyLineEdit::textChanged,
this, &FakeVimExCommandsMappings::commandChanged); this, &FakeVimExCommandsMappings::commandChanged);
m_commandEdit->setValidationFunction([](FancyLineEdit *e) -> Result<> { m_commandEdit->setValidationFunction([](const QString &text) -> Result<> {
if (QRegularExpression(e->text()).isValid()) if (QRegularExpression(text).isValid())
return ResultOk; return ResultOk;
return ResultError(Tr::tr("The pattern \"%1\" is no valid regular expression") return ResultError(Tr::tr("The pattern \"%1\" is no valid regular expression").arg(text));
.arg(e->text()));
}); });
auto resetButton = new QPushButton(Tr::tr("Reset"), m_commandBox); auto resetButton = new QPushButton(Tr::tr("Reset"), m_commandBox);
resetButton->setToolTip(Tr::tr("Reset to default.")); resetButton->setToolTip(Tr::tr("Reset to default."));

View File

@@ -67,7 +67,7 @@ GerritDialog::GerritDialog(const std::shared_ptr<GerritServer> &s,
m_queryLineEdit->setMinimumSize(QSize(400, 0)); m_queryLineEdit->setMinimumSize(QSize(400, 0));
m_queryLineEdit->setPlaceholderText(Git::Tr::tr("Change #, hash, tr:id, owner:email or reviewer:email")); m_queryLineEdit->setPlaceholderText(Git::Tr::tr("Change #, hash, tr:id, owner:email or reviewer:email"));
m_queryLineEdit->setSpecialCompleter(new QCompleter(m_queryModel, this)); m_queryLineEdit->setSpecialCompleter(new QCompleter(m_queryModel, this));
m_queryLineEdit->setValidationFunction([this](FancyLineEdit *) -> Result<> { m_queryLineEdit->setValidationFunction([this](const QString &) -> Result<> {
if (m_model->state() != GerritModel::Error) if (m_model->state() != GerritModel::Error)
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());

View File

@@ -44,12 +44,9 @@ public:
m_nameEdit = new FancyLineEdit(this); m_nameEdit = new FancyLineEdit(this);
m_nameEdit->setHistoryCompleter("Git.RemoteNames"); m_nameEdit->setHistoryCompleter("Git.RemoteNames");
m_nameEdit->setValidationFunction([this](FancyLineEdit *edit) -> Result<> { m_nameEdit->setValidationFunction([this](FancyLineEdit &edit) -> Result<> {
if (!edit) QString input = edit.text();
return ResultError(ResultAssert); edit.setText(input.replace(m_invalidRemoteNameChars, "_"));
QString input = edit->text();
edit->setText(input.replace(m_invalidRemoteNameChars, "_"));
// "Intermediate" patterns, may change to Acceptable when user edits further: // "Intermediate" patterns, may change to Acceptable when user edits further:
if (input.endsWith(".lock")) //..may not end with ".lock" if (input.endsWith(".lock")) //..may not end with ".lock"
@@ -73,11 +70,11 @@ public:
m_urlEdit = new FancyLineEdit(this); m_urlEdit = new FancyLineEdit(this);
m_urlEdit->setHistoryCompleter("Git.RemoteUrls"); m_urlEdit->setHistoryCompleter("Git.RemoteUrls");
m_urlEdit->setValidationFunction([](FancyLineEdit *edit) -> Result<> { m_urlEdit->setValidationFunction([](FancyLineEdit &edit) -> Result<> {
if (!edit || edit->text().isEmpty()) if (edit.text().isEmpty())
return ResultError(QString()); return ResultError(QString());
const GitRemote r(edit->text()); const GitRemote r(edit.text());
if (!r.isValid) if (!r.isValid)
return ResultError(Tr::tr("The URL may not be valid.")); return ResultError(Tr::tr("The URL may not be valid."));

View File

@@ -61,8 +61,8 @@ GitLabCloneDialog::GitLabCloneDialog(const Project &project, QWidget *parent)
m_pathChooser->setExpectedKind(PathChooser::ExistingDirectory); m_pathChooser->setExpectedKind(PathChooser::ExistingDirectory);
form->addRow(Tr::tr("Path"), m_pathChooser); form->addRow(Tr::tr("Path"), m_pathChooser);
m_directoryLE = new FancyLineEdit(this); m_directoryLE = new FancyLineEdit(this);
m_directoryLE->setValidationFunction([this](FancyLineEdit *e) -> Result<> { m_directoryLE->setValidationFunction([this](const QString &text) -> Result<> {
const FilePath fullPath = m_pathChooser->filePath().pathAppended(e->text()); const FilePath fullPath = m_pathChooser->filePath().pathAppended(text);
if (fullPath.exists()) if (fullPath.exists())
return ResultError(Tr::tr("Path \"%1\" already exists.").arg(fullPath.toUserOutput())); return ResultError(Tr::tr("Path \"%1\" already exists.").arg(fullPath.toUserOutput()));
return ResultOk; return ResultOk;

View File

@@ -70,8 +70,8 @@ GitLabServerWidget::GitLabServerWidget(Mode m, QWidget *parent)
m_host.setLabelText(Tr::tr("Host:")); m_host.setLabelText(Tr::tr("Host:"));
m_host.setDisplayStyle(m == Display ? StringAspect::LabelDisplay m_host.setDisplayStyle(m == Display ? StringAspect::LabelDisplay
: StringAspect::LineEditDisplay); : StringAspect::LineEditDisplay);
m_host.setValidationFunction([](FancyLineEdit *l) -> Result<> { m_host.setValidationFunction([](const QString &text) -> Result<> {
if (hostValid(l->text())) if (hostValid(text))
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());
}); });

View File

@@ -917,8 +917,8 @@ BaseSettingsWidget::BaseSettingsWidget(const BaseSettings *settings, QWidget *pa
m_startupBehavior->addItem(startupBehaviorString(BaseSettings::StartBehavior(behavior))); m_startupBehavior->addItem(startupBehaviorString(BaseSettings::StartBehavior(behavior)));
m_startupBehavior->setCurrentIndex(settings->m_startBehavior); m_startupBehavior->setCurrentIndex(settings->m_startBehavior);
m_initializationOptions->setValidationFunction([](FancyLineEdit *edit) -> Result<> { m_initializationOptions->setValidationFunction([](const QString &text) -> Result<> {
const QString value = globalMacroExpander()->expand(edit->text()); const QString value = globalMacroExpander()->expand(text);
if (value.isEmpty()) if (value.isEmpty())
return ResultOk; return ResultOk;

View File

@@ -231,8 +231,8 @@ IDevice::IDevice()
}; };
d->displayName.setValidationFunction( d->displayName.setValidationFunction(
[this, validateDisplayName](FancyLineEdit *edit) -> Result<> { [this, validateDisplayName](const QString &text) -> Result<> {
return validateDisplayName(d->displayName.value(), edit->text()); return validateDisplayName(d->displayName.value(), text);
}); });
d->displayName.setValueAcceptor( d->displayName.setValueAcceptor(

View File

@@ -109,7 +109,7 @@ public:
m_expander.registerVariable("INPUT", Tr::tr("The text edit input to fix up."), m_expander.registerVariable("INPUT", Tr::tr("The text edit input to fix up."),
[this] { return m_currentInput; }); [this] { return m_currentInput; });
m_expander.registerSubProvider([expander]() -> MacroExpander * { return expander; }); m_expander.registerSubProvider([expander]() -> MacroExpander * { return expander; });
setValidationFunction([this, regex](FancyLineEdit *) -> Result<> { setValidationFunction([this, regex](const QString &) -> Result<> {
if (regex.match(text()).hasMatch()) if (regex.match(text()).hasMatch())
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());

View File

@@ -131,7 +131,7 @@ private:
QbsBuildStep *qbsStep() const; QbsBuildStep *qbsStep() const;
Result<> validateProperties(FancyLineEdit *edit); Result<> validateProperties(const QString &text);
class Property class Property
{ {
@@ -485,8 +485,8 @@ QbsBuildStepConfigWidget::QbsBuildStepConfigWidget(QbsBuildStep *step)
propertyEdit = new FancyLineEdit(this); propertyEdit = new FancyLineEdit(this);
propertyEdit->setToolTip(QbsProjectManager::Tr::tr("Properties to pass to the project.")); propertyEdit->setToolTip(QbsProjectManager::Tr::tr("Properties to pass to the project."));
propertyEdit->setValidationFunction([this](FancyLineEdit *edit) { propertyEdit->setValidationFunction([this](const QString &text) {
return validateProperties(edit); return validateProperties(text);
}); });
defaultInstallDirCheckBox = new QCheckBox(this); defaultInstallDirCheckBox = new QCheckBox(this);
@@ -654,10 +654,10 @@ QbsBuildStep *QbsBuildStepConfigWidget::qbsStep() const
return m_qbsStep; return m_qbsStep;
} }
Result<> QbsBuildStepConfigWidget::validateProperties(FancyLineEdit *edit) Result<> QbsBuildStepConfigWidget::validateProperties(const QString &text)
{ {
ProcessArgs::SplitError err; ProcessArgs::SplitError err;
const QStringList argList = ProcessArgs::splitArgs(edit->text(), HostOsInfo::hostOs(), false, &err); const QStringList argList = ProcessArgs::splitArgs(text, HostOsInfo::hostOs(), false, &err);
if (err != ProcessArgs::SplitOk) if (err != ProcessArgs::SplitOk)
return ResultError(QbsProjectManager::Tr::tr("Could not split properties.")); return ResultError(QbsProjectManager::Tr::tr("Could not split properties."));

View File

@@ -132,17 +132,12 @@ void PropertyItemDelegate::setModelData(QWidget *editor,
ValidatingPropertyNameLineEdit::ValidatingPropertyNameLineEdit(const QStringList &forbidden, ValidatingPropertyNameLineEdit::ValidatingPropertyNameLineEdit(const QStringList &forbidden,
QWidget *parent) QWidget *parent)
: Utils::FancyLineEdit(parent) : FancyLineEdit(parent)
, m_forbidden(forbidden) , m_forbidden(forbidden)
{ {
setValidationFunction([this](FancyLineEdit *edit) -> Result<> { setValidationFunction([this](const QString &text) -> Result<> {
if (!edit)
return ResultError(QString());
static const QRegularExpression identifier("^[a-zA-Z0-9_]+$"); static const QRegularExpression identifier("^[a-zA-Z0-9_]+$");
const QString &value = edit->text(); if (!m_forbidden.contains(text) && identifier.match(text).hasMatch())
if (!m_forbidden.contains(value) && identifier.match(value).hasMatch())
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());
}); });
@@ -152,12 +147,12 @@ ValidatingPropertyNameLineEdit::ValidatingPropertyNameLineEdit(const QStringList
ValidatingPropertyContainerLineEdit::ValidatingPropertyContainerLineEdit(const QStringList &allowed, ValidatingPropertyContainerLineEdit::ValidatingPropertyContainerLineEdit(const QStringList &allowed,
QWidget *parent) QWidget *parent)
: Utils::FancyLineEdit(parent) : FancyLineEdit(parent)
, m_allowed(allowed) , m_allowed(allowed)
{ {
setSpecialCompleter(new QCompleter(allowed, this)); setSpecialCompleter(new QCompleter(allowed, this));
setValidationFunction([this](FancyLineEdit *edit) -> Result<> { setValidationFunction([this](const QString &text) -> Result<> {
if (edit && m_allowed.contains(edit->text())) if (m_allowed.contains(text))
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());
}); });

View File

@@ -120,9 +120,9 @@ static QWidget *testCaseEditor(QWidget *parent, const SquishTestTreeItem *item)
const SuiteConf suiteConf = SuiteConf::readSuiteConf(suite->filePath()); const SuiteConf suiteConf = SuiteConf::readSuiteConf(suite->filePath());
const QStringList inUse = suiteConf.usedTestCases(); const QStringList inUse = suiteConf.usedTestCases();
FancyLineEdit *editor = new FancyLineEdit(parent); FancyLineEdit *editor = new FancyLineEdit(parent);
editor->setValidationFunction([inUse](FancyLineEdit *edit) -> Result<> { editor->setValidationFunction([inUse](const QString &text) -> Result<> {
static const QRegularExpression validFileName("^[-a-zA-Z0-9_$. ]+$"); static const QRegularExpression validFileName("^[-a-zA-Z0-9_$. ]+$");
QString testName = edit->text(); QString testName = text;
if (!testName.startsWith("tst_")) if (!testName.startsWith("tst_"))
testName.prepend("tst_"); testName.prepend("tst_");
if (validFileName.match(testName).hasMatch() && !inUse.contains(testName)) if (validFileName.match(testName).hasMatch() && !inUse.contains(testName))
@@ -137,8 +137,8 @@ static QWidget *sharedScriptEditor(QWidget *parent, const SquishTestTreeItem *it
{ {
const FilePath folder = static_cast<SquishTestTreeItem *>(item->parent())->filePath(); const FilePath folder = static_cast<SquishTestTreeItem *>(item->parent())->filePath();
FancyLineEdit *editor = new FancyLineEdit(parent); FancyLineEdit *editor = new FancyLineEdit(parent);
editor->setValidationFunction([folder](FancyLineEdit *edit) -> Result<> { editor->setValidationFunction([folder](const QString &text) -> Result<> {
if (!edit->text().isEmpty() && !folder.pathAppended(edit->text()).exists()) if (!text.isEmpty() && !folder.pathAppended(text).exists())
return ResultOk; return ResultOk;
return ResultError(QString()); return ResultError(QString());
}); });

View File

@@ -53,10 +53,7 @@ ValidatingContainerNameLineEdit::ValidatingContainerNameLineEdit(const QStringLi
: FancyLineEdit(parent) : FancyLineEdit(parent)
, m_forbidden(forbidden) , m_forbidden(forbidden)
{ {
setValidationFunction([this](FancyLineEdit *edit) -> Result<> { setValidationFunction([this](const QString &value) -> Result<> {
if (!edit)
return ResultError(QString());
const QString &value = edit->text();
if (value.isEmpty()) if (value.isEmpty())
return ResultError(QString()); return ResultError(QString());
const QString realName = value.at(0) == ObjectsMapTreeItem::COLON const QString realName = value.at(0) == ObjectsMapTreeItem::COLON