Skip to content

Commit 9f4411c

Browse files
committed
qml: Introduce BitcoinAmount
BitcoinAmount is a helper object can be used to manage inputs in sats or btc.
1 parent b2d8c7b commit 9f4411c

File tree

4 files changed

+184
-0
lines changed

4 files changed

+184
-0
lines changed

src/Makefile.qt.include

+3
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ QT_MOC_CPP = \
4646
qml/models/moc_walletlistmodel.cpp \
4747
qml/models/moc_walletqmlmodel.cpp \
4848
qml/moc_appmode.cpp \
49+
qml/moc_bitcoinamount.cpp \
4950
qml/moc_walletqmlcontroller.cpp \
5051
qt/moc_addressbookpage.cpp \
5152
qt/moc_addresstablemodel.cpp \
@@ -130,6 +131,7 @@ BITCOIN_QT_H = \
130131
qml/models/walletqmlmodel.h \
131132
qml/appmode.h \
132133
qml/bitcoin.h \
134+
qml/bitcoinamount.h \
133135
qml/guiconstants.h \
134136
qml/imageprovider.h \
135137
qml/util.h \
@@ -310,6 +312,7 @@ BITCOIN_QT_WALLET_CPP = \
310312

311313
BITCOIN_QML_BASE_CPP = \
312314
qml/bitcoin.cpp \
315+
qml/bitcoinamount.cpp \
313316
qml/components/blockclockdial.cpp \
314317
qml/controls/linegraph.cpp \
315318
qml/models/chainmodel.cpp \

src/qml/bitcoin.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include <node/interface_ui.h>
1616
#include <noui.h>
1717
#include <qml/appmode.h>
18+
#include <qml/bitcoinamount.h>
1819
#ifdef __ANDROID__
1920
#include <qml/androidnotifier.h>
2021
#endif
@@ -330,6 +331,7 @@ int QmlGuiMain(int argc, char* argv[])
330331
qmlRegisterType<BlockClockDial>("org.bitcoincore.qt", 1, 0, "BlockClockDial");
331332
qmlRegisterType<LineGraph>("org.bitcoincore.qt", 1, 0, "LineGraph");
332333
qmlRegisterUncreatableType<PeerDetailsModel>("org.bitcoincore.qt", 1, 0, "PeerDetailsModel", "");
334+
qmlRegisterType<BitcoinAmount>("org.bitcoincore.qt", 1, 0, "BitcoinAmount");
333335

334336
#ifdef ENABLE_WALLET
335337
qmlRegisterUncreatableType<WalletQmlModel>("org.bitcoincore.qt", 1, 0, "WalletQmlModel",

src/qml/bitcoinamount.cpp

+127
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
// Copyright (c) 2024 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#include <qml/bitcoinamount.h>
6+
7+
#include <QRegExp>
8+
#include <QStringList>
9+
10+
11+
BitcoinAmount::BitcoinAmount(QObject *parent) : QObject(parent)
12+
{
13+
m_unit = Unit::BTC;
14+
}
15+
16+
int BitcoinAmount::decimals(Unit unit)
17+
{
18+
switch (unit) {
19+
case Unit::BTC: return 8;
20+
case Unit::SAT: return 0;
21+
} // no default case, so the compiler can warn about missing cases
22+
assert(false);
23+
}
24+
25+
QString BitcoinAmount::sanitize(const QString &text)
26+
{
27+
QString result = text;
28+
29+
// Remove any invalid characters
30+
result.remove(QRegExp("[^0-9.]"));
31+
32+
// Ensure only one decimal point
33+
QStringList parts = result.split('.');
34+
if (parts.size() > 2) {
35+
result = parts[0] + "." + parts[1];
36+
}
37+
38+
// Limit decimal places to 8
39+
if (parts.size() == 2 && parts[1].length() > 8) {
40+
result = parts[0] + "." + parts[1].left(8);
41+
}
42+
43+
return result;
44+
}
45+
46+
BitcoinAmount::Unit BitcoinAmount::unit() const
47+
{
48+
return m_unit;
49+
}
50+
51+
void BitcoinAmount::setUnit(const Unit unit)
52+
{
53+
m_unit = unit;
54+
Q_EMIT unitChanged();
55+
}
56+
57+
QString BitcoinAmount::unitLabel() const
58+
{
59+
switch (m_unit) {
60+
case Unit::BTC: return "";
61+
case Unit::SAT: return "Sat";
62+
}
63+
assert(false);
64+
}
65+
66+
QString BitcoinAmount::amount() const
67+
{
68+
return m_amount;
69+
}
70+
71+
void BitcoinAmount::setAmount(const QString& new_amount)
72+
{
73+
m_amount = sanitize(new_amount);
74+
Q_EMIT amountChanged();
75+
}
76+
77+
long long BitcoinAmount::toSatoshis(QString& amount, const Unit unit)
78+
{
79+
80+
int num_decimals = decimals(unit);
81+
82+
QStringList parts = amount.remove(' ').split(".");
83+
84+
QString whole = parts[0];
85+
QString decimals;
86+
87+
if(parts.size() > 1)
88+
{
89+
decimals = parts[1];
90+
}
91+
QString str = whole + decimals.leftJustified(num_decimals, '0', true);
92+
93+
return str.toLongLong();
94+
}
95+
96+
QString BitcoinAmount::convert(const QString &amount, Unit unit)
97+
{
98+
if (amount == "") {
99+
return amount;
100+
}
101+
102+
QString result = amount;
103+
int decimalPosition = result.indexOf(".");
104+
105+
if (decimalPosition == -1) {
106+
decimalPosition = result.length();
107+
result.append(".");
108+
}
109+
110+
if (unit == Unit::BTC) {
111+
int numDigitsAfterDecimal = result.length() - decimalPosition - 1;
112+
if (numDigitsAfterDecimal < 8) {
113+
result.append(QString(8 - numDigitsAfterDecimal, '0'));
114+
}
115+
result.remove(decimalPosition, 1);
116+
} else if (unit == Unit::SAT) {
117+
result.remove(decimalPosition, 1);
118+
int newDecimalPosition = decimalPosition - 8;
119+
if (newDecimalPosition < 1) {
120+
result = QString("0").repeated(-newDecimalPosition) + result;
121+
newDecimalPosition = 0;
122+
}
123+
result.insert(newDecimalPosition, ".");
124+
}
125+
126+
return result;
127+
}

src/qml/bitcoinamount.h

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2024 The Bitcoin Core developers
2+
// Distributed under the MIT software license, see the accompanying
3+
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4+
5+
#ifndef BITCOIN_QML_BITCOINAMOUNT_H
6+
#define BITCOIN_QML_BITCOINAMOUNT_H
7+
8+
#include <QObject>
9+
#include <QString>
10+
#include <qobjectdefs.h>
11+
12+
class BitcoinAmount : public QObject
13+
{
14+
Q_OBJECT
15+
Q_PROPERTY(Unit unit READ unit WRITE setUnit NOTIFY unitChanged)
16+
Q_PROPERTY(QString unitLabel READ unitLabel NOTIFY unitChanged)
17+
Q_PROPERTY(QString amount READ amount WRITE setAmount NOTIFY amountChanged)
18+
19+
public:
20+
enum class Unit {
21+
BTC,
22+
SAT
23+
};
24+
Q_ENUM(Unit)
25+
26+
explicit BitcoinAmount(QObject *parent = nullptr);
27+
28+
Unit unit() const;
29+
void setUnit(Unit unit);
30+
QString unitLabel() const;
31+
QString amount() const;
32+
void setAmount(const QString& new_amount);
33+
34+
public Q_SLOTS:
35+
QString sanitize(const QString &text);
36+
QString convert(const QString &text, Unit unit);
37+
38+
Q_SIGNALS:
39+
void unitChanged();
40+
void unitLabelChanged();
41+
void amountChanged();
42+
43+
private:
44+
long long toSatoshis(QString &amount, const Unit unit);
45+
int decimals(Unit unit);
46+
47+
Unit m_unit;
48+
QString m_unitLabel;
49+
QString m_amount;
50+
};
51+
52+
#endif // BITCOIN_QML_BITCOINAMOUNT_H

0 commit comments

Comments
 (0)