Git: Add input validation to RemoteAdditionDialog

Use FancyLineEdits to indicate invalid inputs for
remote names and URLs.

For remote names:
* Check for duplicate remote names and indicate these
* Remove invalid chars during input

For remote URLs:
* Check if the input matches a valid URL or
  existing local directory

Task-number: QTCREATORBUG-15998
Change-Id: I224e669f16e34e2cd3d075c602b431ce5bbdd391
Reviewed-by: Orgad Shaneh <orgads@gmail.com>
This commit is contained in:
Andre Hartmann
2017-03-04 17:38:12 +01:00
committed by André Hartmann
parent b0ac6435b3
commit 209cc21434
4 changed files with 68 additions and 4 deletions

View File

@@ -22,7 +22,7 @@
</widget>
</item>
<item row="0" column="1">
<widget class="QLineEdit" name="nameEdit"/>
<widget class="Utils::FancyLineEdit" name="nameEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="urlLabel">
@@ -32,7 +32,7 @@
</widget>
</item>
<item row="1" column="1">
<widget class="QLineEdit" name="urlEdit"/>
<widget class="Utils::FancyLineEdit" name="urlEdit"/>
</item>
<item row="2" column="0" colspan="2">
<widget class="QDialogButtonBox" name="buttonBox">
@@ -46,6 +46,13 @@
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Utils::FancyLineEdit</class>
<extends>QLineEdit</extends>
<header location="global">utils/fancylineedit.h</header>
</customwidget>
</customwidgets>
<resources/>
<connections>
<connection>

View File

@@ -31,10 +31,12 @@
#include "ui_remotedialog.h"
#include "ui_remoteadditiondialog.h"
#include <utils/fancylineedit.h>
#include <utils/headerviewstretcher.h>
#include <vcsbase/vcsoutputwindow.h>
#include <QMessageBox>
#include <QRegularExpression>
namespace Git {
namespace Internal {
@@ -46,10 +48,55 @@ namespace Internal {
class RemoteAdditionDialog : public QDialog
{
public:
RemoteAdditionDialog()
RemoteAdditionDialog(const QStringList &remoteNames) :
m_invalidRemoteNameChars(GitPlugin::invalidBranchAndRemoteNamePattern()),
m_remoteNames(remoteNames)
{
m_ui.setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
m_ui.nameEdit->setValidationFunction([this](Utils::FancyLineEdit *edit, QString *errorMessage) {
if (!edit)
return false;
QString input = edit->text();
edit->setText(input.replace(m_invalidRemoteNameChars, "_"));
// "Intermediate" patterns, may change to Acceptable when user edits further:
if (input.endsWith(".lock")) //..may not end with ".lock"
return false;
if (input.endsWith('.')) // no dot at the end (but allowed in the middle)
return false;
if (input.endsWith('/')) // no slash at the end (but allowed in the middle)
return false;
if (m_remoteNames.contains(input)) {
if (errorMessage)
*errorMessage = tr("A remote with the name \"%1\" already exists.").arg(input);
return false;
}
// is a valid remote name
return !input.isEmpty();
});
connect(m_ui.nameEdit, &QLineEdit::textChanged, [this]() {
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(m_ui.nameEdit->isValid());
});
m_ui.urlEdit->setValidationFunction([](Utils::FancyLineEdit *edit, QString *errorMessage) {
if (!edit || edit->text().isEmpty())
return false;
const GitRemote r(edit->text());
if (!r.isValid && errorMessage)
*errorMessage = tr("The URL may not be valid.");
return r.isValid;
});
m_ui.buttonBox->button(QDialogButtonBox::Ok)->setEnabled(false);
}
QString remoteName() const
@@ -64,6 +111,8 @@ public:
private:
Ui::RemoteAdditionDialog m_ui;
const QRegularExpression m_invalidRemoteNameChars;
QStringList m_remoteNames;
};
@@ -125,7 +174,7 @@ void RemoteDialog::refreshRemotes()
void RemoteDialog::addRemote()
{
RemoteAdditionDialog addDialog;
RemoteAdditionDialog addDialog(m_remoteModel->allRemoteNames());
if (addDialog.exec() != QDialog::Accepted)
return;

View File

@@ -27,6 +27,8 @@
#include "gitplugin.h"
#include "gitclient.h"
#include <utils/algorithm.h>
namespace Git {
namespace Internal {
@@ -34,6 +36,11 @@ namespace Internal {
RemoteModel::RemoteModel(QObject *parent) : QAbstractTableModel(parent)
{ }
QStringList RemoteModel::allRemoteNames() const
{
return Utils::transform(m_remotes, std::mem_fn(&Remote::name));
}
QString RemoteModel::remoteName(int row) const
{
return m_remotes.at(row).name;

View File

@@ -42,6 +42,7 @@ public:
void clear();
bool refresh(const QString &workingDirectory, QString *errorMessage);
QStringList allRemoteNames() const;
QString remoteName(int row) const;
QString remoteUrl(int row) const;