Merge g537 via gui_bech32_errpos-26+knots

This commit is contained in:
Luke Dashjr 2024-03-25 17:26:53 +00:00
commit 3d011a8ac6
4 changed files with 63 additions and 17 deletions

View File

@ -6,6 +6,8 @@
#include <key_io.h> #include <key_io.h>
#include <vector>
/* Base58 characters are: /* Base58 characters are:
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz" "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"
@ -20,10 +22,8 @@ BitcoinAddressEntryValidator::BitcoinAddressEntryValidator(QObject *parent) :
{ {
} }
QValidator::State BitcoinAddressEntryValidator::validate(QString &input, int &pos) const QValidator::State BitcoinAddressEntryValidator::validate(QString &input, std::vector<int>&error_locations) const
{ {
Q_UNUSED(pos);
// Empty address is "intermediate" input // Empty address is "intermediate" input
if (input.isEmpty()) if (input.isEmpty())
return QValidator::Intermediate; return QValidator::Intermediate;
@ -73,6 +73,7 @@ QValidator::State BitcoinAddressEntryValidator::validate(QString &input, int &po
} }
else else
{ {
error_locations.push_back(idx);
state = QValidator::Invalid; state = QValidator::Invalid;
} }
} }
@ -80,16 +81,25 @@ QValidator::State BitcoinAddressEntryValidator::validate(QString &input, int &po
return state; return state;
} }
QValidator::State BitcoinAddressEntryValidator::validate(QString &input, int &pos) const
{
std::vector<int> error_locations;
const auto ret = validate(input, error_locations);
if (!error_locations.empty()) pos = error_locations.at(0);
return ret;
}
BitcoinAddressCheckValidator::BitcoinAddressCheckValidator(QObject *parent) : BitcoinAddressCheckValidator::BitcoinAddressCheckValidator(QObject *parent) :
QValidator(parent) BitcoinAddressEntryValidator(parent)
{ {
} }
QValidator::State BitcoinAddressCheckValidator::validate(QString &input, int &pos) const QValidator::State BitcoinAddressCheckValidator::validate(QString &input, std::vector<int>&error_locations) const
{ {
Q_UNUSED(pos);
// Validate the passed Bitcoin address // Validate the passed Bitcoin address
if (IsValidDestinationString(input.toStdString())) { std::string error_msg;
CTxDestination dest = DecodeDestination(input.toStdString(), error_msg, &error_locations);
if (IsValidDestination(dest)) {
return QValidator::Acceptable; return QValidator::Acceptable;
} }

View File

@ -7,6 +7,8 @@
#include <QValidator> #include <QValidator>
#include <vector>
/** Base58 entry widget validator, checks for valid characters and /** Base58 entry widget validator, checks for valid characters and
* removes some whitespace. * removes some whitespace.
*/ */
@ -17,19 +19,20 @@ class BitcoinAddressEntryValidator : public QValidator
public: public:
explicit BitcoinAddressEntryValidator(QObject *parent); explicit BitcoinAddressEntryValidator(QObject *parent);
State validate(QString &input, int &pos) const override; virtual State validate(QString &input, std::vector<int>&error_locations) const;
virtual State validate(QString &input, int &pos) const override;
}; };
/** Bitcoin address widget validator, checks for a valid bitcoin address. /** Bitcoin address widget validator, checks for a valid bitcoin address.
*/ */
class BitcoinAddressCheckValidator : public QValidator class BitcoinAddressCheckValidator : public BitcoinAddressEntryValidator
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit BitcoinAddressCheckValidator(QObject *parent); explicit BitcoinAddressCheckValidator(QObject *parent);
State validate(QString &input, int &pos) const override; State validate(QString &input, std::vector<int>&error_locations) const override;
}; };
#endif // BITCOIN_QT_BITCOINADDRESSVALIDATOR_H #endif // BITCOIN_QT_BITCOINADDRESSVALIDATOR_H

View File

@ -7,6 +7,13 @@
#include <qt/bitcoinaddressvalidator.h> #include <qt/bitcoinaddressvalidator.h>
#include <qt/guiconstants.h> #include <qt/guiconstants.h>
#include <QColor>
#include <QCoreApplication>
#include <QFont>
#include <QInputMethodEvent>
#include <QList>
#include <QTextCharFormat>
QValidatedLineEdit::QValidatedLineEdit(QWidget* parent) QValidatedLineEdit::QValidatedLineEdit(QWidget* parent)
: QLineEdit(parent) : QLineEdit(parent)
{ {
@ -24,15 +31,17 @@ void QValidatedLineEdit::setText(const QString& text)
checkValidity(); checkValidity();
} }
void QValidatedLineEdit::setValid(bool _valid, bool with_warning) void QValidatedLineEdit::setValid(bool _valid, bool with_warning, const std::vector<int>&error_locations)
{ {
if(_valid == this->valid) if(_valid && this->valid)
{ {
if (with_warning == m_has_warning || !valid) { if (with_warning == m_has_warning) {
return; return;
} }
} }
QList<QInputMethodEvent::Attribute> attributes;
if(_valid) if(_valid)
{ {
m_has_warning = with_warning; m_has_warning = with_warning;
@ -45,7 +54,22 @@ void QValidatedLineEdit::setValid(bool _valid, bool with_warning)
else else
{ {
setStyleSheet("QValidatedLineEdit { " STYLE_INVALID "}"); setStyleSheet("QValidatedLineEdit { " STYLE_INVALID "}");
if (!error_locations.empty()) {
QTextCharFormat format;
format.setFontUnderline(true);
format.setUnderlineStyle(QTextCharFormat::SpellCheckUnderline);
format.setUnderlineColor(Qt::yellow);
format.setForeground(Qt::yellow);
format.setFontWeight(QFont::Bold);
for (auto error_pos : error_locations) {
attributes.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, error_pos - cursorPosition(), /*length=*/ 1, format));
}
}
} }
QInputMethodEvent event(QString(), attributes);
QCoreApplication::sendEvent(this, &event);
this->valid = _valid; this->valid = _valid;
} }
@ -107,11 +131,20 @@ void QValidatedLineEdit::checkValidity()
if (checkValidator) if (checkValidator)
{ {
QString address = text(); QString address = text();
int pos = 0; QValidator::State validation_result;
if (checkValidator->validate(address, pos) == QValidator::Acceptable) std::vector<int> error_locations;
const BitcoinAddressEntryValidator * const address_validator = dynamic_cast<const BitcoinAddressEntryValidator*>(checkValidator);
if (address_validator) {
validation_result = address_validator->validate(address, error_locations);
} else {
int pos = 0;
validation_result = checkValidator->validate(address, pos);
error_locations.push_back(pos);
}
if (validation_result == QValidator::Acceptable)
setValid(true, has_warning); setValid(true, has_warning);
else else
setValid(false); setValid(/* valid= */ false, /* with_warning= */ false, error_locations);
} }
} }
else else

View File

@ -35,7 +35,7 @@ private:
public Q_SLOTS: public Q_SLOTS:
void setText(const QString&); void setText(const QString&);
void setValid(bool valid, bool with_warning=false); void setValid(bool valid, bool with_warning=false, const std::vector<int>&error_locations=std::vector<int>());
void setEnabled(bool enabled); void setEnabled(bool enabled);
Q_SIGNALS: Q_SIGNALS: