Skip to content

Commit

Permalink
qml: Introduce WalletModel and loadWallet functionality
Browse files Browse the repository at this point in the history
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
  • Loading branch information
johnny9 committed Sep 13, 2024
1 parent e7bea2d commit df375c0
Show file tree
Hide file tree
Showing 13 changed files with 213 additions and 83 deletions.
9 changes: 6 additions & 3 deletions src/Makefile.qt.include
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,9 @@ QT_MOC_CPP = \
qml/models/moc_options_model.cpp \
qml/models/moc_peerlistsortproxy.cpp \
qml/models/moc_walletlistmodel.cpp \
qml/models/moc_walletqmlmodel.cpp \
qml/moc_appmode.cpp \
qml/moc_walletcontroller.cpp \
qml/moc_walletqmlcontroller.cpp \
qt/moc_addressbookpage.cpp \
qt/moc_addresstablemodel.cpp \
qt/moc_askpassphrasedialog.cpp \
Expand Down Expand Up @@ -124,12 +125,13 @@ BITCOIN_QT_H = \
qml/models/options_model.h \
qml/models/peerlistsortproxy.h \
qml/models/walletlistmodel.h \
qml/models/walletqmlmodel.h \
qml/appmode.h \
qml/bitcoin.h \
qml/guiconstants.h \
qml/imageprovider.h \
qml/util.h \
qml/walletcontroller.h \
qml/walletqmlcontroller.h \
qt/addressbookpage.h \
qt/addresstablemodel.h \
qt/askpassphrasedialog.h \
Expand Down Expand Up @@ -314,9 +316,10 @@ BITCOIN_QML_BASE_CPP = \
qml/models/options_model.cpp \
qml/models/peerlistsortproxy.cpp \
qml/models/walletlistmodel.cpp \
qml/models/walletqmlmodel.cpp \
qml/imageprovider.cpp \
qml/util.cpp \
qml/walletcontroller.cpp
qml/walletqmlcontroller.cpp

QML_RES_FONTS = \
qml/res/fonts/Inter-Regular.otf \
Expand Down
17 changes: 14 additions & 3 deletions src/qml/bitcoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@
#include <qml/models/options_model.h>
#include <qml/models/peerlistsortproxy.h>
#include <qml/models/walletlistmodel.h>
#include <qml/models/walletqmlmodel.h>
#include <qml/imageprovider.h>
#include <qml/util.h>
#include <qml/walletcontroller.h>
#include <qml/walletqmlcontroller.h>
#include <qt/guiutil.h>
#include <qt/initexecutor.h>
#include <qt/networkstyle.h>
Expand Down Expand Up @@ -276,8 +277,17 @@ int QmlGuiMain(int argc, char* argv[])
QObject::connect(&node_model, &NodeModel::setTimeRatioList, &chain_model, &ChainModel::setTimeRatioList);
QObject::connect(&node_model, &NodeModel::setTimeRatioListInitial, &chain_model, &ChainModel::setTimeRatioListInitial);


#ifdef ENABLE_WALLET
WalletQmlController wallet_controller(*node);
QObject::connect(&init_executor, &InitExecutor::initializeResult, &wallet_controller, &WalletQmlController::initialize);
#endif

qGuiApp->setQuitOnLastWindowClosed(false);
QObject::connect(qGuiApp, &QGuiApplication::lastWindowClosed, [&] {
#ifdef ENABLE_WALLET
wallet_controller.unloadWallets();
#endif
node->startShutdown();
});

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

WalletController wallet_controller(*node);

QQmlApplicationEngine engine;

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

qmlRegisterUncreatableType<WalletQmlModel>("org.bitcoincore.qt", 1, 0, "WalletQmlModel",
"WalletQmlModel cannot be instantiated from QML");

engine.load(QUrl(QStringLiteral("qrc:///qml/pages/main.qml")));
if (engine.rootObjects().isEmpty()) {
return EXIT_FAILURE;
Expand Down
14 changes: 0 additions & 14 deletions src/qml/models/walletlistmodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ WalletListModel::WalletListModel(interfaces::Node& node, QObject *parent)
: QAbstractListModel(parent)
, m_node(node)
{
setSelectedWallet("Singlesig Wallet");
}

void WalletListModel::listWalletDir()
Expand All @@ -32,19 +31,6 @@ void WalletListModel::listWalletDir()
}
}

void WalletListModel::setSelectedWallet(QString wallet_name)
{
if (m_selected_wallet != wallet_name) {
m_selected_wallet = wallet_name;
Q_EMIT selectedWalletChanged();
}
}

QString WalletListModel::selectedWallet() const
{
return m_selected_wallet;
}

int WalletListModel::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
Expand Down
9 changes: 0 additions & 9 deletions src/qml/models/walletlistmodel.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ class Node;
class WalletListModel : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(QString selectedWallet READ selectedWallet WRITE setSelectedWallet NOTIFY selectedWalletChanged)

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

void setSelectedWallet(QString wallet_name);
QString selectedWallet() const;

public Q_SLOTS:
void listWalletDir();

Q_SIGNALS:
void selectedWalletChanged();

private:
struct Item {
QString name;
Expand All @@ -48,8 +41,6 @@ public Q_SLOTS:

QList<Item> m_items;
interfaces::Node& m_node;
QString m_selected_wallet;

};

#endif // BITCOIN_QML_MODELS_WALLETLISTMODEL_H
34 changes: 34 additions & 0 deletions src/qml/models/walletqmlmodel.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2024 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qml/models/walletqmlmodel.h>

#include <QTimer>

WalletQmlModel::WalletQmlModel(std::unique_ptr<interfaces::Wallet> wallet, QObject *parent)
: QObject(parent)
{
m_wallet = std::move(wallet);
}

WalletQmlModel::WalletQmlModel(QObject *parent)
: QObject(parent)
{
}

qint64 WalletQmlModel::balance() const
{
if (!m_wallet) {
return 0;
}
return m_wallet->getBalances().balance;
}

QString WalletQmlModel::name() const
{
if (!m_wallet) {
return QString();
}
return QString::fromStdString(m_wallet->getWalletName());
}
34 changes: 34 additions & 0 deletions src/qml/models/walletqmlmodel.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright (c) 2024 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#ifndef BITCOIN_QML_WALLETQMLMODEL_H
#define BITCOIN_QML_WALLETQMLMODEL_H

#include <interfaces/wallet.h>

#include <QObject>

class WalletQmlModel : public QObject
{
Q_OBJECT
Q_PROPERTY(QString name READ name NOTIFY nameChanged)
Q_PROPERTY(qint64 balance READ balance NOTIFY balanceChanged)

public:
WalletQmlModel(std::unique_ptr<interfaces::Wallet> wallet, QObject *parent = nullptr);
WalletQmlModel(QObject *parent = nullptr);
~WalletQmlModel() = default;

QString name() const;
qint64 balance() const;

Q_SIGNALS:
void nameChanged();
void balanceChanged();

private:
std::unique_ptr<interfaces::Wallet> m_wallet;
};

#endif // BITCOIN_QML_WALLETQMLMODEL_H
3 changes: 2 additions & 1 deletion src/qml/pages/wallet/DesktopWallets.qml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ Page {
leftItem: WalletBadge {
implicitWidth: 154
implicitHeight: 46
text: walletListModel.selectedWallet
text: walletController.selectedWallet.name
balance: walletController.selectedWallet.balance

MouseArea {
anchors.fill: parent
Expand Down
3 changes: 2 additions & 1 deletion src/qml/pages/wallet/WalletBadge.qml
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ Button {
property string iconSource: ""
property bool showBalance: true
property bool showIcon: true
property int balance: 0

checkable: true
hoverEnabled: AppMode.isDesktop
Expand Down Expand Up @@ -126,7 +127,7 @@ Button {
CoreText {
id: balanceText
visible: root.showBalance
text: formatSatoshis(12300)
text: formatSatoshis(root.balance)
color: Theme.color.neutral7
}
}
Expand Down
3 changes: 2 additions & 1 deletion src/qml/pages/wallet/WalletSelect.qml
Original file line number Diff line number Diff line change
Expand Up @@ -77,11 +77,12 @@ Popup {
width: 220
height: 32
text: name
checked: walletController.selectedWallet.name == name
ButtonGroup.group: buttonGroup
showBalance: false
showIcon: false
onClicked: {
walletListModel.selectedWallet = name
walletController.setSelectedWallet(name)
root.close()
}
}
Expand Down
25 changes: 0 additions & 25 deletions src/qml/walletcontroller.cpp

This file was deleted.

26 changes: 0 additions & 26 deletions src/qml/walletcontroller.h

This file was deleted.

74 changes: 74 additions & 0 deletions src/qml/walletqmlcontroller.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// Copyright (c) 2024 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <qml/walletqmlcontroller.h>

#include <interfaces/node.h>

WalletQmlController::WalletQmlController(interfaces::Node& node, QObject *parent)
: QObject(parent)
, m_node(node)
{
m_selected_wallet = new WalletQmlModel(parent);
}

WalletQmlController::~WalletQmlController()
{
if (m_handler_load_wallet) {
m_handler_load_wallet->disconnect();
}
}

void WalletQmlController::setSelectedWallet(QString path)
{
std::vector<bilingual_str> warning_message;
auto wallet{m_node.walletLoader().loadWallet(path.toStdString(), warning_message)};
if (wallet.has_value()) {
m_selected_wallet = new WalletQmlModel(std::move(wallet.value()));
m_wallets.push_back(m_selected_wallet);
Q_EMIT selectedWalletChanged();
}
}

WalletQmlModel* WalletQmlController::selectedWallet() const
{
return m_selected_wallet;
}

void WalletQmlController::unloadWallets()
{
m_handler_load_wallet->disconnect();
for (WalletQmlModel* wallet : m_wallets) {
delete wallet;
}
m_wallets.clear();
}

void WalletQmlController::handleLoadWallet(std::unique_ptr<interfaces::Wallet> wallet)
{
if (!m_wallets.empty()) {
QString name = QString::fromStdString(wallet->getWalletName());
for (WalletQmlModel* wallet_model : m_wallets) {
if (wallet_model->name() == name) {
return;
}
}
}

m_selected_wallet = new WalletQmlModel(std::move(wallet));
m_wallets.push_back(m_selected_wallet);
Q_EMIT selectedWalletChanged();
}

void WalletQmlController::initialize()
{
m_handler_load_wallet = m_node.walletLoader().handleLoadWallet([this](std::unique_ptr<interfaces::Wallet> wallet) {
handleLoadWallet(std::move(wallet));
});

auto wallets = m_node.walletLoader().getWallets();
for (auto& wallet : wallets) {
handleLoadWallet(std::move(wallet));
}
}
Loading

0 comments on commit df375c0

Please sign in to comment.