Skip to content

Commit 666aff7

Browse files
committed
qml: Add validation to Send form address and amount
1 parent c5937dd commit 666aff7

10 files changed

+226
-70
lines changed

src/qml/bitcoinamount.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ class BitcoinAmount : public QObject
3636
qint64 satoshi() const;
3737
void setSatoshi(qint64 new_amount);
3838

39+
bool isSet() const { return m_isSet; }
40+
3941
static QString satsToBtcString(qint64 sat);
4042

4143
public Q_SLOTS:

src/qml/models/sendrecipient.cpp

Lines changed: 66 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
#include <qml/models/sendrecipient.h>
66

77
#include <qml/bitcoinamount.h>
8+
#include <qml/models/walletqmlmodel.h>
89

9-
SendRecipient::SendRecipient(QObject* parent)
10-
: QObject(parent), m_amount(new BitcoinAmount(this))
10+
#include <key_io.h>
11+
12+
SendRecipient::SendRecipient(WalletQmlModel* wallet, QObject* parent)
13+
: QObject(parent), m_wallet(wallet), m_amount(new BitcoinAmount(this))
1114
{
15+
connect(m_amount, &BitcoinAmount::amountChanged, this, &SendRecipient::validateAmount);
1216
}
1317

1418
QString SendRecipient::address() const
@@ -21,6 +25,20 @@ void SendRecipient::setAddress(const QString& address)
2125
if (m_address != address) {
2226
m_address = address;
2327
Q_EMIT addressChanged();
28+
validateAddress();
29+
}
30+
}
31+
32+
QString SendRecipient::addressError() const
33+
{
34+
return m_addressError;
35+
}
36+
37+
void SendRecipient::setAddressError(const QString& error)
38+
{
39+
if (m_addressError != error) {
40+
m_addressError = error;
41+
Q_EMIT addressErrorChanged();
2442
}
2543
}
2644

@@ -42,6 +60,19 @@ BitcoinAmount* SendRecipient::amount() const
4260
return m_amount;
4361
}
4462

63+
QString SendRecipient::amountError() const
64+
{
65+
return m_amountError;
66+
}
67+
68+
void SendRecipient::setAmountError(const QString& error)
69+
{
70+
if (m_amountError != error) {
71+
m_amountError = error;
72+
Q_EMIT amountErrorChanged();
73+
}
74+
}
75+
4576
QString SendRecipient::message() const
4677
{
4778
return m_message;
@@ -77,3 +108,36 @@ void SendRecipient::clear()
77108
Q_EMIT messageChanged();
78109
Q_EMIT amount()->amountChanged();
79110
}
111+
112+
void SendRecipient::validateAddress()
113+
{
114+
setAddressError("");
115+
116+
if (!m_address.isEmpty() && !IsValidDestinationString(m_address.toStdString())) {
117+
setAddressError(tr("Invalid address"));
118+
}
119+
120+
Q_EMIT isValidChanged();
121+
}
122+
123+
void SendRecipient::validateAmount()
124+
{
125+
setAmountError("");
126+
127+
if (m_amount->isSet()) {
128+
if (m_amount->satoshi() <= 0) {
129+
setAmountError(tr("Amount must be greater than zero"));
130+
} else if (m_amount->satoshi() > MAX_MONEY) {
131+
setAmountError(tr("Amount exceeds maximum limit"));
132+
} else if (m_amount->satoshi() > m_wallet->balanceSatoshi()) {
133+
setAmountError(tr("Amount exceeds available balance"));
134+
}
135+
}
136+
137+
Q_EMIT isValidChanged();
138+
}
139+
140+
bool SendRecipient::isValid() const
141+
{
142+
return m_addressError.isEmpty() && m_amountError.isEmpty() && m_amount->satoshi() > 0 && !m_address.isEmpty();
143+
}

src/qml/models/sendrecipient.h

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
#include <QObject>
1111
#include <QString>
1212

13+
class WalletQmlModel;
14+
1315
class SendRecipient : public QObject
1416
{
1517
Q_OBJECT
@@ -18,17 +20,25 @@ class SendRecipient : public QObject
1820
Q_PROPERTY(QString message READ message WRITE setMessage NOTIFY messageChanged)
1921
Q_PROPERTY(BitcoinAmount* amount READ amount CONSTANT)
2022

23+
Q_PROPERTY(QString addressError READ addressError NOTIFY addressErrorChanged)
24+
Q_PROPERTY(QString amountError READ amountError NOTIFY amountErrorChanged)
25+
Q_PROPERTY(bool isValid READ isValid NOTIFY isValidChanged)
26+
2127
public:
22-
explicit SendRecipient(QObject* parent = nullptr);
28+
explicit SendRecipient(WalletQmlModel* wallet, QObject* parent = nullptr);
2329

2430
QString address() const;
2531
void setAddress(const QString& address);
32+
QString addressError() const;
33+
void setAddressError(const QString& error);
2634

2735
QString label() const;
2836
void setLabel(const QString& label);
2937

3038
BitcoinAmount* amount() const;
3139
void setAmount(const QString& amount);
40+
QString amountError() const;
41+
void setAmountError(const QString& error);
3242

3343
QString message() const;
3444
void setMessage(const QString& message);
@@ -37,18 +47,29 @@ class SendRecipient : public QObject
3747

3848
bool subtractFeeFromAmount() const;
3949

50+
bool isValid() const;
51+
4052
Q_INVOKABLE void clear();
4153

4254
Q_SIGNALS:
4355
void addressChanged();
56+
void addressErrorChanged();
57+
void amountErrorChanged();
4458
void labelChanged();
4559
void messageChanged();
60+
void isValidChanged();
4661

4762
private:
63+
void validateAddress();
64+
void validateAmount();
65+
66+
WalletQmlModel* m_wallet;
4867
QString m_address{""};
68+
QString m_addressError{""};
4969
QString m_label{""};
5070
QString m_message{""};
5171
BitcoinAmount* m_amount;
72+
QString m_amountError{""};
5273
bool m_subtractFeeFromAmount{false};
5374
};
5475

src/qml/models/sendrecipientslistmodel.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

55
#include <qml/models/sendrecipientslistmodel.h>
6+
#include <qml/models/walletqmlmodel.h>
67

78
#include <qml/models/sendrecipient.h>
89

910
SendRecipientsListModel::SendRecipientsListModel(QObject* parent)
1011
: QAbstractListModel(parent)
1112
{
12-
auto* recipient = new SendRecipient(this);
13+
m_wallet = qobject_cast<WalletQmlModel*>(parent);
14+
auto* recipient = new SendRecipient(m_wallet, this);
1315
connect(recipient->amount(), &BitcoinAmount::amountChanged,
1416
this, &SendRecipientsListModel::updateTotalAmount);
1517
m_recipients.append(recipient);
@@ -50,7 +52,7 @@ void SendRecipientsListModel::add()
5052
{
5153
const int row = m_recipients.size();
5254
beginInsertRows(QModelIndex(), row, row);
53-
auto* recipient = new SendRecipient(this);
55+
auto* recipient = new SendRecipient(m_wallet, this);
5456
connect(recipient->amount(), &BitcoinAmount::amountChanged,
5557
this, &SendRecipientsListModel::updateTotalAmount);
5658
m_recipients.append(recipient);
@@ -129,7 +131,7 @@ void SendRecipientsListModel::clear()
129131
m_current = 0;
130132
m_totalAmount = 0;
131133

132-
auto* recipient = new SendRecipient(this);
134+
auto* recipient = new SendRecipient(m_wallet, this);
133135
connect(recipient->amount(), &BitcoinAmount::amountChanged,
134136
this, &SendRecipientsListModel::updateTotalAmount);
135137
m_recipients.append(recipient);

src/qml/models/sendrecipientslistmodel.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55
#ifndef BITCOIN_QML_MODELS_SENDRECIPIENTSLISTMODEL_H
66
#define BITCOIN_QML_MODELS_SENDRECIPIENTSLISTMODEL_H
77

8-
#include <qml/models/sendrecipient.h>
9-
108
#include <QAbstractListModel>
11-
#include <QList>
12-
#include <qobjectdefs.h>
9+
10+
class SendRecipient;
11+
class WalletQmlModel;
1312

1413
class SendRecipientsListModel : public QAbstractListModel
1514
{
@@ -56,6 +55,7 @@ class SendRecipientsListModel : public QAbstractListModel
5655
private:
5756
void updateTotalAmount();
5857

58+
WalletQmlModel* m_wallet;
5959
QList<SendRecipient*> m_recipients;
6060
int m_current{0};
6161
qint64 m_totalAmount{0};

src/qml/models/walletqmlmodel.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,14 @@ QString WalletQmlModel::balance() const
5555
return BitcoinUnits::format(BitcoinUnits::Unit::BTC, m_wallet->getBalance());
5656
}
5757

58+
CAmount WalletQmlModel::balanceSatoshi() const
59+
{
60+
if (!m_wallet) {
61+
return 0;
62+
}
63+
return m_wallet->getBalance();
64+
}
65+
5866
QString WalletQmlModel::name() const
5967
{
6068
if (!m_wallet) {

src/qml/models/walletqmlmodel.h

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,21 @@
55
#ifndef BITCOIN_QML_MODELS_WALLETQMLMODEL_H
66
#define BITCOIN_QML_MODELS_WALLETQMLMODEL_H
77

8-
#include <interfaces/handler.h>
9-
#include <interfaces/wallet.h>
108
#include <qml/models/activitylistmodel.h>
119
#include <qml/models/coinslistmodel.h>
1210
#include <qml/models/sendrecipient.h>
1311
#include <qml/models/sendrecipientslistmodel.h>
1412
#include <qml/models/walletqmlmodeltransaction.h>
13+
14+
#include <consensus/amount.h>
15+
#include <interfaces/handler.h>
16+
#include <interfaces/wallet.h>
1517
#include <wallet/coincontrol.h>
1618

17-
#include <QObject>
1819
#include <memory>
1920
#include <vector>
2021

21-
class ActivityListModel;
22+
#include <QObject>
2223

2324
class WalletQmlModel : public QObject
2425
{
@@ -37,6 +38,8 @@ class WalletQmlModel : public QObject
3738

3839
QString name() const;
3940
QString balance() const;
41+
CAmount balanceSatoshi() const;
42+
4043
ActivityListModel* activityListModel() const { return m_activity_list_model; }
4144
CoinsListModel* coinsListModel() const { return m_coins_list_model; }
4245
SendRecipientsListModel* sendRecipientList() const { return m_send_recipients; }

src/qml/models/walletqmlmodeltransaction.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44

55
#include <qml/models/walletqmlmodeltransaction.h>
66

7+
#include <qml/models/sendrecipient.h>
8+
#include <qml/models/sendrecipientslistmodel.h>
9+
710
#include <policy/policy.h>
811

912
WalletQmlModelTransaction::WalletQmlModelTransaction(const SendRecipientsListModel* recipient, QObject* parent)

0 commit comments

Comments
 (0)