Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13115997
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Subscribers
None
View Options
diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp
index 4ba89dbac..452697658 100644
--- a/src/qt/walletcontroller.cpp
+++ b/src/qt/walletcontroller.cpp
@@ -1,142 +1,147 @@
// Copyright (c) 2019 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 <qt/walletcontroller.h>
#include <interfaces/handler.h>
#include <interfaces/node.h>
#include <QApplication>
#include <QMessageBox>
#include <QMutexLocker>
#include <QThread>
#include <QWindow>
#include <algorithm>
WalletController::WalletController(interfaces::Node &node,
const PlatformStyle *platform_style,
OptionsModel *options_model, QObject *parent)
: QObject(parent), m_node(node), m_platform_style(platform_style),
m_options_model(options_model) {
m_handler_load_wallet = m_node.handleLoadWallet(
[this](std::unique_ptr<interfaces::Wallet> wallet) {
getOrCreateWallet(std::move(wallet));
});
for (std::unique_ptr<interfaces::Wallet> &wallet : m_node.getWallets()) {
getOrCreateWallet(std::move(wallet));
}
+
+ m_activity_thread.start();
}
// Not using the default destructor because not all member types definitions are
// available in the header, just forward declared.
-WalletController::~WalletController() {}
+WalletController::~WalletController() {
+ m_activity_thread.quit();
+ m_activity_thread.wait();
+}
std::vector<WalletModel *> WalletController::getWallets() const {
QMutexLocker locker(&m_mutex);
return m_wallets;
}
std::vector<std::string> WalletController::getWalletsAvailableToOpen() const {
QMutexLocker locker(&m_mutex);
std::vector<std::string> wallets = m_node.listWalletDir();
for (WalletModel *wallet_model : m_wallets) {
auto it = std::remove(wallets.begin(), wallets.end(),
wallet_model->wallet().getWalletName());
if (it != wallets.end()) {
wallets.erase(it);
}
}
return wallets;
}
WalletModel *WalletController::openWallet(const CChainParams ¶ms,
const std::string &name,
QWidget *parent) {
std::string error, warning;
WalletModel *wallet_model =
getOrCreateWallet(m_node.loadWallet(params, name, error, warning));
if (wallet_model == nullptr) {
QMessageBox::warning(parent, tr("Open Wallet"),
QString::fromStdString(error));
}
if (!warning.empty()) {
QMessageBox::information(parent, tr("Open Wallet"),
QString::fromStdString(warning));
}
return wallet_model;
}
WalletModel *WalletController::getOrCreateWallet(
std::unique_ptr<interfaces::Wallet> wallet) {
QMutexLocker locker(&m_mutex);
// Return model instance if exists.
if (!m_wallets.empty()) {
std::string name = wallet->getWalletName();
for (WalletModel *wallet_model : m_wallets) {
if (wallet_model->wallet().getWalletName() == name) {
return wallet_model;
}
}
}
// Instantiate model and register it.
WalletModel *wallet_model = new WalletModel(
std::move(wallet), m_node, m_platform_style, m_options_model, nullptr);
m_wallets.push_back(wallet_model);
connect(wallet_model, &WalletModel::unload, [this, wallet_model] {
// Defer removeAndDeleteWallet when no modal widget is active.
// TODO: remove this workaround by removing usage of QDiallog::exec.
if (QApplication::activeModalWidget()) {
connect(
qApp, &QApplication::focusWindowChanged, wallet_model,
[this, wallet_model]() {
if (!QApplication::activeModalWidget()) {
removeAndDeleteWallet(wallet_model);
}
},
Qt::QueuedConnection);
} else {
removeAndDeleteWallet(wallet_model);
}
});
// Re-emit coinsSent signal from wallet model.
connect(wallet_model, &WalletModel::coinsSent, this,
&WalletController::coinsSent);
// Notify walletAdded signal on the GUI thread.
if (QThread::currentThread() == thread()) {
addWallet(wallet_model);
} else {
// Handler callback runs in a different thread so fix wallet model
// thread affinity.
wallet_model->moveToThread(thread());
QMetaObject::invokeMethod(this, "addWallet", Qt::QueuedConnection,
Q_ARG(WalletModel *, wallet_model));
}
return wallet_model;
}
void WalletController::addWallet(WalletModel *wallet_model) {
// Take ownership of the wallet model and register it.
wallet_model->setParent(this);
Q_EMIT walletAdded(wallet_model);
}
void WalletController::removeAndDeleteWallet(WalletModel *wallet_model) {
// Unregister wallet model.
{
QMutexLocker locker(&m_mutex);
m_wallets.erase(
std::remove(m_wallets.begin(), m_wallets.end(), wallet_model));
}
Q_EMIT walletRemoved(wallet_model);
// Currently this can trigger the unload since the model can hold the last
// CWallet shared pointer.
delete wallet_model;
}
diff --git a/src/qt/walletcontroller.h b/src/qt/walletcontroller.h
index 4da2825c1..44a35784a 100644
--- a/src/qt/walletcontroller.h
+++ b/src/qt/walletcontroller.h
@@ -1,65 +1,68 @@
// Copyright (c) 2019 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_QT_WALLETCONTROLLER_H
#define BITCOIN_QT_WALLETCONTROLLER_H
#include <qt/walletmodel.h>
#include <sync.h>
#include <QMutex>
#include <list>
#include <memory>
#include <vector>
+#include <QThread>
+
class OptionsModel;
class PlatformStyle;
namespace interfaces {
class Handler;
class Node;
} // namespace interfaces
/**
* Controller between interfaces::Node, WalletModel instances and the GUI.
*/
class WalletController : public QObject {
Q_OBJECT
WalletModel *getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet);
void removeAndDeleteWallet(WalletModel *wallet_model);
public:
WalletController(interfaces::Node &node,
const PlatformStyle *platform_style,
OptionsModel *options_model, QObject *parent);
~WalletController();
std::vector<WalletModel *> getWallets() const;
std::vector<std::string> getWalletsAvailableToOpen() const;
WalletModel *openWallet(const CChainParams ¶ms, const std::string &name,
QWidget *parent = nullptr);
private Q_SLOTS:
void addWallet(WalletModel *wallet_model);
Q_SIGNALS:
void walletAdded(WalletModel *wallet_model);
void walletRemoved(WalletModel *wallet_model);
void coinsSent(WalletModel *wallet_model, SendCoinsRecipient recipient,
QByteArray transaction);
private:
+ QThread m_activity_thread;
interfaces::Node &m_node;
const PlatformStyle *const m_platform_style;
OptionsModel *const m_options_model;
mutable QMutex m_mutex;
std::vector<WalletModel *> m_wallets;
std::unique_ptr<interfaces::Handler> m_handler_load_wallet;
};
#endif // BITCOIN_QT_WALLETCONTROLLER_H
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sun, Mar 2, 13:03 (18 h, 28 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5183161
Default Alt Text
(7 KB)
Attached To
rABC Bitcoin ABC
Event Timeline
Log In to Comment