Skip to content

Commit e677cd7

Browse files
promagmajcosta
authored andcommitted
[backport#15450 1/5] gui: Refactor OpenWalletActivity
Summary: bitcoin/bitcoin@bc6d8a3 Partial backport of Core [[bitcoin/bitcoin#15450 | PR15450]] depends on D7108 Test Plan: ninja check Open bitcoin-qt open and close wallets to make sure it works as before Reviewers: #bitcoin_abc, deadalnix Reviewed By: #bitcoin_abc, deadalnix Subscribers: deadalnix Differential Revision: https://reviews.bitcoinabc.org/D7102
1 parent ad8837b commit e677cd7

File tree

3 files changed

+113
-73
lines changed

3 files changed

+113
-73
lines changed

src/qt/bitcoingui.cpp

Lines changed: 5 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -459,39 +459,15 @@ void BitcoinGUI::createActions() {
459459
continue;
460460
}
461461

462-
connect(action, &QAction::triggered, [this, name, path] {
463-
OpenWalletActivity *activity =
464-
m_wallet_controller->openWallet(
465-
config->GetChainParams(), path);
466-
467-
QProgressDialog *dialog = new QProgressDialog(this);
468-
dialog->setLabelText(tr("Opening Wallet <b>%1</b>...")
469-
.arg(name.toHtmlEscaped()));
470-
dialog->setRange(0, 0);
471-
dialog->setCancelButton(nullptr);
472-
dialog->setWindowModality(Qt::ApplicationModal);
473-
dialog->show();
474-
475-
connect(activity, &OpenWalletActivity::message, this,
476-
[this](QMessageBox::Icon icon, QString text) {
477-
QMessageBox box;
478-
box.setIcon(icon);
479-
box.setText(tr("Open Wallet Failed"));
480-
box.setInformativeText(text);
481-
box.setStandardButtons(QMessageBox::Ok);
482-
box.setDefaultButton(QMessageBox::Ok);
483-
connect(this, &QObject::destroyed, &box,
484-
&QDialog::accept);
485-
box.exec();
486-
});
462+
connect(action, &QAction::triggered, [this, path] {
463+
auto activity =
464+
new OpenWalletActivity(m_wallet_controller, this,
465+
this->config->GetChainParams());
487466
connect(activity, &OpenWalletActivity::opened, this,
488467
&BitcoinGUI::setCurrentWallet);
489468
connect(activity, &OpenWalletActivity::finished, activity,
490469
&QObject::deleteLater);
491-
connect(activity, &OpenWalletActivity::finished, dialog,
492-
&QObject::deleteLater);
493-
bool invoked = QMetaObject::invokeMethod(activity, "open");
494-
assert(invoked);
470+
activity->open(path);
495471
});
496472
}
497473
if (m_open_wallet_menu->isEmpty()) {

src/qt/walletcontroller.cpp

Lines changed: 67 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,25 @@
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

5+
#include <qt/guiutil.h>
56
#include <qt/walletcontroller.h>
67

78
#include <interfaces/handler.h>
89
#include <interfaces/node.h>
910

1011
#include <QApplication>
1112
#include <QMutexLocker>
13+
#include <QTimer>
1214
#include <QWindow>
1315

1416
#include <algorithm>
1517

1618
WalletController::WalletController(interfaces::Node &node,
1719
const PlatformStyle *platform_style,
1820
OptionsModel *options_model, QObject *parent)
19-
: QObject(parent), m_node(node), m_platform_style(platform_style),
20-
m_options_model(options_model) {
21+
: QObject(parent), m_activity_thread(new QThread(this)),
22+
m_activity_worker(new QObject), m_node(node),
23+
m_platform_style(platform_style), m_options_model(options_model) {
2124
m_handler_load_wallet = m_node.handleLoadWallet(
2225
[this](std::unique_ptr<interfaces::Wallet> wallet) {
2326
getOrCreateWallet(std::move(wallet));
@@ -27,14 +30,16 @@ WalletController::WalletController(interfaces::Node &node,
2730
getOrCreateWallet(std::move(wallet));
2831
}
2932

30-
m_activity_thread.start();
33+
m_activity_worker->moveToThread(m_activity_thread);
34+
m_activity_thread->start();
3135
}
3236

3337
// Not using the default destructor because not all member types definitions are
3438
// available in the header, just forward declared.
3539
WalletController::~WalletController() {
36-
m_activity_thread.quit();
37-
m_activity_thread.wait();
40+
m_activity_thread->quit();
41+
m_activity_thread->wait();
42+
delete m_activity_worker;
3843
}
3944

4045
std::vector<WalletModel *> WalletController::getOpenWallets() const {
@@ -57,13 +62,6 @@ std::map<std::string, bool> WalletController::listWalletDir() const {
5762
return wallets;
5863
}
5964

60-
OpenWalletActivity *WalletController::openWallet(const CChainParams &params,
61-
const std::string &name,
62-
QWidget *parent) {
63-
OpenWalletActivity *activity = new OpenWalletActivity(this, name, params);
64-
activity->moveToThread(&m_activity_thread);
65-
return activity;
66-
}
6765
void WalletController::closeWallet(WalletModel *wallet_model, QWidget *parent) {
6866
QMessageBox box(parent);
6967
box.setWindowTitle(tr("Close wallet"));
@@ -150,25 +148,65 @@ void WalletController::removeAndDeleteWallet(WalletModel *wallet_model) {
150148
delete wallet_model;
151149
}
152150

151+
WalletControllerActivity::WalletControllerActivity(
152+
WalletController *wallet_controller, QWidget *parent_widget,
153+
const CChainParams &chainparams)
154+
: QObject(wallet_controller), m_wallet_controller(wallet_controller),
155+
m_parent_widget(parent_widget), m_chainparams(chainparams) {}
156+
157+
WalletControllerActivity::~WalletControllerActivity() {
158+
delete m_progress_dialog;
159+
}
160+
161+
void WalletControllerActivity::showProgressDialog(const QString &label_text) {
162+
m_progress_dialog = new QProgressDialog(m_parent_widget);
163+
164+
m_progress_dialog->setLabelText(label_text);
165+
m_progress_dialog->setRange(0, 0);
166+
m_progress_dialog->setCancelButton(nullptr);
167+
m_progress_dialog->setWindowModality(Qt::ApplicationModal);
168+
GUIUtil::PolishProgressDialog(m_progress_dialog);
169+
}
170+
153171
OpenWalletActivity::OpenWalletActivity(WalletController *wallet_controller,
154-
const std::string &name,
155-
const CChainParams &params)
156-
: m_wallet_controller(wallet_controller), m_name(name),
157-
m_chain_params(params) {}
158-
159-
void OpenWalletActivity::open() {
160-
std::string error, warning;
161-
std::unique_ptr<interfaces::Wallet> wallet =
162-
m_wallet_controller->m_node.loadWallet(m_chain_params, m_name, error,
163-
warning);
164-
if (!warning.empty()) {
165-
Q_EMIT message(QMessageBox::Warning, QString::fromStdString(warning));
172+
QWidget *parent_widget,
173+
const CChainParams &chainparams)
174+
: WalletControllerActivity(wallet_controller, parent_widget, chainparams) {}
175+
176+
void OpenWalletActivity::finish() {
177+
m_progress_dialog->hide();
178+
179+
if (!m_error_message.empty()) {
180+
QMessageBox::critical(m_parent_widget, tr("Open wallet failed"),
181+
QString::fromStdString(m_error_message));
182+
} else if (!m_warning_message.empty()) {
183+
QMessageBox::warning(m_parent_widget, tr("Open wallet warning"),
184+
QString::fromStdString(m_warning_message));
166185
}
167-
if (wallet) {
168-
Q_EMIT opened(
169-
m_wallet_controller->getOrCreateWallet(std::move(wallet)));
170-
} else {
171-
Q_EMIT message(QMessageBox::Critical, QString::fromStdString(error));
186+
187+
if (m_wallet_model) {
188+
Q_EMIT opened(m_wallet_model);
172189
}
190+
173191
Q_EMIT finished();
174192
}
193+
194+
void OpenWalletActivity::open(const std::string &path) {
195+
QString name = path.empty() ? QString("[" + tr("default wallet") + "]")
196+
: QString::fromStdString(path);
197+
198+
showProgressDialog(
199+
tr("Opening Wallet <b>%1</b>...").arg(name.toHtmlEscaped()));
200+
201+
QTimer::singleShot(0, worker(), [this, path] {
202+
std::unique_ptr<interfaces::Wallet> wallet = node().loadWallet(
203+
this->m_chainparams, path, m_error_message, m_warning_message);
204+
205+
if (wallet) {
206+
m_wallet_model =
207+
m_wallet_controller->getOrCreateWallet(std::move(wallet));
208+
}
209+
210+
QTimer::singleShot(0, this, &OpenWalletActivity::finish);
211+
});
212+
}

src/qt/walletcontroller.h

Lines changed: 41 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@
1212

1313
#include <map>
1414
#include <memory>
15+
#include <string>
1516
#include <vector>
1617

1718
#include <QMessageBox>
19+
#include <QProgressDialog>
20+
#include <QString>
1821
#include <QThread>
1922

2023
class OptionsModel;
@@ -26,14 +29,14 @@ class Node;
2629
} // namespace interfaces
2730

2831
class OpenWalletActivity;
32+
class WalletControllerActivity;
2933

3034
/**
3135
* Controller between interfaces::Node, WalletModel instances and the GUI.
3236
*/
3337
class WalletController : public QObject {
3438
Q_OBJECT
3539

36-
WalletModel *getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet);
3740
void removeAndDeleteWallet(WalletModel *wallet_model);
3841

3942
public:
@@ -45,13 +48,12 @@ class WalletController : public QObject {
4548
//! Returns wallet models currently open.
4649
std::vector<WalletModel *> getOpenWallets() const;
4750

51+
WalletModel *getOrCreateWallet(std::unique_ptr<interfaces::Wallet> wallet);
52+
4853
//! Returns all wallet names in the wallet dir mapped to whether the wallet
4954
//! is loaded.
5055
std::map<std::string, bool> listWalletDir() const;
5156

52-
OpenWalletActivity *openWallet(const CChainParams &params,
53-
const std::string &name,
54-
QWidget *parent = nullptr);
5557
void closeWallet(WalletModel *wallet_model, QWidget *parent = nullptr);
5658

5759
Q_SIGNALS:
@@ -62,36 +64,60 @@ class WalletController : public QObject {
6264
QByteArray transaction);
6365

6466
private:
65-
QThread m_activity_thread;
67+
QThread *const m_activity_thread;
68+
QObject *const m_activity_worker;
6669
interfaces::Node &m_node;
6770
const PlatformStyle *const m_platform_style;
6871
OptionsModel *const m_options_model;
6972
mutable QMutex m_mutex;
7073
std::vector<WalletModel *> m_wallets;
7174
std::unique_ptr<interfaces::Handler> m_handler_load_wallet;
7275

73-
friend class OpenWalletActivity;
76+
friend class WalletControllerActivity;
77+
};
78+
79+
class WalletControllerActivity : public QObject {
80+
Q_OBJECT
81+
82+
public:
83+
WalletControllerActivity(WalletController *wallet_controller,
84+
QWidget *parent_widget,
85+
const CChainParams &chainparams);
86+
virtual ~WalletControllerActivity();
87+
88+
Q_SIGNALS:
89+
void finished();
90+
91+
protected:
92+
interfaces::Node &node() const { return m_wallet_controller->m_node; }
93+
QObject *worker() const { return m_wallet_controller->m_activity_worker; }
94+
95+
void showProgressDialog(const QString &label_text);
96+
97+
WalletController *const m_wallet_controller;
98+
QWidget *const m_parent_widget;
99+
QProgressDialog *m_progress_dialog{nullptr};
100+
WalletModel *m_wallet_model{nullptr};
101+
std::string m_error_message;
102+
std::string m_warning_message;
103+
104+
const CChainParams &m_chainparams;
74105
};
75106

76-
class OpenWalletActivity : public QObject {
107+
class OpenWalletActivity : public WalletControllerActivity {
77108
Q_OBJECT
78109

79110
public:
80111
OpenWalletActivity(WalletController *wallet_controller,
81-
const std::string &name, const CChainParams &params);
112+
QWidget *parent_widget, const CChainParams &chainparams);
82113

83-
public Q_SLOTS:
84-
void open();
114+
void open(const std::string &path);
85115

86116
Q_SIGNALS:
87-
void message(QMessageBox::Icon icon, const QString text);
88-
void finished();
89117
void opened(WalletModel *wallet_model);
90118

91119
private:
92-
WalletController *const m_wallet_controller;
93-
std::string const m_name;
94-
const CChainParams &m_chain_params;
120+
void finish();
95121
};
96122

97123
#endif // BITCOIN_QT_WALLETCONTROLLER_H

0 commit comments

Comments
 (0)