Page MenuHomePhabricator

No OneTemporary

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 &params,
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 &params, 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

Mime Type
text/x-diff
Expires
Sun, Mar 2, 13:03 (22 h, 5 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
5183161
Default Alt Text
(7 KB)

Event Timeline