Skip to content

Commit fcea24d

Browse files
committed
qml: Introduce WalletModel and loadWallet functionality
When a user selects a wallet from the WAlletSelect menu the wallet controller can now load the wallet data in and the name and balance will appear in the WalletBadge
1 parent e7bea2d commit fcea24d

12 files changed

+213
-69
lines changed

src/Makefile.qt.include

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,9 @@ QT_MOC_CPP = \
4343
qml/models/moc_options_model.cpp \
4444
qml/models/moc_peerlistsortproxy.cpp \
4545
qml/models/moc_walletlistmodel.cpp \
46+
qml/models/moc_walletqmlmodel.cpp \
4647
qml/moc_appmode.cpp \
47-
qml/moc_walletcontroller.cpp \
48+
qml/moc_walletqmlcontroller.cpp \
4849
qt/moc_addressbookpage.cpp \
4950
qt/moc_addresstablemodel.cpp \
5051
qt/moc_askpassphrasedialog.cpp \
@@ -124,12 +125,13 @@ BITCOIN_QT_H = \
124125
qml/models/options_model.h \
125126
qml/models/peerlistsortproxy.h \
126127
qml/models/walletlistmodel.h \
128+
qml/models/walletqmlmodel.h \
127129
qml/appmode.h \
128130
qml/bitcoin.h \
129131
qml/guiconstants.h \
130132
qml/imageprovider.h \
131133
qml/util.h \
132-
qml/walletcontroller.h \
134+
qml/walletqmlcontroller.h \
133135
qt/addressbookpage.h \
134136
qt/addresstablemodel.h \
135137
qt/askpassphrasedialog.h \
@@ -314,9 +316,10 @@ BITCOIN_QML_BASE_CPP = \
314316
qml/models/options_model.cpp \
315317
qml/models/peerlistsortproxy.cpp \
316318
qml/models/walletlistmodel.cpp \
319+
qml/models/walletqmlmodel.cpp \
317320
qml/imageprovider.cpp \
318321
qml/util.cpp \
319-
qml/walletcontroller.cpp
322+
qml/walletqmlcontroller.cpp
320323

321324
QML_RES_FONTS = \
322325
qml/res/fonts/Inter-Regular.otf \

src/qml/bitcoin.cpp

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@
2727
#include <qml/models/options_model.h>
2828
#include <qml/models/peerlistsortproxy.h>
2929
#include <qml/models/walletlistmodel.h>
30+
#include <qml/models/walletqmlmodel.h>
3031
#include <qml/imageprovider.h>
3132
#include <qml/util.h>
32-
#include <qml/walletcontroller.h>
33+
#include <qml/walletqmlcontroller.h>
3334
#include <qt/guiutil.h>
3435
#include <qt/initexecutor.h>
3536
#include <qt/networkstyle.h>
@@ -276,8 +277,17 @@ int QmlGuiMain(int argc, char* argv[])
276277
QObject::connect(&node_model, &NodeModel::setTimeRatioList, &chain_model, &ChainModel::setTimeRatioList);
277278
QObject::connect(&node_model, &NodeModel::setTimeRatioListInitial, &chain_model, &ChainModel::setTimeRatioListInitial);
278279

280+
281+
#ifdef ENABLE_WALLET
282+
WalletQmlController wallet_controller(*node);
283+
QObject::connect(&init_executor, &InitExecutor::initializeResult, &wallet_controller, &WalletQmlController::initialize);
284+
#endif
285+
279286
qGuiApp->setQuitOnLastWindowClosed(false);
280287
QObject::connect(qGuiApp, &QGuiApplication::lastWindowClosed, [&] {
288+
#ifdef ENABLE_WALLET
289+
wallet_controller.unloadWallets();
290+
#endif
281291
node->startShutdown();
282292
});
283293

@@ -288,8 +298,6 @@ int QmlGuiMain(int argc, char* argv[])
288298
GUIUtil::LoadFont(":/fonts/inter/regular");
289299
GUIUtil::LoadFont(":/fonts/inter/semibold");
290300

291-
WalletController wallet_controller(*node);
292-
293301
QQmlApplicationEngine engine;
294302

295303
QScopedPointer<const NetworkStyle> network_style{NetworkStyle::instantiate(Params().GetChainType())};
@@ -316,6 +324,9 @@ int QmlGuiMain(int argc, char* argv[])
316324
qmlRegisterType<BlockClockDial>("org.bitcoincore.qt", 1, 0, "BlockClockDial");
317325
qmlRegisterType<LineGraph>("org.bitcoincore.qt", 1, 0, "LineGraph");
318326

327+
qmlRegisterUncreatableType<WalletQmlModel>("org.bitcoincore.qt", 1, 0, "WalletQmlModel",
328+
"WalletQmlModel cannot be instantiated from QML");
329+
319330
engine.load(QUrl(QStringLiteral("qrc:///qml/pages/main.qml")));
320331
if (engine.rootObjects().isEmpty()) {
321332
return EXIT_FAILURE;

src/qml/models/walletlistmodel.h

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ class Node;
1616
class WalletListModel : public QAbstractListModel
1717
{
1818
Q_OBJECT
19-
Q_PROPERTY(QString selectedWallet READ selectedWallet WRITE setSelectedWallet NOTIFY selectedWalletChanged)
2019

2120
public:
2221
WalletListModel(interfaces::Node& node, QObject *parent = nullptr);
@@ -30,15 +29,9 @@ class WalletListModel : public QAbstractListModel
3029
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
3130
QHash<int, QByteArray> roleNames() const override;
3231

33-
void setSelectedWallet(QString wallet_name);
34-
QString selectedWallet() const;
35-
3632
public Q_SLOTS:
3733
void listWalletDir();
3834

39-
Q_SIGNALS:
40-
void selectedWalletChanged();
41-
4235
private:
4336
struct Item {
4437
QString name;
@@ -48,8 +41,6 @@ public Q_SLOTS:
4841

4942
QList<Item> m_items;
5043
interfaces::Node& m_node;
51-
QString m_selected_wallet;
52-
5344
};
5445

5546
#endif // BITCOIN_QML_MODELS_WALLETLISTMODEL_H

src/qml/models/walletqmlmodel.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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/models/walletqmlmodel.h>
6+
7+
#include <QTimer>
8+
9+
WalletQmlModel::WalletQmlModel(std::unique_ptr<interfaces::Wallet> wallet, QObject *parent)
10+
: QObject(parent)
11+
{
12+
m_wallet = std::move(wallet);
13+
}
14+
15+
WalletQmlModel::WalletQmlModel(QObject *parent)
16+
: QObject(parent)
17+
{
18+
}
19+
20+
qint64 WalletQmlModel::balance() const
21+
{
22+
if (!m_wallet) {
23+
return 0;
24+
}
25+
return m_wallet->getBalances().balance;
26+
}
27+
28+
QString WalletQmlModel::name() const
29+
{
30+
if (!m_wallet) {
31+
return QString();
32+
}
33+
return QString::fromStdString(m_wallet->getWalletName());
34+
}

src/qml/models/walletqmlmodel.h

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
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_WALLETQMLMODEL_H
6+
#define BITCOIN_QML_WALLETQMLMODEL_H
7+
8+
#include <interfaces/wallet.h>
9+
10+
#include <QObject>
11+
12+
class WalletQmlModel : public QObject
13+
{
14+
Q_OBJECT
15+
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
16+
Q_PROPERTY(qint64 balance READ balance NOTIFY balanceChanged)
17+
18+
public:
19+
WalletQmlModel(std::unique_ptr<interfaces::Wallet> wallet, QObject *parent = nullptr);
20+
WalletQmlModel(QObject *parent = nullptr);
21+
~WalletQmlModel() = default;
22+
23+
QString name() const;
24+
qint64 balance() const;
25+
26+
Q_SIGNALS:
27+
void nameChanged();
28+
void balanceChanged();
29+
30+
private:
31+
std::unique_ptr<interfaces::Wallet> m_wallet;
32+
};
33+
34+
#endif // BITCOIN_QML_WALLETQMLMODEL_H

src/qml/pages/wallet/DesktopWallets.qml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ Page {
2424
leftItem: WalletBadge {
2525
implicitWidth: 154
2626
implicitHeight: 46
27-
text: walletListModel.selectedWallet
27+
text: walletController.selectedWallet.name
28+
balance: walletController.selectedWallet.balance
2829

2930
MouseArea {
3031
anchors.fill: parent

src/qml/pages/wallet/WalletBadge.qml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ Button {
8585
property string iconSource: ""
8686
property bool showBalance: true
8787
property bool showIcon: true
88+
property int balance: 0
8889

8990
checkable: true
9091
hoverEnabled: AppMode.isDesktop
@@ -126,7 +127,7 @@ Button {
126127
CoreText {
127128
id: balanceText
128129
visible: root.showBalance
129-
text: formatSatoshis(12300)
130+
text: formatSatoshis(root.balance)
130131
color: Theme.color.neutral7
131132
}
132133
}

src/qml/pages/wallet/WalletSelect.qml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,11 +77,12 @@ Popup {
7777
width: 220
7878
height: 32
7979
text: name
80+
checked: walletController.selectedWallet.name == name
8081
ButtonGroup.group: buttonGroup
8182
showBalance: false
8283
showIcon: false
8384
onClicked: {
84-
walletListModel.selectedWallet = name
85+
walletController.setSelectedWallet(name)
8586
root.close()
8687
}
8788
}

src/qml/walletcontroller.cpp

Lines changed: 0 additions & 25 deletions
This file was deleted.

src/qml/walletcontroller.h

Lines changed: 0 additions & 26 deletions
This file was deleted.

src/qml/walletqmlcontroller.cpp

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
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/walletqmlcontroller.h>
6+
7+
#include <interfaces/node.h>
8+
9+
WalletQmlController::WalletQmlController(interfaces::Node& node, QObject *parent)
10+
: QObject(parent)
11+
, m_node(node)
12+
{
13+
m_selected_wallet = new WalletQmlModel(parent);
14+
}
15+
16+
WalletQmlController::~WalletQmlController()
17+
{
18+
if (m_handler_load_wallet) {
19+
m_handler_load_wallet->disconnect();
20+
}
21+
}
22+
23+
void WalletQmlController::setSelectedWallet(QString path)
24+
{
25+
std::vector<bilingual_str> warning_message;
26+
auto wallet{m_node.walletLoader().loadWallet(path.toStdString(), warning_message)};
27+
if (wallet.has_value()) {
28+
m_selected_wallet = new WalletQmlModel(std::move(wallet.value()));
29+
m_wallets.push_back(m_selected_wallet);
30+
Q_EMIT selectedWalletChanged();
31+
}
32+
}
33+
34+
WalletQmlModel* WalletQmlController::selectedWallet() const
35+
{
36+
return m_selected_wallet;
37+
}
38+
39+
void WalletQmlController::unloadWallets()
40+
{
41+
m_handler_load_wallet->disconnect();
42+
for (WalletQmlModel* wallet : m_wallets) {
43+
delete wallet;
44+
}
45+
m_wallets.clear();
46+
}
47+
48+
void WalletQmlController::handleLoadWallet(std::unique_ptr<interfaces::Wallet> wallet)
49+
{
50+
if (!m_wallets.empty()) {
51+
QString name = QString::fromStdString(wallet->getWalletName());
52+
for (WalletQmlModel* wallet_model : m_wallets) {
53+
if (wallet_model->name() == name) {
54+
return;
55+
}
56+
}
57+
}
58+
59+
m_selected_wallet = new WalletQmlModel(std::move(wallet));
60+
m_wallets.push_back(m_selected_wallet);
61+
Q_EMIT selectedWalletChanged();
62+
}
63+
64+
void WalletQmlController::initialize()
65+
{
66+
m_handler_load_wallet = m_node.walletLoader().handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
67+
handleLoadWallet(std::move(wallet));
68+
});
69+
70+
auto wallets = m_node.walletLoader().getWallets();
71+
for (auto& wallet : wallets) {
72+
handleLoadWallet(std::move(wallet));
73+
}
74+
}

0 commit comments

Comments
 (0)