From 32a8c6abfe32d5b89bf4505ca8397bdb44867614 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Sat, 12 Jan 2019 11:34:05 +0000 Subject: gui: Add openWallet and getWalletsAvailableToOpen to WalletController --- src/qt/walletcontroller.cpp | 25 +++++++++++++++++++++++++ src/qt/walletcontroller.h | 3 +++ 2 files changed, 28 insertions(+) (limited to 'src/qt') diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index df2b7a3f9b..0730afca98 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -9,6 +9,7 @@ #include +#include #include #include @@ -37,6 +38,30 @@ std::vector WalletController::getWallets() const return m_wallets; } +std::vector WalletController::getWalletsAvailableToOpen() const +{ + QMutexLocker locker(&m_mutex); + std::vector 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 std::string& name, QWidget* parent) +{ + std::string error, warning; + WalletModel* wallet_model = getOrCreateWallet(m_node.loadWallet(name, error, warning)); + if (!wallet_model) { + 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 wallet) { QMutexLocker locker(&m_mutex); diff --git a/src/qt/walletcontroller.h b/src/qt/walletcontroller.h index 22b71b07ff..523e47d27a 100644 --- a/src/qt/walletcontroller.h +++ b/src/qt/walletcontroller.h @@ -37,6 +37,9 @@ public: ~WalletController(); std::vector getWallets() const; + std::vector getWalletsAvailableToOpen() const; + + WalletModel* openWallet(const std::string& name, QWidget* parent = nullptr); private Q_SLOTS: void addWallet(WalletModel* wallet_model); -- cgit v1.2.3 From 6c49a55b472fa4ec403e48ec718af85bfd402199 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Sat, 12 Jan 2019 11:40:30 +0000 Subject: gui: Add Open Wallet menu --- src/qt/bitcoingui.cpp | 16 ++++++++++++++++ src/qt/bitcoingui.h | 1 + 2 files changed, 17 insertions(+) (limited to 'src/qt') diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index ba7e8c7daf..e7279e1229 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -334,6 +334,10 @@ void BitcoinGUI::createActions() openAction = new QAction(platformStyle->TextColorIcon(":/icons/open"), tr("Open &URI..."), this); openAction->setStatusTip(tr("Open a bitcoin: URI or payment request")); + m_open_wallet_action = new QAction(tr("Open Wallet"), this); + m_open_wallet_action->setMenu(new QMenu(this)); + m_open_wallet_action->setStatusTip(tr("Open a wallet")); + showHelpMessageAction = new QAction(platformStyle->TextColorIcon(":/icons/info"), tr("&Command-line options"), this); showHelpMessageAction->setMenuRole(QAction::NoRole); showHelpMessageAction->setStatusTip(tr("Show the %1 help message to get a list with possible Bitcoin command-line options").arg(tr(PACKAGE_NAME))); @@ -361,6 +365,16 @@ void BitcoinGUI::createActions() connect(usedSendingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedSendingAddresses); connect(usedReceivingAddressesAction, &QAction::triggered, walletFrame, &WalletFrame::usedReceivingAddresses); connect(openAction, &QAction::triggered, this, &BitcoinGUI::openClicked); + connect(m_open_wallet_action->menu(), &QMenu::aboutToShow, [this] { + m_open_wallet_action->menu()->clear(); + for (std::string path : m_wallet_controller->getWalletsAvailableToOpen()) { + QString name = path.empty() ? QString("["+tr("default wallet")+"]") : QString::fromStdString(path); + QAction* action = m_open_wallet_action->menu()->addAction(name); + connect(action, &QAction::triggered, [this, path] { + setCurrentWallet(m_wallet_controller->openWallet(path)); + }); + } + }); } #endif // ENABLE_WALLET @@ -382,6 +396,8 @@ void BitcoinGUI::createMenuBar() QMenu *file = appMenuBar->addMenu(tr("&File")); if(walletFrame) { + file->addAction(m_open_wallet_action); + file->addSeparator(); file->addAction(openAction); file->addAction(backupWalletAction); file->addAction(signMessageAction); diff --git a/src/qt/bitcoingui.h b/src/qt/bitcoingui.h index c31cefe603..c226494020 100644 --- a/src/qt/bitcoingui.h +++ b/src/qt/bitcoingui.h @@ -147,6 +147,7 @@ private: QAction* openRPCConsoleAction = nullptr; QAction* openAction = nullptr; QAction* showHelpMessageAction = nullptr; + QAction* m_open_wallet_action{nullptr}; QAction* m_wallet_selector_label_action = nullptr; QAction* m_wallet_selector_action = nullptr; -- cgit v1.2.3 From be82dea23c3e6931f9ae7ab8c6a8595ae950587f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Mon, 21 Jan 2019 16:57:22 +0000 Subject: gui: Add thread to run background activity in WalletController --- src/qt/walletcontroller.cpp | 8 +++++++- src/qt/walletcontroller.h | 2 ++ 2 files changed, 9 insertions(+), 1 deletion(-) (limited to 'src/qt') diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index 0730afca98..a103f4c89b 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -26,11 +26,17 @@ WalletController::WalletController(interfaces::Node& node, const PlatformStyle* for (std::unique_ptr& 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 WalletController::getWallets() const { diff --git a/src/qt/walletcontroller.h b/src/qt/walletcontroller.h index 523e47d27a..1664fa6f3f 100644 --- a/src/qt/walletcontroller.h +++ b/src/qt/walletcontroller.h @@ -13,6 +13,7 @@ #include #include +#include class OptionsModel; class PlatformStyle; @@ -51,6 +52,7 @@ Q_SIGNALS: 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; -- cgit v1.2.3 From 8847cdaaaeb45c1ddee89f43ac4b8fafb20e5c0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Mon, 21 Jan 2019 16:58:20 +0000 Subject: gui: Add OpenWalletActivity --- src/qt/bitcoin.cpp | 2 +- src/qt/bitcoingui.cpp | 4 +++- src/qt/walletcontroller.cpp | 36 ++++++++++++++++++++++++++---------- src/qt/walletcontroller.h | 27 ++++++++++++++++++++++++++- 4 files changed, 56 insertions(+), 13 deletions(-) (limited to 'src/qt') diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp index 85d79ee26c..d6c6fd6e98 100644 --- a/src/qt/bitcoin.cpp +++ b/src/qt/bitcoin.cpp @@ -456,7 +456,7 @@ int GuiMain(int argc, char* argv[]) // IMPORTANT if it is no longer a typedef use the normal variant above qRegisterMetaType< CAmount >("CAmount"); qRegisterMetaType< std::function >("std::function"); - + qRegisterMetaType("QMessageBox::Icon"); /// 2. Parse command-line options. We do this after qt in order to show an error if there are problems parsing these // Command-line options take precedence: node->setupServerArgs(); diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index e7279e1229..3622bd5657 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -371,7 +371,9 @@ void BitcoinGUI::createActions() QString name = path.empty() ? QString("["+tr("default wallet")+"]") : QString::fromStdString(path); QAction* action = m_open_wallet_action->menu()->addAction(name); connect(action, &QAction::triggered, [this, path] { - setCurrentWallet(m_wallet_controller->openWallet(path)); + OpenWalletActivity* activity = m_wallet_controller->openWallet(path); + connect(activity, &OpenWalletActivity::opened, this, &BitcoinGUI::setCurrentWallet); + connect(activity, &OpenWalletActivity::finished, activity, &QObject::deleteLater); }); } }); diff --git a/src/qt/walletcontroller.cpp b/src/qt/walletcontroller.cpp index a103f4c89b..3483c75970 100644 --- a/src/qt/walletcontroller.cpp +++ b/src/qt/walletcontroller.cpp @@ -55,17 +55,12 @@ std::vector WalletController::getWalletsAvailableToOpen() const return wallets; } -WalletModel* WalletController::openWallet(const std::string& name, QWidget* parent) +OpenWalletActivity* WalletController::openWallet(const std::string& name, QWidget* parent) { - std::string error, warning; - WalletModel* wallet_model = getOrCreateWallet(m_node.loadWallet(name, error, warning)); - if (!wallet_model) { - QMessageBox::warning(parent, tr("Open Wallet"), QString::fromStdString(error)); - } - if (!warning.empty()) { - QMessageBox::information(parent, tr("Open Wallet"), QString::fromStdString(warning)); - } - return wallet_model; + OpenWalletActivity* activity = new OpenWalletActivity(this, name); + activity->moveToThread(&m_activity_thread); + QMetaObject::invokeMethod(activity, "open", Qt::QueuedConnection); + return activity; } WalletModel* WalletController::getOrCreateWallet(std::unique_ptr wallet) @@ -124,3 +119,24 @@ void WalletController::removeAndDeleteWallet(WalletModel* wallet_model) // CWallet shared pointer. delete wallet_model; } + + +OpenWalletActivity::OpenWalletActivity(WalletController* wallet_controller, const std::string& name) + : m_wallet_controller(wallet_controller) + , m_name(name) +{} + +void OpenWalletActivity::open() +{ + std::string error, warning; + std::unique_ptr wallet = m_wallet_controller->m_node.loadWallet(m_name, error, warning); + if (!warning.empty()) { + Q_EMIT message(QMessageBox::Warning, QString::fromStdString(warning)); + } + if (wallet) { + Q_EMIT opened(m_wallet_controller->getOrCreateWallet(std::move(wallet))); + } else { + Q_EMIT message(QMessageBox::Critical, QString::fromStdString(error)); + } + Q_EMIT finished(); +} diff --git a/src/qt/walletcontroller.h b/src/qt/walletcontroller.h index 1664fa6f3f..f19c0e1f3d 100644 --- a/src/qt/walletcontroller.h +++ b/src/qt/walletcontroller.h @@ -12,6 +12,7 @@ #include #include +#include #include #include @@ -23,6 +24,8 @@ class Handler; class Node; } // namespace interfaces +class OpenWalletActivity; + /** * Controller between interfaces::Node, WalletModel instances and the GUI. */ @@ -40,7 +43,7 @@ public: std::vector getWallets() const; std::vector getWalletsAvailableToOpen() const; - WalletModel* openWallet(const std::string& name, QWidget* parent = nullptr); + OpenWalletActivity* openWallet(const std::string& name, QWidget* parent = nullptr); private Q_SLOTS: void addWallet(WalletModel* wallet_model); @@ -59,6 +62,28 @@ private: mutable QMutex m_mutex; std::vector m_wallets; std::unique_ptr m_handler_load_wallet; + + friend class OpenWalletActivity; +}; + +class OpenWalletActivity : public QObject +{ + Q_OBJECT + +public: + OpenWalletActivity(WalletController* wallet_controller, const std::string& name); + +public Q_SLOTS: + void open(); + +Q_SIGNALS: + void message(QMessageBox::Icon icon, const QString text); + void finished(); + void opened(WalletModel* wallet_model); + +private: + WalletController* const m_wallet_controller; + std::string const m_name; }; #endif // BITCOIN_QT_WALLETCONTROLLER_H -- cgit v1.2.3 From 1951ea4342db4122032660139248b79a02c574f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Barbosa?= Date: Tue, 22 Jan 2019 13:02:45 +0000 Subject: gui: Show indeterminate progress dialog while opening walllet --- src/qt/bitcoingui.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) (limited to 'src/qt') diff --git a/src/qt/bitcoingui.cpp b/src/qt/bitcoingui.cpp index 3622bd5657..f7a4bad916 100644 --- a/src/qt/bitcoingui.cpp +++ b/src/qt/bitcoingui.cpp @@ -370,10 +370,29 @@ void BitcoinGUI::createActions() for (std::string path : m_wallet_controller->getWalletsAvailableToOpen()) { QString name = path.empty() ? QString("["+tr("default wallet")+"]") : QString::fromStdString(path); QAction* action = m_open_wallet_action->menu()->addAction(name); - connect(action, &QAction::triggered, [this, path] { + connect(action, &QAction::triggered, [this, name, path] { OpenWalletActivity* activity = m_wallet_controller->openWallet(path); + + QProgressDialog* dialog = new QProgressDialog(this); + dialog->setLabelText(tr("Opening Wallet %1...").arg(name.toHtmlEscaped())); + dialog->setRange(0, 0); + dialog->setCancelButton(nullptr); + dialog->setWindowModality(Qt::ApplicationModal); + dialog->show(); + + connect(activity, &OpenWalletActivity::message, this, [this] (QMessageBox::Icon icon, QString text) { + QMessageBox box; + box.setIcon(icon); + box.setText(tr("Open Wallet Failed")); + box.setInformativeText(text); + box.setStandardButtons(QMessageBox::Ok); + box.setDefaultButton(QMessageBox::Ok); + connect(this, &QObject::destroyed, &box, &QDialog::accept); + box.exec(); + }); connect(activity, &OpenWalletActivity::opened, this, &BitcoinGUI::setCurrentWallet); connect(activity, &OpenWalletActivity::finished, activity, &QObject::deleteLater); + connect(activity, &OpenWalletActivity::finished, dialog, &QObject::deleteLater); }); } }); -- cgit v1.2.3