Merge pull request #7025

2a8e8c2 [Qt] don't allow to store invalid proxy ports (Jonas Schnelli)
d16d1b7 [Qt] refactor and optimize proxy settings behavior (Jonas Schnelli)
This commit is contained in:
Jonas Schnelli 2015-11-30 09:08:25 +01:00
commit c28d3937b0
No known key found for this signature in database
GPG key ID: 29D4BCB6416F53EC
4 changed files with 65 additions and 53 deletions

View file

@ -34,8 +34,7 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
QDialog(parent), QDialog(parent),
ui(new Ui::OptionsDialog), ui(new Ui::OptionsDialog),
model(0), model(0),
mapper(0), mapper(0)
fProxyIpsValid(true)
{ {
ui->setupUi(this); ui->setupUi(this);
@ -60,12 +59,11 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool))); connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyIp, SLOT(setEnabled(bool)));
connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool))); connect(ui->connectSocks, SIGNAL(toggled(bool)), ui->proxyPort, SLOT(setEnabled(bool)));
connect(ui->connectSocks, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState()));
connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool))); connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyIpTor, SLOT(setEnabled(bool)));
connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool))); connect(ui->connectSocksTor, SIGNAL(toggled(bool)), ui->proxyPortTor, SLOT(setEnabled(bool)));
connect(ui->connectSocksTor, SIGNAL(toggled(bool)), this, SLOT(updateProxyValidationState()));
ui->proxyIp->installEventFilter(this);
ui->proxyIpTor->installEventFilter(this);
/* Window elements init */ /* Window elements init */
#ifdef Q_OS_MAC #ifdef Q_OS_MAC
@ -119,7 +117,12 @@ OptionsDialog::OptionsDialog(QWidget *parent, bool enableWallet) :
mapper->setOrientation(Qt::Vertical); mapper->setOrientation(Qt::Vertical);
/* setup/change UI elements when proxy IPs are invalid/valid */ /* setup/change UI elements when proxy IPs are invalid/valid */
connect(this, SIGNAL(proxyIpChecks(QValidatedLineEdit *, int)), this, SLOT(doProxyIpChecks(QValidatedLineEdit *, int))); ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent));
ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent));
connect(ui->proxyIp, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState()));
connect(ui->proxyIpTor, SIGNAL(validationDidChange(QValidatedLineEdit *)), this, SLOT(updateProxyValidationState()));
connect(ui->proxyPort, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState()));
connect(ui->proxyPortTor, SIGNAL(textChanged(const QString&)), this, SLOT(updateProxyValidationState()));
} }
OptionsDialog::~OptionsDialog() OptionsDialog::~OptionsDialog()
@ -200,18 +203,6 @@ void OptionsDialog::setMapper()
mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls); mapper->addMapping(ui->thirdPartyTxUrls, OptionsModel::ThirdPartyTxUrls);
} }
void OptionsDialog::enableOkButton()
{
/* prevent enabling of the OK button when data modified, if there is an invalid proxy address present */
if(fProxyIpsValid)
setOkButtonState(true);
}
void OptionsDialog::disableOkButton()
{
setOkButtonState(false);
}
void OptionsDialog::setOkButtonState(bool fState) void OptionsDialog::setOkButtonState(bool fState)
{ {
ui->okButton->setEnabled(fState); ui->okButton->setEnabled(fState);
@ -269,24 +260,20 @@ void OptionsDialog::clearStatusLabel()
ui->statusLabel->clear(); ui->statusLabel->clear();
} }
void OptionsDialog::doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort) void OptionsDialog::updateProxyValidationState()
{ {
Q_UNUSED(nProxyPort); QValidatedLineEdit *pUiProxyIp = ui->proxyIp;
QValidatedLineEdit *otherProxyWidget = (pUiProxyIp == ui->proxyIpTor) ? ui->proxyIp : ui->proxyIpTor;
CService addrProxy; if (pUiProxyIp->isValid() && (!ui->proxyPort->isEnabled() || ui->proxyPort->text().toInt() > 0) && (!ui->proxyPortTor->isEnabled() || ui->proxyPortTor->text().toInt() > 0))
/* Check for a valid IPv4 / IPv6 address */
if (!(fProxyIpsValid = LookupNumeric(pUiProxyIp->text().toStdString().c_str(), addrProxy)))
{ {
disableOkButton(); setOkButtonState(otherProxyWidget->isValid()); //only enable ok button if both proxys are valid
pUiProxyIp->setValid(false); ui->statusLabel->clear();
ui->statusLabel->setStyleSheet("QLabel { color: red; }");
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
} }
else else
{ {
enableOkButton(); setOkButtonState(false);
ui->statusLabel->clear(); ui->statusLabel->setStyleSheet("QLabel { color: red; }");
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
} }
} }
@ -312,18 +299,18 @@ void OptionsDialog::updateDefaultProxyNets()
(strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false); (strProxy == strDefaultProxyGUI.toStdString()) ? ui->proxyReachTor->setChecked(true) : ui->proxyReachTor->setChecked(false);
} }
bool OptionsDialog::eventFilter(QObject *object, QEvent *event) ProxyAddressValidator::ProxyAddressValidator(QObject *parent) :
QValidator(parent)
{ {
if(event->type() == QEvent::FocusOut) }
{
if(object == ui->proxyIp) QValidator::State ProxyAddressValidator::validate(QString &input, int &pos) const
{ {
Q_EMIT proxyIpChecks(ui->proxyIp, ui->proxyPort->text().toInt()); Q_UNUSED(pos);
} // Validate the proxy
else if(object == ui->proxyIpTor) proxyType addrProxy = proxyType(CService(input.toStdString(), 9050), true);
{ if (addrProxy.IsValid())
Q_EMIT proxyIpChecks(ui->proxyIpTor, ui->proxyPortTor->text().toInt()); return QValidator::Acceptable;
}
} return QValidator::Invalid;
return QDialog::eventFilter(object, event);
} }

View file

@ -6,6 +6,7 @@
#define BITCOIN_QT_OPTIONSDIALOG_H #define BITCOIN_QT_OPTIONSDIALOG_H
#include <QDialog> #include <QDialog>
#include <QValidator>
class OptionsModel; class OptionsModel;
class QValidatedLineEdit; class QValidatedLineEdit;
@ -18,6 +19,18 @@ namespace Ui {
class OptionsDialog; class OptionsDialog;
} }
/** Proxy address widget validator, checks for a valid proxy address.
*/
class ProxyAddressValidator : public QValidator
{
Q_OBJECT
public:
explicit ProxyAddressValidator(QObject *parent);
State validate(QString &input, int &pos) const;
};
/** Preferences dialog. */ /** Preferences dialog. */
class OptionsDialog : public QDialog class OptionsDialog : public QDialog
{ {
@ -30,14 +43,7 @@ public:
void setModel(OptionsModel *model); void setModel(OptionsModel *model);
void setMapper(); void setMapper();
protected:
bool eventFilter(QObject *object, QEvent *event);
private Q_SLOTS: private Q_SLOTS:
/* enable OK button */
void enableOkButton();
/* disable OK button */
void disableOkButton();
/* set OK button state (enabled / disabled) */ /* set OK button state (enabled / disabled) */
void setOkButtonState(bool fState); void setOkButtonState(bool fState);
void on_resetButton_clicked(); void on_resetButton_clicked();
@ -46,7 +52,7 @@ private Q_SLOTS:
void showRestartWarning(bool fPersistent = false); void showRestartWarning(bool fPersistent = false);
void clearStatusLabel(); void clearStatusLabel();
void doProxyIpChecks(QValidatedLineEdit *pUiProxyIp, int nProxyPort); void updateProxyValidationState();
/* query the networks, for which the default proxy is used */ /* query the networks, for which the default proxy is used */
void updateDefaultProxyNets(); void updateDefaultProxyNets();
@ -57,7 +63,6 @@ private:
Ui::OptionsDialog *ui; Ui::OptionsDialog *ui;
OptionsModel *model; OptionsModel *model;
QDataWidgetMapper *mapper; QDataWidgetMapper *mapper;
bool fProxyIpsValid;
}; };
#endif // BITCOIN_QT_OPTIONSDIALOG_H #endif // BITCOIN_QT_OPTIONSDIALOG_H

View file

@ -99,9 +99,25 @@ void QValidatedLineEdit::checkValidity()
} }
else else
setValid(false); setValid(false);
Q_EMIT validationDidChange(this);
} }
void QValidatedLineEdit::setCheckValidator(const QValidator *v) void QValidatedLineEdit::setCheckValidator(const QValidator *v)
{ {
checkValidator = v; checkValidator = v;
} }
bool QValidatedLineEdit::isValid()
{
// use checkValidator in case the QValidatedLineEdit is disabled
if (checkValidator)
{
QString address = text();
int pos = 0;
if (checkValidator->validate(address, pos) == QValidator::Acceptable)
return true;
}
return valid;
}

View file

@ -18,6 +18,7 @@ public:
explicit QValidatedLineEdit(QWidget *parent); explicit QValidatedLineEdit(QWidget *parent);
void clear(); void clear();
void setCheckValidator(const QValidator *v); void setCheckValidator(const QValidator *v);
bool isValid();
protected: protected:
void focusInEvent(QFocusEvent *evt); void focusInEvent(QFocusEvent *evt);
@ -31,6 +32,9 @@ public Q_SLOTS:
void setValid(bool valid); void setValid(bool valid);
void setEnabled(bool enabled); void setEnabled(bool enabled);
Q_SIGNALS:
void validationDidChange(QValidatedLineEdit *validatedLineEdit);
private Q_SLOTS: private Q_SLOTS:
void markValid(); void markValid();
void checkValidity(); void checkValidity();