Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/qt/forms/optionsdialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@
</widget>
</item>
<item>
<widget class="QLineEdit" name="proxyPort">
<widget class="QValidatedLineEdit" name="proxyPort">
<property name="minimumSize">
<size>
<width>55</width>
Expand Down Expand Up @@ -660,7 +660,7 @@
</widget>
</item>
<item>
<widget class="QLineEdit" name="proxyPortTor">
<widget class="QValidatedLineEdit" name="proxyPortTor">
<property name="minimumSize">
<size>
<width>55</width>
Expand Down
111 changes: 95 additions & 16 deletions src/qt/optionsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,13 +278,33 @@ OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet)
ui->proxyPortTor->setEnabled(false);
ui->proxyPortTor->setValidator(new QIntValidator(1, 65535, this));

connect(ui->connectSocks, &QPushButton::toggled, ui->proxyIp, &QWidget::setEnabled);
connect(ui->connectSocks, &QPushButton::toggled, ui->proxyPort, &QWidget::setEnabled);
connect(ui->connectSocks, &QPushButton::toggled, this, &OptionsDialog::updateProxyValidationState);

connect(ui->connectSocksTor, &QPushButton::toggled, ui->proxyIpTor, &QWidget::setEnabled);
connect(ui->connectSocksTor, &QPushButton::toggled, ui->proxyPortTor, &QWidget::setEnabled);
connect(ui->connectSocksTor, &QPushButton::toggled, this, &OptionsDialog::updateProxyValidationState);
#if (QT_VERSION >= QT_VERSION_CHECK(6, 7, 0))
connect(ui->connectSocks, &QCheckBox::checkStateChanged, [this](const Qt::CheckState state){
const bool enabled = (state == Qt::Checked);
ui->proxyIp->setEnabled(enabled);
ui->proxyPort->setEnabled(enabled);
updateProxyValidationState();
});
connect(ui->connectSocksTor, &QCheckBox::checkStateChanged, [this](const Qt::CheckState state){
const bool enabled = (state == Qt::Checked);
ui->proxyIpTor->setEnabled(enabled);
ui->proxyPortTor->setEnabled(enabled);
updateProxyValidationState();
});
#else
connect(ui->connectSocks, &QCheckBox::stateChanged, [this](int state){
const bool enabled = (state == Qt::Checked);
ui->proxyIp->setEnabled(enabled);
ui->proxyPort->setEnabled(enabled);
updateProxyValidationState();
});
connect(ui->connectSocksTor, &QCheckBox::stateChanged, [this](int state){
const bool enabled = (state == Qt::Checked);
ui->proxyIpTor->setEnabled(enabled);
ui->proxyPortTor->setEnabled(enabled);
updateProxyValidationState();
});
#endif

ui->maxuploadtarget->setMinimum(144 /* MiB/day */);
ui->maxuploadtarget->setMaximum(std::numeric_limits<int>::max());
Expand Down Expand Up @@ -720,10 +740,23 @@ OptionsDialog::OptionsDialog(QWidget* parent, bool enableWallet)
/* setup/change UI elements when proxy IPs are invalid/valid */
ui->proxyIp->setCheckValidator(new ProxyAddressValidator(parent));
ui->proxyIpTor->setCheckValidator(new ProxyAddressValidator(parent));

// do not allow empty input for validation for all proxy fields
ui->proxyIp->setAllowEmptyInput(false);
ui->proxyIpTor->setAllowEmptyInput(false);
ui->proxyPort->setAllowEmptyInput(false);
ui->proxyPortTor->setAllowEmptyInput(false);

// Enable validation while typing for all proxy fields
ui->proxyIp->setAllowValidationWhileEditing(true);
ui->proxyPort->setAllowValidationWhileEditing(true);
ui->proxyIpTor->setAllowValidationWhileEditing(true);
ui->proxyPortTor->setAllowValidationWhileEditing(true);

connect(ui->proxyIp, &QValidatedLineEdit::validationDidChange, this, &OptionsDialog::updateProxyValidationState);
connect(ui->proxyIpTor, &QValidatedLineEdit::validationDidChange, this, &OptionsDialog::updateProxyValidationState);
connect(ui->proxyPort, &QLineEdit::textChanged, this, &OptionsDialog::updateProxyValidationState);
connect(ui->proxyPortTor, &QLineEdit::textChanged, this, &OptionsDialog::updateProxyValidationState);
connect(ui->proxyPort, &QValidatedLineEdit::validationDidChange, this, &OptionsDialog::updateProxyValidationState);
connect(ui->proxyPortTor, &QValidatedLineEdit::validationDidChange, this, &OptionsDialog::updateProxyValidationState);

if (!QSystemTrayIcon::isSystemTrayAvailable()) {
ui->showTrayIcon->setChecked(false);
Expand Down Expand Up @@ -1152,6 +1185,16 @@ void OptionsDialog::on_okButton_clicked()
model->setData(model->index(OptionsModel::dustdynamic, 0), "off");
}

// Before mapper->submit()
if (!ui->connectSocks->isChecked()) {
ui->proxyIp->clear();
ui->proxyPort->clear();
}
if (!ui->connectSocksTor->isChecked()) {
ui->proxyIpTor->clear();
ui->proxyPortTor->clear();
}

mapper->submit();
accept();
updateDefaultProxyNets();
Expand All @@ -1174,11 +1217,13 @@ void OptionsDialog::on_showTrayIcon_stateChanged(int state)

void OptionsDialog::changeEvent(QEvent* e)
{
// First let the base class update all child widget palettes
// required for qvalidatedlineedit invalid colors to update properly
QWidget::changeEvent(e);
if (e->type() == QEvent::PaletteChange) {
// Then update theme colors with the new palette
updateThemeColors();
}

QWidget::changeEvent(e);
}

void OptionsDialog::togglePruneWarning(bool enabled)
Expand Down Expand Up @@ -1211,17 +1256,51 @@ void OptionsDialog::clearStatusLabel()

void OptionsDialog::updateProxyValidationState()
{
QValidatedLineEdit *pUiProxyIp = ui->proxyIp;
QValidatedLineEdit *otherProxyWidget = (pUiProxyIp == ui->proxyIpTor) ? ui->proxyIp : ui->proxyIpTor;
if (pUiProxyIp->isValid() && (!ui->proxyPort->isEnabled() || ui->proxyPort->text().toInt() > 0) && (!ui->proxyPortTor->isEnabled() || ui->proxyPortTor->text().toInt() > 0))
bool socksProxyEnabled = ui->connectSocks->isChecked();
bool torProxyEnabled = ui->connectSocksTor->isChecked();

bool proxyIpValid = ui->proxyIp->isValid();
bool proxyPortValid = ui->proxyPort->isValid();
bool proxyIpTorValid = ui->proxyIpTor->isValid();
bool proxyPortTorValid = ui->proxyPortTor->isValid();

// proxy is OK if: disabled OR (enabled AND valid ip and valid port)
bool socksProxyOk = !socksProxyEnabled || (proxyIpValid && proxyPortValid);
bool torProxyOk = !torProxyEnabled || (proxyIpTorValid && proxyPortTorValid);

// Both must be OK for the form to be valid
if (socksProxyOk && torProxyOk)
{
setOkButtonState(otherProxyWidget->isValid()); //only enable ok button if both proxies are valid
setOkButtonState(true);
clearStatusLabel();
}
else
{
setOkButtonState(false);
ui->statusLabel->setText(tr("The supplied proxy address is invalid."));
QStringList socksErrors;

if (socksProxyEnabled) {
if (!proxyIpValid && !proxyPortValid) {
socksErrors.append(tr("The supplied proxy address and port are invalid."));
} else if (!proxyIpValid) {
socksErrors.append(tr("The supplied proxy address is invalid."));
} else if (!proxyPortValid) {
socksErrors.append(tr("The supplied proxy port is invalid."));
}
}
if (torProxyEnabled) {
if (!proxyIpTorValid && !proxyPortTorValid) {
socksErrors.append(tr("The supplied Tor proxy address and port are invalid."));
} else if (!proxyIpTorValid) {
socksErrors.append(tr("The supplied Tor proxy address is invalid."));
} else if (!proxyPortTorValid) {
socksErrors.append(tr("The supplied Tor proxy port is invalid."));
}
}

if (socksErrors.size() > 0) {
ui->statusLabel->setText(socksErrors.join(" "));
}
}
}

Expand Down
36 changes: 32 additions & 4 deletions src/qt/qvalidatedlineedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@

#include <QColor>
#include <QCoreApplication>
#include <QEvent>
#include <QFocusEvent>
#include <QFont>
#include <QInputMethodEvent>
#include <QList>
#include <QTextCharFormat>
#include <QValidator>

QValidatedLineEdit::QValidatedLineEdit(QWidget* parent)
: QLineEdit(parent)
Expand Down Expand Up @@ -92,8 +95,13 @@ void QValidatedLineEdit::setValid(bool _valid, bool with_warning, const std::vec

void QValidatedLineEdit::focusInEvent(QFocusEvent *evt)
{
// Clear invalid flag on focus
setValid(true);
if (!m_allow_validation_while_editing) {
// Clear invalid flag on focus for normal fields
setValid(true);
} else {
// For validation-while-editing fields, recheck validity
checkValidity();
}

QLineEdit::focusInEvent(evt);
}
Expand All @@ -105,10 +113,27 @@ void QValidatedLineEdit::focusOutEvent(QFocusEvent *evt)
QLineEdit::focusOutEvent(evt);
}

void QValidatedLineEdit::changeEvent(QEvent *e)
{
if (e->type() == QEvent::PaletteChange) {
if (!valid) {
// Refresh styling using setValid function
setValid(valid);
}
}

QLineEdit::changeEvent(e);
}

void QValidatedLineEdit::markValid()
{
// As long as a user is typing ensure we display state as valid
setValid(true);
// unless we're validating while editing
if (m_allow_validation_while_editing) {
checkValidity();
} else {
setValid(true);
}
}

void QValidatedLineEdit::clear()
Expand All @@ -122,6 +147,9 @@ void QValidatedLineEdit::setEnabled(bool enabled)
if (!enabled)
{
// A disabled QValidatedLineEdit should be marked valid
// Clear focus first to trigger focusOutEvent
// required to properly clear invalid visual state
if (hasFocus()) { clearFocus(); }
setValid(true);
}
else
Expand All @@ -138,7 +166,7 @@ void QValidatedLineEdit::checkValidity()
const bool has_warning = checkWarning();
if (text().isEmpty())
{
setValid(true);
setValid(m_allow_empty_input);
}
else if (hasAcceptableInput())
{
Expand Down
11 changes: 11 additions & 0 deletions src/qt/qvalidatedlineedit.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@

#include <QLineEdit>

QT_BEGIN_NAMESPACE
class QEvent;
class QFocusEvent;
class QValidator;
QT_END_NAMESPACE

/** Line edit that can be marked as "invalid" to show input validation feedback. When marked as invalid,
it will get a red background until it is focused.
*/
Expand All @@ -22,16 +28,21 @@ class QValidatedLineEdit : public QLineEdit
bool isValid();
void setWarningValidator(const QValidator *);
bool hasWarning() const;
void setAllowEmptyInput(bool allow) { m_allow_empty_input = allow; }
void setAllowValidationWhileEditing(bool allow) { m_allow_validation_while_editing = allow; }

protected:
void focusInEvent(QFocusEvent *evt) override;
void focusOutEvent(QFocusEvent *evt) override;
void changeEvent(QEvent *e) override;

private:
bool valid{true};
const QValidator* checkValidator{nullptr};
bool m_has_warning{false};
const QValidator *m_warning_validator{nullptr};
bool m_allow_empty_input{true};
bool m_allow_validation_while_editing{false};

public Q_SLOTS:
void setText(const QString&);
Expand Down
13 changes: 0 additions & 13 deletions src/qt/signverifymessagedialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -327,19 +327,6 @@ void SignVerifyMessageDialog::updateThemeColors()
// Update status labels
updateStatusLabelColor(ui->statusLabel_SM);
updateStatusLabelColor(ui->statusLabel_VM);

// Re-trigger validation on all input fields to update their styling
// including background and text color
// Use setText to trigger validation
if (ui->addressIn_SM) {
ui->addressIn_SM->setText(ui->addressIn_SM->text());
}
if (ui->addressIn_VM) {
ui->addressIn_VM->setText(ui->addressIn_VM->text());
}
if (ui->signatureIn_VM) {
ui->signatureIn_VM->setText(ui->signatureIn_VM->text());
}
}

void SignVerifyMessageDialog::updateStatusLabelColor(QLabel* label)
Expand Down